Example #1
0
        public void BuildSeries(ChartControl chart)
        {
            seriesProj.data.Clear();
            if (chart.StockSeries.Data.Count < 3)
            {
                return;
            }

            List <ExtremumPair> pairs;

            if (Source == PivotSource.ЗигЗаг)
            {
                // получить вершины ЗЗ
                pairs = new List <ExtremumPair>();
                var pivots = ZigZag.GetPivots(chart.StockSeries.Data.Candles, ThresholdPercent, ZigZagSourceType);
                for (var i = 1; i < pivots.Count; i++)
                {
                    pairs.Add(new ExtremumPair {
                        start = pivots[i - 1], end = pivots[i]
                    });
                }
            }
            else
            {
                // получить вершины из "фракталов"
                pairs = GetPivotsByFractals();
            }
            // построить "проекции" Фибо
            MakeFiboProj(pairs);
        }
Example #2
0
        public void BuildSeries(ChartControl chart)
        {
            seriesTurnBar.barsKey.Clear();
            seriesTurnBar.barsTurn.Clear();
            if (chart.StockSeries.Data.Count < 3)
            {
                return;
            }
            // получить вершины ЗЗ
            var pivots = ZigZag.GetPivots(chart.StockSeries.Data.Candles, ThresholdPercent, ZigZagSourceType);

            MakeFiboBars(pivots);
            if (CalculateHits)
            {
                DoCalculateHits(pivots);
            }
        }
        private void FindTrends(float zzThreshold)
        {
            trends.Clear();
            chartCandles = chart.chart.StockSeries.Data.Candles;
            if (chartCandles.Count < 10)
            {
                return;
            }
            var pivots = ZigZag.GetPivots(chartCandles, zzThreshold, ZigZagSource.HighLow);

            for (var i = 1; i < pivots.Count; i++)
            {
                var deltaAbs = Math.Abs(pivots[i].price - pivots[i - 1].price);
                trends.Add(new Trend
                {
                    startIndex = pivots[i - 1].index,
                    endIndex   = pivots[i].index,
                    points     = (decimal)deltaAbs * pointCost
                });
            }
        }
Example #4
0
        public void BuildSeries(ChartControl chart)
        {
            if (DrawPane != owner.StockPane)
            {
                DrawPane.Title = UniqueName;
            }
            seriesZigZag.Data.Clear();
            if (chart.StockSeries.Data.Count < 3)
            {
                return;
            }

            seriesZigZag.LineColor     = lineColor;
            seriesZigZag.LineWidth     = (float)lineWidth;
            seriesZigZag.LineDashStyle = lineStyle;

            // индекс - индикатор
            var pivots = ZigZag.GetPivots(chart.StockSeries.Data.Candles, ThresholdPercent, ZigZagSourceType);

            if (pivots.Count == 0)
            {
                return;
            }

            // построить отрезки
            var lastPivot = pivots[0];

            for (var i = 1; i < pivots.Count; i++)
            {
                var pivot = pivots[i];
                var step  = (double)(pivot.b - lastPivot.b) / (pivot.a - lastPivot.a);
                for (var j = lastPivot.a; j < pivot.a; j++)
                {
                    seriesZigZag.Data.Add((double)lastPivot.b + step * (j - lastPivot.a));
                }
                lastPivot = pivot;
            }
        }
Example #5
0
        public void BuildSeries(ChartControl chart)
        {
            if (DrawPane != owner.StockPane)
            {
                DrawPane.Title = UniqueName;
            }
            seriesZigZag.parts.Clear();
            if (chart.StockSeries.Data.Count < 3)
            {
                return;
            }

            seriesZigZag.LineColor = TrendColor;
            seriesZigZag.LineWidth = (float)LineWidth;
            //seriesZigZag.LineDashStyle = lineStyle;

            // индекс - индикатор
            var correctionPercent = CorrectionPercent < ThresholdPercent ? CorrectionPercent : ThresholdPercent;
            var pivots            = ZigZag.GetPivots(chart.StockSeries.Data.Candles, ThresholdPercent, correctionPercent,
                                                     chart.StockSeries.Data.Candles.Count - 1, ZigZagSourceType);

            if (pivots.Count == 0)
            {
                return;
            }

            // построить отрезки
            for (var i = 1; i < pivots.Count; i++)
            {
                var color = pivots[i - 1].nextArc == ZigZagPivot.ZigZagArc.Correction ? CorrectionColor : TrendColor;
                seriesZigZag.parts.Add(new PartSeries.Polyline(
                                           color,
                                           new PartSeriesPoint(pivots[i - 1].index, (decimal)pivots[i - 1].price),
                                           new PartSeriesPoint(pivots[i].index, (decimal)pivots[i].price)));
            }
        }
        /// <summary>
        /// от двух пар последних точек ЗЗ построить проекции
        /// </summary>
        public void BuildSeries(ChartControl chart)
        {
            spans.data.Clear();
            //spans.ExtendYAxis = ExtendChartBounds;
            // получить точки Зиг-Зага
            var pivots = ZigZag.GetPivots(chart.StockSeries.Data.Candles, ThresholdPercent, ZigZagSourceType);

            if (pivots.Count < 3)
            {
                return;
            }
            // построить проекции
            var pointA = pivots[pivots.Count - 3];
            var pointB = pivots[pivots.Count - 2];
            var pointC = pivots[pivots.Count - 1];

            var spanA = new ProjectionPair(pointA.index, pointA.price)
            {
                HideFarParts     = false,
                Color            = pointB.price > pointA.price ? ColorLineLower : ColorLineUpper,
                ProjectionLength = ProjectionBars,
                LevelsProj       = LevelsProj,
                Markers          = Markers
            };

            spanA.AddPoint(pointB.index, pointB.price);
            var spanB = new ProjectionPair(pointB.index, pointB.price)
            {
                HideFarParts     = false,
                Color            = pointB.price < pointA.price ? ColorLineLower : ColorLineUpper,
                ProjectionLength = ProjectionBars,
                LevelsProj       = LevelsProj,
                Markers          = Markers
            };

            spanB.AddPoint(pointC.index, pointC.price);
            spans.data.Add(spanA);
            spans.data.Add(spanB);
            // коррекции?
            if (!CorrectionEnabled)
            {
                return;
            }
            if (correctionBcLength > 0)
            {
                var spanC = new ProjectionPair(pointB.index, pointB.price)
                {
                    HideFarParts     = false,
                    Color            = pointB.price < pointA.price ? ColorLineLower : ColorLineUpper,
                    ProjectionLength = CorrectionBcLength,
                    LevelsCorr       = LevelsCorr,
                    IsExtension      = false,
                    IsCorrection     = true,
                    Markers          = Markers
                };
                spanC.AddPoint(pointC.index, pointC.price);
                spans.data.Add(spanC);
            }
            if (correctionAbLength > 0)
            {
                var spanC = new ProjectionPair(pointA.index, pointA.price)
                {
                    HideFarParts     = false,
                    Color            = pointB.price < pointA.price ? ColorLineLower : ColorLineUpper,
                    ProjectionLength = CorrectionAbLength,
                    LevelsCorr       = LevelsCorr,
                    IsExtension      = false,
                    IsCorrection     = true,
                    Markers          = Markers
                };
                spanC.AddPoint(pointB.index, pointB.price);
                spans.data.Add(spanC);
            }
        }
Example #7
0
        public override List <string> OnQuotesReceived(string[] names, CandleDataBidAsk[] quotes, bool isHistoryStartOff)
        {
            CandleDataBidAsk quote = null;

            for (var i = 0; i < names.Length; i++)
            {
                if (names[i] == ticker)
                {
                    quote = quotes[i];
                    break;
                }
            }
            var events = new List <string>();

            if (quote == null)
            {
                return(events);
            }
            // сопроводить сделки, коли треба...

            var candle = packer.UpdateCandle(quote);

            if (candle == null)
            {
                return(events);
            }
            candles.Add(candle);

            // получить уровни ЗигЗага
            var pivots = ZigZag.GetPivots(candles, ZigZagPeriodPercent, ZigZagSourceType);

            if (pivots.Count < 3)
            {
                return(events);
            }
            // проверить последнюю вершину ЗЗ - отстоит ли она от предпоследней на ZigZagPeriodPercent
            //var lastValid = Math.Abs(100*(pivots[pivots.Count - 1].b - pivots[pivots.Count - 2].b)/
            //                         pivots[pivots.Count - 2].b)
            //                >= ZigZagPeriodPercent;
            //if (!lastValid && pivots.Count == 3) return events;
            //var screenPointB = lastValid ? pivots[pivots.Count - 1] : pivots[pivots.Count - 2];
            //var screenPointA = lastValid ? pivots[pivots.Count - 2] : pivots[pivots.Count - 3];

            var ptB = pivots[pivots.Count - 2];
            var ptA = pivots[pivots.Count - 3];


            // отметить вершину ЗЗ
            if (ShowFiboTurnBars && (markedZigZagPivots.Count == 0 ||
                                     markedZigZagPivots[markedZigZagPivots.Count - 1] < ptA.a))
            {
                markedZigZagPivots.Add(ptA.a);
                events.Add(new RobotHint(ticker, Graphics[0].b.ToString(), "З.З", "З.З", "z", ptA.b)
                {
                    ColorFill     = Color.Olive,
                    Time          = candles[ptA.a].timeOpen,
                    RobotHintType = RobotHint.HintType.Коментарий
                }.ToString());
            }

            // соблюдаются ли условия входа в рынок?
            // - уровень Фибо пройден N-м баром Фибо
            // - с клоза того бара рынок вырос (для продаж)
            var fiboLevel = ptA.b + (ptA.b - ptB.b) * fiboLevels[0];
            //var potentialDealSide = screenPointA.b > screenPointB.b ? -1 : 1;
            var   fiboBreachIndex = -1;
            float fiboBreachPrice = 0;

            foreach (var fiboMember in fiboBars)
            {
                var index = fiboMember + ptB.a - 1;
                if (index >= candles.Count)
                {
                    break;
                }
                // свеча закрылась дальше расширения Фибо?
                var close       = candles[index].close;
                var fiboReached = ptA.b > ptB.b ? close > fiboLevel : close < fiboLevel;
                if (!fiboReached)
                {
                    continue;
                }
                fiboBreachIndex = index;
                fiboBreachPrice = close;
                break;
            }

            // считаем, сколько потенциально могло быть совершено входов
            // с момента пробития Фибо
            if (fiboBreachIndex > 0)
            {
                var countDeals = 1;
                // потенциальные сделки
                for (var i = fiboBreachIndex + 1; i < candles.Count - 1; i++)
                {
                    if ((candles[i].close > fiboBreachPrice && ptA.b > ptB.b) ||
                        (candles[i].close < fiboBreachPrice && ptA.b < ptB.b))
                    {
                        fiboBreachPrice = candles[i].close;
                        countDeals++;
                    }
                }
                var isEnterBetter = (candle.close > fiboBreachPrice && ptA.b > ptB.b) ||
                                    (candle.close < fiboBreachPrice && ptA.b < ptB.b);

                if ((isEnterBetter || fiboBreachIndex == candles.Count - 1) &&
                    countDeals <= maxDealsInSeries)
                {// войти в рынок, закрыв противонаправленные сделки
                    var dealSide = ptA.b > ptB.b ? -1 : 1;

                    List <MarketOrder> orders;
                    robotContext.GetMarketOrders(robotContext.AccountInfo.ID, out orders);
                    if (orders.Count > 0)
                    {
                        orders = orders.Where(o => o.Magic == Magic && o.Side != dealSide).ToList();
                    }
                    foreach (var order in orders)
                    {
                        robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                                      robotContext.AccountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                    }

                    // открыть сделку
                    OpenDeal(quote.GetCloseQuote(), dealSide);
                    events.Add(new RobotHint(ticker, Graphics[0].b.ToString(),
                                             "Вход", "Вход по З.З", "e", dealSide < 0 ? quote.close : quote.closeAsk)
                    {
                        ColorFill     = dealSide > 0 ? Color.Green : Color.Red,
                        Time          = quote.timeClose,
                        RobotHintType = dealSide > 0 ? RobotHint.HintType.Покупка : RobotHint.HintType.Продажа
                    }.ToString());
                }
            }

            return(events);
        }
Example #8
0
        public override List <string> OnQuotesReceived(string[] names, CandleDataBidAsk[] quotes, bool isHistoryStartOff)
        {
            if (/*formulaResolver == null || */ packer == null)
            {
                return(null);
            }
            curTime = quotes[0].timeClose;

            // обновить табличку цен
            for (var i = 0; i < names.Length; i++)
            {
                if (lastBids.ContainsKey(names[i]))
                {
                    lastBids[names[i]] = (double)quotes[i].close;
                }
                else
                {
                    lastBids.Add(names[i], (double)quotes[i].close);
                }
            }

            CandleDataBidAsk curQuote = null;

            for (var i = 0; i < names.Length; i++)
            {
                if (names[i] == ticker)
                {
                    curQuote = quotes[i];
                    break;
                }
            }

            if (curQuote == null)
            {
                return(null);                  // нет торгуемой котировки
            }
            // обновить свечки
            var candle = packer.UpdateCandle(curQuote);

            var hints = new List <RobotHint>();

            if (candle != null)
            {
                // закрылась полная свеча, проводим вычисления
                candles.Add(candle);


                countCandles++;
                // обновить очереди (для индекса, переменные вида usdjpy#15)
                if (lastBidLists.Count > 0)
                {
                    foreach (var listTicker in lastBidLists)
                    {
                        double price;
                        if (!lastBids.TryGetValue(listTicker.Key, out price))
                        {
                            price = 0;
                        }
                        listTicker.Value.Add(price);
                    }
                }

                // посчитать индексы
                foreach (var ind in IndexList)
                {
                    ind.CalculateValue(tickerNames, candles, lastBidLists, curTime, randomGener);
                }

                // если это период "разгона" конвейера
                if (isHistoryStartOff)
                {
                    return(null);
                }

                var hintText = new StringBuilder();
                List <MarketOrder> orders;

                #region ТОРГОВЫЙ МОДУЛЬ

                #region проверяем необходимость добавок к открытым позициям

                // проверяем состояние робота, если у нас нет позиций и робот торгует, возвращаем в исходное состояние
                GetMarketOrders(out orders);
                if (orders.Count == 0 && stopsOnPositions == StopPositionsState.ЗащитаУстановлена)
                {
                    RobotTradeState = TradeState.ПоискТочекВхода;
                    TerminalLog.Instance.SaveRobotLog("Atracotes MTS: Позиции закрылись");
                    TerminalLog.Instance.SaveRobotLog("Atracotes MTS: RobotTradeState = " + RobotTradeState);
                    stopsOnPositions = StopPositionsState.Незащищены;
                }
                var addPosFlag = 0;
                if (RobotTradeState == TradeState.НаращиваниеПокупок || RobotTradeState == TradeState.НаращиваниеПродаж)
                {
                    var side = RobotTradeState == TradeState.НаращиваниеПокупок ? 1 :
                               RobotTradeState == TradeState.НаращиваниеПродаж ? -1 : 0;
                    if (AddPositionRules == AddPositionRule.НаБареЛучшейЦены)
                    {
                        //GetMarketOrders(out orders);
                        if (orders.Count == 0)
                        {
                            addPosFlag = RobotTradeState == TradeState.НаращиваниеПокупок ? 1 : -1;
                        }
                        else
                        {
                            var averagePrice = GetAveragePrice(orders, side, curQuote.close, ProtectType.ПоЛучшейПозиции);
                            if (side == 1 && curQuote.close < averagePrice)
                            {
                                addPosFlag = 1;
                            }
                            if (side == -1 && curQuote.close > averagePrice)
                            {
                                addPosFlag = -1;
                            }

                            // проверяю достижение актуального фибоуровня
                            if (ActualFiboLevel != null)
                            {
                                // если условие выполнилось, то мы не достигли уровня для открытия позиций
                                if ((addPosFlag == 1 && ActualFiboLevel < curQuote.close) ||
                                    (addPosFlag == -1 && ActualFiboLevel > curQuote.close))
                                {
                                    addPosFlag = 0;
                                }
                            }
                        }
                    }
                }

                if (addPosFlag != 0)
                {
                    GetMarketOrders(out orders);
                    var ordersCount = orders.Count;
                    // проверяем можно ли еще открыть позиции
                    if (ordersCount < CountTrades)
                    {
                        // открыть позу в направлении знака дивера
                        robotContext.SendNewOrderRequest(
                            protectedContext.MakeProtectedContext(),
                            RequestUniqueId.Next(),
                            new MarketOrder
                        {
                            AccountID     = robotContext.AccountInfo.ID,
                            Magic         = Magic,
                            Symbol        = ticker,
                            Volume        = GetTradeLot(),
                            Side          = addPosFlag,
                            ExpertComment = "Atracotes MTS"
                        },
                            OrderType.Market, 0, 0);

                        if (ordersCount > 0)
                        {
                            hintText.AppendLine(string.Format("Добавка к {0}, текущая цена {1}",
                                                              addPosFlag == 1 ? "покупкам" : "продажам", curQuote.close));
                        }
                        else
                        {
                            hintText.AppendLine(string.Format("{0}, текущая цена {1}", addPosFlag == 1 ? "покупка" : "продажа",
                                                              curQuote.close));
                        }
                        TerminalLog.Instance.SaveRobotLog("Atracotes MTS: " + hintText);
                        hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(), hintText.ToString(),
                                                addPosFlag > 0 ? "BUY" : "SELL", "e", curQuote.close)
                        {
                            Time          = curQuote.timeClose,
                            ColorFill     = addPosFlag > 0 ? Color.Green : Color.Red,
                            ColorLine     = Color.Black,
                            RobotHintType = addPosFlag > 0 ? RobotHint.HintType.Покупка : RobotHint.HintType.Продажа
                        });
                        stopsOnPositions = StopPositionsState.Незащищены;
                        if (ordersCount + 1 == CountTrades)
                        {
                            RobotTradeState = TradeState.НабранПолныйОбъем;
                            TerminalLog.Instance.SaveRobotLog("Atracotes MTS: RobotTradeState = " + RobotTradeState);
                        }
                    }
                }
                #endregion

                #region считаем зигзагу и уровни расширений

                var quotesList = candles.ToList();
                var pivots     = ZigZag.GetPivots(quotesList, ThresholdPercent, ZigZagSourceType);
                if (pivots.Count > 1)
                {
                    // появились точки, рассчитываем уровни
                    // проверяем процентный порог перешагнули или нет

                    for (var i = pivots.Count; i > 1; i--)
                    {
                        var index0  = i - 1;
                        var index1  = i - 2;
                        var percent = Math.Abs(pivots[index0].b - pivots[index1].b) / pivots[index1].b * 100;
                        if (percent > ThresholdPercent)
                        {
                            // процентный порог пройден, вычисляем уровни
                            // теперь вычисляем уровни расширений
                            var sign  = pivots[index0].b > pivots[index1].b ? -1 : 1;
                            var delta = Math.Abs(pivots[index0].b - pivots[index1].b);

                            // очищаем все предыдущие уровни расширений как устаревшие
                            // extLevels.Clear();

                            foreach (var level in fiboLevels)
                            {
                                var lev = new ExtensionsLevel
                                {
                                    startIndex = countCandles > CandlesInIndexHistory ? countCandles - CandlesInIndexHistory + pivots[index0].a : pivots[index0].a,
                                    length     = BarsCount,
                                    price      = pivots[index0].b + delta * sign * (1 + level),
                                    delta      = DalSpot.Instance.GetAbsValue(ticker, DeltaLevel),
                                    goalFrom   = -sign
                                };
                                extLevels.Add(lev);
                            }
                            break;
                        }
                    }
                }
                #endregion

                #region ищем дивергенции на индексах и курсе валютной пары
                var divergenceSign = 0;

                foreach (var ind in IndexList)
                {
                    var commentOnDivergence = string.Empty;

                    var indiDiverSign = ind.GetDivergenceSign(candles, out commentOnDivergence);
                    if (indiDiverSign != 0)
                    {
                        if (hintText.Length != 0)
                        {
                            hintText.AppendLine();
                        }
                        hintText.AppendLine("Дивергенция на индексе №" + indexList.IndexOf(ind));
                        hintText.AppendLine(commentOnDivergence);
                        hintText.AppendLine("Переменные:");
                        // ReSharper disable PossibleNullReferenceException)
                        foreach (var pair in ind.indexCalculator.varValues)
                        // ReSharper restore PossibleNullReferenceException
                        {
                            hintText.AppendLine(string.Format("{1}{0}{2:f4}", (char)9, pair.Key, pair.Value));
                        }

                        //hints.Add(new RobotHint(hintText.ToString(),
                        //indiDiverSign > 0 ? "BUY" : "SELL", "e", curQuote.Bid)
                        //{
                        //    Time = candle.timeOpen,
                        //    ColorFill = indiDiverSign > 0 ? Color.Green : Color.Red,
                        //    ColorLine = Color.Black
                        //});
                    }


                    divergenceSign += indiDiverSign;
                }
                #endregion


                // теперь получен список дивергенций и уровни расширения.

                #region удаляем старые уровни
                for (var i = 0; i < extLevels.Count; i++)
                {
                    // проверка актуальности уровня по свечам
                    if (countCandles - 1 <= extLevels[i].startIndex + extLevels[i].length)
                    {
                        continue;
                    }
                    // уровень устарел, прошли максимальную длину свечей
                    extLevels.RemoveAt(i);
                    i--;
                }
                #endregion

                // проверяем достижение уровней расширения текущей ценой и если есть - входим в рынок
                divergenceSign = Math.Sign(divergenceSign);



                if (stopsOnPositions == StopPositionsState.Незащищены && divergenceSign != 0)
                {
                    GetMarketOrders(out orders);
                    stopsOnPositions = ProtectPositions(orders, -divergenceSign, curQuote.close);
                    if (stopsOnPositions == StopPositionsState.ЗащитаУстановлена)
                    {
                        TerminalLog.Instance.SaveRobotLog("Atracotes MTS: Позиции защищены ны дивергенции");
                        hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(),
                                                "Защита позиций на дивергенции", "PROTECT", -divergenceSign > 0 ? "PB" : "PS", curQuote.close)
                        {
                            Time          = curQuote.timeClose,
                            ColorFill     = Color.Blue,
                            ColorLine     = Color.Black,
                            RobotHintType = RobotHint.HintType.Поджатие
                        });
                    }
                }

                if (true || RobotTradeState == TradeState.НетПозиций || RobotTradeState == TradeState.ПоискТочекВхода || RobotTradeState == TradeState.НабранПолныйОбъем)
                {
                    foreach (var level in extLevels)
                    {
                        // проверяем попадание цены на уровень
                        //var prevCandle = candles.GetItemByIndex(candles.Count() - 2, true);
                        if ((level.goalFrom == -1 && candles[candles.Count - 1].close >= (level.price - level.delta)) ||
                            (level.goalFrom == 1 && candles[candles.Count - 1].close <= (level.price + level.delta)))
                        {
                            GetMarketOrders(out orders);
                            if (stopsOnPositions == StopPositionsState.Незащищены && divergenceSign == 0)
                            {
                                // надо поджать позиции
                                stopsOnPositions = ProtectPositions(orders, -level.goalFrom, curQuote.close);
                                if (stopsOnPositions == StopPositionsState.ЗащитаУстановлена)
                                {
                                    TerminalLog.Instance.SaveRobotLog("Atracotes MTS: Позиции защищены по достижению уровня расширения");
                                    hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(),
                                                            "Защита позиций по достижению уровня расширения",
                                                            "PROTECT", -level.goalFrom > 0 ? "PB" : "PS", curQuote.close)
                                    {
                                        Time          = curQuote.timeClose,
                                        ColorFill     = Color.Blue,
                                        ColorLine     = Color.Black,
                                        RobotHintType = RobotHint.HintType.Поджатие
                                    });
                                }
                                break;
                            }

                            if (divergenceSign == 0)
                            {
                                continue;
                            }

                            var ordersCount = orders.Count;
                            // цена поднялась до целевого уровня
                            var level1        = level;
                            var ordersToClose = orders.FindAll(o => o.Side != divergenceSign);

                            foreach (var order in ordersToClose)
                            {
                                robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                                              robotContext.AccountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                                ordersCount--;
                            }
                            // закрыли ордера и теперь начинаем открывать позиции в обратную сторону

                            // проверяем можно ли еще открыть позиции
                            if (ordersCount >= CountTrades)
                            {
                                break;
                            }

                            // не добавляем позиции по новому диверу
                            if (RobotTradeState == TradeState.НаращиваниеПокупок && divergenceSign == 1 ||
                                RobotTradeState == TradeState.НаращиваниеПродаж && divergenceSign == -1)
                            {
                                break;
                            }

                            // открыть позу в направлении знака дивера
                            robotContext.SendNewOrderRequest(
                                protectedContext.MakeProtectedContext(),
                                RequestUniqueId.Next(),
                                new MarketOrder
                            {
                                AccountID     = robotContext.AccountInfo.ID,
                                Magic         = Magic,
                                Symbol        = ticker,
                                Volume        = GetTradeLot(),
                                Side          = divergenceSign,
                                ExpertComment = "Atracotes MTS"
                            },
                                OrderType.Market, 0, 0);

                            hintText.AppendLine(string.Format("Пересечение уровня {0} {1}, текущая цена {2}",
                                                              level1.price,
                                                              level1.goalFrom == -1 ? "снизу" : "сверху", curQuote.close));

                            TerminalLog.Instance.SaveRobotLog("Atracotes MTS: " + hintText + ", " + (divergenceSign > 0 ? "покупка" : "продажа"));
                            hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(),
                                                    hintText.ToString(), divergenceSign > 0 ? "BUY" : "SELL", "e", curQuote.close)
                            {
                                Time          = curQuote.timeClose,
                                ColorFill     = divergenceSign > 0 ? Color.Green : Color.Red,
                                ColorLine     = Color.Black,
                                RobotHintType = divergenceSign > 0 ? RobotHint.HintType.Покупка : RobotHint.HintType.Продажа
                            });

                            RobotTradeState = divergenceSign == 1
                                                  ? TradeState.НаращиваниеПокупок

                                                  : TradeState.НаращиваниеПродаж;
                            TerminalLog.Instance.SaveRobotLog("Atracotes MTS: RobotTradeState = " + RobotTradeState);
                            stopsOnPositions = StopPositionsState.Незащищены;
                            break;
                        }
                    }
                }

                #endregion
            }

            var retHint = hints.Select(hint => hint.ToString()).ToList();
            return(retHint.Count > 0 ? retHint : null);
        }