/*================================================================================ * Стратегия: Donchian breakout * Платформа: TSLab версия 1.1.8.0 * Дата создания: 02.09.2010 * Реализовано: Laber *================================================================================*/ using System; using System.Collections.Generic; using TSLab.Script; using TSLab.Script.Handlers; using TSLab.Script.Optimization; using TSLab.Script.Helpers; namespace TSLab.Donchian_breakout { //================================================================================ public class System_Donchian_breakout : IExternalScript { // используем переменные-флаги для сигналов public bool bBuy; // флаг сигнала открытия длинной позиции public bool bSell; // флаг сигнала закрытия длинной позиции public bool bShort; // флаг сигнала открытия короткой позиции public bool bCover; // флаг сигнала закрытия короткой позиции public IPosition LongPos, ShortPos; //================================================================================ // функция вычисления (последовательность значений) public IList GenValue(ISecurity source) { double vValue = 0; // серия значений IList nValue = new List(source.Bars.Count); for (int bar = 0; bar < source.Bars.Count; bar++) { vValue = source.HighPrices[bar] - source.LowPrices[bar]; //-------------------------------------------------------------------------------- // добавление нового значения в последовательность nValue.Add(vValue); } return nValue; } //================================================================================ // Параметры оптимизации // параметра для длинных позиций public OptimProperty LongOpenPeriodParam = new OptimProperty(6, 4, 20, 2); public OptimProperty LongClosePeriodParam = new OptimProperty(16, 2, 20, 1); public OptimProperty LongStepParam = new OptimProperty(3, 1, 5, 1); // параметра для коротких позиций public OptimProperty ShortOpenPeriodParam = new OptimProperty(16, 4, 20, 2); public OptimProperty ShortClosePeriodParam = new OptimProperty(19, 2, 20, 1); public OptimProperty ShortStepParam = new OptimProperty(1, 1, 5, 1); //================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { int StartBar = 0; #region Variables // для длинных позиций // период расчета int LongOpenPeriod; // для открытия позиции int LongClosePeriod; // для закрытия позиции int LongLowPeriod; int LongStep; double vLow; double BuyPrice; double SellPrice; // для коротких позиций // период расчета int ShortOpenPeriod; // для открытия позиции int ShortClosePeriod; // для закрытия позиции int ShortHighPeriod; int ShortStep; double vHigh; double ShortPrice; double CoverPrice; #endregion //-------------------------------------------------------------------------------- #region Obtain parameters LongOpenPeriod = LongOpenPeriodParam; LongClosePeriod = LongClosePeriodParam; LongLowPeriod = LongClosePeriod; LongStep = LongStepParam; ShortOpenPeriod = ShortOpenPeriodParam; ShortClosePeriod = ShortClosePeriodParam; ShortHighPeriod = ShortClosePeriod; ShortStep = ShortStepParam; StartBar = LongOpenPeriod; if (LongClosePeriod > StartBar) StartBar = LongClosePeriod; if (ShortOpenPeriod > StartBar) StartBar = ShortOpenPeriod; if (ShortClosePeriod > StartBar) StartBar = ShortClosePeriod; // Вычисляем верхнюю и нижнюю границы // Используем GetData для кеширования данных и ускорения оптимизации. // для длинных позиций // серия для максимумов для открытия позиции IList nLongHigh = ctx.GetData("LongHigh", new[] {LongOpenPeriod.ToString()}, delegate { return Series.Highest(source.HighPrices, LongOpenPeriod); }); // для коротких позиций // серия для минимумов для открытия позиции IList nShortLow = ctx.GetData("ShortLow", new[] {ShortOpenPeriod.ToString()}, delegate { return Series.Lowest(source.LowPrices, ShortOpenPeriod); }); #endregion //================================================================================ #region основной цикл - проход по барам int barsCount = source.Bars.Count; for (int bar = StartBar; bar < barsCount-1; bar++) { //-------------------------------------------------------------------------------- #region calculate values #endregion //-------------------------------------------------------------------------------- #region generate signals // сброс значений сигналов bBuy = false; bSell = false; bShort = false; bCover = false; BuyPrice = 0; SellPrice = 0; ShortPrice = 0; CoverPrice = 0; BuyPrice = nLongHigh[bar]; ShortPrice = nShortLow[bar]; if (LongPos != null) { LongLowPeriod = LongLowPeriod - LongStep; if (LongLowPeriod < 1) LongLowPeriod = 1; vLow = source.LowPrices[bar]; for (int i=0; i vHigh) vHigh = source.HighPrices[bar-i]; } CoverPrice = vHigh; } // установка сигналов по условиям // для длинных позиций //bBuy = true; //bSell = true; // для коротких позиций //bShort = true; //bCover = true; #endregion //================================================================================ #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции if (BuyPrice > 0) { // Если есть сигнал Buy, // выдаем условный ордер на открыте новой длинной позиции. source.Positions.BuyIfGreater(bar+1, 1, BuyPrice, "LN"); } LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos != null) LongLowPeriod = LongClosePeriod; } else { // Если есть активная длинная позиция if (SellPrice > 0) { // Если есть сигнал Sell, // выдаем условный ордер на закрыте длинной позиции. LongPos.CloseAtStop(bar+1, SellPrice, "LX"); } } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции if (ShortPrice > 0) { // Если есть сигнал Short // выдаем условный ордер на открыте новой короткой позиции. source.Positions.SellIfLess(bar+1, 1, ShortPrice, "SN"); } ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos != null) ShortHighPeriod = ShortClosePeriod; } else { // Если есть активная короткая позиция, if (CoverPrice > 0) { // Если есть сигнал Cover // выдаем условный ордер на закрыте короткой позиции. ShortPos.CloseAtStop(bar+1, CoverPrice, "SX"); } } #endregion } #endregion //================================================================================ #region прорисовка графиков // Берем основную панель (Pane) IPane mainPane = ctx.First; // для длинных позиций // Отрисовка скользящих средних mainPane.AddList("LongHigh", nLongHigh, ListStyles.LINE, 0x0000a0, LineStyles.DOT, PaneSides.RIGHT); // для коротких позиций // Отрисовка скользящих средних mainPane.AddList("ShortLow", nShortLow, ListStyles.LINE, 0xa00000, LineStyles.DOT, PaneSides.RIGHT); #endregion //-------------------------------------------------------------------------------- } } }