Example #1
0
 // chat managing
 public void Start()
 {
     if (!isStopping)
     {
         return;
     }
     // чтение паролей на комнаты
     foreach (var room in ChatSettings.Instance.Rooms)
     {
         roomPasswords.UpdateValues(room, ChatSettings.Instance.Passwords[ChatSettings.Instance.Rooms.IndexOf(room)]);
     }
     // подготовка к сетевому взаимодействию
     receiver = new ChatClientCallback();
     receiver.AllUsersReceivedD        += AllUsersReceivedInternal;
     receiver.UserEntered              += UserEnteredInternal;
     receiver.UserExited               += UserExitedInternal;
     receiver.UserEnteredRoom          += UserEnteredRoomInternal;
     receiver.UserLeftRoom             += UserLeftRoomInternal;
     receiver.RoomsReceivedD           += RoomsReceivedInternal;
     receiver.MessageReceivedD         += MessageReceivedInternal;
     receiver.PendingMessagesReceivedD += PendingMessagesReceivedInternal;
     sender                       = new ChatSenderStable(receiver);
     sender.Entered              += EnteredInternal;
     sender.Exited               += ExitedInternal;
     sender.RequestQueueFilled   += RequestQueueFilledInternal;
     sender.RequestQueueCleared  += RequestQueueClearedInternal;
     sender.RequestErrorOccurred += RequestErrorOccurredInternal;
     sender.Logged               += LoggedInternal;
     sender.UserInfoExReceived   += UserInfoExReceivedInternal;
     liveRoomCheckTime.SetTime(DateTime.Now + aliveTimeSpan);
     liveRoomThread = new Thread(CheckRoomEntered);
     liveRoomThread.Start();
     isStopping = false;
 }
Example #2
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));
            }
        }
        /// <summary>
        /// проверить - не пора ли начислить своп?
        /// </summary>
        private void CheckSwap()
        {
            // проверить час
            var timeNow = DateTime.Now.ToUniversalTime();
            var hourGmt = timeNow.Hour;

            if (swapCheckHourGmt != hourGmt)
            {
                return;
            }

            // проверить день
            if (timeNow.DayOfWeek == DayOfWeek.Sunday)
            {
                return;
            }

            // проверить, не было ли уже начисления свопа
            var lastTimeChecked = swapCheckedTime.GetLastHitIfHitted();

            if (lastTimeChecked.HasValue && lastTimeChecked.Value.Date == timeNow.Date)
            {
                return;
            }

            // сколько минут прошло с часа Х
            if (timeNow.Minute > minutesToCheckSwap)
            {
                return;
            }

            swapCheckedTime.SetTime(timeNow);
            // таки насчитать своп
            DoMakeSwap();
        }
 private void RequestQueuedOnClient(ChatRequest request)
 {
     if (isStopping)
     {
         return;
     }
     if (!liveServerCheckTime.GetLastHitIfHitted().HasValue)
     {
         liveServerCheckTime.SetTime(DateTime.Now + aliveTimeSpan);
     }
     else if (RequestQueueFilled != null)
     {
         RequestQueueFilled();
     }
     if (Logged != null)
     {
         Logged(request.ToString());
     }
 }
Example #5
0
        private FarmScheduler()
        {
            threadIntervalMils = 100;
            var sectPortfolio = new IniFile(iniFilePath).ReadSection("portfolio");

            // прочитать время последней перетасовки портфеля
            string lastTimeUpdatedStr;

            if (sectPortfolio.TryGetValue("uptime", out lastTimeUpdatedStr))
            {
                var lastTimeUpdatedVal = lastTimeUpdatedStr.ToDateTimeUniformSafe();
                if (lastTimeUpdatedVal.HasValue)
                {
                    lastTimeUpdated.SetTime(lastTimeUpdatedVal.Value);
                }
            }
        }
Example #6
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);
        }