Beispiel #1
0
        private void OpenDeal(QuoteData quote, int dealSide)
        {
            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            decimal?stop = StopLossPoints == 0
                                ? (decimal?)null
                                : (decimal)quote.bid -
                           dealSide * DalSpot.Instance.GetAbsValue(ticker, (decimal)StopLossPoints);
            decimal?take = TakeProfitPoints == 0
                                ? (decimal?)null
                                : (decimal)quote.bid +
                           dealSide * DalSpot.Instance.GetAbsValue(ticker, (decimal)TakeProfitPoints);

            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Symbol        = ticker,
                Volume        = dealVolumeDepo,
                Side          = dealSide,
                StopLoss      = (float?)stop,
                TakeProfit    = (float?)take,
                ExpertComment = "FibonacciRobot"
            },
                OrderType.Market, 0, 0);
        }
        public RequestStatus OpenPosition(string hash, string userLogin, long localTime, int accountId,
                                          string symbol, int volume, int side, float stopLoss, float takeProfit, int magic, string comment)
        {
            var status = CheckCredentials(hash, userLogin, localTime, accountId, true);

            if (status != RequestStatus.OK)
            {
                return(status);
            }

            status = managerTrade.SendNewOrderRequest(ProtectedOperationContext.MakeServerSideContext(),
                                                      RequestUniqueId.Next(), new MarketOrder
            {
                AccountID  = accountId,
                Symbol     = symbol,
                Volume     = volume,
                Side       = side,
                StopLoss   = stopLoss == 0 ? (float?)null : stopLoss,
                TakeProfit = takeProfit == 0 ? (float?)null : takeProfit,
                Magic      = magic,
                Comment    = comment
            },
                                                      OrderType.Market,
                                                      0, 0);
            return(status);
        }
Beispiel #3
0
        private void OpenDeal(float price, int dealSide)
        {
            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            float?stop = StopLossPoints == 0
                                ? (float?)null
                                : price -
                         dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)StopLossPoints);
            float?take = TakeProfitPoints == 0
                                ? (float?)null
                                : price +
                         dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)TakeProfitPoints);

            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Symbol        = ticker,
                Volume        = dealVolumeDepo,
                Side          = dealSide,
                StopLoss      = stop,
                TakeProfit    = take,
                ExpertComment = "RencoRobot"
            },
                OrderType.Market, 0, 0);
        }
Beispiel #4
0
        private void OpenDeal(float price, int dealSide)
        {
            var dealVolumeDepo = CalculateVolume(ticker, Leverage, FixedVolume);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            var sl = stopLossPoints == 0 ? (float?)null
                : price - dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)stopLossPoints);
            var tp = takeProfitPoints == 0 ? (float?)null
                : price + dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)takeProfitPoints);

            // открыть сделку
            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Symbol        = ticker,
                Volume        = dealVolumeDepo,
                Side          = dealSide,
                StopLoss      = sl,
                TakeProfit    = tp,
                ExpertComment = "CaymanRobot"
            },
                OrderType.Market, 0, 0);
        }
Beispiel #5
0
        /// <summary>
        /// Открыть новую сделку по указанной цене price, указанного типа dealSide (покупка или продажа)
        /// </summary>
        private void OpenDeal(float price, int dealSide)
        {
            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            // Пересчёт значений Stop loss и Take profit из пунктов в конкретную цену. Эти значения не могут быть 0
            var stop = StopLossPoints == 0
                                ? (float?)null
                                : price -
                       dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)StopLossPoints);
            var take = TakeProfitPoints == 0
                                ? (float?)null
                                : price +
                       dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)TakeProfitPoints);

            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,    // Уникальный идентификатор чёта
                Magic         = Magic,                          // Этот параметр позволяет отличать сделки разных роботов
                Symbol        = ticker,                         // Инструмент по которому совершается сделка
                Volume        = dealVolumeDepo,                 // Объём средств, на который совершается сделка
                Side          = dealSide,                       // Устанавливаем тип сделки - покупка или продажа
                StopLoss      = stop,                           // Устанавливаем величину Stop loss для открываемой сделки
                TakeProfit    = take,                           // Устанавливаем величину Take profit для открываемой сделки
                ExpertComment = "MARobot"                       // Комментарий по сделке, оставленный роботом
            },
                OrderType.Market, 0, 0);
        }
Beispiel #6
0
        /// <summary>
        /// Send pending order
        /// </summary>
        /// <param name="magic"></param>
        /// <param name="symbol"></param>
        /// <param name="volume"></param>
        /// <param name="side"></param>
        /// <param name="pendingOrdType"></param>
        /// <param name="targetPriceFrom"></param>
        /// <param name="targetPriceTo"></param>
        /// <param name="dateFrom"></param>
        /// <param name="dateTo"></param>
        /// <param name="stopPrice"></param>
        /// <param name="takePrice"></param>
        /// <param name="comment"></param>
        /// <returns></returns>
        protected RequestStatus NewPendingOrder(PendingOrder order)
        {
            order.AccountID = robotContext.AccountInfo.ID;

            return(robotContext.SendNewPendingOrderRequest(
                       protectedContext.MakeProtectedContext(),
                       RequestUniqueId.Next(), order));
        }
Beispiel #7
0
 /// <summary>
 /// Send market or instant order
 /// </summary>
 /// <param name="order">все параметры ордера</param>
 /// <param name="ordType"></param>
 /// <param name="slippagePoints"></param>
 /// <returns></returns>
 protected RequestStatus NewOrder(MarketOrder order, OrderType ordType,
                                  decimal requestedPrice, decimal slippagePoints)
 {
     order.Magic     = magic;
     order.AccountID = robotContext.AccountInfo.ID;
     return(robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                order,
                ordType, requestedPrice, slippagePoints));
 }
        private bool OpenDeal(float price, int dealSide)
        {
            List <MarketOrder> orders;

            robotContext.GetMarketOrders(robotContext.AccountInfo.ID, out orders);
            orders = orders.Where(o => o.Magic == Magic && o.Symbol == ticker).ToList();

            // закрыть сделки противонаправленные текущему знаку
            foreach (var order in orders.Where(o => o.Side != dealSide).ToList())
            {
                robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                              robotContext.AccountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
            }
            // если была, например, покупка - повторно не покупаем
            if (orders.Any(o => o.Side == dealSide))
            {
                return(false);
            }

            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return(false);
            }

            // Пересчёт значений Stop loss и Take profit из пунктов в конкретную цену. Эти значения не могут быть 0
            var stop = StopLossPoints == 0
                                ? (float?)null
                                : price -
                       dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)StopLossPoints);
            var take = TakeProfitPoints == 0
                                ? (float?)null
                                : price +
                       dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)TakeProfitPoints);

            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,    // Уникальный идентификатор чёта
                Magic         = Magic,                          // Этот параметр позволяет отличать сделки разных роботов
                Symbol        = ticker,                         // Инструмент по которому совершается сделка
                Volume        = dealVolumeDepo,                 // Объём средств, на который совершается сделка
                Side          = dealSide,                       // Устанавливаем тип сделки - покупка или продажа
                StopLoss      = stop,                           // Устанавливаем величину Stop loss для открываемой сделки
                TakeProfit    = take,                           // Устанавливаем величину Take profit для открываемой сделки
                ExpertComment = "IchimokuRobot"                 // Комментарий по сделке, оставленный роботом
            },
                OrderType.Market, 0, 0);
            return(true);
        }
 public RequestStatus SendNewPendingOrderRequestSafe(int requestUniqueId, PendingOrder order)
 {
     if (requestUniqueId == 0)
     {
         requestUniqueId = RequestUniqueId.Next();
     }
     if (InvokeRequired)
     {
         return((RequestStatus)Invoke(new Func <PendingOrder, int, RequestStatus>(SendNewPendingOrderRequestUnsafe),
                                      order, requestUniqueId));
     }
     return(SendNewPendingOrderRequestUnsafe(order, requestUniqueId));
 }
Beispiel #10
0
        private void OpenOrder(Cortege3 <string, int, DateTime> order)
        {
            var ticker = order.a;
            var side   = order.b;

            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            float?sl = null;

            if (CheckDice(probStopLoss))
            {
                var quote = QuoteStorage.Instance.ReceiveValue(ticker);
                if (quote != null)
                {
                    var points = minStopPoints;
                    if (CheckDice(propRandomStopStep))
                    {
                        points = points + rnd.Next(maxStopPoints - minStopPoints + 1);
                    }
                    else
                    {
                        points = points + rnd.Next((maxStopPoints - minStopPoints) / stepStopPoints + 1) * stepStopPoints;
                    }
                    sl  = side > 0 ? quote.ask : quote.bid;
                    sl -= side * DalSpot.Instance.GetAbsValue(ticker, (float)points);
                }
            }

            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                Symbol        = ticker,
                Side          = side,
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Volume        = dealVolumeDepo,
                ExpertComment = "RandomRobot",
                Comment       = "",
                StopLoss      = sl,
                TakeProfit    = null
            },
                OrderType.Market, 0, 0);
        }
        private void OpenDeal(float price, int dealSide, string symbol, List <PendingOrder> orders)
        {
            // такой ордер уже размещен?
            var minDeltaPrice = (float)pointCost[symbol] * 2;

            if (orders.Any(o => o.Side == dealSide && Math.Abs(o.PriceFrom - price) < minDeltaPrice))
            {
                return;
            }

            var dealVolumeDepo = CalculateVolume(symbol);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            float?stop = StopLossPoints == 0
                                ? (float?)null
                                : price -
                         dealSide * DalSpot.Instance.GetAbsValue(symbol, (float)StopLossPoints);
            float?take = TakeProfitPoints == 0
                                ? (float?)null
                                : price +
                         dealSide * DalSpot.Instance.GetAbsValue(symbol, (float)TakeProfitPoints);

            robotContext.SendNewPendingOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new PendingOrder
            {
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Symbol        = symbol,
                Volume        = dealVolumeDepo,
                Side          = dealSide,
                StopLoss      = stop,
                TakeProfit    = take,
                ExpertComment = "Kovzharoff",
                PriceFrom     = price,
                PriceSide     = PendingOrderType.Stop
            });
        }
        private void OpenDeal(float price, int dealSide)
        {
            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            // Посчитать stopLoss и takeProfit
            stopLoss = StopLossPoints == 0
                ? dealSide > 0 ? extremumQueue.Min(q => q.a) : extremumQueue.Max(q => q.a)
                : price - dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)StopLossPoints);
            takeProfit = TakeProfitPoints == 0
                                ? extremumQueue.First.a
                                : price + dealSide * DalSpot.Instance.GetAbsValue(ticker, (float)TakeProfitPoints);

            // очистить очередь экстремумов
            extremumQueue.Clear();

            // открыть сделку
            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Symbol        = ticker,
                Volume        = dealVolumeDepo,
                Side          = dealSide,
                StopLoss      = stopLoss,
                TakeProfit    = takeProfit * TakeRange / 100,
                ExpertComment = "DoubleTopRobot"
            },
                OrderType.Market, 0, 0);
        }
Beispiel #13
0
        private void OpenDeal(int dealSide)
        {
            var dealVolumeDepo = CalculateVolume(ticker);

            if (dealVolumeDepo == 0)
            {
                return;
            }

            // открыть сделку
            robotContext.SendNewOrderRequest(
                protectedContext.MakeProtectedContext(),
                RequestUniqueId.Next(),
                new MarketOrder
            {
                AccountID     = robotContext.AccountInfo.ID,
                Magic         = Magic,
                Symbol        = ticker,
                Volume        = dealVolumeDepo,
                Side          = dealSide,
                ExpertComment = "TailBodyRobot"
            },
                OrderType.Market, 0, 0);
        }
Beispiel #14
0
        private void CopyOrdersFromMt4(List <string> events)
        {
            if (!ordersFromMt4Received)
            {
                return;
            }

            try
            {
                // ордера из МТ4
                var ordersMt4 = ordersFromMt4.ExtractAll(1000);

                // ордера из самого терминала
                List <MarketOrder> ordersTs;
                GetMarketOrders(out ordersTs, !ControlOrdersDisregardMagic);

                // для каждого ордера терминала найти аналогичный ордер в списке от МТ4
                // "лишние" ордера удалить
                foreach (var orderTs in ordersTs)
                {
                    var side   = orderTs.Side;
                    var symbol = orderTs.Symbol;

                    var orderTicket = 0;
                    if (orderTs.ExpertComment.StartsWith("Mt4ticket="))
                    {
                        orderTicket = orderTs.ExpertComment.Substring("Mt4ticket=".Length).ToIntSafe() ?? 0;
                    }
                    var existOrderMt4 = ordersMt4.FirstOrDefault(o => o.Magic == orderTicket &&
                                                                 o.Side == side && o.Symbol == symbol);
                    if (existOrderMt4 == null)
                    {
                        // закрыть ордер
                        events.Add(string.Format("Ордер {0} не найден в МТ4 (всего {1} ордеров) и будет закрыт",
                                                 orderTs, ordersMt4.Count));
                        robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                                      robotContext.AccountInfo.ID, orderTs.ID, PositionExitReason.ClosedByRobot);
                        continue;
                    }

                    // проверить, совпадают ли цены SL / TP для ордера в МТ4 и T#
                    var deltaStop = DalSpot.Instance.GetPointsValue(symbol, Math.Abs((orderTs.StopLoss ?? 0) -
                                                                                     (existOrderMt4.StopLoss ?? 0)));
                    var deltaTake = DalSpot.Instance.GetPointsValue(symbol, Math.Abs((orderTs.TakeProfit ?? 0) -
                                                                                     (existOrderMt4.TakeProfit ?? 0)));
                    // обновить цены TP / SL
                    if (deltaStop > 1 || deltaTake > 1)
                    {
                        orderTs.StopLoss   = existOrderMt4.StopLoss;
                        orderTs.TakeProfit = existOrderMt4.TakeProfit;
                        robotContext.SendEditMarketRequest(protectedContext.MakeProtectedContext(), orderTs);
                    }
                }

                // открыть новые ордера
                var requestsWhatHaveBeenAlreadySent = sentRequests.ExtractAll(1000);
                foreach (var orderMt4 in ordersMt4)
                {
                    var orderTicket = orderMt4.Magic.Value;
                    var side        = orderMt4.Side;
                    var symbol      = orderMt4.Symbol;
                    var comment     = "Mt4ticket=" + orderTicket;

                    if (ordersTs.Any(o => o.ExpertComment == comment &&
                                     o.Side == side && o.Symbol == symbol))
                    {
                        continue;
                    }

                    orderMt4.ExpertComment = comment;
                    // пересчитать объем
                    orderMt4.Volume = CalcTradeSharpDealVolume(orderMt4.Volume);
                    if (orderMt4.Volume == 0)
                    {
                        continue;
                    }

                    orderMt4.AccountID = robotContext.AccountInfo.ID;
                    orderMt4.Magic     = Magic;

                    // антифлад
                    if (requestsWhatHaveBeenAlreadySent.Contains(orderTicket))
                    {
                        continue;
                    }
                    // таки открыть ордер
                    var response = robotContext.SendNewOrderRequest(protectedContext.MakeProtectedContext(),
                                                                    RequestUniqueId.Next(), orderMt4, OrderType.Market,
                                                                    (decimal)orderMt4.PriceEnter, 0);
                    requestsWhatHaveBeenAlreadySent.Add(orderTicket);
                }
                sentRequests.ReplaceRange(requestsWhatHaveBeenAlreadySent, 1000);
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в CopyOrdersFromMt4()", ex);
            }
            finally
            {
                ordersFromMt4Received = false;
            }
        }
        public override string ActivateScript(string ticker)
        {
            if (!AccountStatus.Instance.isAuthorized)
            {
                MessageBox.Show("Не авторизован");
                return("Не авторизован");
            }
            var equity = AccountStatus.Instance.AccountData.Equity;

            if (equity <= 0)
            {
                MessageBox.Show("На счете отсутствуют денежные средства");
                return("На счете отсутствуют денежные средства");
            }

            var   orders = MarketOrdersStorage.Instance.MarketOrders.Where(o => o.Symbol == ticker).ToList();
            var   side   = orders.Count == 0 ? DealType.Buy : (DealType)orders[0].Side;
            float?sl     = orders.Count == 0 ? null : orders[0].StopLoss;

            // открыть окно выбора направления входа и SL
            var dlg = new TradeFromSLDlg(orders.Count, side, sl);

            if (dlg.ShowDialog() != DialogResult.OK)
            {
                return("Отменено пользователем");
            }
            side = dlg.Side;
            var targetSl = dlg.StopLoss;

            // выставить стоп остальным ордерам
            foreach (var order in orders)
            {
                var delta       = Math.Abs((order.StopLoss ?? 0) - targetSl);
                var deltaPoints = DalSpot.Instance.GetPointsValue(ticker, delta);
                if (deltaPoints < 2)
                {
                    continue;
                }

                // редактировать ордер
                order.StopLoss = targetSl;
                MainForm.Instance.SendEditMarketRequestSafe(order);
            }

            // получить текущую цену
            var       quotes = QuoteStorage.Instance.ReceiveAllData();
            QuoteData quote;

            quotes.TryGetValue(ticker, out quote);
            if (quote == null)
            {
                return("Нет котировки " + ticker);
            }

            // коэфф пересчета из контрвалюты в валюту депо
            var kCounterDepo = 1f;

            if (!ticker.EndsWith("USD"))
            {
                kCounterDepo = 1 / ((quote.ask + quote.bid) * 0.5f);
            }
            // посчитать макс. допустимый объем входа исходя из просадки
            var ordersResult = orders.Sum(o => o.Volume * o.Side * (targetSl - o.PriceEnter) * kCounterDepo); // убыток (прибыль) по сделкам

            var     priceEnter   = side == DealType.Buy ? quote.ask : quote.bid;
            var     orderLossAbs = ((int)side) * (decimal)(targetSl - priceEnter);
            decimal volumeMax    = decimal.MaxValue;

            // от текущего баланса считать сумму потерь
            var loss = equity * lossPercent / 100;

            if (orderLossAbs < 0)
            {
                volumeMax = (decimal)kCounterDepo * (loss + (decimal)ordersResult) / (-orderLossAbs);
            }

            // вход невозможен
            if (volumeMax < 0)
            {
                var err = string.Format(
                    "Потери по уже открытым позициям для SL {0:f4} ({1:f0}) превысят допустимый процент " +
                    "потерь ({2:f1}%, {3:f0} USD)", targetSl, ordersResult, lossPercent, loss);
                MessageBox.Show(err);
                return(err);
            }

            // множитель для объема
            var indexK = orders.Count;

            if (indexK >= volumePercent.Length)
            {
                indexK = volumePercent.Length - 1;
            }
            var koeffVolume = volumePercent[indexK];

            if (volumeMax < decimal.MaxValue)
            {
                volumeMax *= (koeffVolume / 100M);
            }

            // сравнить объем с предельно допустимым
            var maxVolumeDepo = equity * LeverageMax;
            var maxVolumeBase = maxVolumeDepo / (decimal)((quote.bid + quote.ask) * 0.5f);

            var volumeEnter = Math.Min(volumeMax, maxVolumeBase);

            // округлить объем
            var volume = MarketOrder.RoundDealVolume((int)volumeEnter, VolumeRound,
                                                     volumeMin, volumeStep);

            if (volume == 0)
            {
                var err = string.Format("Объем входа ({0:f0}) после округления равен 0",
                                        volumeEnter);
                MessageBox.Show(err);
                return(err);
            }

            // подтвердить вход)
            if (confirmTrade)
            {
                var orderLoss = volume * ((int)side) * (targetSl - priceEnter);
                var lossStr   = ordersResult != 0
                                  ? string.Format("{0}{1:f0} по уже открытым ордерам и {2:f0} по новому ордеру",
                                                  ordersResult > 0 ? "прибыль" : "", Math.Abs(ordersResult), (-orderLoss))
                                  : (-orderLoss).ToString("f0");
                var prompt = string.Format("Будет открыта позиция: {0} {1} {2}, SL={3:f4}. Потери при SL: {4}. Продолжить?",
                                           side, volume, ticker, targetSl, lossStr);
                if (MessageBox.Show(prompt, "Подтвердить сделку", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    return("Отменено пользователем");
                }
            }

            // войти в рынок
            MainForm.Instance.SendNewOrderRequestSafe(
                RequestUniqueId.Next(),
                AccountStatus.Instance.accountID,
                new MarketOrder
            {
                Volume   = volume,
                Side     = (int)side,
                Symbol   = ticker,
                StopLoss = targetSl
            },
                (decimal)priceEnter, 0, OrderType.Market);

            return("Операция успешна");
        }
Beispiel #16
0
        private List <string> ProcessQuotes(string[] names, CandleDataBidAsk[] quotes, bool isHistoryStartOff)
        {
            var result = new List <string>();

            // дописываем лог
            foreach (var m in pendingLogMessages.Where(e => !logMessages.Contains(e)))
            {
                logMessages.Add(m);
                result.Add(MakeLog(m));
            }

            // проверяем инициализацию
            var message = "не инициализирован, остановлен";

            if (newsSettings == null || currencySettings == null)
            {
                if (!logMessages.Contains(message))
                {
                    logMessages.Add(message);
                    result.Add(MakeLog(message));
                }
                return(result);
            }

            // all ok inform
            // информируем о начале работы
            message = "запущен";
            if (!logMessages.Contains(message))
            {
                logMessages.Add(message);
                result.Add(MakeLog(message));
            }

            // saving to cache
            // сохраняем кэш котировок
            for (var i = 0; i < names.Length; i++)
            {
                var name = names[i];
                if (!quoteStorage.ContainsKey(name))
                {
                    quoteStorage.Add(name, new List <QuoteData>());
                }
                quoteStorage[name].Add(quotes[i].GetCloseQuote());
            }

            // if this call is used for caching quotes - exiting
            // если мы в режиме наполнения кэша - выходим
            if (isHistoryStartOff)
            {
                return(result);
            }

            // detemining model time
            // определение модельного времени
            if (quotes.Length == 0)
            {
                return(result);
            }
            var now = quotes[0].timeClose;

            // update orders' SL & TP
            // обновляем сделки
            List <MarketOrder> orders;

            robotContext.GetMarketOrders(robotContext.AccountInfo.ID, out orders);
            result.AddRange(UpdateOrders(now, orders));

            // working with news
            // make GrabNews calls unfrequent
            // сокращаем частоту вызовов GrabNews
            if ((now - lastGrabNewsCall.GetLastHit()).TotalSeconds < PauseForNewsReadingSeconds)
            {
                return(result);
            }
            var grab = true;                                        // in present - grab each PauseForNewsReadingSeconds

            if (now.Date < DateTime.Today)                          // working in the past (testing)
            {
                if (now.Date == lastGrabNewsCall.GetLastHit().Date) // grabbing only once in day
                {
                    grab = false;
                }
            }
            // grabbing
            // извлечение с Alpari
            if (grab)
            {
                List <string> parseErrors;
                var           news = GrabNews(new DateTime(now.Year, now.Month, now.Day), out parseErrors);
                foreach (var m in parseErrors.Where(e => !logMessages.Contains(e)))
                {
                    logMessages.Add(m);
                    result.Add(MakeLog(m));
                }
                if (news.Count == 0)
                {
                    logNoFlood.LogMessageFormatCheckFlood(LogEntryType.Error,
                                                          LogMsgNoNewsParsed, 1000 * 60 * 5, "Прочитано 0 новостей");
                }
                else
                {
                    logNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                          LogMsgNewsParsed, 1000 * 60 * 5, "Прочитано {0} новостей",
                                                          news.Count);
                }
                freshNews.AddRange(news);
                lastGrabNewsCall.SetTime(now);
            }
            // processing
            // обработка новостей (внешний цикл)
            foreach (var curNews in freshNews)
            {
                var currentNews = curNews;

                // сверяем время
                if (oldNews.Contains(currentNews)) // news already processed
                {
                    continue;
                }
                // news obsolete
                // новость устарела
                if ((now - currentNews.Time - new TimeSpan(0, NewsProcessingDelayMinutes, 0)).TotalMinutes > NewsObsolescenceTimeMinutes)
                {
                    oldNews.Add(currentNews);
                    continue;
                }
                // news in future; skip processing
                // придержим новость на будущее
                if (currentNews.Time + new TimeSpan(0, NewsProcessingDelayMinutes, 0) > now)
                {
                    continue;
                }

                var timeNear = currentNews.Time.AddMinutes(TimeNearMinutes);
                var timeFar  = currentNews.Time.AddMinutes(-TimeFarMinutes);

                result.Add(MakeLog("обрабатывается " + currentNews));
                var chatMessage = "\n"; // здесь формируется сообщение в чат
                chatMessage += string.Format("Обрабатывается новость: [{0}] {1}\nВремя: {2}, прогноз: {3}, фактическое: {4}\n",
                                             currentNews.CountryCode, currentNews.Title, currentNews.Time,
                                             currentNews.ProjectedValue, currentNews.Value);

                // calc weights
                // вычисляем веса, определяем знак
                int valueWeight;
                if (currentNews.ProjectedValue > currentNews.Value)
                {
                    valueWeight = -1;
                }
                else if ((currentNews.ProjectedValue < currentNews.Value))
                {
                    valueWeight = 1;
                }
                else
                {
                    valueWeight = 0;
                }
                var delta = currentNews.ProjectedValue == 0
                                ? 100
                                : (int)Math.Abs((currentNews.Value - currentNews.ProjectedValue) / currentNews.ProjectedValue * 100);
                var newsWeight = GetWeight(currentNews.CountryCode, currentNews.Title, delta);
                // 4 debug

                /*if (newsWeight == 0)
                 * {
                 *  message = string.Format("Valuable news not processed: [{0}] {1}", currentNews.CountryCode,
                 *                              currentNews.Title);
                 *  if (!logMessages.Contains(message))
                 *  {
                 *      logMessages.Add(message);
                 *      result.AddRange(MakeLog(message));
                 *  }
                 * }*/
                var sign = valueWeight * newsWeight;
                if (sign == 0)
                {
                    oldNews.Add(currentNews);
                    chatMessage += "Результат: нет входа в рынок\n";
                    chatMessage += "Причина: " +
                                   (newsWeight == 0
                                        ? "вес новости равен 0\n"
                                        : "отклонение экономического показателя равно 0\n");
                    if (SendMessageInRoom != null)
                    {
                        SendMessageInRoom(chatMessage, chatRoom);
                    }
                    continue;
                }

                // gathering tickers for affected currecncies
                // определяем затронутые новостью валютные пары и их знак новостного сигнала
                var tickersAndSigns = new List <Cortege2 <string, int> >();
                var currencies      = currencySettings.Where(c => c.CountryCode == currentNews.CountryCode).Select(c => c.CurrencyCode);
                foreach (var currency in currencies)
                {
                    var cur = currency;
                    var tickersWithBaseCur = Graphics.Where(g => g.a.StartsWith(cur)).Select(g => g.a);
                    tickersAndSigns.AddRange(tickersWithBaseCur.Select(t => new Cortege2 <string, int>(t, sign)).ToList());
                    var tickersWithQuoteCur = Graphics.Where(g => g.a.EndsWith(cur)).Select(g => g.a);
                    tickersAndSigns.AddRange(
                        tickersWithQuoteCur.Select(t => new Cortege2 <string, int>(t, -sign)).ToList());
                }

                // processing tickers
                // работаем с выбранными валютными парами (внутренний цикл)
                foreach (var tickerAndSign in tickersAndSigns)
                {
                    var ticker  = tickerAndSign.a;
                    var curSign = tickerAndSign.b;

                    // определение действующей на этот момент котировки
                    var data = GetDataFromStorage(ticker, currentNews.Time, currentNews.Time.AddMinutes(5));
                    if (data.Count == 0)
                    {
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: нет котировки для " + ticker + " в диапазоне от " +
                                       currentNews.Time + " до " + currentNews.Time.AddMinutes(5) + "\n";
                        if (SendMessageInRoom != null)
                        {
                            SendMessageInRoom(chatMessage, chatRoom);
                        }
                        continue;
                    }

                    // опорное значение для определения трендов и величины сделки - цена спроса
                    var value = data[0].bid;

                    // определение тренда
                    int signNear = 0, signFar = 0;
                    data = GetDataFromStorage(ticker, timeNear, timeNear.AddMinutes(5));
                    if (data.Count == 0)
                    {
                        // 4 debug
                        var hint = new RobotHint(ticker, "", "insufficient data for near-trend",
                                                 curSign > 0 ? "BUY no near-data" : "SELL no near-data", "e", value)
                        {
                            Time = now, ColorFill = Color.Red
                        };
                        result.Add(hint.ToString());
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: недостаточно данных для определения тренда после выхода новости\n";
                        if (SendMessageInRoom != null)
                        {
                            SendMessageInRoom(chatMessage, chatRoom);
                        }
                        continue;
                    }
                    var valueNear = data[0].bid;
                    if (value > valueNear)
                    {
                        signNear = 1;
                    }
                    else if (value < valueNear)
                    {
                        signNear = -1;
                    }
                    data = GetDataFromStorage(ticker, timeFar, timeFar.AddMinutes(5));
                    if (data.Count == 0)
                    {
                        // 4 debug
                        var hint = new RobotHint(ticker, "", "insufficient data for far-trend",
                                                 curSign > 0 ? "BUY no far-data" : "SELL no far-data", "e", value)
                        {
                            Time = now, ColorFill = Color.Red
                        };
                        result.Add(hint.ToString());
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: недостаточно данных для определения тренда до выхода новости\n";
                        if (SendMessageInRoom != null)
                        {
                            SendMessageInRoom(chatMessage, chatRoom);
                        }
                        continue;
                    }
                    var valueFar = data[0].bid;
                    if (value > valueFar)
                    {
                        signFar = 1;
                    }
                    else if (value < valueFar)
                    {
                        signFar = -1;
                    }

                    // определяем необходимость входа в рынок
                    var values = new Dictionary <string, double>();
                    values.Add("tn", curSign);
                    values.Add("tba", signFar);
                    values.Add("tcb", signNear);
                    double formulaResult;
                    var    resultFlag = expressionResolver.Calculate(values, out formulaResult);
                    if (!resultFlag)
                    {
                        result.Add(MakeLog("Ошибка в расчете по формуле для входа в рынок"));
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: ошибка в расчете по формуле для входа в рынок\n";
                        if (SendMessageInRoom != null)
                        {
                            SendMessageInRoom(chatMessage, chatRoom);
                        }
                        continue;
                    }

                    // вход в рынок
                    var tradeSign = 0;
                    switch (EnterSign)
                    {
                    case EnterSignEnum.Tn:
                        tradeSign = curSign;
                        break;

                    case EnterSignEnum.NotTn:
                        tradeSign = -curSign;
                        break;

                    case EnterSignEnum.Tba:
                        tradeSign = signFar;
                        break;

                    case EnterSignEnum.NotTba:
                        tradeSign = -signFar;
                        break;

                    case EnterSignEnum.Tcb:
                        tradeSign = signNear;
                        break;

                    case EnterSignEnum.NotTcb:
                        tradeSign = -signNear;
                        break;
                    }
                    if (formulaResult != 0)
                    {
                        // если получен сигнал на покупку - купить, закрыв продажи
                        // наоборот, если получен сигнал на продажу - продать, закрыв покупки
                        robotContext.GetMarketOrders(robotContext.AccountInfo.ID, out orders);
                        var ordersToClose = orders.Where(o => o.Symbol == ticker && o.Side != tradeSign).ToList();
                        foreach (var order in ordersToClose)
                        {
                            robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                                          robotContext.AccountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                        }
                        // создаем ордер
                        var decreaseSl = DalSpot.Instance.GetAbsValue(ticker, (float)InitialSlPoints);
                        var slValue    = value - tradeSign * decreaseSl;
                        var decreaseTp = DalSpot.Instance.GetAbsValue(ticker, (float)InitialTpPoints);
                        var tpValue    = value + tradeSign * decreaseTp;
                        var newOrder   = new MarketOrder
                        {
                            AccountID     = robotContext.AccountInfo.ID,
                            Magic         = Magic,
                            Symbol        = ticker,
                            Volume        = Volume,
                            Side          = tradeSign,
                            StopLoss      = slValue,
                            TakeProfit    = tpValue,
                            ExpertComment = currentNews.Title
                        };

                        var status = robotContext.SendNewOrderRequest(protectedContext.MakeProtectedContext(),
                                                                      RequestUniqueId.Next(),
                                                                      newOrder,
                                                                      OrderType.Market, (decimal)value, 0);
                        if (status != RequestStatus.OK)
                        {
                            var hint = new RobotHint(ticker, "",
                                                     "SendNewOrderRequest error: " +
                                                     EnumFriendlyName <RequestStatus> .GetString(status) + " news: " +
                                                     currentNews,
                                                     tradeSign > 0 ? "BUY error" : "SELL error", "e", value)
                            {
                                Time      = now,
                                ColorFill = Color.Red
                            };
                            result.Add(hint.ToString());
                        }
                        else
                        {
                            var hint = new RobotHint(ticker, "", "SendNewOrderRequest Ok, news: " + currentNews,
                                                     tradeSign > 0 ? "BUY" : "SELL", "i", value)
                            {
                                Time = now, ColorFill = Color.Red
                            };
                            result.Add(MakeLog("вход в рынок по новости " + currentNews));
                            result.Add(hint.ToString());
                            chatMessage += "Результат: вход в рынок: " + (tradeSign > 0 ? "покупка " : "продажа ") + ticker + "\n";
                        }
                    }
                    else
                    {
                        var hint = new RobotHint(ticker, "", "Market condition fulfill failed, news: " + currentNews,
                                                 tradeSign > 0 ? "BUY no condition" : "SELL no condition", "e", value)
                        {
                            Time = now, RobotHintType = RobotHint.HintType.Стоп
                        };
                        result.Add(hint.ToString());
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: не выполнено условие входа\n";
                    }
                    if (SendMessageInRoom != null)
                    {
                        SendMessageInRoom(chatMessage, chatRoom);
                    }
                }
                oldNews.Add(currentNews);
            }
            return(result);
        }
        public override string ActivateScript(string ticker)
        {
            if (!AccountStatus.Instance.isAuthorized)
            {
                MessageBox.Show("Не авторизован");
                return("Не авторизован");
            }
            var account = AccountStatus.Instance.AccountData;

            if (account == null)
            {
                MessageBox.Show("Не авторизован");
                return("Не авторизован");
            }

            var equity = account.Equity;

            if (equity <= 0)
            {
                MessageBox.Show("На счете отсутствуют денежные средства");
                return("На счете отсутствуют денежные средства");
            }

            var     dealSide = side;
            decimal?sl = null, tp = null;
            float?  trailLevel = null, trailTarget = null;

            // предполагаемая цена входа
            var       quotes = QuoteStorage.Instance.ReceiveAllData();
            QuoteData currentQuote;

            quotes.TryGetValue(ticker, out currentQuote);
            var reqPrice = currentQuote == null
                               ? 0
                               : Side == DealType.Buy
                                     ? currentQuote.ask
                                     : currentQuote.bid;

            if (OrderType == ScriptOrderType.Отложенный && currentQuote == null)
            {
                return("Отложенный ордер не создан - нет котировки " + ticker);
            }

            // для отложенного ордера обязательно запросим цену
            decimal priceEnter = 0;
            float   dealPrice  = 0;

            if (RequestSide || OrderType == ScriptOrderType.Отложенный)
            {
                var dlg = new ScriptPartDepoFormDialog(
                    (int)side,
                    currentQuote == null ? (float?)null : currentQuote.bid,
                    OrderType == ScriptOrderType.Отложенный)
                {
                    TradeTicker = ticker
                };
                if (dlg.ShowDialog() == DialogResult.Cancel)
                {
                    return("Отменен");
                }
                priceEnter = dlg.Price ?? 0;
                sl         = dlg.SL;
                tp         = dlg.TP;
                dealSide   = (DealType)dlg.Side;

                if (dlg.Trailing != null && dlg.Trailing.Length == 2 && (dlg.Trailing[0] != 0 || dlg.Trailing[1] != 0))
                {
                    if (currentQuote == null)
                    {
                        var msg = string.Format("Нет котировки \"{0}\" для расчета пп трейлинга", ticker);
                        MessageBox.Show(msg);
                        return(msg);
                    }

                    var trailPrice = dlg.Trailing[0];
                    dealPrice =
                        OrderType == ScriptOrderType.Отложенный ? (float)priceEnter : (dealSide == DealType.Buy ? currentQuote.ask : currentQuote.bid);
                    var trailPips = DalSpot.Instance.GetPointsValue(ticker, ((int)dealSide) * (trailPrice - dealPrice));

                    // преобразовать цену в пп от входа
                    trailLevel  = trailPips;
                    trailTarget = dlg.Trailing[1];
                }
            }

            // объем в валюте депозита
            var volumeDepo = equity * leverage;
            var volumeBase = volumeDepo;

            // из объема депо пересчитать в объем базовой валюты
            var depoCurx = AccountStatus.Instance.AccountData.Currency;

            bool inverse, pairsEqual;
            var  tickerTrans = DalSpot.Instance.FindSymbol(ticker, true, depoCurx,
                                                           out inverse, out pairsEqual);

            if (!pairsEqual)
            {
                QuoteData quote;
                quotes.TryGetValue(tickerTrans, out quote);
                if (quote == null)
                {
                    var msgError = string.Format(
                        "Невозможно рассчитать объем - отсутствует котировка \"{0}\"", tickerTrans);
                    MessageBox.Show(msgError);
                    return(msgError);
                }
                var priceTrans = inverse ? 1 / quote.bid : quote.ask;
                volumeBase /= (decimal)priceTrans;
            }

            // округлить объем
            var lotSize = DalSpot.Instance.GetMinStepLot(ticker, account.Group);

            volumeBase = MarketOrder.RoundDealVolume((int)volumeBase, VolumeRound,
                                                     lotSize.minVolume, lotSize.volumeStep);
            if (volumeBase == 0)
            {
                var msgError = $"Рассчетный объем входа ({volumeBase}) меньше допустимого ({lotSize.minVolume})";
                MessageBox.Show(msgError);
                return(msgError);
            }

            // проверить количество входов (по тикеру либо вообще)
            var ordersCount =
                DealCounting == DealCountingType.ОбщийУчет
                    ? MarketOrdersStorage.Instance.MarketOrders.Count
                    : MarketOrdersStorage.Instance.MarketOrders.Count(o => o.Symbol == ticker);

            if (ordersCount >= dealsMax)
            {
                var msgError =
                    DealCounting == DealCountingType.ОбщийУчет
                    ? $"Уже открыто {ordersCount} сделок из {dealsMax} макс."
                        : $"По \"{ticker}\" уже открыто {ordersCount} сделок из {dealsMax} макс.";
                MessageBox.Show(msgError);
                return(msgError);
            }

            // подтверждение
            var confirmPrice = dealPrice;

            if (confirmPrice == 0)
            {
                confirmPrice = (dealSide == DealType.Buy ? currentQuote.ask : currentQuote.bid);
            }

            if (confirmTrade)
            {
                if (MessageBox.Show(string.Format("Будет совершена {0} {1} {2} по {3}. Продолжить?",
                                                  dealSide == DealType.Buy ? "покупка" : "продажа",
                                                  volumeBase.ToStringUniformMoneyFormat(), depoCurx,
                                                  confirmPrice.ToStringUniformPriceFormat()),
                                    "Подтверждение", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    return("отменено пользователем");
                }
            }

            // таки войти в рынок
            if (OrderType == ScriptOrderType.ыночный)
            {
                MainForm.Instance.SendNewOrderRequestSafe(
                    RequestUniqueId.Next(),
                    AccountStatus.Instance.accountID,
                    new MarketOrder
                {
                    Volume       = (int)volumeBase,
                    Side         = (int)dealSide,
                    Symbol       = ticker,
                    StopLoss     = (float?)sl,
                    TakeProfit   = (float?)tp,
                    TrailLevel1  = trailLevel,
                    TrailTarget1 = trailTarget
                },
                    priceEnter, 0, Contract.Entity.OrderType.Market);
            }
            else
            {
                // создать отложенник
                var orderType = PendingOrderType.Limit;
                if (((int)dealSide == 1 && currentQuote.ask < (float)priceEnter) ||
                    ((int)dealSide == -1 && currentQuote.bid > (float)priceEnter))
                {
                    orderType = PendingOrderType.Stop;
                }
                var pendingOrder = new PendingOrder
                {
                    AccountID    = AccountStatus.Instance.accountID,
                    Symbol       = ticker,
                    Volume       = (int)volumeBase,
                    Side         = (int)dealSide,
                    PriceSide    = orderType,
                    PriceFrom    = (float)priceEnter,
                    StopLoss     = (float?)sl,
                    TakeProfit   = (float?)tp,
                    TrailLevel1  = trailLevel,
                    TrailTarget1 = trailTarget
                };

                MainForm.Instance.SendNewPendingOrderRequestSafe(RequestUniqueId.Next(), pendingOrder);
            }

            return("Сделка с фиксированным плечом (" + dealSide + " " + ticker + ") совершена");
        }
        public override List <string> OnQuotesReceived(string[] names, QuoteData[] quotes, bool isHistoryStartOff)
        {
            if (formulaResolver == null || packer == null)
            {
                return(null);
            }
            curTime = quotes[0].time;

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

            QuoteData 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.bid, curQuote.time);
            Dictionary <string, double> varValues = null;

            if (candle != null)
            {
                candles.Add(candle);
                countCandles++;
                // обновить очереди (для индекса, переменные вида usdjpy#15)
                if (lastBidLists.Count > 0)
                {
                    foreach (var listTicker in lastBidLists)
                    {
                        float price;
                        if (!lastBids.TryGetValue(listTicker.Key, out price))
                        {
                            price = 0;
                        }
                        listTicker.Value.Add(price);
                    }
                }
                // посчитать индекс
                double index;
                varValues = GetVariableValues();
                if (formulaResolver.Calculate(varValues, out index))
                {
                    lastIndexValue = double.IsNaN(index) ? 0 : (float)index;
                }
                lastIndicies.Add(lastIndexValue ?? 0);
            }

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

            RobotHint hint = null;

            // получить знак дивергенции
            if (candle != null)
            {
                string             commentOnDivergence = string.Empty;
                var                divergenceSign      = GetDivergenceSign(out commentOnDivergence);
                List <MarketOrder> orders;
                robotContext.GetMarketOrders(robotContext.accountInfo.ID, out orders);
                if (divergenceSign != 0)
                {
                    var hintText = new StringBuilder();
                    hintText.AppendLine(commentOnDivergence);
                    hintText.AppendLine("Переменные:");
                    // ReSharper disable PossibleNullReferenceException)
                    foreach (var pair in varValues)
                    // ReSharper restore PossibleNullReferenceException
                    {
                        hintText.AppendLine(string.Format("{1}{0}{2:f4}", (char)9, pair.Key, pair.Value));
                    }

                    hint = new RobotHint(Graphics[0].a, Graphics[0].b.ToString(),
                                         hintText.ToString(), divergenceSign > 0 ? "BUY" : "SELL", "e", curQuote.bid)
                    {
                        Time = candle.timeOpen,
                        //curTime
                        ColorFill     = divergenceSign > 0 ? Color.Green : Color.Red,
                        ColorLine     = Color.Black,
                        RobotHintType = divergenceSign > 0
                                                       ? RobotHint.HintType.Покупка
                                                       : RobotHint.HintType.Продажа
                    };

                    // если получен сигнал на покупку - купить, закрыв продажи
                    // наоборот, если получен сигнал на продажу - продать, закрыв покупки
                    var ordersToClose = orders.FindAll(o => o.Side != divergenceSign);
                    foreach (var order in ordersToClose)
                    {
                        robotContext.SendCloseRequest(CurrentProtectedContext.Instance.MakeProtectedContext(),
                                                      robotContext.accountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                    }

                    // открыть позу в направлении знака дивера
                    decimal?stop = StopLossPoints == 0
                                        ? (decimal?)null
                                        : (decimal)curQuote.bid -
                                   divergenceSign * DalSpot.Instance.GetAbsValue(ticker, (decimal)StopLossPoints);
                    decimal?take = TakeProfitPoints == 0
                                        ? (decimal?)null
                                        : (decimal)curQuote.bid +
                                   divergenceSign * DalSpot.Instance.GetAbsValue(ticker, (decimal)TakeProfitPoints);

                    robotContext.SendNewOrderRequest(CurrentProtectedContext.Instance.MakeProtectedContext(),
                                                     RequestUniqueId.Next(), robotContext.accountInfo.ID, Magic, ticker, Volume,
                                                     divergenceSign, OrderType.Market, 0, 0,
                                                     stop, take, null, null, string.Empty, "OscillatorBasedRobot");
                }
            }

            return(hint != null ? new List <string> {
                hint.ToString()
            } : null);
        }
Beispiel #19
0
        private void OpenMarket(int side, OrderType ordType)
        {
            Account account = null;

            if (AccountStatus.Instance.connectionStatus == AccountConnectionStatus.Connected)
            {
                account = AccountStatus.Instance.AccountData;
            }
            if (account == null)
            {
                MessageBox.Show(EnumFriendlyName <AccountConnectionStatus> .GetString(AccountConnectionStatus.NotConnected),
                                Localizer.GetString("TitleWarning"));
                return;
            }

            var sl = tbSL.Text.Replace(",", ".").ToDecimalUniformSafe();
            var tp = tbTP.Text.Replace(",", ".").ToDecimalUniformSafe();

            float?[] trailingLevels;
            float?[] trailTargets;
            GetTrailingLevels(side, out trailingLevels, out trailTargets);

            var symbol = cbCurx.Text;

            // для инстант-ордера получить текущую цену
            var slipPoints     = 0f;
            var requestedPrice = 0f;
            var quote          = QuoteStorage.Instance.ReceiveValue(symbol);

            if (cbSlippage.Checked)
            {
                slipPoints = udSlippagePoints.Text.ToFloatUniform();

                if (quote == null)
                {
                    MessageBox.Show(string.Format(Localizer.GetString("MessageNoPriceForInstantOrderFmt"), symbol),
                                    Localizer.GetString("TitleWarning"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
                requestedPrice = side > 0 ? quote.ask : quote.bid;
            }

            var volm = cbVolume.Text.Replace(" ", "").ToInt();

            // предупредить трейдера?
            if (!CheckMargin(symbol, side, volm))
            {
                return;
            }

            RequestStatus status;

            try
            {
                status = MainForm.Instance.SendNewOrderRequestSafe(
                    RequestUniqueId.Next(),
                    account.ID,
                    new MarketOrder
                {
                    Volume       = volm,
                    Side         = side,
                    Symbol       = symbol,
                    StopLoss     = (float?)(sl != 0 ? sl : null),
                    TakeProfit   = (float?)(tp != 0 ? tp : null),
                    Magic        = tbMagic.Text.ToIntSafe(),
                    Comment      = tbComment.Text,
                    TrailLevel1  = trailingLevels[0],
                    TrailTarget1 = trailTargets[0]
                },
                    (decimal)requestedPrice, (decimal)slipPoints, ordType);
            }
            catch (Exception ex)
            {
                Logger.Error("Server proxy: SendNewOrderRequest error: ", ex);
                MessageBox.Show(Localizer.GetString("MessageUnableToDeliverRequest"),
                                Localizer.GetString("TitleError"),
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (status != RequestStatus.OK)
            {
                MessageBox.Show(
                    EnumFriendlyName <RequestStatus> .GetString(status),
                    Localizer.GetString("TitleError"),
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
Beispiel #20
0
        private void MakePending(int side)
        {
            var priceVal = tbPrice.Text.Replace(",", ".").ToFloatUniformSafe();

            if (!priceVal.HasValue)
            {
                MessageBox.Show(Localizer.GetString("MessagePriceNotProvided"));
                tbPrice.Focus();
                return;
            }
            var price = priceVal.Value;

            if (price <= 0)
            {
                MessageBox.Show(Localizer.GetString("MessagePriceMustBePositive"));
                tbPrice.Text = "";
                tbPrice.Focus();
                return;
            }

            if (lastQuote == null)
            {
                MessageBox.Show(Localizer.GetString("MessageNoQuote"));
                return;
            }

            // создать новый отложенный ордер
            var volm      = cbVolume.Text.Replace(" ", "").ToInt();
            var orderType = PendingOrderType.Limit;

            if ((side == 1 && lastQuote.ask < price) || (side == -1 && lastQuote.bid > price))
            {
                orderType = PendingOrderType.Stop;
            }
            var orderOCO   = (PendingOrder)cbOrderOCO.SelectedItem;
            var orderOCOId = orderOCO == null ? (int?)null : orderOCO.ID;

            float?[] trailingLevels;
            float?[] trailTargets;
            GetTrailingLevels(side, out trailingLevels, out trailTargets);

            var order = new PendingOrder
            {
                AccountID     = AccountStatus.Instance.accountID,
                Symbol        = Ticker,
                Magic         = tbMagic.Text.ToIntSafe(),
                Volume        = volm,
                Side          = side,
                PriceSide     = orderType,
                PriceFrom     = price,
                PriceTo       = tbPriceTo.Text.Replace(",", ".").ToFloatUniformSafe(),
                TimeFrom      = cbStartFrom.Checked ? dpTimeFrom.Value : (DateTime?)null,
                TimeTo        = cbEndTime.Checked ? dpTimeTo.Value : (DateTime?)null,
                StopLoss      = tbSL.Text.Replace(",", ".").ToFloatUniformSafe(),
                TakeProfit    = tbTP.Text.Replace(",", ".").ToFloatUniformSafe(),
                PairOCO       = orderOCOId > 0 ? orderOCO.ID : (int?)null,
                Comment       = tbComment.Text,
                ExpertComment = tbExpertComment.Text,
                // трейлинг
                TrailLevel1  = trailingLevels[0],
                TrailLevel2  = trailingLevels[1],
                TrailLevel3  = trailingLevels[2],
                TrailLevel4  = trailingLevels[3],
                TrailTarget1 = trailTargets[0],
                TrailTarget2 = trailTargets[1],
                TrailTarget3 = trailTargets[2],
                TrailTarget4 = trailTargets[3],
            };

            MainForm.Instance.SendNewPendingOrderRequestSafe(RequestUniqueId.Next(), order);
        }
Beispiel #21
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);
        }
Beispiel #22
0
        public void CheckPendingOrder(PendingOrder order, Dictionary <string, QuoteData> curPrices)
        {
            // проверка на зафлаживание
            if (pendingFloodTimes.ContainsKey(order.ID))
            {
                var time = pendingFloodTimes[order.ID];
                if (DateTime.Now < time)
                {
                    return;
                }
                pendingFloodTimes.Remove(order.ID);
            }
            // отменить устаревший ордер)
            if (order.TimeTo.HasValue)
            {
                if (DateTime.Now > order.TimeTo)
                {
                    //var pairCancel = curPrices.ContainsKey(order.Symbol) ? curPrices[order.Symbol] : null;
                    //var priceCancel = pairCancel == null ? 0 : order.Side > 0 ? pairCancel.Bid : pairCancel.Ask;
                    proxyTrade.SendDeletePendingOrderRequest(ProtectedOperationContext.MakeServerSideContext(),
                                                             order, PendingOrderStatus.Отменен, null, "Экспирация");
                    return;
                }
            }
            // получить текущую котировку
            if (!curPrices.ContainsKey(order.Symbol))
            {
                if ((DateTime.Now - timeStarted).TotalMilliseconds > MinMillsToReportError)
                {
                    floodSafeLogger.LogMessageFormatCheckFlood(LogEntryType.Debug, MsgNoQuoteMagic, 5 * 60 * 1000,
                                                               "CheckOrder: нет котировки по {0} для отлож. ордера #{1}",
                                                               order.Symbol, order.ID);
                }
                return;
            }
            var pricePair = curPrices[order.Symbol];
            var price     = order.Side > 0 ? pricePair.ask : pricePair.bid;

            // проверить нахождение в рамках цены и времени
            if (order.TimeFrom.HasValue)
            {
                if (DateTime.Now < order.TimeFrom)
                {
                    return;
                }
            }
            // цена...
            var orderFires = false;

            if (order.Side > 0 && ((PendingOrderPriceSide)order.PriceSide) == PendingOrderPriceSide.Limit)
            {
                if (price <= order.PriceFrom && (order.PriceTo == null ? true : price >= order.PriceTo))
                {
                    orderFires = true;
                }
            }
            else
            if (order.Side < 0 && ((PendingOrderPriceSide)order.PriceSide) == PendingOrderPriceSide.Limit)
            {
                if (price >= order.PriceFrom && (order.PriceTo == null ? true : price <= order.PriceTo))
                {
                    orderFires = true;
                }
            }
            else
            if (order.Side > 0 && ((PendingOrderPriceSide)order.PriceSide) == PendingOrderPriceSide.Stop)
            {
                if (price >= order.PriceFrom && (order.PriceTo == null ? true : price <= order.PriceTo))
                {
                    orderFires = true;
                }
            }
            else
            {
                if (price <= order.PriceFrom && (order.PriceTo == null ? true : price >= order.PriceTo))
                {
                    orderFires = true;
                }
            }
            if (!orderFires)
            {
                return;
            }
            Logger.InfoFormat("Активация отлож. ордера #{0} ({1} {2} at {3}), цена {4}",
                              order.ID, (DealType)order.Side, order.PriceSide,
                              order.PriceFrom.ToStringUniformPriceFormat(true),
                              price.ToStringUniformPriceFormat(true));

            // активировать ордер
            var orderMarket = new MarketOrder
            {
                AccountID  = order.AccountID,
                Magic      = order.Magic,
                Symbol     = order.Symbol,
                Volume     = order.Volume,
                Side       = order.Side,
                StopLoss   = order.StopLoss,
                TakeProfit = order.TakeProfit,
                Comment    = string.Format("по ордеру #{0}", order.ID)
            };

            var reqStatus = proxyTrade.SendNewOrderRequest(
                ProtectedOperationContext.MakeServerSideContext(),
                RequestUniqueId.Next(),
                orderMarket,
                OrderType.Market,
                0, 0);     // проскальзывание

            if (reqStatus == RequestStatus.OK)
            {
                // удалить парный ордер
                if (order.PairOCO.HasValue && order.PairOCO > 0)
                {
                    List <PendingOrder> orders;
                    try
                    {
                        proxyAccount.GetPendingOrders(order.AccountID, out orders);
                        var orderPair = orders == null ? null : orders.FirstOrDefault(o => o.ID == order.PairOCO.Value);
                        if (orderPair != null)
                        {
                            proxyTrade.SendDeletePendingOrderRequest(ProtectedOperationContext.MakeServerSideContext(),
                                                                     orderPair, PendingOrderStatus.Отменен, null, "OCO");
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("Ошибка удаления парного ордера {0} для ордера {1}: {2}",
                                           order.PairOCO, order, ex);
                    }
                }

                // удалить ордер
                proxyTrade.SendDeletePendingOrderRequest(ProtectedOperationContext.MakeServerSideContext(),
                                                         order, PendingOrderStatus.Отменен, null, "Активирован");
            }
            else
            {
                // зафлаживание
                Logger.ErrorFormat("Ошибка активации отлож. ордера #{0}: {1}", order.ID, reqStatus);
                var nextTime = DateTime.Now.AddMilliseconds(PendingFloodTimeoutMils);
                if (pendingFloodTimes.ContainsKey(order.ID))
                {
                    pendingFloodTimes[order.ID] = nextTime;
                }
                else
                {
                    pendingFloodTimes.Add(order.ID, nextTime);
                }
            }
        }
Beispiel #23
0
        public override List <string> OnQuotesReceived(string[] names, CandleDataBidAsk[] quotes, bool isHistoryStartOff)
        {
            var events = new List <string>();

            if (tickers.Length == 0 || isHistoryStartOff)
            {
                return(events);
            }

            if (lastTrade == null)
            {
                lastTrade = new ThreadSafeTimeStamp();
                lastTrade.Touch();
            }

            // секунд с последнего трейда...
            var timeSince = (DateTime.Now - lastTrade.GetLastHit()).TotalSeconds;

            if (timeSince < tradeIntervalSec)
            {
                return(events);
            }

            lastTrade.Touch();

            // затребовать все сделки со своим magic
            List <MarketOrder> orders;

            GetMarketOrders(out orders, true);
            var sides = tickers.ToDictionary(t => t, t => 1);

            if (orders != null)
            {
                foreach (var order in orders)
                {
                    if (sides.ContainsKey(order.Symbol))
                    {
                        sides[order.Symbol] = -order.Side;
                    }
                    // закрыть старую сделку
                    CloseMarketOrder(order.ID);
                }
            }

            // открыть новые сделки
            foreach (var tickerSide in sides)
            {
                var newOrd = new MarketOrder
                {
                    Symbol        = tickerSide.Key,
                    Side          = tickerSide.Value,
                    AccountID     = robotContext.AccountInfo.ID,
                    Magic         = Magic,
                    Volume        = FixedVolume,
                    ExpertComment = "SimpleTradeMachine"
                };
                var rst = robotContext.SendNewOrderRequest(protectedContext.MakeProtectedContext(),
                                                           RequestUniqueId.Next(), newOrd, OrderType.Market, 0, 0);
            }

            return(events);
        }