/*================================================================================ * Стратегия: Trendfollower (channel breakout, stop-loss with ATR) * Платформа: TSLab версия 1.1.8.0 * Дата создания: 19.07.2010 * Реализовано: Laber *================================================================================*/ using System.Collections.Generic; using TSLab.Script; using TSLab.Script.Handlers; using TSLab.Script.Optimization; using TSLab.Script.Helpers; namespace TSLab.Trendfollower { public class System_Trendfollower : IExternalScript { public IPosition LongPos, ShortPos; // Параметры оптимизации задаются при помощи типа OptimProperty. // Параметры оптимизации для длинных позиций public OptimProperty LongHighPeriod = new OptimProperty(25, 10, 100, 5); public OptimProperty LongLowPeriod = new OptimProperty(20, 10, 100, 5); public OptimProperty LongATRPeriod = new OptimProperty(12, 5, 35, 2); public OptimProperty LongStopKoef = new OptimProperty(3, 1, 10, 0.5); // Параметры оптимизации для коротких позици public OptimProperty ShortLowPeriod = new OptimProperty(20, 10, 100, 5); public OptimProperty ShortHighPeriod = new OptimProperty(25, 10, 100, 5); public OptimProperty ShortATRPeriod = new OptimProperty(12, 5, 35, 2); public OptimProperty ShortStopKoef = new OptimProperty(4, 1, 10, 0.5); public virtual void Execute(IContext ctx, ISecurity source) { #region Вычисляем максимумы и минимумы. // Используем GetData для кеширования данных и ускорения оптимизация. IList nLongHigh = ctx.GetData("LongHigh", new[] {LongHighPeriod.ToString()}, delegate { return Series.Highest(source.HighPrices, LongHighPeriod); }); IList nLongLow = ctx.GetData("LongLow", new[] {LongLowPeriod.ToString()}, delegate { return Series.Lowest(source.LowPrices, LongLowPeriod); }); // серия для ATR IList nLongATR = ctx.GetData("LongATR", new[] {LongATRPeriod.ToString()}, delegate { return Series.AverageTrueRange(source.Bars, LongATRPeriod); }); IList nShortHigh = ctx.GetData("ShortHigh", new[] {ShortHighPeriod.ToString()}, delegate { return Series.Highest(source.HighPrices, ShortHighPeriod); }); IList nShortLow = ctx.GetData("ShortLow", new[] {ShortLowPeriod.ToString()}, delegate { return Series.Lowest(source.LowPrices, ShortLowPeriod); }); // серия для ATR IList nShortATR = ctx.GetData("ShortATR", new[] {ShortATRPeriod.ToString()}, delegate { return Series.AverageTrueRange(source.Bars, ShortATRPeriod); }); #endregion // ================================================= #region Variables double BuyPrice; // цена открытия длинной позиции double ShortPrice; // цена открытия короткой позиции double SellPrice; // цена закрытия длинной позиции double CoverPrice; // цена закрытия короткой позиции double LongStopPrice; // цена скользящего стопа длинной позиции double ShortStopPrice; // цена скользящего стопа короткой позиции // серия значений стоп-цены длинной позиции IList nLongStopPrice = new List(source.Bars.Count); // серия значений стоп-цены короткой позиции IList nShortStopPrice = new List(source.Bars.Count); #endregion //-------------------------------------------------------------------------------- #region Init vars // начальные значения переменным задавать не обязательно // при открытии позиции переменным задаются реальные значения #endregion // ================================================= // ================================================= #region Основной цикл обработки (торговля). int barsCount = source.Bars.Count; for (int bar = 0; (bar < barsCount); bar++) { BuyPrice = nLongHigh[bar]; SellPrice = nLongLow[bar]; ShortPrice = nShortLow[bar]; CoverPrice = nShortHigh[bar]; LongStopPrice = 0; ShortStopPrice = 0; if (LongPos != null) { LongStopPrice = LongPos.EntryPrice - LongStopKoef * nLongATR[bar]; if (LongStopPrice > SellPrice) SellPrice = LongStopPrice; } if (ShortPos != null) { ShortStopPrice = ShortPos.EntryPrice + ShortStopKoef * nShortATR[bar]; if (ShortStopPrice < CoverPrice) CoverPrice = ShortStopPrice; } // выполнение сигналов для длинной позиции LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции, // выдаем условный ордер на открыте новой длинной позиции. source.Positions.BuyIfGreater(bar + 1, 1, BuyPrice, "LN"); } else { // Если есть активная длинная позиция, // выдаем условный ордер на закрыте длинной позиции. LongPos.CloseAtStop(bar + 1, SellPrice, "LX"); } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции, // выдаем условный ордер на открыте новой короткой позиции. source.Positions.SellIfLess(bar + 1, 1, ShortPrice, "SN"); } else { // Если есть активная короткая позиция, // выдаем условный ордер на закрыте короткой позиции. ShortPos.CloseAtStop(bar + 1, CoverPrice, "SX"); } // добавляем значения стопов для текущего бара в соответствующие серии nLongStopPrice.Add(LongStopPrice); nShortStopPrice.Add(ShortStopPrice); } #endregion // ================================================= #region прорисовка графиков // Берем основную панель (Pane). IPane mainPane = ctx.First; // Отрисовка графиков. mainPane.AddList(string.Format("Long High({0}) [{1}]", LongHighPeriod, source.Symbol), nLongHigh, ListStyles.LINE, 0x00ff00, LineStyles.SOLID, PaneSides.RIGHT); mainPane.AddList(string.Format("Long Low({0}) [{1}]", LongLowPeriod, source.Symbol), nLongLow, ListStyles.LINE, 0xff0000, LineStyles.SOLID, PaneSides.RIGHT); mainPane.AddList(string.Format("Short Low({0}) [{1}]", ShortLowPeriod, source.Symbol), nShortLow, ListStyles.LINE, 0xff0000, LineStyles.DASH, PaneSides.RIGHT); mainPane.AddList(string.Format("Short High({0}) [{1}]", ShortHighPeriod, source.Symbol), nShortHigh, ListStyles.LINE, 0x00ff00, LineStyles.DASH, PaneSides.RIGHT); // прорисовка стопов //mainPane.AddList("LongStop", nLongStopPrice, ListStyles.LINE, 0xff00a0, LineStyles.SOLID, PaneSides.RIGHT); //mainPane.AddList("ShortStop", nShortStopPrice, ListStyles.LINE, 0xa000ff, LineStyles.SOLID, PaneSides.RIGHT); // Создаем дополнительную панель для индикатора ATR. IPane ATRPane = ctx.CreatePane("ATR", 10, false, false); // Отрисовка графика индикатора ATRPane.AddList(string.Format("LongATR"), nLongATR, ListStyles.LINE, 0x5050f0, LineStyles.SOLID, PaneSides.RIGHT); ATRPane.AddList(string.Format("ShortATR"), nShortATR, ListStyles.LINE, 0xf05050, LineStyles.SOLID, PaneSides.RIGHT); #endregion } } }