Beispiel #1
0
        /// <summary>
        /// подвинуть nextUpdateTime чуть назад, так, чтобы след. обновление произошло не позднее,
        /// чем через maxMillisecondsDelay милисекунд
        /// </summary>
        public void HurryUpUpdateMaxDelay(int maxMillisecondsDelay)
        {
            var delay = (nextUpdateTime.GetLastHit() - DateTime.Now).TotalMilliseconds;

            if (delay > maxMillisecondsDelay)
            {
                nextUpdateTime.SetTime(DateTime.Now.AddMilliseconds(maxMillisecondsDelay));
            }
        }
Beispiel #2
0
 private void CheckRoomEntered()
 {
     while (!isStopping)
     {
         Thread.Sleep(100);
         if (!sender.IsOnline)
         {
             continue;
         }
         var checkTime = liveRoomCheckTime.GetLastHit();
         if (checkTime > DateTime.Now)
         {
             continue;
         }
         foreach (var room in ChatSettings.Instance.Rooms)
         {
             bool timeoutFlag;
             if (!enteredRooms.Contains(room, LockTimeout, out timeoutFlag))
             {
                 try
                 {
                     // TODO: пароль берется из оперативного списка. если вход не удался, то пароль сбрасывается
                     sender.EnterRoom(room, GetRoomPassword(room));
                 }
                 catch (Exception ex)
                 {
                     Logger.Error("Ошибка входа в комнату чата (ChatControlBackEnd.CheckRoomEntered)", ex);
                 }
             }
         }
         liveRoomCheckTime.SetTime(DateTime.Now + aliveTimeSpan);
     }
 }
Beispiel #3
0
        public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            if (string.IsNullOrEmpty(order.ExpertComment))
            {
                Logger.ErrorFormat("SignalDealer.SendCloseRequest({0}) - поле ExpertComment не заполнено",
                                   order.ID);
                //return RequestStatus.DealerError;
            }
            // получить цену
            var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);

            if (quote == null)
            {
                return(RequestStatus.NoPrice);
            }
            var price = order.Side > 0 ? quote.GetPrice(QuoteType.Bid) : quote.GetPrice(QuoteType.Ask);
            // отправить сигнал
            var signal = new ManagerSignal {
                Id     = order.ExpertComment, PriceClose = (decimal)price, Category = signalCategoryCode,
                Symbol = order.Symbol, Leverage = 0, Price = (decimal)order.PriceEnter, Side = order.Side
            };
            var timeExec = new ThreadSafeTimeStamp();

            timeExec.Touch();
            if (!string.IsNullOrEmpty(order.ExpertComment) && !SendSignal(signal, false))
            {
                return(RequestStatus.DealerError);
            }
            var endTime = DateTime.Now - timeExec.GetLastHit();

            Logger.InfoFormat("Время исполнения SendCloseRequest SendSignal: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
            timeExec.Touch();
            // закрыть ордер немедленно
            var result = ServerInterface.CloseOrder(order, (decimal)price, reason);

            endTime = DateTime.Now - timeExec.GetLastHit();
            Logger.InfoFormat("Время исполнения SendCloseRequest - CloseOrder: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
            return(result ? RequestStatus.OK : RequestStatus.ServerError);
        }
Beispiel #4
0
        public User GetUser(int id)
        {
            var result = GetAllUsers().FirstOrDefault(u => u.ID == id);

            if (result == null && DateTime.Now.Subtract(lastRequestTime.GetLastHit()).TotalMinutes > 1)
            {
                if (GetAllPlatformUsers == null)
                {
                    return(null);
                }
                users.AddRange(GetAllPlatformUsers().Select(u => new User(u)), LockTimeout);
                result = GetAllUsers().FirstOrDefault(u => u.ID == id);
            }
            return(result);
        }
        public void ThreadSafeTimeStampTest()
        {
            var timeSt = new ThreadSafeTimeStamp();

            var method = new WaitCallback(s =>
            {
                for (var i = 0; i < 4; i++)
                {
                    timeSt.Touch();
                    Thread.Sleep(200);
                    var delta = (DateTime.Now - timeSt.GetLastHit()).TotalMilliseconds;
                }
            });

            ThreadPool.QueueUserWorkItem(method);
            ThreadPool.QueueUserWorkItem(method);
        }
        private void StoreRoutine()
        {
            const int iterationLen = 100;
            int       nIters       = storeInterval / iterationLen;
            int       curIter      = 0;

            while (!isStopping)
            {
                curIter++;
                if (curIter <= nIters)
                {
                    Thread.Sleep(iterationLen);
                    continue;
                }
                curIter = 0;

                // сохранить котировки из списка
                bool isTimeout;
                var  candles = queueCandles.ExtractAll(QueueTimeout, out isTimeout);
                if (isTimeout)
                {
                    loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Error,
                                                             LogMagicQueueTimeout, 60 * 1000 * 10,
                                                             "QuoteStoreStream: таймаут чтения очереди ({0}), длина очереди {1}",
                                                             QueueTimeout, queueLength);
                    continue;
                }
                if (candles.Count == 0)
                {
                    var lastTime = lastQuoteTime.GetLastHit();
                    if ((DateTime.Now - lastTime).TotalMilliseconds > ModuleStatusController.MaxMillsBetweenQuotes)
                    {
                        ModuleStatusController.Instance.Status.AddError(ServiceProcessState.HasCriticalErrors,
                                                                        "quote stream", DateTime.Now, "QUOTE");
                    }
                    continue;
                }
                lastQuoteTime.Touch();
                ModuleStatusController.Instance.Status.RemoveError(ServiceProcessState.HasCriticalErrors,
                                                                   "QUOTE");
                queueLength = 0;

                // собственно сохранить
                DoSaveCandles(candles);
            }
        }
        public void OnCandleUpdated(CandleData updatedCandle, List <CandleData> newCandles)
        {
            if (updatedCandle == null)
            {
                return;
            }

            // перерисовка должна производиться не чаще, чем раз в N секунд
            // (если свеча просто обновилась)
            if (newCandles == null || newCandles.Count == 0)
            {
                var deltaSeconds = (DateTime.Now - lastUpdateTime.GetLastHit()).TotalSeconds;
                if (deltaSeconds < redrawSeconds)
                {
                    return;
                }
            }

            BuildSeries(owner);
        }
Beispiel #8
0
        private void CheckTimeout()
        {
            // поток котировок может быть не включен в рабочий день
            if (!WorkingDay.Instance.IsWorkingDay(DateTime.Now))
            {
                return;
            }
            var delta = (DateTime.Now - lastMessageReceived.GetLastHit()).TotalMilliseconds;

            if (delta < timeoutIntervalMils)
            {
                return;
            }
            Logger.Error("TCPFeeder: сработал таймаут TCP получателя котировок, перезапускаем");
            // инициировать таймаут

            /*receiver.Stop();
             * lastMessageReceived.Touch();
             *
             * StartTcpReceiver();*/
        }
Beispiel #9
0
        private void TranslateOrdersToMt4(List <MarketOrder> orders)
        {
            orders = orders.Where(o => o.State == PositionState.Opened).ToList();
            if ((DateTime.Now - timeSinceActList.GetLastHit()).TotalMilliseconds > MilsBetweenSendActualOrdersList)
            {
                SendActualOrdersCommand(orders);
                SendReportCommand();
                timeSinceActList.Touch();
            }

            if (!ordersAreRead)
            {
                ordersAreRead = true;
                currentOrders = orders;
                return;
            }

            var ordersNew = (from order in orders let orderId = order.ID where
                                                                !currentOrders.Any(o => o.ID == orderId) select order).ToList();
            var ordersClosed = (from order in currentOrders
                                let orderId = order.ID
                                              where
                                              !orders.Any(o => o.ID == orderId)
                                              select order).ToList();

            currentOrders = orders;

            // сформировать и отправить команды на закрытие ордеров
            if (ordersClosed.Count > 0)
            {
                SendCloseCommands(ordersClosed);
            }
            if (ordersNew.Count > 0)
            {
                SendOpenCommands(ordersNew);
            }
        }
Beispiel #10
0
        private void CheckTimeout()
        {
            // поток котировок может быть не включен в рабочий день
            if (!WorkingDay.Instance.IsWorkingDay(DateTime.Now))
            {
                return;
            }
            var delta = (DateTime.Now - lastMessageReceived.GetLastHit()).TotalMilliseconds;

            if (delta < timeoutIntervalMils)
            {
                return;
            }
            return;

            // инициировать таймаут
            //client.Stop();
            //lastMessageReceived.Touch();
            //Logger.InfoFormat("TcpQuoteReceiver - таймаут, {0} секунд", (int)(delta / 1000));
            //client = new TcpReceiverClient(AppConfig.GetStringParam("Quote.ServerHost", "70.38.11.49"),
            //    AppConfig.GetIntParam("Quote.ServerPort", 55056));
            //client.OnTcpPacketReceived += OnTcpPacketReceived;
            //client.Connect();
        }
Beispiel #11
0
        public override List <string> OnQuotesReceived(string[] names, CandleDataBidAsk[] quotes, bool isHistoryStartOff)
        {
            if (isHistoryStartOff)
            {
                return(new List <string>());
            }
            if (!string.IsNullOrEmpty(errorMessage))
            {
                var evts = new List <string> {
                    errorMessage
                };
                errorMessage = string.Empty;
                return(evts);
            }

            var evsList = spamMessage.GetMessages().Select(m => m.b).ToList();

            if (TradeSharpAccount > 0)
            {
                var account = robotContext.AccountInfo;
                if (account != null && account.ID != TradeSharpAccount)
                {
                    spamMessage.PutMessage(SpamMessage.MessageCategory.AccountMismatch,
                                           "Открыт счет #" + account.ID + ", ожидается счет #" + TradeSharpAccount);
                    return(evsList);
                }
            }

            if (!initMessageWasSent)
            {
                // сообщить - привет, я торговый робот, делаю то-то и то-то
                initMessageWasSent = true;
                evsList.Add(string.Format("MT4 робот, слушает порт {0}, отправляет на порт {1}",
                                          portOwn, portMt4));
            }

            // проверить время с последней проверки ордеров
            var lastTime   = timeSinceUpdate.GetLastHit();
            var nowTime    = DateTime.Now;
            var milsPassed = (nowTime - lastTime).TotalMilliseconds;

            if (milsPassed < MilsBetweenChecks)
            {
                return(evsList);
            }
            timeSinceUpdate.Touch();

            // транслировать сделки в МТ4
            if (Mode == RobotMode.УправлятьМТ4)
            {
                List <MarketOrder> orders;
                // проверить имеющиеся ордера
                GetMarketOrders(out orders, false);
                TranslateOrdersToMt4(orders);
                return(evsList);
            }

            // копировать сделки из МТ4
            if (Mode == RobotMode.КопироватьОрдераМТ4)
            {
                CopyOrdersFromMt4(evsList);
                return(evsList);
            }

            return(evsList);
        }
Beispiel #12
0
        public RequestStatus SendNewOrderRequest(Account account,
                                                 MarketOrder order,
                                                 OrderType orderType,
                                                 decimal requestedPrice,
                                                 decimal slippagePoints)
        {
            order.TimeEnter = DateTime.Now;
            order.State     = PositionState.Opened;

            // подставить текущую цену
            var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);

            if (quote == null)
            {
                return(RequestStatus.NoPrice);
            }
            order.PriceEnter = order.Side > 0 ? quote.ask : quote.bid;

            // проверить проскальзывание
            if (slippagePoints != 0)
            {
                var slippageAbs = DalSpot.Instance.GetAbsValue(order.Symbol, slippagePoints);
                var delta       = Math.Abs(order.PriceEnter - (float)requestedPrice);
                if (delta > (float)slippageAbs)
                {
                    return(RequestStatus.Slippage);
                }
            }

            if (account.Balance <= 0)
            {
                Logger.ErrorFormat("SendNewOrderRequest (счет {0}) - баланс счета равен 0", account.ID);
                return(RequestStatus.DealerError);
            }
            // получить уникальный Id сигнала, он же - Magic для ордера
            // посчитать плечо, пересчитав объем в валюту депо
            bool areEqual, inverse;
            var  baseTicker = DalSpot.Instance.FindSymbol(order.Symbol, true, account.Currency,
                                                          out inverse, out areEqual);

            if (!areEqual && string.IsNullOrEmpty(baseTicker))
            {
                Logger.ErrorFormat("SendNewOrderRequest - неизвестный сивол пересчета базовой валюты ({0})",
                                   order.Symbol);
                return(RequestStatus.DealerError);
            }
            var rateDepo = 1f;

            if (!areEqual)
            {
                var baseQuote = QuoteStorage.Instance.ReceiveValue(baseTicker);
                if (baseQuote == null)
                {
                    Logger.ErrorFormat("SendNewOrderRequest - нет котировки {0} для пересчета базовой валюты",
                                       baseQuote);
                    return(RequestStatus.DealerError);
                }
                rateDepo = inverse ? 1 / quote.ask : quote.bid;
            }
            var volumeDepo = order.Volume * rateDepo;
            var leverage   = (decimal)volumeDepo / account.Balance;

            // отправить сигнал
            var signal = new ManagerSignal
            {
                Id       = DateTime.Now.Ticks.ToString(),
                Price    = (decimal)order.PriceEnter,
                Side     = order.Side,
                Symbol   = order.Symbol,
                Leverage = (decimal)leverage,
                Category = signalCategoryCode
            };

            // !!!
            // переделал ID сигнала в запись поля expertComment вместо comment
            //order.Comment = signal.Id;
            order.ExpertComment = signal.Id;

            // отправка сигнала успешна?)
            var timeExec = new ThreadSafeTimeStamp();

            timeExec.Touch();
            if (!SendSignal(signal, true))
            {
                return(RequestStatus.DealerError);
            }
            int posID;
            // сохранить ордер (и уведомить клиента)
            var endTime = DateTime.Now - timeExec.GetLastHit();

            Logger.InfoFormat("Время исполнения SendNewOrderRequest SendSignal: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
            timeExec.Touch();
            var result = ServerInterface.SaveOrderAndNotifyClient(order, out posID);

            endTime = DateTime.Now - timeExec.GetLastHit();
            Logger.InfoFormat("Время исполнения SendNewOrderRequest - SaveOrderAndNotifyClient: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
            return(result ? RequestStatus.OK : RequestStatus.SerializationError);
        }
Beispiel #13
0
        private void DoSend()
        {
            Chat            = new ChatClientStable(chatCallback, TerminalBindings.Chat);
            Chat.Connected += () => { if (Connected != null)
                                      {
                                          Connected();
                                      }
            };
            Chat.Disconnected += () => { if (Disconnected != null)
                                         {
                                             Disconnected();
                                         }
            };
            UserInfoSource = new UserInfoExCache(TradeSharpAccountStatistics.Instance.proxy);
            while (!isStopping)
            {
                bool timeoutFlag;
                var  allRequests = requests.ExtractAll(lockTimeout, out timeoutFlag);
                if (timeoutFlag)
                {
                    continue;
                }
                // флаг повтора запроса;
                // перезапросы возникают из-за ошибок сети;
                // в этом случае ожидание между запросами увеличено, чтобы не загружать проц без пользы
                var repeatRequest = false;
                foreach (var request in allRequests)
                {
                    try
                    {
                        switch (request.Code)
                        {
                        case RequestCode.GetAllUsers:
                            request.Id = Chat.GetAllUsers((string)request.Arguments[0]);
                            break;

                        case RequestCode.Enter:
                            request.Id = Chat.Enter((User)request.Arguments[0]);
                            break;

                        case RequestCode.Exit:
                            request.Id = Chat.Exit();
                            break;

                        case RequestCode.GetRooms:
                            request.Id = Chat.GetRooms();
                            break;

                        case RequestCode.EnterRoom:
                            request.Id = Chat.EnterRoom((string)request.Arguments[0], (string)request.Arguments[1]);
                            break;

                        case RequestCode.MoveToRoom:
                            request.Id = Chat.MoveToRoom((int)request.Arguments[0], (string)request.Arguments[1],
                                                         (string)request.Arguments[2]);
                            break;

                        case RequestCode.LeaveRoom:
                            request.Id = Chat.LeaveRoom((string)request.Arguments[0]);
                            break;

                        case RequestCode.CreateRoom:
                            request.Id = Chat.CreateRoom((Room)request.Arguments[0]);
                            break;

                        case RequestCode.DestroyRoom:
                            request.Id = Chat.DestroyRoom((string)request.Arguments[0]);
                            break;

                        case RequestCode.SendPrivateMessage:
                            request.Id = Chat.SendPrivateMessage((int)request.Arguments[0],
                                                                 (string)request.Arguments[1]);
                            break;

                        case RequestCode.SendMessage:
                            request.Id = Chat.SendMessage((string)request.Arguments[0],
                                                          (string)request.Arguments[1]);
                            break;

                        case RequestCode.GetPendingMessages:
                            request.Id = Chat.GetPendingMessages((DateTime)request.Arguments[0],
                                                                 (string)request.Arguments[1]);
                            break;

                        case RequestCode.GetPendingPrivateMessages:
                            request.Id = Chat.GetPendingPrivateMessages((DateTime)request.Arguments[0],
                                                                        (int)request.Arguments[1]);
                            break;

                        case RequestCode.Ping:
                            Chat.Ping();
                            break;

                        case RequestCode.GetUserInfoEx:
                            var userinfo = UserInfoSource.GetUserInfo((int)request.Arguments[0]);
                            if (UserInfoExReceived != null)
                            {
                                UserInfoExReceived(userinfo ?? new UserInfoEx {
                                    Id = (int)request.Arguments[0]
                                });
                            }
                            break;

                        case RequestCode.SetUserInfoEx:
                            UserInfoSource.SetUserInfo((UserInfoEx)request.Arguments[0]);
                            break;
                        }
                        if (request.Id == 0)
                        {
                            QueueRequest(request); // if server refused request - try again
                            repeatRequest = true;
                        }
                        else if (request.Id != -1) // skip Ping, GetUserInfoEx, SetUserInfoEx
                        {
                            request.Status = ChatResultCode.InProgress;
                            pendingRequests.UpdateValues(request.Id, request);

                            /*if (pendingRequestsLock.TryEnterWriteLock(lockTimeout))
                             * {
                             *  pendingRequests.Add(request.Id, request);
                             *  pendingRequestsLock.ExitWriteLock();
                             * }
                             * else
                             *  Console.WriteLine("ChatSender.DoSend: pendingRequestsWriteLock timeout");*/
                            var requestCopy = new ChatRequest(request);
                            if (RequestQueuedOnServer != null)
                            {
                                RequestQueuedOnServer(requestCopy);
                            }
                            if (forwardAnswers.ContainsKey(request.Id))
                            {
                                pendingRequests.Remove(request.Id);
                                requestCopy.Status = forwardAnswers.ReceiveValue(request.Id);
                                if (RequestProcessed != null)
                                {
                                    RequestProcessed(requestCopy);
                                }
                                forwardAnswers.Remove(request.Id);
                            }
                        }
                    }
                    catch (Exception ex) // probably communication error
                    {
                        Logger.ErrorFormat("DoSend exception: {0}", ex);
                        if (request.Code != RequestCode.Ping)
                        {
                            QueueRequest(request);
                        }
                        repeatRequest = true;
                    }
                }

                //проверка соединения - ping
                if (allRequests.Count == 0)
                {
                    if (DateTime.Now.Subtract(lastConnectionCheck.GetLastHit()).TotalSeconds > 15)
                    {
                        var request = new ChatRequest(RequestCode.Ping, new List <object>(), -1);
                        QueueRequest(request);
                        lastConnectionCheck.Touch();
                    }
                }

                Thread.Sleep(repeatRequest ? 1000 : 100);
            }
        }
Beispiel #14
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);
        }
Beispiel #15
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);
        }