private void CheckUpdates() { // проверка уже запущена? if (updateCheckInProgress) { return; } // проверка запускалась недавно? var lastTimeUpdated = lastCheckUpdate.GetLastHitIfHitted(); if (!lastTimeUpdated.HasValue) { lastCheckUpdate.Touch(); return; } var milsSince = (DateTime.Now - lastTimeUpdated.Value).TotalMilliseconds; if (milsSince < CheckUpdateIntervalMils) { return; } // асинхронно запустить проверку if (updateCheckInProgress) { return; } updateCheckInProgress = true; ThreadPool.QueueUserWorkItem(DoCheckUpdates, null); }
public void Start() { StartTcpReceiver(); processQuotesThread = new Thread(ProcessQuotesLoop); lastMessageReceived.Touch(); processQuotesThread.Start(); }
public TcpQuoteReceiver() { client = new TcpReceiverClient(AppConfig.GetStringParam("Quote.ServerHost", "70.38.11.49"), AppConfig.GetIntParam("Quote.ServerPort", 55056)); client.OnTcpPacketReceived += OnTcpPacketReceived; client.Connect(); processQuotesThread = new Thread(ProcessQuotesLoop); processNewsThread = new Thread(ProcessNewsLoop); lastMessageReceived.Touch(); processQuotesThread.Start(); processNewsThread.Start(); }
private AllUsers() { bool timeoutFlag; users.ExtractAll(LockTimeout, out timeoutFlag); if (GetAllPlatformUsers == null) { return; } try { var allUsers = GetAllPlatformUsers(); if (allUsers == null) { return; } users.AddRange(allUsers.Select(u => new User(u)), LockTimeout); lastRequestTime.Touch(); } catch (Exception ex) { //Console.WriteLine("Ошибка получения списка пользователей\n" + ex); Logger.Error("Ошибка получения списка пользователей", ex); } }
private void UpdateSignallers() { try { locker.AcquireWriterLock(LockTimeout); } catch (ApplicationException) { return; } try { using (var ctx = DatabaseContext.Instance.Make()) { var accounts = ctx.ACCOUNT_TRADE_SIGNAL.Where(a => ((a.RightsMask & TradeSignalCategory.TradeAutoFlag) != 0) && ((a.RightsMask & TradeSignalCategory.SignalMakerFlag) != 0)); traderAccounts.Clear(); foreach (var ac in accounts) { traderAccounts.Add(ac.Account, ac.Signal); } } lastUpdated.Touch(); } catch (Exception ex) { Logger.Error("ManagementTraderList - ошибка DAL", ex); } finally { locker.ReleaseWriterLock(); } }
public override string ActivateScript(bool byTrigger) { // проверить количество повторений и интервал ожидания if (repeatTimes == 0) { return(string.Empty); } var timeAct = timeActivated.GetLastHitIfHitted(); if (timeAct.HasValue) { if ((DateTime.Now - timeAct.Value).TotalSeconds < freezeSeconds) { return(string.Empty); } } // таки проиграть сигнал EventSoundPlayer.Instance.PlayEvent(eventSound); if (repeatTimes > 0) { repeatTimes--; } timeActivated.Touch(); MainForm.Instance.AddMessageToStatusPanelSafe(DateTime.Now, scriptMessage); return(scriptMessage); }
private void UpdateSignallers() { var dicSignaller = new Dictionary <int, int>(); try { using (var ctx = DatabaseContext.Instance.Make()) { var accounts = ctx.SERVICE.Where(a => a.AccountId.HasValue).ToList(); foreach (var ac in accounts) { // ReSharper disable PossibleInvalidOperationException if (!dicSignaller.ContainsKey(ac.AccountId.Value)) { // ReSharper restore PossibleInvalidOperationException dicSignaller.Add(ac.AccountId.Value, ac.ID); } } } } catch (Exception ex) { Logger.Error("ManagementTraderList - UpdateSignallers - ошибка DAL", ex); return; } try { locker.AcquireWriterLock(LockTimeout); } catch (ApplicationException) { return; } try { traderAccounts.Clear(); foreach (var ac in dicSignaller) { traderAccounts.Add(ac.Key, ac.Value); } lastUpdated.Touch(); } catch (Exception ex) { Logger.Error("ManagementTraderList - ошибка DAL", ex); } finally { locker.ReleaseWriterLock(); } if (firstUpdate) { firstUpdate = false; Logger.Info("Signallers are users: " + string.Join(", ", dicSignaller.Keys)); } }
public void ScheduleTopPortfolioUpdates(IEnumerable <FarmAccount> accountsList) { schedules = new[] { new Schedule( () => { var nowTime = DateTime.Now; var lastUpdated = lastTimeUpdated.GetLastHitIfHitted(); // если портфель уже тасовался - обновить его минимум сутки спустя if (lastUpdated.HasValue) { var daysPassed = (nowTime - lastUpdated.Value).TotalDays; if (daysPassed < 1) { return; } } // иначе - обновить портфель на промежутке 0:00 - 0:30 else if (nowTime.Hour > 0 || nowTime.Minute > 30) { return; } // таки обновить портфели по всем счетам Logger.Info("Обновить портфели по счетам"); var accounts = RobotFarm.Instance.Accounts; foreach (var ac in accounts) { if (RobotFarm.Instance.State == FarmState.Stopping) { break; } ac.UpdatePortfolio(); } // сохранить время последнего обновления lastTimeUpdated.Touch(); new IniFile(iniFilePath).WriteValue("portfolio", "uptime", DateTime.Now.ToStringUniform()); }, SecondsBetweenCheckTossTime * 1000), new Schedule( () => { var accounts = RobotFarm.Instance.Accounts; foreach (var ac in accounts) { if (RobotFarm.Instance.State == FarmState.Stopping) { break; } ac.ReviveChannel(); } }, SecondsBetweenReviveChannel * 1000) }; }
/// <summary> /// если за последние N (к примеру, 60) /// секунд накопилось больше N * K сообщений (к примеру, больше 60 * 20) - /// вернуть True /// </summary> public bool CheckOverflood() { var lastCheckedTime = lastTimeFloodChecked.GetLastHitIfHitted(); var secondsSinceLastCheck = lastCheckedTime == null ? int.MaxValue : (DateTime.Now - lastCheckedTime.Value).TotalSeconds; if (secondsSinceLastCheck < checkFloodIntervalSeconds) { return(false); } lastTimeFloodChecked.Touch(); requestLocker.EnterReadLock(); List <DateTime> requestTimes; try { requestTimes = tradeRequestList.Select(r => r.requestTime).ToList(); } finally { requestLocker.ExitReadLock(); } if (requestTimes.Count < 10) { return(false); } var nowTime = DateTime.Now; requestTimes = requestTimes.OrderByDescending(t => t).ToList(); var countInQueue = 0; foreach (var time in requestTimes) { var secondsLeft = (nowTime - time).TotalSeconds; if (secondsLeft > checkFloodSeconds) { break; } countInQueue++; } var maxMessages = checkFloodSeconds * checkFloodMsgPerSecond; if (countInQueue > maxMessages) { Logger.ErrorFormat("Mt4Dealer - flood, {0} messages for {1} seconds ({2} are allowed)", countInQueue, checkFloodSeconds, maxMessages); return(true); } return(false); }
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); }
/// <summary> /// обновить список последних N workspace, вернуть признак того, что список обновился /// </summary> public bool AddWorkspace(string filePath) { filePath = filePath.ToLower(); if (lastWorkspaces.Count > MaxWorkspacesInList) { lastWorkspaces.RemoveAt(lastWorkspaces.Count - 1); } var index = lastWorkspaces.IndexOf(filePath); if (index == 0) { return(false); } if (index > 0) { // поменять элементы местами var names = new List <string> { filePath }; names.AddRange(lastWorkspaces.Where(w => w != filePath)); lastTimeModified.Touch(); return(true); } // дописать в начало lastWorkspaces.Insert(0, filePath); if (lastWorkspaces.Count > MaxWorkspacesInList) { lastWorkspaces.RemoveAt(lastWorkspaces.Count - 1); } lastTimeModified.Touch(); return(true); }
public override void Initialize(BacktestServerProxy.RobotContext grobotContext, CurrentProtectedContext protectedContext) { base.Initialize(grobotContext, protectedContext); initMessageWasSent = false; timeSinceUpdate.Touch(); ordersFromMt4.ExtractAll(1000 * 10); ordersFromMt4Received = false; sentRequests.ExtractAll(1000 * 10); // стартовать прослушку порта try { var e = new IPEndPoint(IPAddress.Parse(hostMt4), portOwn); client = new UdpClient(e); client.BeginReceive(ReceiveCallback, null); } catch (ArgumentOutOfRangeException) { errorMessage = string.Format("MT4 транслятор: порт ({0}) задан неверно. Допустимый диапазон: {1} - {2}", portOwn, IPEndPoint.MinPort, IPEndPoint.MaxPort); client = null; return; } catch (Exception ex) { client = null; errorMessage = string.Format("MT4 транслятор: ошибка прослушивания порта ({0}): {1}", portOwn, ex.Message); } // стратовать поток отправки команд commandSendThread = new Thread(CommandSendRoutine); commandSendThread.Start(); }
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 override string ActivateScript(bool byTrigger) { if (!byTrigger) { throw new Exception("Неверный тип вызова скрипта \"ShowRobotSummary\""); } var nowTime = DateTime.Now; var lastHit = lastTimeCalled.GetLastHitIfHitted(); if (lastHit.HasValue) { var deltaSeconds = (nowTime - lastHit.Value).TotalSeconds; if (deltaSeconds < 0.5) { return(""); } } lastTimeCalled.Touch(); var robots = MainForm.Instance.RobotFarm.GetRobotsAsIs().ToList(); if (robots.Count == 0) { return(""); } var charts = MainForm.Instance.GetChartList(true); foreach (var chart in charts) { var commentText = GetCommentForChart(chart.Symbol, chart.Timeframe, robots); if (string.IsNullOrEmpty(commentText)) { continue; } var comment = chart.seriesComment.data.FirstOrDefault(c => c.Name == CommentSpecName); if (comment != null) { comment.Text = commentText; } } return(""); }
private void UpdateLotByGroup() { var timUpdated = lastTimeLotByGroupUpdated.GetLastHitIfHitted(); if (timUpdated.HasValue) { var deltaMils = (DateTime.Now - timUpdated.Value).TotalMilliseconds; if (deltaMils <= updateIntervalMils) { return; } } lotByGroup.Clear(); try { using (var ctx = DatabaseContext.Instance.Make()) { foreach (var lotGroup in ctx.LOT_BY_GROUP) { Dictionary <string, VolumeStep> dic; if (!lotByGroup.dictionary.TryGetValue(lotGroup.Group, out dic)) { dic = new Dictionary <string, VolumeStep>(); lotByGroup.dictionary.Add(lotGroup.Group, dic); } dic.Add(lotGroup.Spot, new VolumeStep((int)lotGroup.MinVolume, (int)lotGroup.MinStepVolume)); } } } catch (Exception ex) { Logger.Error("Ошибка в UpdateLotByGroup()", ex); throw; } finally { lotByGroup.GetHashCodeForDic(); lastTimeLotByGroupUpdated.Touch(); } lotByGroup.GetHashCodeForDic(); }
public static List <PerformerStatRecord> GetRecords() { var timeSinceUpdate = lastUpdated.GetLastHitIfHitted(); if (timeSinceUpdate.HasValue) { var deltaSec = (DateTime.Now - timeSinceUpdate.Value).TotalSeconds; bool isTimeout; if (deltaSec < RecordsUpdateIntervalSeconds) { return(recordsSafe.GetAll(TimeoutIntervalMils, out isTimeout)); } } var records = new List <PerformerStatRecord>(); // обратиться к сервису TradeSharp.SiteBridge try { try { var performers = TradeSharpAccountStatistics.Instance.proxy.GetAllPerformers(false) ?? new List <PerformerStat>(); var recs = performers.Select(p => new PerformerStatRecord(p)).ToList(); recordsSafe.ReplaceRange(recs, TimeoutIntervalMils); return(recs); } catch (Exception ex) { //Logger.Error("Невозможно получить информацию о подписчиках - необходимо обновить файл конфигурации сайта", ex); Logger.Error("GetPerformers() error", ex); return(records); } } finally { lastUpdated.Touch(); } }
public DateTime GetServerTickerHistoryStart(string ticker) { var lastUpTime = lastUpdated.GetLastHitIfHitted(); var needUpdate = !lastUpTime.HasValue || (DateTime.Now - lastUpTime.Value).TotalMinutes >= MinutesToRefreshTickerHistory; if (needUpdate) { try { IQuoteStorage quoteStorage; try { quoteStorage = Contract.Util.Proxy.QuoteStorage.Instance.proxy; } catch (Exception) { Logger.Error("Связь с сервером (IQuoteStorageBinding) не установлена"); return(DateTime.Now.Date.AddDays(-355)); } tickerFirstRecord = quoteStorage.GetTickersHistoryStarts(); } catch (Exception ex) { tickerFirstRecord = new Dictionary <string, DateSpan>(); Logger.Error("GetServerTickerHistoryStart() - ошибка получения истории", ex); } finally { lastUpdated.Touch(); } } DateSpan span; return(!tickerFirstRecord.TryGetValue(ticker, out span) ? DateTime.Now.Date.AddDays(-355) : span.start); }
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); } }
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); }
private void OnQuotesReceived(string[] names, QuoteData[] quotes) { var nowTime = DateTime.Now.AddDays(offsetHours); // лок на запись в словарь свечей if (!lockCandles.TryEnterWriteLock(LockTimeout)) { Logger.Error("OnQuotesReceived - таймаут записи"); return; } try { if (!lockCandlesM1.TryEnterWriteLock(LockTimeout)) { Logger.Error("OnQuotesReceived - таймаут записи (m1)"); return; } try { // обновить свечи foreach (var packerDic in packers) { var timeframeCode = packerDic.Key; var isM1 = timeframeCode == barSettingsCodeM1; for (var i = 0; i < names.Length; i++) { var name = names[i]; CandlePacker packer; packerDic.Value.TryGetValue(name, out packer); if (packer == null) { continue; } var newCandle = packer.UpdateCandle(quotes[i].bid, nowTime); if (newCandle != null) { candles[timeframeCode][name].Add(newCandle); if (isM1) { candlesM1[name].Add(newCandle); } } } } } finally { lockCandlesM1.ExitWriteLock(); } } finally { lockCandles.ExitWriteLock(); } // если пришло время выгрузить m1 в файл... выгрузить var timeSaved = lastTimeCandlesSaved.GetLastHitIfHitted(); if (timeSaved.HasValue) { if ((DateTime.Now - timeSaved.Value).TotalSeconds > flushCandlesIntervalSec) { FlushCandlesInFiles(); // таки выгрузить lastTimeCandlesSaved.Touch(); } } else { lastTimeCandlesSaved.Touch(); } }
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); } }
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); }
public IndicatorFiboDiver() { CreateOwnPanel = false; lastUpdateTime.Touch(); }