// 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; }
/// <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()); } }
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); } } }
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); }