/*================================================================================ * Стратегия: Channel breakout RealTime * Платформа: TSLab версия 1.1.8.0 * Дата создания: 20.08.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.Breakout_RT { //================================================================================ public class System_Breakout_RT : IExternalScript { // используем переменные-флаги для сигналов public bool bBuy; // флаг сигнала открытия длинной позиции public bool bSell; // флаг сигнала закрытия длинной позиции public bool bShort; // флаг сигнала открытия короткой позиции public bool bCover; // флаг сигнала закрытия короткой позиции public IPosition LongPos, ShortPos; //================================================================================ // Параметры оптимизации // параметра для длинных позиций public OptimProperty LongOpenPeriodParam = new OptimProperty(14, 5, 30, 1); public OptimProperty LongClosePeriodParam = new OptimProperty(3, 2, 20, 1); public OptimProperty LongStopParam = new OptimProperty(1, 0.5, 10, 0.5); // параметра для коротких позиций public OptimProperty ShortOpenPeriodParam = new OptimProperty(7, 5, 30, 1); public OptimProperty ShortClosePeriodParam = new OptimProperty(3, 2, 20, 1); public OptimProperty ShortStopParam = new OptimProperty(1, 0.5, 10, 0.5); // параметра для объема позиций (длинных и коротких) public OptimProperty PositionVolumeParam = new OptimProperty(1, 1, 1, 1); //================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { int StartBar = 0; #region Variables // для длинных позиций // период расчета int LongOpenPeriod; // для открытия позиции int LongClosePeriod; // для закрытия позиции int LongStop; // размер стопа double BuyPrice; double SellPrice; double LongStopPrice; // для коротких позиций // период расчета int ShortOpenPeriod; // для открытия позиции int ShortClosePeriod; // для закрытия позиции int ShortStop; // размер стопа double ShortPrice; double CoverPrice; double ShortStopPrice; int PositionVolume; // объем позиции #endregion //-------------------------------------------------------------------------------- #region Obtain parameters LongOpenPeriod = LongOpenPeriodParam; LongClosePeriod = LongClosePeriodParam; LongStop = LongStopParam; ShortOpenPeriod = ShortOpenPeriodParam; ShortClosePeriod = ShortClosePeriodParam; ShortStop = ShortStopParam; PositionVolume = PositionVolumeParam; 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 nLongLow = ctx.GetData("LongLow", new[] {LongClosePeriod.ToString()}, delegate { return Series.Lowest(source.LowPrices, LongClosePeriod); }); // для коротких позиций // серия минимумов для открытия позиции IList nShortLow = ctx.GetData("ShortLow", new[] {ShortOpenPeriod.ToString()}, delegate { return Series.Lowest(source.LowPrices, ShortOpenPeriod); }); // серия максимумов для закрытия позиции IList nShortHigh = ctx.GetData("ShortHigh", new[] {ShortClosePeriod.ToString()}, delegate { return Series.Highest(source.HighPrices, ShortClosePeriod); }); #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; LongStopPrice = 0; ShortStopPrice = 0; // установка сигналов по условиям // для длинных позиций //bBuy = true; //bSell = true; BuyPrice = nLongHigh[bar]; SellPrice = nLongLow[bar]; LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos != null) { LongStopPrice = LongPos.EntryPrice * (1.0 - LongStop / 100.0); } if (LongStopPrice > 0 && LongStopPrice > SellPrice) SellPrice = LongStopPrice; // для коротких позиций //bShort = true; //bCover = true; ShortPrice = nShortLow[bar]; CoverPrice = nShortHigh[bar]; ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos != null) { ShortStopPrice = ShortPos.EntryPrice * (1.0 + ShortStop / 100.0); } if (ShortStopPrice > 0 && ShortStopPrice < CoverPrice) CoverPrice = ShortStopPrice; #endregion //================================================================================ #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции if (BuyPrice > 0) { // выдаем условный ордер на открытие новой длинной позиции. source.Positions.BuyIfGreater(bar+1, PositionVolume, BuyPrice, "LN"); LongPos = source.Positions.GetLastActiveForSignal("LN"); } if (LongPos == null && bBuy) { // Если нет активной длинной позиции // Если есть сигнал Buy, // выдаем ордер на открытие новой длинной позиции. source.Positions.BuyAtMarket(bar+1, PositionVolume, "LN"); } } else { // Если есть активная длинная позиция if (SellPrice > 0) { // выдаем условный ордер на закрытие длинной позиции. LongPos.CloseAtStop(bar+1, SellPrice, "LX"); } if (LongPos.IsActive && bSell) { // Если длинная позиция активна // Если есть сигнал Sell, // выдаем ордер на закрытие длинной позиции. LongPos.CloseAtMarket(bar+1, "LX"); } } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции if (ShortPrice > 0) { // выдаем условный ордер на открытие новой короткой позиции. source.Positions.SellIfLess(bar+1, PositionVolume, ShortPrice, "SN"); ShortPos = source.Positions.GetLastActiveForSignal("SN"); } if (ShortPos == null && bShort) { // Если нет активной короткой позиции // Если есть сигнал Short // выдаем ордер на открытие новой короткой позиции. source.Positions.SellAtMarket(bar+1, PositionVolume, "SN"); } } else { // Если есть активная короткая позиция, if (CoverPrice > 0) { // выдаем условный ордер на закрытие короткой позиции. ShortPos.CloseAtStop(bar+1, CoverPrice, "SX"); } if (ShortPos.IsActive && bSell) { // Если короткая позиция активна // Если есть сигнал Sell, // выдаем ордер на закрытие короткой позиции. ShortPos.CloseAtMarket(bar+1, "SX"); } } #endregion } #endregion //================================================================================ #region прорисовка графиков // Берем основную панель (Pane) IPane mainPane = ctx.First; // для длинных позиций mainPane.AddList("LongHigh", nLongHigh, ListStyles.LINE, 0x0000a0, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("LongLow", nLongLow, ListStyles.LINE, 0x007070, LineStyles.DOT, PaneSides.RIGHT); // для коротких позиций mainPane.AddList("ShortLow", nShortLow, ListStyles.LINE, 0xa00000, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("ShortHigh", nShortHigh, ListStyles.LINE, 0x700070, LineStyles.DOT, PaneSides.RIGHT); #endregion //-------------------------------------------------------------------------------- } } }