/*================================================================================ * Стратегия: KT trading system * Платформа: TSLab версия 1.1.8.0 * Дата создания: 16.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.KT_trading { //================================================================================ public class System_KT_trading : IExternalScript { // используем переменные-флаги для сигналов public bool bBuy; // флаг сигнала открытия длинной позиции public bool bSell; // флаг сигнала закрытия длинной позиции public bool bShort; // флаг сигнала открытия короткой позиции public bool bCover; // флаг сигнала закрытия короткой позиции public IPosition LongPos, ShortPos; //================================================================================ // функция вычисления StochK (последовательность значений) public IList GenStochK(ISecurity source, int Period) { var high = Series.Highest(source.HighPrices, Period); var low = Series.Lowest(source.LowPrices, Period); IList nValue = new List(source.Bars.Count); for (int i = 0; i < source.Bars.Count; i++) { var stochK = 100 * (source.ClosePrices[i] - low[i]) / (high[i] - low[i]); nValue.Add(stochK); } return nValue; } //================================================================================ // функция вычисления (последовательность значений) public IList GenValue(ISecurity source, int Period) { 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 LongPeriodParam = new OptimProperty(10, 5, 50, 5); public OptimProperty LongTriggerParam = new OptimProperty(5, 5, 20, 5); public OptimProperty LongStartParam = new OptimProperty(10, 5, 20, 2); public OptimProperty LongStepParam = new OptimProperty(5, 2, 10, 2); // параметра для коротких позиций public OptimProperty ShortPeriodParam = new OptimProperty(15, 5, 50, 5); //================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { int StartBar = 0; #region Variables // для длинных позиций // период расчета int LongPeriod; // для открытия позиции int LongTrigger; int LongStart; int LongStep; int LongS1Period; int LongS2Period; int LongS3Period; int LongS4Period; int LongS5Period; bool bLT1, bLT2, bLT3, bLT4, bLT5; // для коротких позиций // период расчета int ShortPeriod; // для открытия позиции #endregion //-------------------------------------------------------------------------------- #region Obtain parameters LongPeriod = LongPeriodParam; LongTrigger = LongTriggerParam; LongStart = LongStartParam; LongStep = LongStepParam; LongS1Period = LongStart; LongS2Period = LongS1Period + LongStep; LongS3Period = LongS2Period + LongStep; LongS4Period = LongS3Period + LongStep; LongS5Period = LongS4Period + LongStep; ShortPeriod = ShortPeriodParam; StartBar = LongPeriod; if (LongS5Period > StartBar) StartBar = LongS5Period; if (ShortPeriod > StartBar) StartBar = ShortPeriod; // Вычисляем верхнюю и нижнюю границы // Используем GetData для кеширования данных и ускорения оптимизации. // для длинных позиций // серия для простой скользящей средней SMA для открытия позиции IList nLongSMA = ctx.GetData("LongSMA", new[] {LongPeriod.ToString()}, delegate { return Series.SMA(source.ClosePrices, LongPeriod); }); IList nLongS1 = ctx.GetData("LongStoch1", new[] {LongS1Period.ToString()}, delegate { return GenStochK(source, LongS1Period); }); IList nLongS2 = ctx.GetData("LongStoch2", new[] {LongS2Period.ToString()}, delegate { return GenStochK(source, LongS2Period); }); IList nLongS3 = ctx.GetData("LongStoch3", new[] {LongS3Period.ToString()}, delegate { return GenStochK(source, LongS3Period); }); IList nLongS4 = ctx.GetData("LongStoch4", new[] {LongS4Period.ToString()}, delegate { return GenStochK(source, LongS4Period); }); IList nLongS5 = ctx.GetData("LongStoch5", new[] {LongS5Period.ToString()}, delegate { return GenStochK(source, LongS5Period); }); // для коротких позиций // серия для простой скользящей средней SMA для открытия позиции IList nShortSMA = ctx.GetData("ShortSMA", new[] {ShortPeriod.ToString()}, delegate { return Series.SMA(source.ClosePrices, ShortPeriod); }); #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; // установка сигналов по условиям // для длинных позиций bLT1 = (nLongS1[bar] < LongTrigger); bLT2 = (nLongS2[bar] < LongTrigger); bLT3 = (nLongS3[bar] < LongTrigger); bLT4 = (nLongS4[bar] < LongTrigger); bLT5 = (nLongS5[bar] < LongTrigger); if (bLT1 && bLT2 && bLT3 && bLT4 && bLT5) { bBuy = true; } LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos != null) { if ((bar - LongPos.EntryBarNum) > LongPeriod) bSell = true; } #endregion //================================================================================ #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции if (bBuy) { // Если есть сигнал Buy, // выдаем ордер на открыте новой длинной позиции. source.Positions.BuyAtMarket(bar+1, 1, "LN"); } } else { // Если есть активная длинная позиция if (bSell) { // Если есть сигнал Sell, // выдаем ордер на закрыте длинной позиции. LongPos.CloseAtMarket(bar+1, "LX"); } } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции if (bShort) { // Если есть сигнал Short // выдаем ордер на открыте новой короткой позиции. source.Positions.SellAtMarket(bar+1, 1, "SN"); } } else { // Если есть активная короткая позиция, if (bCover) { // Если есть сигнал Cover // выдаем ордер на закрыте короткой позиции. ShortPos.CloseAtMarket(bar+1, "SX"); } } #endregion } #endregion //================================================================================ #region прорисовка графиков // Берем основную панель (Pane) IPane mainPane = ctx.First; // для длинных позиций // Отрисовка скользящих средних mainPane.AddList("LongSMA", nLongSMA, ListStyles.LINE, 0x00a0a0, LineStyles.DOT, PaneSides.RIGHT); // для коротких позиций // Отрисовка скользящих средних mainPane.AddList("ShortSMA", nShortSMA, ListStyles.LINE, 0xa000a0, LineStyles.DOT, PaneSides.RIGHT); // Создаем дополнительную панель для индикатора. IPane LSPane = ctx.CreatePane("LongStoch", 10, false, false); // Отрисовка графика индикатора LSPane.AddList(string.Format("Stoch 1"), nLongS1, ListStyles.LINE, 0x5050f0, LineStyles.SOLID, PaneSides.RIGHT); LSPane.AddList(string.Format("Stoch 2"), nLongS2, ListStyles.LINE, 0x5050f0, LineStyles.SOLID, PaneSides.RIGHT); LSPane.AddList(string.Format("Stoch 3"), nLongS3, ListStyles.LINE, 0x5050f0, LineStyles.SOLID, PaneSides.RIGHT); LSPane.AddList(string.Format("Stoch 4"), nLongS4, ListStyles.LINE, 0x5050f0, LineStyles.SOLID, PaneSides.RIGHT); LSPane.AddList(string.Format("Stoch 5"), nLongS5, ListStyles.LINE, 0x5050f0, LineStyles.SOLID, PaneSides.RIGHT); #endregion //-------------------------------------------------------------------------------- } } }