コード例 #1
0
        private void InitInteractiveSimpleLine(IGraphPane pane)
        {
            var id = Value.Data.GetId();

            m_interactiveSimpleLine = (IInteractiveSimpleLine)pane.GetInteractiveObject(id);
            var         intColor = ColorParser.Parse(Color);
            MarketPoint marketPosition;

            if (m_interactiveSimpleLine != null)
            {
                marketPosition = new MarketPoint(m_interactiveSimpleLine.MarketPosition.X, Value.Value);
                if (m_interactiveSimpleLine.PaneSides == PaneSide && m_interactiveSimpleLine.Color == intColor)
                {
                    m_interactiveSimpleLine.Thickness      = Thickness;
                    m_interactiveSimpleLine.MarketPosition = marketPosition;
                    pane.AddUnremovableInteractiveObjectId(id);
                    return;
                }
                pane.RemoveInteractiveObject(id);
            }
            else
            {
                marketPosition = new MarketPoint(DateTime.UtcNow, Value.Value);
            }

            m_interactiveSimpleLine           = pane.AddInteractiveSimpleLine(id, PaneSide, false, intColor, InteractiveSimpleLineMode.Horizontal, marketPosition);
            m_interactiveSimpleLine.Thickness = Thickness;
        }
コード例 #2
0
        private IInteractiveLine GetInteractiveLine(IGraphPane pane, IReadOnlyList <IDataBar> bars)
        {
            var minDate              = bars.First().Date;
            var maxDate              = bars.Last().Date;
            var interactiveLine      = (IInteractiveLine)pane.GetInteractiveObject(VariableId);
            var intColor             = ColorParser.Parse(Color);
            var firstMarketPosition  = new MarketPoint(FirstDateTime.Value, FirstValue.Value);
            var secondMarketPosition = new MarketPoint(SecondDateTime.Value, SecondValue.Value);

            if (interactiveLine != null)
            {
                interactiveLine.ExecutionDataBars = bars;
                CorrectMarketPointsEx(ref firstMarketPosition, ref secondMarketPosition, minDate, maxDate);

                if (interactiveLine.PaneSides == PaneSide && interactiveLine.Color == intColor && interactiveLine.Mode == Mode)
                {
                    pane.AddUnremovableInteractiveObjectId(VariableId);
                    interactiveLine.Thickness = Thickness;
                    interactiveLine.FirstPoint.MarketPosition  = firstMarketPosition;
                    interactiveLine.SecondPoint.MarketPosition = secondMarketPosition;
                    return(m_interactiveLine = interactiveLine);
                }
                pane.RemoveInteractiveObject(VariableId);
            }
            else
            {
                CorrectMarketPointsEx(ref firstMarketPosition, ref secondMarketPosition, minDate, maxDate);
            }

            m_interactiveLine                   = pane.AddInteractiveLine(VariableId, PaneSide, false, intColor, Mode, firstMarketPosition, secondMarketPosition);
            m_interactiveLine.Thickness         = Thickness;
            m_interactiveLine.ExecutionDataBars = bars;
            return(m_interactiveLine);
        }
コード例 #3
0
        public void Execute(IContext ctx, ISecurity sec)
        {
            if (Display.Value.ToString().Equals(DisplayGraph.Display.ToString()))
            {
                IGraphPane pane        = ctx.First ?? ctx.CreateGraphPane("First", "First");
                Color      colorCandle = ScriptColors.Black;

                var graphSec = pane.AddList(sec.Symbol, sec, CandleStyles.BAR_CANDLE, colorCandle, PaneSides.RIGHT);
            }
        }
コード例 #4
0
        public IList <double> Execute(IGraphPane pane)
        {
            if (pane == null)
            {
                throw new ArgumentNullException(nameof(pane));
            }

            var id        = typeof(IInteractiveConstGen).Name + "." + Value.Data.GetId();
            var container = (NotClearableContainer <InteractiveConstGen>)Context.LoadObject(id);

            container?.Content.Unsubscribe();
            InitInteractiveSimpleLine(pane);
            Subscribe();
            MakeList(Context.BarsCount, Value.Value);
            Context.StoreObject(id, new NotClearableContainer <InteractiveConstGen>(this));
            return(this);
        }
コード例 #5
0
        public IList <double> Execute(IGraphPane pane, ISecurity security)
        {
            if (pane == null)
            {
                throw new ArgumentNullException(nameof(pane));
            }

            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            var id        = typeof(IInteractiveLineGen).Name + "." + VariableId;
            var container = (NotClearableContainer <InteractiveLineGen>)Context.LoadObject(id);

            container?.Content.Unsubscribe();
            var result = GetLine(pane, m_bars = security.Bars);

            Subscribe();
            Context.StoreObject(id, new NotClearableContainer <InteractiveLineGen>(this));
            return(result);
        }
コード例 #6
0
        public void Execute(ISecurity sec, IGraphPane pane, int barNum)
        {
            int barsCount = Context.BarsCount;

            if (!Context.IsLastBarUsed)
            {
                barsCount--;
            }

            if (barNum < barsCount - 1)
            {
                return;
            }

            // Если все уже нарисовано -- выходим
            if (m_executed)
            {
                return;
            }

            m_executed = true;
            DrawTrades(sec, pane);
        }
コード例 #7
0
        public void Execute(IContext ctx, ISecurity sec)
        {
            // таймер для определения времени выполнения скрипта
            var sw = Stopwatch.StartNew();

            // проверка таймфрейма, используемого для торговли
            if (sec.IntervalInstance != new Interval(30, DataIntervals.MINUTE))
            {
                throw new InvalidOperationException($"Выбран не корректный интервал для торговли{sec.IntervalInstance}. Работать только на таймфрейме 30 минут!");
            }

            #region расчет индикаторов
            // канал Дончиана для основного таймфрема
            IList <double> upChannel = ctx.GetData("UpChannel",
                                                   new string[] { PeriodChannel.ToString() },
                                                   () => Series.Highest(sec.HighPrices, PeriodChannel));
            IList <double> downChannel = ctx.GetData("DownChannel",
                                                     new string[] { PeriodChannel.ToString() },
                                                     () => Series.Lowest(sec.LowPrices, PeriodChannel));

            // свечи дневного таймфрейма
            var daySec = sec.CompressTo(new Interval(1, DataIntervals.DAYS));

            // канал Дончиана для дневного таймфрейма
            IList <double> upChannelDay = ctx.GetData("UpChannelDay",
                                                      new string[] { PeriodChannelDay.ToString() },
                                                      () =>
            {
                var res = Series.Highest(daySec.HighPrices, PeriodChannelDay);
                return(daySec.Decompress(res));
            });

            IList <double> downChannelDay = ctx.GetData("DownChannelDay",
                                                        new string[] { PeriodChannelDay.ToString() },
                                                        () =>
            {
                var res = Series.Lowest(daySec.LowPrices, PeriodChannelDay);
                return(daySec.Decompress(res));
            });
            #endregion

            #region первый и последний бар для расчетов
            // первый бар, используемый для расчетов
            int startBar = Math.Max(PeriodChannel + 1, ctx.TradeFromBar);

            // значение счетчика баров, используемое для расчетов
            int barsCount = ctx.BarsCount;
            if (!ctx.IsLastBarClosed)
            {
                barsCount--;
            }
            #endregion

            // цены закрытия, используемые для торговли
            var closePrices = sec.ClosePrices;

            // вначале трейл-стоп отключен, он будет включен при открытии добавочной позиции LED
            var onTrailStop    = false;
            var trailEnable    = false;
            var lastTrailPrice = 0.0;

            #region Торговый цикл
            for (int i = startBar; i < barsCount; i++)
            {
                // базовая позиция LEB
                var lebPosition = sec.Positions.GetLastActiveForSignal("LEB", i);

                // добавочная позиция LEA, открывается при получении заданного уровня профита по базовой позиции
                var leaPosition = sec.Positions.GetLastActiveForSignal("LEA", i);

                // суммарно базовая и добавочная позиции - позиции, начинающиеся на "LA"
                var lePositions = sec.Positions.GetActiveForBar(i).Where(p => p.EntrySignalName.StartsWith("LE")).ToList();

                // добавочная позиция LED при выходе цены за дневной канал
                var ledPosition = sec.Positions.GetLastActiveForSignal("LED", i);

                // если нет базовой позиции, то выставляем условную заявку на её открытие
                if (lebPosition == null)
                {
                    sec.Positions.BuyIfGreater(i + 1, 1, upChannel[i], Slippage * sec.Tick, "LEB");
                    onTrailStop      = false;
                    trailEnable      = false;
                    lastTrailPrice   = 0.0;
                    OnStopLoss.Value = true;
                }
                else
                {
                    // если есть базовая позиция LEB, нет добавочной позиции LEA и нет добавочной позиции LED
                    // то выставляем условную заявку на открытие добавочной позиции LEA
                    if (leaPosition == null && ledPosition == null)
                    {
                        // цена входа в добавочную позицию
                        double entryPrice = lebPosition.EntryPrice * (1 + AddPositionLevel / 100.0);
                        sec.Positions.BuyIfGreater(i + 1, 1, entryPrice, Slippage, "LEA");
                    }

                    // если нет добавочной позиции LED и цена пробила дневной канал, то открываем добавочную позицию LED
                    if (ledPosition == null && (closePrices[i - 1] <= upChannelDay[i - 1]) && (closePrices[i] > upChannelDay[i]))
                    {
                        sec.Positions.BuyAtMarket(i + 1, 2, "LED");
                        OnStopLoss.Value = false;
                        onTrailStop      = true;
                    }

                    // выставляем стоп-лосс и тейк-профит для всех открытых позиций по средней цене входа,
                    // вычисляем среднюю цену входа в позицию
                    var avrEntryPrice = lePositions.GetAvgEntryPrice();

                    // стоп-лосc
                    foreach (var pos in lePositions)
                    {
                        if (OnStopLoss || OnBreakevenStop || onTrailStop)
                        {
                            // цена стоп-лосса
                            double stopPrice = (OnStopLoss)
                                ? (avrEntryPrice * (1 - StopLossPct / 100.0))
                                : 0;

                            // цена инструмента для перевода позиции в безубыток
                            double movePosBreakevenPrice = avrEntryPrice * (1 + ProfitForBreakevenPct / 100.0);

                            // цена стопа для перевода позиции в безубыток
                            double breakevenStopPrice = (OnBreakevenStop && closePrices[i] > movePosBreakevenPrice)
                                ? avrEntryPrice
                                : 0;

                            // цена трейл-стопа
                            double trailPrice = 0.0;
                            if (onTrailStop)
                            {
                                double onTrailStopPrice = avrEntryPrice * (1 + TrailStopEnablePct / 100.0);
                                if (closePrices[i] > onTrailStopPrice)
                                {
                                    trailEnable = true;
                                }

                                trailPrice = (trailEnable)
                                    ? sec.HighPrices[i] * (1 - TrailStopPct / 100.0)
                                    : avrEntryPrice * (1 - StopLossPct / 100.0);

                                trailPrice = lastTrailPrice = Math.Max(trailPrice, lastTrailPrice);
                            }

                            // берем максимальное значение стопа-лосса
                            stopPrice = Math.Max(stopPrice, breakevenStopPrice);
                            stopPrice = Math.Max(stopPrice, trailPrice);
                            stopPrice = Math.Max(stopPrice, pos.GetStop(i));
                            if (stopPrice != 0)
                            {
                                pos.CloseAtStop(i + 1, stopPrice, Slippage, "LXS");
                            }
                        }
                    }

                    // тейк-профит
                    if (OnTakeProfit)
                    {
                        double profitPrice = avrEntryPrice * (1 + TakeProfitPct / 100.0);
                        lePositions.ForEach(p => p.CloseAtProfit(i + 1, profitPrice, Slippage, "LXP"));
                    }
                }
            }
            #endregion

            #region Прорисовка графиков
            // Если идет процесс оптимизации, то графики рисовать не нужно, это замедляет работу
            if (ctx.IsOptimization)
            {
                return;
            }

            IGraphPane pane = ctx.First ?? ctx.CreateGraphPane("First", "First");

            Color colorCandle = ScriptColors.Black;
            pane.AddList(sec.Symbol,
                         sec,
                         CandleStyles.BAR_CANDLE,
                         colorCandle,
                         PaneSides.RIGHT);

            var lineUpChannel = pane.AddList(string.Format($"UpChannel ({PeriodChannel,0})"),
                                             upChannel,
                                             ListStyles.LINE,
                                             ScriptColors.Blue,
                                             LineStyles.SOLID,
                                             PaneSides.RIGHT);

            var lineDownChannel = pane.AddList(string.Format($"DwChannel ({PeriodChannel,0}"),
                                               downChannel,
                                               ListStyles.LINE,
                                               ScriptColors.Blue,
                                               LineStyles.SOLID,
                                               PaneSides.RIGHT);

            var lineUpChannelDay = pane.AddList(string.Format($"UpChannelDay ({PeriodChannelDay,0}"),
                                                upChannelDay,
                                                ListStyles.LINE,
                                                ScriptColors.Red,
                                                LineStyles.DASH,
                                                PaneSides.RIGHT);
            lineUpChannelDay.Thickness = 2;

            var lineDownChannelDay = pane.AddList(string.Format($"DwChannelDay ({PeriodChannelDay,0}"),
                                                  downChannelDay,
                                                  ListStyles.LINE,
                                                  ScriptColors.Red,
                                                  LineStyles.DASH,
                                                  PaneSides.RIGHT);
            lineDownChannelDay.Thickness = 2;

            #endregion

            #region 'Вывод в лог'
            // Вывод в лог времени выполнения скрипта только в режиме Лаборатория
            if (!ctx.Runtime.IsAgentMode)
            {
                ctx.Log($"Скрипт выполнен за время: {sw.Elapsed}", MessageType.Info, true);
            }
            #endregion
        }
コード例 #8
0
        /// <summary>
        /// Вывод графиков в TSLab
        /// </summary>
        private void DrawGraph()
        {
            // Если идет процесс оптимизации, то графики не выводим
            if (_ctx.IsOptimization)
            {
                return;
            }

            IGraphPane pane1       = _ctx.First ?? _ctx.CreateGraphPane("First", "First");
            Color      colorCandle = ScriptColors.Black;

            var graphSec1 = pane1.AddList(_sec1.Symbol,
                                          _sec1,
                                          CandleStyles.BAR_CANDLE,
                                          colorCandle,
                                          PaneSides.RIGHT);

            IGraphPane pane2        = _ctx.CreateGraphPane("Second", "Second");
            Color      colorCandle2 = ScriptColors.Black;

            var graphSec2 = pane2.AddList(_sec2.Symbol,
                                          _sec2,
                                          CandleStyles.BAR_CANDLE,
                                          colorCandle,
                                          PaneSides.RIGHT);

            IGraphPane pane3        = _ctx.CreateGraphPane("Delta", "Delta");
            Color      colorCandle3 = ScriptColors.Black;
            var        graphSpred   = pane3.AddList("Spred",
                                                    _delta,
                                                    ListStyles.HISTOHRAM,
                                                    ScriptColors.Blue,
                                                    LineStyles.SOLID,
                                                    PaneSides.RIGHT);

            var graphUpChannel = pane3.AddList($"UpChannel",
                                               _upChannel,
                                               ListStyles.LINE,
                                               ScriptColors.Red,
                                               LineStyles.SOLID,
                                               PaneSides.RIGHT);

            var graphDownChannel = pane3.AddList($"DownChannel",
                                                 _downChannel,
                                                 ListStyles.LINE,
                                                 ScriptColors.Red,
                                                 LineStyles.SOLID,
                                                 PaneSides.RIGHT);

            /*
             * var graphSignalLE = pane.AddList("SignalLE",
             *  _arrSignalLE,
             *  ListStyles.HISTOHRAM,
             *  ScriptColors.Green,
             *  LineStyles.SOLID,
             *  PaneSides.LEFT);
             *
             * var graphignalSE = pane.AddList("SignalSE",
             *  _arrSignalSE,
             *  ListStyles.HISTOHRAM,
             *  ScriptColors.Red,
             *  LineStyles.SOLID,
             *  PaneSides.LEFT);
             *
             *
             * // раскрашиваем бары в зависимости от наличия позиции
             * _arrVolume = new double[_barsCount];
             * for (int i = 0; i < _barsCount; i++)
             * {
             *  var activePositions1 = _sec1.Positions.GetActiveForBar(i).ToList();
             *  graphSec1.SetColor(i, activePositions1.Any() ? ScriptColors.Black : ScriptColors.DarkGray);
             *  var activePositions2 = _sec1.Positions.GetActiveForBar(i).ToList();
             *  graphSec2.SetColor(i, activePositions2.Any() ? ScriptColors.Black : ScriptColors.DarkGray);
             * }
             * /*
             * IGraphPane pane4 = _ctx.CreateGraphPane("Four", "Four");
             * var graphVolume = pane4.AddList("Volume",
             *  _arrVolume,
             *  ListStyles.HISTOHRAM_LINE,
             *  ScriptColors.Blue,
             *  LineStyles.SOLID,
             *  PaneSides.RIGHT);
             */
        }
コード例 #9
0
        public virtual void Execute(IContext context, ISecurity symbol)  // IContext ctx - источник данных, ISecurity sec - фин инструмент и инф.о нем
        {
            #region Забираем значения из параметров
            double punktPriceRub   = _punktPriceRub.Value;   // 2d / 100 * 66; //стоимость пункта по фьючу на РТС
            double maxKontraktSize = _maxKontraktSize.Value; //Указываем максимальное количество контрактов. Защита "От Дурака" на момент отладки
            double maxPercentRisk  = _maxPercentRisk.Value;  //максимальный риск в одной сделке,
            double absComission    = _absComission.Value;


            int CandlesForHighFractal = _CandlesForHighFractal.Value; //_periodExit.ValueInt; //Определяем период канала
            int CandlesForLowFractal  = _CandlesForLowFractal.Value;  //_periodExit.ValueInt; //Определяем период канала

            bool writeToLog = _writeToLog.Value;                      //по умолчанию true

            #endregion

            #region Переменные для работы с Агентом

            double extraBalanceMoney      = 0;  //для режима "Агент" сколько денег временно вывели со счёта
            double countOfTradingSystems  = 10; //количество одновременно торгуемых систем
            double currentBalanceForAgent = 0;  //Переменная для определения суммы на счёте в ТСЛаб

            #endregion

            #region забираем данные из xml - файла

            string pathXML_TSLab = @"D:\Лаборатория Трейдинга - VisualStudio\Файл конфигурации\configXML.xml";
            //     string pathXML_TSLab = @"C:\TSLab2 - Tools\Файл конфигурации XML\configXML.xml";

            XmlDocument doc = new XmlDocument(); //экземпляр класса для работы с xml документами
            doc.Load(pathXML_TSLab);             //загружаем созданный xml - документ

            foreach (XmlNode node in doc.DocumentElement)
            {
                string name = node.Attributes[0].Value;
                if (name == "ALOR_TradingLab") //указываем тот счёт на котором должна вестись торговля
                {
                    extraBalanceMoney     = double.Parse(node["extraBalanceMoney"].InnerText);
                    countOfTradingSystems = double.Parse(node["countOfTradingSystems"].InnerText);
                    break;
                }
            }

            #endregion

            #region определяем процент на одну торговую систему

            double pctForSystem       = 100.0 / countOfTradingSystems; //указываем максимальный процент денег на одну систему
            double maxPctForOneSystem = 10.0;                          //указываем максимальный процент на одну торговую систему
            pctForSystem = Math.Min(maxPctForOneSystem, pctForSystem);
            pctForSystem = Math.Round(pctForSystem, 2);

            #endregion

            #region Переменные для торговой системы

            int firstValidValue = 0;          // Первое значение свечки при которой существуют все индикаторы

            double FinResForBar          = 0; //Переменная, в которой указывается фин. результат на текущий бар
            double moneyForTradingSystem = 0; //Переменная, которая будет хранить в себе оценку портфеля


            bool   signalBuy         = false; //Сигнал на вход в длинную позицию
            double orderEntryLong    = 0;     // Цена, где будет расположен вход в длинную позицию
            double stopPriceLong     = 0;     // Цена где будет расположен StopLoss длинной позиции
            double kontraktShort_mPR = 0;

            bool   signalShort     = false; // Сигналы на вход в короткую позиции
            double orderEntryShort = 0;     //Цена, где будет расположен вод в короткую позицию
            double stopPriceShort  = 0;     // Цена где будет расположен StopLoss длинной позиции
            double kontraktBuy_mPR = 0;

            double exitLimitPrice = 0;              //Цена выставления Лимитированной заявки на выход

            string HandlerName = String.Format(""); //текстовая переменная для названия индикатора
            string ErrorText   = String.Format(""); //текстовая переменная для вывода текста ошибки


            #endregion

            #region Проводим расчёт Абсолютной комиссии (AbsComission) - не индикатор, а проводим расчёт:

            HandlerName = String.Format("Абсолютная комиссия по {0}", symbol.CacheName);
            ErrorText   = String.Format("Ошибка при вычислении блока {0}. Индекс за пределами диапазона.", HandlerName);

            //Устанавливаем размер комиссии

            AbsComission_h.Commission = absComission; //устанавливаем комиссию в рублях на контракт
            AbsComission_h.Execute(symbol);           //Показываем, что эта комиссия должна учитываться для фин. инструмента

            #endregion

            ISecurityRt rtSymbol = symbol as ISecurityRt;// создаем объект для доступа к информации реальной торговли

            #region Создаём удобное обращение к ценам (по аналогии с Wealth-Lab)

            IList <double> Close = symbol.GetClosePrices(context);
            IList <double> Open  = symbol.GetOpenPrices(context);
            IList <double> High  = symbol.GetHighPrices(context);//получаем список максимальных цен
            IList <double> Low   = symbol.GetLowPrices(context);

            #endregion


            #region Индикаторы

            #region  Верхние фракталы

            FractalBuyDouble_h.Context    = context;
            FractalBuyDouble_h.CurrentBar = 0; //появляется когда фрактал полностью сформируется
            FractalBuyDouble_h.Fractal    = 0;
            FractalBuyDouble_h.Left       = CandlesForHighFractal;
            FractalBuyDouble_h.Right      = CandlesForHighFractal;

            HandlerName = String.Format("Верхний фрактал (свечей влево: {0}, свечей вправо: {1}) по инструменту: {2}", CandlesForHighFractal, CandlesForHighFractal, symbol.CacheName);
            ErrorText   = String.Format("Ошибка при вычислении блока {0}. Индекс за пределами диапазона.", HandlerName);


            IList <double> highFractal = context.GetData
                                             (HandlerName,          //вводим название нового индикатора
                                             new[] { HandlerName }, //работа с буфером данных
                                             delegate               // именно здесь расчитывается индикатор
            {
                try { return(FractalBuyDouble_h.Execute(symbol)); } //Рассчитываем индикатор
                catch (ArgumentOutOfRangeException)                 //если произошла ошибка
                { throw new ScriptException(ErrorText); }           //выводим текст ошибки
            }
                                             );

            firstValidValue = Math.Max(firstValidValue, CandlesForHighFractal * 2 + 1);

            #endregion

            #region  Нижние фракталы

            FractalSellDouble_h.Context    = context;
            FractalSellDouble_h.CurrentBar = 0; //появляется когда фрактал полностью сформируется
            FractalSellDouble_h.Fractal    = 0;
            FractalSellDouble_h.Left       = CandlesForLowFractal;
            FractalSellDouble_h.Right      = CandlesForLowFractal;

            HandlerName = String.Format("Нижний фрактал (свечей влево: {0}, свечей вправо: {1}) по инструменту: {2}", CandlesForLowFractal, CandlesForLowFractal, symbol.CacheName);
            ErrorText   = String.Format("Ошибка при вычислении блока {0}. Индекс за пределами диапазона.", HandlerName);


            IList <double> lowFractal = context.GetData
                                            (HandlerName,            //вводим название нового индикатора
                                            new[] { HandlerName },   //работа с буфером данных
                                            delegate                 // именно здесь расчитывается индикатор
            {
                try { return(FractalSellDouble_h.Execute(symbol)); } //Рассчитываем индикатор
                catch (ArgumentOutOfRangeException)                  //если произошла ошибка
                { throw new ScriptException(ErrorText); }            //выводим текст ошибки
            }
                                            );

            firstValidValue = Math.Max(firstValidValue, CandlesForHighFractal * 2 + 1);

            #endregion

            #endregion

            #region Пишем сообщение в лог о начале срабатывания метода Execute() - если значение writeLog == true
            if (writeToLog == true)
            {
                if (symbol.IsRealtime)
                {
                    string logText = String.Format
                                         ("Привет! Я ТСЛаб. Запускаю стратегию в Режиме Агента. ExtraMoney={0}; торгуется систем: {1}; % для системы = {2}",
                                         extraBalanceMoney.ToString(), countOfTradingSystems, pctForSystem);

                    context.Log(logText, new Color(0, 0, 0), true); //выводим сообщение в лог
                }
                else
                {
                    string logText = String.Format
                                         ("Привет! Я ТСЛаб. Я начала тестировать стратегию в Режиме Лаборатории. ExtraMoney={0}; торгуется систем: {1}; % для системы = {2}",
                                         extraBalanceMoney, countOfTradingSystems, pctForSystem);

                    context.Log(logText, new Color(0, 0, 0), true); //выводим сообщение в лог
                }
            }
            #endregion


            #region Главный торговый цикл

            for (int bar = firstValidValue; bar < symbol.Bars.Count; bar++)
            {
                this.LastActivePosition = symbol.Positions.GetLastPositionActive(bar);// получить ссылку на последнию позицию

                #region Определяем цены  лимитных заявок:

                orderEntryLong = Close[bar];
                orderEntryLong = symbol.RoundPrice(orderEntryLong);

                orderEntryShort = Close[bar];
                orderEntryShort = symbol.RoundPrice(orderEntryShort);

                exitLimitPrice = Close[bar];
                exitLimitPrice = symbol.RoundPrice(exitLimitPrice);

                #endregion

                #region Условия на вход в позицию

                signalBuy = Close[bar] > highFractal[bar] && highFractal[bar] > lowFractal[bar];

                signalShort = Close[bar] < lowFractal[bar] && highFractal[bar] > lowFractal[bar];


                #endregion

                #region Сопровождение и выход из позиции

                #region если позиция существует

                if (LastActivePosition != null) // Если позиция есть
                {
                    #region Длинная позиция

                    if (LastActivePosition.IsLong == true)
                    {
                        bool ExitLong = false;

                        ExitLong = Close[bar] < lowFractal[bar]; //signalShort;

                        #region нужно выходить на следующем баре
                        if (ExitLong == true && signalBuy == false)
                        {
                            LastActivePosition.CloseAtPrice(bar + 1, exitLimitPrice, "Exit Long");
                        }
                        #endregion
                    }

                    #endregion

                    #region Короткая позиция

                    else if (LastActivePosition.IsShort)
                    {
                        bool ExitShort = false;
                        ExitShort = Close[bar] > highFractal[bar]; //signalBuy;

                        #region нужно выходить на следующем баре

                        if (ExitShort == true && signalShort == false)
                        {
                            LastActivePosition.CloseAtPrice(bar + 1, exitLimitPrice, "Exit Short");
                        }
                        #endregion
                    }

                    #endregion
                }

                #endregion

                #region если позиция отсутствует

                else // Если нет позиции
                {
                    #region Нужно входить в длинную позицию?

                    if (signalBuy)                                        // Пришёл сигнал в длинную позицию
                    {
                        stopPriceLong = lowFractal[bar];                  //Math.Min(valueLow_1, valueLow_2); //устанавливаем стоп-лос
                        stopPriceLong = symbol.RoundPrice(stopPriceLong); //округляем цену до минимального тика

                        #region Определяем кол-во контрактов на покупку (в зависимости от режима торговли - Лаборатория или Агент:

                        #region Находимся в режиме Агента?

                        if (symbol.IsRealtime) //если находимся в режиме агента
                        {
                            //определяем текущий баланс счёта (В ТСЛаб)
                            currentBalanceForAgent = rtSymbol.EstimatedBalance;
                            moneyForTradingSystem  = (currentBalanceForAgent + extraBalanceMoney) * (pctForSystem / 100.0);

                            lots_maxPercentRisk_h.LotSize        = symbol.LotSize; //устанавливаем размер лота
                            lots_maxPercentRisk_h.MaxPercentRisk = maxPercentRisk; //указываем процент риска который используем
                            lots_maxPercentRisk_h.punktPriceRUB  = punktPriceRub;  //указываем стоимость пункта

                            kontraktBuy_mPR = lots_maxPercentRisk_h.Execute(moneyForTradingSystem, orderEntryLong, stopPriceLong, bar);
                            kontraktBuy_mPR = symbol.RoundShares(kontraktBuy_mPR);

                            kontraktBuy_mPR = Math.Min(kontraktBuy_mPR, maxKontraktSize); //ограничиваем максимальное кол-во контрактов на вход (не более ... контрактов)

                            #region пишем сообщение в лог:

                            if (bar > symbol.Bars.Count - 2)
                            {
                                string logTextBuy = String.Format(
                                    "Хочу войти в long: {0} контрактами: Баланс на счёте: {1}; ExtraMoney: {2} руб.; %для системы: {3}, Деньги для системы: {4}",
                                    kontraktBuy_mPR, currentBalanceForAgent, extraBalanceMoney, pctForSystem, moneyForTradingSystem);

                                context.Log(logTextBuy, MessageType.Info, true); //выводим сообщение в лог
                            }

                            #endregion
                        }

                        #endregion

                        #region Находимся в режиме Лаборатории?

                        else //если находимся в режиме лаборатории
                        {
                            string logTextBuy = "";

                            WholeTimeProfit_h.ProfitKind = ProfitKind.Unfixed;     //если хотим узнать стоимость счёта с учётом ещё незафиксированной прибыли
                                                                                   //  WholeTimeProfit_h.ProfitKind = ProfitKind.Fixed; //если хотим узнать стоимость счёта без учёта ещё незафиксированной прибыли
                            FinResForBar = WholeTimeProfit_h.Execute(symbol, bar); //Рассчитываем стоимость дохода на текущий бар в пунктах
                            FinResForBar = FinResForBar * punktPriceRub;           //переводим финрез в рубли
                            //     определяем сумму для торговой системы
                            moneyForTradingSystem = symbol.InitDeposit + FinResForBar;

                            lots_maxPercentRisk_h.LotSize        = symbol.LotSize; //устанавливаем размер лота
                            lots_maxPercentRisk_h.MaxPercentRisk = maxPercentRisk; //указываем процент риска который используем
                            lots_maxPercentRisk_h.punktPriceRUB  = punktPriceRub;  //указываем стоимость пункта

                            kontraktBuy_mPR = lots_maxPercentRisk_h.Execute(moneyForTradingSystem, orderEntryLong, stopPriceLong, bar);
                            kontraktBuy_mPR = symbol.RoundShares(kontraktBuy_mPR);

                            #region пишем сообщение в лог (если не в режиме оптимизации):

                            if (writeToLog == true)
                            {
                                if (context.IsOptimization == false) //если не в режиме оптимизации
                                {
                                    logTextBuy = String.Format(
                                        "Цена входа: {0} - Stop: {1} Результат по закрытым позициям: {2}; Начальный депозит: {3} руб.; Деньги для системы: {4}. бар №{5} - Хочу войти в long: {6} контрактами: ",
                                        orderEntryLong, stopPriceLong, FinResForBar, symbol.InitDeposit, moneyForTradingSystem, bar, kontraktBuy_mPR);

                                    context.Log(logTextBuy, new Color(0, 0, 0), false); //выводим сообщение в лог
                                }
                            }
                            #endregion
                        }

                        #endregion

                        #endregion

                        #region Входим не менее чем на 1 контракт

                        if (kontraktBuy_mPR > 0)
                        {
                            // kontraktBuy_mPR = 1;
                            string orderText = String.Format("LongEnter");
                            symbol.Positions.BuyAtPrice(bar + 1, kontraktBuy_mPR, orderEntryLong, orderText);
                        }
                        else
                        {
                            kontraktBuy_mPR = 1;                                                 //даже если не хватает денег - заходим одним контрактом
                            string orderText = String.Format("LongEnter_minKontrakt");
                            symbol.Positions.BuyAtPrice(bar + 1, 1, kontraktBuy_mPR, orderText); // входим хотя бы 1 контрактом
                        }
                        #endregion
                    }

                    #endregion

                    #region Нужно входить в короткую позицию?

                    else if (signalShort)
                    {
                        // Пришёл сигнал в короткую позицию
                        stopPriceShort = highFractal[bar]; //Math.Max(valueHigh_1, valueHigh_2); //Устанавливаем Стоп (для расчёта кол-ва контрактов)


                        #region Определяем кол-во контрактов на продажу (в зависимости от режима торговли - Лаборатория или Агент:

                        #region Если находимся в режиме агента

                        if (symbol.IsRealtime) //если находимся в режиме агента
                        {
                            //определяем текущий баланс счёта (В ТСЛаб)
                            currentBalanceForAgent = rtSymbol.EstimatedBalance;
                            moneyForTradingSystem  = (currentBalanceForAgent + extraBalanceMoney) * (pctForSystem / 100.0);

                            lots_maxPercentRisk_h.LotSize        = symbol.LotSize; //устанавливаем размер лота
                            lots_maxPercentRisk_h.MaxPercentRisk = maxPercentRisk; //указываем процент риска который используем
                            kontraktShort_mPR = lots_maxPercentRisk_h.Execute(moneyForTradingSystem, orderEntryShort, stopPriceShort, bar);
                            kontraktShort_mPR = symbol.RoundShares(kontraktShort_mPR);


                            // Защита от дурака (от непредвиденных событий) - только в режими агента
                            kontraktShort_mPR = Math.Min(kontraktShort_mPR, maxKontraktSize); //ограничиваем максимальное кол-во контрактов на вход (не более ... контрактов)

                            #region пишем сообщение в лог:

                            if (bar > symbol.Bars.Count - 2)
                            {
                                string logTextShort = String.Format(
                                    "Хочу войти в short: {0} контрактами: Баланс на счёте: {1}; ExtraMoney: {2} руб.; %для системы: {3}, Деньги для системы: {4}",
                                    kontraktShort_mPR, currentBalanceForAgent, extraBalanceMoney, pctForSystem, moneyForTradingSystem);

                                context.Log(logTextShort, MessageType.Info, true); //выводим сообщение в лог
                            }

                            #endregion
                        }

                        #endregion

                        #region Если находимся в режиме Лаборатории
                        else //если находимся в режиме лаборатории
                        {
                            //определяем прибыль от торговли на текущий момент и показываем, что хотим учесть даже ещё незафиксированную прибыль

                            WholeTimeProfit_h.ProfitKind = ProfitKind.Unfixed;     //если хотим узнать стоимость счёта с учётом ещё незафиксированной прибыли
                            FinResForBar = WholeTimeProfit_h.Execute(symbol, bar); //Рассчитываем доход по портфелю на текущий бар в пунктах
                            FinResForBar = FinResForBar * punktPriceRub;           //переводим Фин. Рез. в рубли

                            //     определяем сумму для торговой системы
                            moneyForTradingSystem = symbol.InitDeposit + FinResForBar;

                            //расчет с помощью "кубика"

                            lots_maxPercentRisk_h.LotSize        = symbol.LotSize; //устанавливаем размер лота
                            lots_maxPercentRisk_h.MaxPercentRisk = maxPercentRisk; //указываем процент риска который используем
                            lots_maxPercentRisk_h.punktPriceRUB  = punktPriceRub;
                            kontraktShort_mPR = lots_maxPercentRisk_h.Execute(moneyForTradingSystem, orderEntryShort, stopPriceShort, bar);
                            kontraktShort_mPR = symbol.RoundShares(kontraktShort_mPR);

                            #region пишем сообщение в лог (если не в  режиме оптимизации):

                            if (writeToLog == true)
                            {
                                if (context.IsOptimization == false)
                                {
                                    string logTextShort = "";
                                    logTextShort = String.Format(
                                        "Цена входа: {0} - Stop: {1} Результат по закрытым позициям: {2}; Начальный депозит: {3} руб.; Деньги для системы: {4}. бар №{5} - Хочу войти в short: {6} контрактами: ",
                                        orderEntryShort, stopPriceShort, FinResForBar, symbol.InitDeposit, moneyForTradingSystem, bar, kontraktShort_mPR);

                                    context.Log(logTextShort, new Color(0, 0, 0), false); //выводим сообщение в лог
                                }
                            }
                            #endregion
                        }

                        #endregion

                        #endregion

                        #region Входим не менее чем на 1 контракт

                        if (kontraktShort_mPR > 0)
                        {
                            // kontraktShort_mPR = 1;
                            string orderText = String.Format("ShortEnter");
                            symbol.Positions.SellAtPrice(bar + 1, kontraktShort_mPR, orderEntryShort, orderText);
                        }
                        else
                        {
                            kontraktShort_mPR = 1; //даже если не хватает денег - заходим одним контрактом
                            string orderText = String.Format("ShortEnter_minKontrakt");
                            symbol.Positions.SellAtPrice(bar + 1, kontraktShort_mPR, orderEntryShort, orderText);
                        }
                        #endregion
                    }

                    #endregion
                }

                #endregion

                #endregion
            }


            #endregion


            #region Прорисовка графиков



            if (context.IsOptimization == false) // Если находимся не в режиме оптимизации, то пропускаем отрисовку
            {
                #region Пишем сообщение в лог о завершении стратегии
                if (writeToLog == true)
                {
                    if (symbol.IsRealtime)
                    {
                        string logText = String.Format("Режима агента. Осталось только раскрасить график");
                        context.Log(logText, new Color(0, 0, 0), true); //выводим сообщение в лог
                    }
                    else
                    {
                        string logText = String.Format("Режим Лаборатории: Осталось только раскрасить график!");
                        context.Log(logText, new Color(0, 0, 0), true); //выводим сообщение в лог
                    }
                }
                #endregion

                #region Панель для цен и индикаторов (по ценам)


                #region Создаём панель для цен:

                IGraphPane pricePane = context.CreateGraphPane(symbol.ToString(), null);
                pricePane.Visible    = true;  //является ли панель видимой?
                pricePane.HideLegend = false; //скрыть (true) или показать (false) легенду
                pricePane.SizePct    = 100;   //сколько % составляет

                #endregion

                #region создаём переменные для цветов

                Color LightGray  = 0xc0c0c0;               //Серый цвет
                Color Blue       = 0x0000ff;               //Синий цвет
                Color redColor   = new Color(255, 0, 0);   //создаём красный цвет c помощью RGB (берём значение в Яндексе по запросу "красный цвет код")
                Color greenColor = new Color(50, 205, 50); //создаём зелёный цвет

                #endregion

                #region Заносим бары на панель графика

                IGraphList candlesGraph = pricePane.AddList(symbol.ToString(), symbol, CandleStyles.BAR_CANDLE, LightGray, PaneSides.RIGHT);
                symbol.ConnectSecurityList(candlesGraph);                                 //подключить график к ценной бумаге для обновления в режиме реального времени
                candlesGraph.AlternativeColor = LightGray;                                //для чисел (к отрицательным) для баров (к медвежьим)
                candlesGraph.Autoscaling      = true;
                pricePane.UpdatePrecision(TSLab.Script.PaneSides.RIGHT, symbol.Decimals); //обновить значение на графике

                #endregion

                //Рисуем индикаторы


                #region Свойства индикаторов

                string highLevelText = String.Format("Верхняя фрактальная граница канала (слева: {0}, справа: {1})", CandlesForHighFractal, CandlesForHighFractal);
                string lowLevelText  = String.Format("Нижняя фрактальная граница канала (слева: {0}, справа: {1})", CandlesForLowFractal, CandlesForLowFractal);
                //          string lowTrailingText = String.Format("LongTrailingStop (период канала: {0}, Количество шагов: {1})", periodExit, steps);
                //          string highTrailingText = String.Format("ShortTrailingStop (период канала: {0}, Количество шагов: {1})", periodExit, steps);



                LineStyles highLevelLineStyle = LineStyles.SOLID; //устанавливаем тип линии (по умолчанию Dot) для нижнего канала
                LineStyles lowLevelLineStyle  = LineStyles.SOLID; //устанавливаем тип линии (по умолчанию Dot) для нижнего канала
                //       LineStyles lowTrailingLineStyle = LineStyles.DOT; //устанавливаем тип линии (по умолчанию Dot) для нижнего канала
                //       LineStyles highTrailingLineStyle = LineStyles.DOT; //устанавливаем тип линии (по умолчанию Dot) для нижнего канала

                ListStyles highLevelListStyle = ListStyles.POINT; //Устанавливаем форму линии (по умолчанию Line) для нижнего канала
                ListStyles lowLevelListStyle  = ListStyles.POINT; //Устанавливаем форму линии (по умолчанию Line) для нижнего канала
                //       ListStyles lowTrailingListStyle = ListStyles.LINE_WO_ZERO; //Устанавливаем форму линии (по умолчанию Line) для нижнего канала
                //       ListStyles highTrailingListStyle = ListStyles.LINE_WO_ZERO; //Устанавливаем форму линии (по умолчанию Line) для нижнего канала

                #endregion

                #region Наносим индикаторы на график

                IGraphListBase lowLevelGraph = pricePane.AddList("lowFractalLevel", lowLevelText, lowFractal, lowLevelListStyle, redColor, lowLevelLineStyle, PaneSides.RIGHT);
                lowLevelGraph.Thickness        = 2; //устанавливаем толщину отображаемой линии
                lowLevelGraph.AlternativeColor = redColor;

                IGraphListBase highLevelGraph = pricePane.AddList("highFractalLevel", highLevelText, highFractal, highLevelListStyle, greenColor, highLevelLineStyle, PaneSides.RIGHT);
                highLevelGraph.Thickness        = 1; //устанавливаем толщину отображаемой линии
                highLevelGraph.AlternativeColor = greenColor;

                //IGraphListBase lowTrailingGraph = pricePane.AddList("TralingForLong", lowTrailingText, TrailingForLong, lowTrailingListStyle, redColor, lowTrailingLineStyle, PaneSides.RIGHT);
                //lowTrailingGraph.Thickness = 2; //устанавливаем толщину отображаемой линии
                //lowTrailingGraph.AlternativeColor = redColor;

                //IGraphListBase highTrailingGraph = pricePane.AddList("TrailingForShort", highTrailingText, TrailingForShort, highTrailingListStyle, redColor, highTrailingLineStyle, PaneSides.RIGHT);
                //highTrailingGraph.Thickness = 2; //устанавливаем толщину отображаемой линии
                //highTrailingGraph.AlternativeColor = redColor;



                #endregion


                #endregion

                #region  асскрашиваем свечи в цвета в зависимости от наличия и типа позиции
                for (int i = 0; i < context.BarsCount; i++)
                {
                    //Расскрашиваем свечи в цвета, если в позиции
                    var ActivePositionsList = symbol.Positions.GetActiveForBar(i);

                    if (ActivePositionsList.Any())                //если есть хотя бы одна позиция
                    {
                        if (ActivePositionsList.First().IsLong)   //ElementAt(0).IsLong)
                        {
                            candlesGraph.SetColor(i, greenColor); //Зелёный цвет если в длинной позиции
                        }
                        else
                        {
                            candlesGraph.SetColor(i, redColor); //Красный цвет - если в короткой позиции
                        }
                    }
                    else
                    {
                        //  lst.SetColor(i, LightGray); //Серый цвет если позиции нет
                    }
                }
                #endregion
            }



            #endregion

            #region Пишем сообщение в лог о завершении стратегии
            if (writeToLog == true)
            {
                if (symbol.IsRealtime)
                {
                    string logText = String.Format("Режима агента. Стратегия выполнена. Жду дальнейших указаний!");
                    context.Log(logText, new Color(0, 0, 0), true); //выводим сообщение в лог
                }
                else
                {
                    string logText = String.Format("Режим Лаборатории: Стратегия выполнена - можно отдохнуть!");
                    context.Log(logText, new Color(0, 0, 0), true); //выводим сообщение в лог
                }
            }
            #endregion
        }
コード例 #10
0
        /// <summary>
        /// Основной метод бота
        /// </summary>
        /// <param name="ctx">Контекст TSLab</param>
        /// <param name="sec">Инструмент</param>
        public void Execute(IContext ctx, ISecurity sec)
        {
            // таймер для определения времени выполнения скрипта
            var sw = Stopwatch.StartNew();

            #region расчет индикаторов
            IList <double> upChannel = ctx.GetData("UpChannel",
                                                   new string[] { PeriodChannel.ToString() },
                                                   () => Series.Highest(sec.HighPrices, PeriodChannel));

            IList <double> downChannel = ctx.GetData("DownChannel",
                                                     new string[] { PeriodChannel.ToString() },
                                                     () => Series.Lowest(sec.LowPrices, PeriodChannel));
            #endregion

            #region первый и последний бар для расчетов
            // первый бар, используемый для расчетов
            int startBar = Math.Max(PeriodChannel + 1, ctx.TradeFromBar);

            // последний бар, используемый для расчетов
            var barsCount = sec.Bars.Count;
            if (!ctx.IsLastBarClosed)
            {
                barsCount--;
            }
            #endregion

            // цены закрытия инструмента
            var closePrices = sec.ClosePrices;

            #region Создание объекта для трейлинг стопа
            _trailStopHnd = new TrailStop()
            {
                StopLoss    = StopLossPct,
                TrailEnable = TrailLossEnablePct,
                TrailLoss   = TrailLossPct
            };
            #endregion


            #region Торговый цикл
            for (int i = startBar; i < barsCount; i++)
            {
                #region Формируем торговые сигналы
                // сигнал входа в лонг, сигнал активен в течение 2-х бар при выхода цены закрытия из канала
                bool signalLE = closePrices[i] > upChannel[i - 1] && closePrices[i - 2] <= upChannel[i - 3];

                // сигнал входа в шорт, сигнал активен в течение 2-х бар при выхода цены закрытия из канала
                bool signalSE = closePrices[i] < downChannel[i - 1] && closePrices[i - 2] >= downChannel[i - 3];

                // сигнал выхода из лонга
                bool signalLX = closePrices[i] < downChannel[i - 1];

                // сигнал выхода из шорта
                bool signalSX = closePrices[i] > upChannel[i - 1];
                #endregion

                #region Получаем активные позиции
                var lePosition    = sec.Positions.GetLastActiveForSignal("LE", i);
                var sePosition    = sec.Positions.GetLastActiveForSignal("SE", i);
                var openPositions = sec.Positions.GetActiveForBar(i).ToList();
                #endregion

                #region Выход из позиции, реверс позиции, установка стоп-лосса и тейк-профита
                if (openPositions.Count != 0)
                {
                    foreach (IPosition pos in openPositions)
                    {
                        switch (pos.EntrySignalName)
                        {
                            #region обработка позиции лонг LE
                        case "LE":
                            //условие выхода из лонга
                            if (signalLX)
                            {
                                //закрытие лонга по лимиту
                                pos.CloseAtPriceSlip(i + 1, closePrices[i], Slippage, "LX");

                                // условие реверса позиции
                                if (_regimeBot != RegimeBot.OnlyShort &&
                                    _regimeBot != RegimeBot.OnlyClosePosition)
                                {
                                    // открытие шорта по лимиту для реверса позиции
                                    sec.SellAtPriceSlip(i + 1, 1, closePrices[i], Slippage, "SE");
                                }
                            }
                            // если не было сигнала выхода, то выставляем стопы и профиты
                            else
                            {
                                // выставление стоп-лосса
                                if (OnStopLoss || OnBreakevenStop)
                                {
                                    SetStopLoss(pos, i);
                                }

                                // выставление тейк-профотита
                                if (OnTakeProfit)
                                {
                                    SetTakeProfit(pos, i);
                                }
                            }
                            break;
                            #endregion

                            #region обработка позиции шорт SE
                        case "SE":
                            // условие выхода из шорта
                            if (signalSX)
                            {
                                // закрытие шорта по лимиту
                                pos.CloseAtPriceSlip(i + 1, closePrices[i], Slippage, "SX");

                                // условие реверса позиции
                                if (_regimeBot != RegimeBot.OnlyShort &&
                                    _regimeBot != RegimeBot.OnlyClosePosition)
                                {
                                    // открытие лонга по лимиту для реверса позиции
                                    sec.BuyAtPriceSlip(i + 1, 1, closePrices[i], Slippage, "LE");
                                }
                            }
                            // если не было сигналов на выход, то выставляем стоп-лосс и тейк-профит
                            else
                            {
                                // выставление стопа-лосса
                                if (OnStopLoss || OnBreakevenStop)
                                {
                                    SetStopLoss(pos, i);
                                }

                                // выставление тейк-профита
                                if (OnTakeProfit)
                                {
                                    SetTakeProfit(pos, i);
                                }
                            }
                            break;
                            #endregion

                            #region обработка прочих позиций
                        default:
                            ctx.Log($"Обработка прочих позиций {pos.EntrySignalName}", MessageType.Warning);
                            break;
                            #endregion
                        }
                    }
                }
                #endregion

                if (_regimeBot == RegimeBot.OnlyClosePosition)
                {
                    continue;
                }

                #region Вход в первую позицию
                // если нет ни одной активной позиции, то проверяем условие входа в первую позицию
                if (openPositions.Count == 0)
                {
                    // лонг
                    if (signalLE && _regimeBot != RegimeBot.OnlyShort)
                    {
                        sec.BuyAtPriceSlip(i + 1, 1, closePrices[i], Slippage, "LE");
                    }
                    // шорт
                    else if (signalSE && _regimeBot != RegimeBot.OnlyLong)
                    {
                        sec.SellAtPriceSlip(i + 1, 1, closePrices[i], Slippage, "SE");
                    }
                }
                #endregion
            }
            #endregion

            #region Прорисовка графиков
            // Если идет процесс оптимизации, то графики рисовать не нужно, это замедляет работу
            if (ctx.IsOptimization)
            {
                return;
            }

            IGraphPane pane        = ctx.First ?? ctx.CreateGraphPane("First", "First");
            Color      colorCandle = ScriptColors.Black;
            pane.AddList(sec.Symbol, sec, CandleStyles.BAR_CANDLE, colorCandle, PaneSides.RIGHT);
            var lineUpChannel = pane.AddList(string.Format($"UpChannel ({PeriodChannel,0})"),
                                             upChannel,
                                             ListStyles.LINE,
                                             ScriptColors.Red,
                                             LineStyles.SOLID,
                                             PaneSides.RIGHT);

            //lineUpChannel.Thickness = 2;

            var lineDownChannel = pane.AddList(string.Format($"DwChannel ({PeriodChannel,0}"),
                                               downChannel,
                                               ListStyles.LINE,
                                               ScriptColors.Blue,
                                               LineStyles.SOLID,
                                               PaneSides.RIGHT);

            //lineDownChannel.Thickness = 2;

            #endregion

            #region Вывод в лог
            // Вывод в лог времени выполнения скрипта только в режиме Лаборатория
            if (!ctx.Runtime.IsAgentMode)
            {
                ctx.Log($"Скрипт выполнен за время: {sw.Elapsed}", MessageType.Info, true);
            }
            #endregion
        }
コード例 #11
0
        private IList <double> GetLine(IGraphPane pane, IReadOnlyList <IDataBar> bars)
        {
            m_interactiveLine = null;
            if (bars == null || bars.Count == 0)
            {
                return(EmptyArrays.Double);
            }

            if (bars.Count == 1)
            {
                return(s_defaultResult1);
            }

            var interactiveLine = GetInteractiveLine(pane, bars);
            var firstPosition   = interactiveLine.FirstPoint.MarketPosition;
            var secondPosition  = interactiveLine.SecondPoint.MarketPosition;

            if (firstPosition.X == secondPosition.X)
            {
                return(new ConstList(double.NaN, bars.Count));
            }

            var firstBarIndex  = GetBarIndex(bars, firstPosition.X);
            var secondBarIndex = GetBarIndex(bars, secondPosition.X);

            if (firstBarIndex == null || secondBarIndex == null || firstBarIndex == secondBarIndex)
            {
                return(new ConstList(double.NaN, bars.Count));
            }

            var a = (secondPosition.Y - firstPosition.Y) / (secondBarIndex.Value - firstBarIndex.Value);
            var b = firstPosition.Y - a * firstBarIndex.Value;

            int minIndex;
            int maxIndex;

            switch (Mode)
            {
            case InteractiveLineMode.Finite:
                if (firstBarIndex < secondBarIndex)
                {
                    minIndex = firstBarIndex.Value;
                    maxIndex = secondBarIndex.Value;
                }
                else
                {
                    minIndex = secondBarIndex.Value;
                    maxIndex = firstBarIndex.Value;
                }
                break;

            case InteractiveLineMode.Infinite:
                minIndex = 0;
                maxIndex = bars.Count - 1;
                break;

            case InteractiveLineMode.Ray:
                if (firstBarIndex < secondBarIndex)
                {
                    minIndex = firstBarIndex.Value;
                    maxIndex = bars.Count - 1;
                }
                else
                {
                    minIndex = 0;
                    maxIndex = firstBarIndex.Value;
                }
                break;

            default:
                throw new InvalidOperationException();
            }
            return(a == 0 ? (IList <double>) new ConstList(b, bars.Count, minIndex, maxIndex) : new LineList(a, b, bars.Count, minIndex, maxIndex));
        }
コード例 #12
0
        /// <summary>
        /// Вывод графиков в TSLab
        /// </summary>
        private void DrawGraph()
        {
            // Если идет процесс оптимизации, то графики не выводим
            if (_ctx.IsOptimization)
            {
                return;
            }

            IGraphPane pane        = _ctx.First ?? _ctx.CreateGraphPane("First", "First");
            Color      colorCandle = ScriptColors.Black;

            var graphSec = pane.AddList(_sec.Symbol,
                                        _sec,
                                        CandleStyles.BAR_CANDLE,
                                        colorCandle,
                                        PaneSides.RIGHT);

            var graphFastAlligator = pane.AddList($"fastAlligator ({AlligatorFastLenght}-{AlligatorFastShift})",
                                                  _fastAlligator,
                                                  ListStyles.LINE,
                                                  ScriptColors.Red,
                                                  LineStyles.SOLID,
                                                  PaneSides.RIGHT);

            var graphMiddleAlligator = pane.AddList($"middleAlligator ({AlligatorMiddleLenght}-{AlligatorMiddleShift})",
                                                    _middleAlligator,
                                                    ListStyles.LINE,
                                                    ScriptColors.Green,
                                                    LineStyles.SOLID,
                                                    PaneSides.RIGHT);

            var graphSlowAlligator = pane.AddList($"slowAlligator ({AlligatorSlowLenght}-{AlligatorSlowShift})",
                                                  _slowAlligator,
                                                  ListStyles.LINE,
                                                  ScriptColors.Blue,
                                                  LineStyles.SOLID,
                                                  PaneSides.RIGHT);

            /*
             * var graphSignalLE = pane.AddList("SignalLE",
             *  _arrSignalLE,
             *  ListStyles.HISTOHRAM,
             *  ScriptColors.Green,
             *  LineStyles.SOLID,
             *  PaneSides.LEFT);
             *
             * var graphignalSE = pane.AddList("SignalSE",
             *  _arrSignalSE,
             *  ListStyles.HISTOHRAM,
             *  ScriptColors.Red,
             *  LineStyles.SOLID,
             *  PaneSides.LEFT);
             * /*
             * var graphSignalLX = pane.AddList("SignalLX",
             *  _arrSignalLX,
             *  ListStyles.HISTOHRAM,
             *  ScriptColors.Yellow,
             *  LineStyles.SOLID,
             *  PaneSides.LEFT);
             *
             * var graphignalSX = pane.AddList("SignalSX",
             *  _arrSignalSX,
             *  ListStyles.HISTOHRAM,
             *  ScriptColors.Magenta,
             *  LineStyles.SOLID,
             *  PaneSides.LEFT);
             *
             * /*
             * // раскрашиваем бары в зависимости от наличия позиции
             * // и определяем объем входа в позицию на каждом баре
             * _arrVolume = new double[_barsCount];
             * for (int i = 0; i < _barsCount; i++)
             * {
             *  var activePositions = _sec.Positions.GetActiveForBar(i).ToList();
             *  graphSec.SetColor(i, activePositions.Any() ? ScriptColors.Black : ScriptColors.DarkGray);
             *
             *  foreach (var pos in activePositions)
             *  {
             *      if (pos.EntryBar.Date.Date == _sec.Bars[i].Date.Date &&
             *          pos.EntryBar.Date.TimeOfDay == _sec.Bars[i].Date.TimeOfDay)
             *          _arrVolume[i] += pos.Shares;
             *  }
             * }
             *
             * IGraphPane pane2 = _ctx.CreateGraphPane("Second", "Second");
             * var graphVolume = pane2.AddList("Volume",
             *  _arrVolume,
             *  ListStyles.HISTOHRAM_LINE,
             *  ScriptColors.Blue,
             *  LineStyles.SOLID,
             *  PaneSides.RIGHT);
             */
        }
コード例 #13
0
 public PaneTSLab(IGraphPane pane)
 {
     this.pane = pane;
 }
コード例 #14
0
        public virtual void Execute(IContext ctx, ISecurity source)
        {
            double[] pyData          = new double[DataLen]; // Array of data we want to send to Python App
            var      indicatorValues = new List <double>();


            for (int i = 0; i < DataLen; i++)
            {
                // Fill first `DataLen` elements for indicator and full python array
                pyData[i] = source.ClosePrices[i];
                indicatorValues.Add(0);
            }

            //--------------------------------------------------------------------------------
            #region Trading cycle


            int barsCount    = source.Bars.Count;
            int lastEntryBar = 0;

            for (int bar = DataLen; bar < barsCount; bar++)
            {
                //Create new array. Copy DataLen -1 elements from old array and insert new datapoint.
                // We always have DataLen last points of data
                double[] newData = new double[DataLen];
                Array.Copy(pyData, 1, newData, 0, DataLen - 1);
                newData[DataLen - 1] = source.ClosePrices[bar];
                pyData = newData;

                var val = GetFromPY(pyData); // Send to python and get calculated value

                // Insert calculated value if it's not NaN
                if (double.IsNaN(val))
                {
                    indicatorValues.Add(0);
                }
                else
                {
                    indicatorValues.Add(val);
                }

                // Some dummy trade logic
                IPosition LongPos = source.Positions.GetLastActiveForSignal("LN", bar);
                if (LongPos == null)
                {
                    if (val < LongEntryThreshold)
                    {
                        source.Positions.BuyAtPrice(bar + 1, 1, source.ClosePrices[bar], "LN");
                        lastEntryBar = bar + 1;
                    }
                }
                else
                {
                    if (val > ShortEntryThreshold)
                    {
                        LongPos.CloseAtPrice(bar + 1, source.ClosePrices[bar], "LX");
                    }
                }
            }


            #endregion

            //--------------------------------------------------------------------------------
            #region Draw charts

            IGraphPane mainPane = ctx.CreateGraphPane("Main", "");

            //Candlestick
            IGraphList CandleChart = mainPane.AddList(
                "Candle Chart",
                string.Format("Symbol:  [{0}]", source.Symbol),
                source, CandleStyles.BAR_CANDLE, CandleFillStyle.Decreasing,
                true, -14685179, PaneSides.RIGHT
                );

            source.ConnectSecurityList(CandleChart);
            CandleChart.AlternativeColor = -262137;
            CandleChart.Autoscaling      = true;
            mainPane.UpdatePrecision(PaneSides.RIGHT, source.Decimals);

            //Python indicator
            IGraphList ind = mainPane.AddList(
                "Indicator", indicatorValues, ListStyles.LINE, 0xa000a0,
                LineStyles.SOLID, PaneSides.RIGHT);

            mainPane.Visible     = true;
            mainPane.HideLegend  = false;
            mainPane.SizePct     = 100;
            ind.AlternativeColor = -6153042;
            ind.Autoscaling      = true;
            mainPane.UpdatePrecision(PaneSides.RIGHT, source.Decimals);
            #endregion
        }
コード例 #15
0
        /// <summary>
        /// Вывод графиков в TSLab
        /// </summary>
        private void DrawGraph()
        {
            // Если идет процесс оптимизации, то графики не выводим
            if (_ctx.IsOptimization)
            {
                return;
            }

            IGraphPane pane        = _ctx.First ?? _ctx.CreateGraphPane("First", "First");
            Color      colorCandle = ScriptColors.Black;

            var graphSec = pane.AddList(_sec.Symbol,
                                        _sec,
                                        CandleStyles.BAR_CANDLE,
                                        colorCandle,
                                        PaneSides.RIGHT);

            var graphUpBollinger = pane.AddList($"upBollinger ({PeriodBollinger} - {DeviationBollinger})",
                                                _upBollinger,
                                                ListStyles.LINE,
                                                ScriptColors.Blue,
                                                LineStyles.SOLID,
                                                PaneSides.RIGHT);

            var graphDownBollinger = pane.AddList($"downBollinger ({PeriodBollinger} - {DeviationBollinger})",
                                                  _downBollinger,
                                                  ListStyles.LINE,
                                                  ScriptColors.Blue,
                                                  LineStyles.SOLID,
                                                  PaneSides.RIGHT);

            if (MethodOutOfPosition.Value == 2)
            {
                var graphCenterBollinger = pane.AddList("centerBollinger",
                                                        _centerBollinger,
                                                        ListStyles.LINE,
                                                        ScriptColors.Blue,
                                                        LineStyles.SOLID,
                                                        PaneSides.RIGHT);
            }

            var graphSignalLE = pane.AddList("SignalLE",
                                             _arrSignalLE,
                                             ListStyles.HISTOHRAM,
                                             ScriptColors.Green,
                                             LineStyles.SOLID,
                                             PaneSides.LEFT);

            var graphignalSE = pane.AddList("SignalSE",
                                            _arrSignalSE,
                                            ListStyles.HISTOHRAM,
                                            ScriptColors.Red,
                                            LineStyles.SOLID,
                                            PaneSides.LEFT);

            // раскрашиваем бары в зависимости от наличия позиции
            // и определяем объем входа в позицию на каждом баре
            _arrVolume = new double[_barsCount];
            for (int i = 0; i < _barsCount; i++)
            {
                var activePositions = _sec.Positions.GetActiveForBar(i).ToList();
                graphSec.SetColor(i, activePositions.Any() ? ScriptColors.Black : ScriptColors.DarkGray);

                foreach (var pos in activePositions)
                {
                    if (pos.EntryBar.Date.Date == _sec.Bars[i].Date.Date &&
                        pos.EntryBar.Date.TimeOfDay == _sec.Bars[i].Date.TimeOfDay)
                    {
                        _arrVolume[i] += pos.Shares;
                    }
                }
            }

            IGraphPane pane2       = _ctx.CreateGraphPane("Second", "Second");
            var        graphVolume = pane2.AddList("Volume",
                                                   _arrVolume,
                                                   ListStyles.HISTOHRAM_LINE,
                                                   ScriptColors.Blue,
                                                   LineStyles.SOLID,
                                                   PaneSides.RIGHT);
        }
コード例 #16
0
 public void Execute(IOption opt, IGraphPane pane)
 {
     Execute(opt.UnderlyingAsset, pane);
 }
コード例 #17
0
        private void DrawTrades(ISecurity sec, IGraphPane pane)
        {
            // TODO: нужна такая проверка?
            //if (!sec.IsRealtime)
            //{
            //    string msg = RM.GetStringFormat("OptHandlerMsg.PositionsManager.RunAsAgent",
            //        Context.Runtime.TradeName + ":" + MsgId, sec.IsRealtime);
            //    Context.Log(msg, MessageType.Warning, true);
            //    return;
            //}

            //// Позиций нет? Выходим. Ловить нечего.
            //if (sec.Positions.HavePositions)
            //    return;

            // В оптимизации ничего рисовать не надо
            if (Context.IsOptimization)
            {
                return;
            }

            // 0. Чистим за собой мусор от предыдущих прогонов?
            var oldObjects = pane.GetInteractiveObjects(); // Клонирование делается внутри метода

            foreach (var oldObj in oldObjects)
            {
                var oldPoint = oldObj as GraphPane.IInteractivePoint;
                if (oldPoint != null)
                {
                    if (oldPoint.Id.StartsWith(ExecutedOrdPrefix))
                    {
                        pane.RemoveInteractiveObject(oldPoint.Id);
                    }
                    continue;
                }

                var oldLine = oldObj as GraphPane.IInteractiveLine;
                if (oldLine != null)
                {
                    if (oldLine.Id.StartsWith(ActiveOrdPrefix))
                    {
                        pane.RemoveInteractiveObject(oldLine.Id);
                    }
                    continue;
                }
            }

            ISecurityRt secRt;

            if (sec is ISecurityRt)
            {
                secRt = (ISecurityRt)sec;
            }
            else
            {
                secRt = (from s in Context.Runtime.Securities
                         where s.SecurityDescription.Equals(sec) && (s is ISecurityRt)
                         select(ISecurityRt) s).SingleOrDefault();
            }

            if (secRt == null)
            {
                return;
            }

            // ОТЛИЧНО! Эта коллекция позволит мне нарисовать свои заявки и сделки
            var orders         = secRt.Orders.ToList();
            var activeOrders   = new List <IOrder>();
            var executedOrders = new List <IOrder>();

            for (int j = 0; j < orders.Count; j++)
            {
                IOrder ord = orders[j];
                if (ord.IsActive)
                {
                    activeOrders.Add(ord);
                }
                else if (ord.Status == OrderStatus.Executed)
                {
                    executedOrders.Add(ord);
                }
                else
                {
                    //string str = "Все остальное игнорируем?";
                }
            }

            int      id          = 0;
            IDataBar lastBar     = sec.Bars.LastOrDefault();
            int      intervalSec = Context.Runtime.IntervalInstance.ToSeconds();
            DateTime now         = (lastBar != null) ? lastBar.Date : (sec.FinInfo != null) ? sec.FinInfo.LastUpdate : DateTimeUtils.Now;

            // 1. Рисуем активные заявки в виде линий
            foreach (IOrder ord in activeOrders)
            {
                string itemId    = ActiveOrdPrefix + id;
                var    end       = new GraphPane.MarketPoint(now, ord.Price);
                var    beg       = new GraphPane.MarketPoint(now.AddSeconds(-10 * intervalSec), ord.Price);
                Color  actualCol = ord.IsBuy ? s_green : s_red;
                pane.AddInteractiveLine(itemId, PaneSides.RIGHT, true, actualCol,
                                        GraphPane.InteractiveLineMode.Finite, beg, end);

                id++;
            }

            // 2. Рисуем исполненные заявки в виде точек
            foreach (IOrder ord in executedOrders)
            {
                string itemId    = ExecutedOrdPrefix + id;
                Color  actualCol = ord.IsBuy ? s_green : s_red;
                var    point     = new GraphPane.MarketPoint(ord.Date, ord.Price);
                pane.AddInteractivePoint(itemId, PaneSides.RIGHT, true, actualCol, point);

                id++;
            }

            //var point = new GraphPane.MarketPoint(DateTime.Now, 50000);
            //pane.AddInteractivePoint("0", PaneSides.RIGHT, true, new Color(255, 0, 0), point);
        }
コード例 #18
0
 public void Execute(IOption opt, IGraphPane pane, int barNum)
 {
     Execute(opt.UnderlyingAsset, pane, barNum);
 }
コード例 #19
0
 public void Execute(ISecurity sec, IGraphPane pane)
 {
     DrawTrades(sec, pane);
 }