using System.Linq; using TSLab.Script; using TSLab.Script.Handlers; using TSLab.Script.Helpers; using TSLab.Script.Optimization; using static TSLab.Script.ScriptColors; namespace GanovCubes { public class TemplateNew : IExternalScript { #region Fields private readonly ScriptData sd; private int _firstUsedBar = 1; private readonly int lots = 1; private const string nameSignalLE = "LEMK"; private const string nameSignalSE = "SEMK"; #endregion #region OptimParams // CommonParams public StringOptimProperty _TradeName = new("BaseScriptName"); public OptimProperty _ComIterInitilazer = new(1, 1, 1000, 1); public BoolOptimProperty _WriteLog = new(true); public IntOptimProperty _CompressRatioMinutes = new(5, 5, 60, 5); // TradeParams public OptimProperty SMAShort_Period = new(10, 10, 160, 25, 0); public OptimProperty SMALong_Period = new(20, 20, 350, 30, 0); #endregion public TemplateNew() => sd = new ScriptData(this) { WriteLog = _WriteLog }; public void Execute(IContext ctx, ISecurity sec) { sd.Execute(ctx, sec, _CompressRatioMinutes); #region AdditionalCubes var crossUp = new CrossUnder() { Context = ctx }; var crossDown = new CrossOver() { Context = ctx }; #endregion #region Indicators // Индикаторы инициализация // Индикаторы расчет var smaShortCompr = ctx.GetData("smaShort", new string[] { SMAShort_Period.ToString() }, () => Series.SMA(sd.SecCompressed.ClosePrices, SMAShort_Period)); var smaShortBase = sd.SecCompressed.Decompress(smaShortCompr); var smaLongCompr = ctx.GetData("smaLong", new string[] { SMALong_Period.ToString() }, () => Series.SMA(sd.SecCompressed.ClosePrices, SMALong_Period)); var smaLongBase = sd.SecCompressed.Decompress(smaLongCompr); var crossUpCondCompr = ctx.GetData("CrossUp", new string[] { SMAShort_Period.ToString(), SMALong_Period.ToString() }, () => crossUp.Execute(smaLongCompr, smaShortCompr)); var crossDownCondCompr = ctx.GetData("CrossDown", new string[] { SMAShort_Period.ToString(), SMALong_Period.ToString() }, () => crossUp.Execute(smaShortCompr, smaLongCompr)); var crossUpCondBase = sd.SecCompressed.Decompress(crossUpCondCompr, TSLab.DataSource.DecompressMethodWithDef.Default); var crossDownCondBase = sd.SecCompressed.Decompress(crossDownCondCompr, TSLab.DataSource.DecompressMethodWithDef.Default); // Устанавливаем первый бар для торговли var indicatorsPeriods = new int[] { SMAShort_Period*_CompressRatioMinutes, SMALong_Period*_CompressRatioMinutes, }; _firstUsedBar = indicatorsPeriods.Max(); #endregion // TODO: в случае если появился сигнал на выход, то сохраняем его пока фактически не произошло выхода // то есть между пересчетами также сохраняем for (int bar = _firstUsedBar; bar <= sd.LastBarNum; bar++) { sd.ExecuteOnBar(bar); #region TradeLogic var posLE = sec.Positions.GetLastActiveForSignal(nameSignalLE, bar); var posSE = sec.Positions.GetLastActiveForSignal(nameSignalSE, bar); // Long if (posLE == null) { var signalLE = crossUpCondBase[bar]; // Фильтры var filterContrPos = posSE != null; // signalLE &= filterContrPos; if (signalLE) sec.Positions.BuyAtMarket(bar + 1, lots, nameSignalLE); } else { var signalLX = crossDownCondBase[bar]; if (signalLX) posLE.CloseAtMarket(bar + 1, "LXMK"); } // Short if (posSE == null) { var signalSE = crossDownCondBase[bar]; var filterContrPos = posLE != null; // signalSE &= filterContrPos; if (signalSE) sec.Positions.SellAtMarket(bar + 1, lots, nameSignalSE); } else { var signalSX = crossUpCondBase[bar]; if (signalSX) posSE.CloseAtMarket(bar + 1, "SXMK"); } #endregion } #region Graphs if (!ctx.IsOptimization) { var secPane = ctx.GetSecPane(sec, sd.SecCompressed, 255, "base"); // Индикаторы secPane.AddList(smaShortCompr.GetHashCode().ToString(), "smaShort", smaShortBase, ListStyles.LINE, Red, LineStyles.SOLID, PaneSides.RIGHT); secPane.AddList(smaLongCompr.GetHashCode().ToString(), "smaLong", smaLongBase, ListStyles.LINE, DarkBlue, LineStyles.SOLID, PaneSides.RIGHT); var crossUpCondBaseList = secPane.AddList(crossUpCondBase.GetHashCode().ToString(), "crossUpCondBase", crossUpCondBase, ListStyles.HISTOHRAM, DarkGreen, LineStyles.SOLID, PaneSides.LEFT); crossUpCondBaseList.Opacity = 200; var crossDownCondBaseList = secPane.AddList(crossDownCondBase.GetHashCode().ToString(), "crossDownCondBase", crossDownCondBase, ListStyles.HISTOHRAM, DarkRed, LineStyles.SOLID, PaneSides.LEFT); crossDownCondBaseList.Opacity = 200; } #endregion } } }