/*================================================================================ * Стратегия: High-Low с фильтром на основе NRTR * Платформа: TSLab версия 1.1.7.0 * Дата создания: 01.07.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.High_Low_NRTR { public class System_High_Low_NRTR : IExternalScript { //================================================================================ // функция вычисления индикатора NRTR (последовательность значений) // Period - период скользящей средней для расчета NRTR // Multiple - множитель для расчета NRTR public IList GenNRTR(ISecurity source, int Period, double Multiple) { double vNRTR; double K, PrevK; double Reverse = 0; double Price; double HighPrice; double LowPrice; int Trend = 0; int NewTrend; IList nNRTR = new List(source.Bars.Count); //-------------------------------------------------------------------------------- K = source.ClosePrices[0]; vNRTR = source.ClosePrices[0]; HighPrice = source.HighPrices[0]; LowPrice = source.LowPrices[0]; for (int bar = 0; bar < source.Bars.Count-1; bar++) { //-------------------------------------------------------------------------------- #region calculate values Price = source.ClosePrices[bar]; PrevK = K; K = (PrevK + (Price - PrevK) / Period) * Multiple; NewTrend = 0; if (Trend >= 0) { if (Price > HighPrice) HighPrice = Price; Reverse = HighPrice - K; if (Price <= Reverse) { NewTrend = -1; LowPrice = Price; Reverse = LowPrice + K; } } if (Trend <= 0) { if (Price < LowPrice) LowPrice = Price; Reverse = LowPrice + K; if (Price >= Reverse) { NewTrend = +1; HighPrice = Price; Reverse = HighPrice - K; } } if (NewTrend != 0) Trend = NewTrend; // значение NRTR vNRTR = Reverse; #endregion //-------------------------------------------------------------------------------- // добавление нового значения в последовательность nNRTR.Add(vNRTR); } return nNRTR; } //================================================================================ // Параметры оптимизации задаются при помощи типа OptimProperty. // Параметры оптимизации для длинных позиций public OptimProperty High1Period = new OptimProperty(85, 10, 100, 5); public OptimProperty Low1Period = new OptimProperty(60, 10, 100, 5); // Параметры оптимизации для коротких позици public OptimProperty Low2Period = new OptimProperty(70, 10, 100, 5); public OptimProperty High2Period = new OptimProperty(85, 10, 100, 5); // Параметры оптимизации для расчета индикатора NRMA // ParamPeriod - параметр оптимизации для периода скользящей средней // ParamMultiple - параметр оптимизации для множителя public OptimProperty ParamPeriod = new OptimProperty(10, 2, 20, 2); public OptimProperty ParamMultiple = new OptimProperty(0.1, 0.1, 1, 0.1); //================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { #region Variables int MDir; // напраление индикатора NRTR (+1 вверх, -1 вниз) double vNRTR; // значение NRTR для текущего бара int Period; // период скользящей средней для расчета NRTR double Multiple; // множитель для расчета NRTR double Price; // текущая цена закрытия #endregion //-------------------------------------------------------------------------------- // Obtain parameters Period = ParamPeriod; Multiple = ParamMultiple; MDir = 0; // серия значений индикатора NRTR // кэширование с учетом параметров Period и Multiple IList nNRTR = ctx.GetData("NRTR", new[] {Period.ToString()+"_"+Multiple.ToString()}, delegate { return GenNRTR(source, Period, Multiple); }); // серия значений для направления скользящей средней IList nMDir = new List(source.Bars.Count); //================================================================================ #region Вычисляем максимумы и минимумы. // Используем GetData для кеширования данных и ускорения оптимизация. // При неиспользовании кэша увеличивается объем обрабатываемых данных, что ведет к сильному замедлению оптимизации. // Следует учесть, что необходимо перечислить абсолютно все изменяемые переменные используемые в вычислениях. // Не соблюдение этого правила приведет к некорректной работе и результатам оптимизации. IList high1 = ctx.GetData("Highest", new[] {High1Period.ToString()}, delegate { return Series.Highest(source.HighPrices, High1Period); }); IList low1 = ctx.GetData("Lowest", new[] {Low1Period.ToString()}, delegate { return Series.Lowest(source.LowPrices, Low1Period); }); IList high2 = ctx.GetData("Highest", new[] {High2Period.ToString()}, delegate { return Series.Highest(source.HighPrices, High2Period); }); IList low2 = ctx.GetData("Lowest", new[] {Low2Period.ToString()}, delegate { return Series.Lowest(source.LowPrices, Low2Period); }); #endregion // ================================================= #region прорисовка графиков // Берем основную панель (Pane). IPane mainPane = ctx.First; // Отрисовка графиков. mainPane.AddList(string.Format("High1({0}) [{1}]", High1Period, source.Symbol), high1, ListStyles.LINE, 0x00ff00, LineStyles.SOLID, PaneSides.RIGHT); mainPane.AddList(string.Format("Low1({0}) [{1}]", Low1Period, source.Symbol), low1, ListStyles.LINE, 0xff0000, LineStyles.SOLID, PaneSides.RIGHT); mainPane.AddList(string.Format("Low2({0}) [{1}]", Low2Period, source.Symbol), low2, ListStyles.LINE, 0xff0000, LineStyles.DASH, PaneSides.RIGHT); mainPane.AddList(string.Format("High2({0}) [{1}]", High2Period, source.Symbol), high2, ListStyles.LINE, 0x00ff00, LineStyles.DASH, PaneSides.RIGHT); mainPane.AddList("NRTR", nNRTR, ListStyles.LINE, 0xa000a0, LineStyles.SOLID, PaneSides.RIGHT); #endregion // ================================================= #region Основной цикл обработки (торговля). int barsCount = source.Bars.Count; for (int bar = 0; (bar < barsCount-1); bar++) { //-------------------------------------------------------------------------------- #region calculate values // значение NRTR vNRTR = nNRTR[bar]; Price = source.ClosePrices[bar]; // изменение направления индикатора NRTR if ((MDir > -1) && (vNRTR < Price)) MDir = -1; if ((MDir < 1) && (vNRTR > Price)) MDir = 1; // добавление новых значений в последовательность nMDir.Add(MDir); #endregion //-------------------------------------------------------------------------------- #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции IPosition LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции, if (MDir > 0) { // если направление индикатора NRMA вверх // выдаем условный ордер на открыте новой длинной позиции. source.Positions.BuyIfGreater(bar + 1, 1, high1[bar], "LN"); } } else { // Если есть активная длинная позиция, // выдаем условный ордер на закрыте длинной позиции. LongPos.CloseAtStop(bar + 1, low1[bar], "LX"); } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции IPosition ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции, if (MDir < 0) { // если направление индикатора NRMA вниз // выдаем условный ордер на открыте новой короткой позиции. source.Positions.SellIfLess(bar + 1, 1, low2[bar], "SN"); } } else { // Если есть активная короткая позиция, // выдаем условный ордер на закрыте короткой позиции. ShortPos.CloseAtStop(bar + 1, high2[bar], "SX"); } #endregion } #endregion //================================================================================ #region прорисовка графиков // Создаем дополнительную панель. IPane FilterPane = ctx.CreatePane("Filtr", 10, false, false); // Отрисовка графика фильтра позиции FilterPane.AddList(string.Format("Filter NRTR"), nMDir, ListStyles.LINE, 0x00ff00, LineStyles.SOLID, PaneSides.RIGHT); #endregion // ================================================= } } }