public void RequestProcessed(BrokerService.Contract.Entity.BrokerResponse response) { var request = RequestStorage.Instance.FindRequest(response.RequestId); if (request == null) { Logger.Info("MT4 executor - исходный запрос не найден: " + response); return; } Logger.Info("Ответ MT4 executor: " + response); if (response.Status != OrderStatus.Executed) { return; } // закрытие ордера if (request.request.IsClosingRequest) { if (!response.Price.HasValue) { Logger.Error("Ответ MT4 executor - закрытие позиции - нет цены"); return; } ServerInterface.CloseOrder(request.requestedOrder.ID, response.Price.Value, PositionExitReason.Closed); return; } // открытие ордера if (!response.Price.HasValue) { response.RejectReason = OrderRejectReason.UnknownOrder; } if (response.RejectReason.HasValue && response.RejectReason.Value != OrderRejectReason.None) { ServerInterface.NotifyClientOnOrderRejected(request.requestedOrder, response.RejectReasonString); Logger.DebugFormat("{0}: order {1} is rejected for reason {2}", DealerCode, request.requestedOrder.ToStringShort(), response.RejectReason); return; } var order = request.requestedOrder; order.PriceEnter = (float)response.Price.Value; order.AccountID = request.request.Account; order.TimeEnter = DateTime.Now; order.State = PositionState.Opened; order.MasterOrder = response.Mt4OrderId; int openedOrderId; ServerInterface.SaveOrderAndNotifyClient(order, out openedOrderId); }
public virtual RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason) { // получить цену 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); // закрыть ордер немедленно return(ServerInterface.CloseOrder(order, (decimal)price, reason) ? RequestStatus.OK : RequestStatus.ServerError); }
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); }
public void RequestProcessed(BrokerService.Contract.Entity.BrokerResponse response) { var request = RequestStorage.Instance.FindRequest(response.RequestId); if (request == null) { Logger.Info("MT4 executor - исходный запрос не найден: " + response); return; } Logger.Info("Ответ MT4 executor: " + response); if (response.Status != OrderStatus.Executed) { return; } // закрытие ордера if (request.request.IsClosingRequest) { if (!response.Price.HasValue) { Logger.Error("Ответ MT4 executor - закрытие позиции - нет цены"); return; } ServerInterface.CloseOrder(request.requestedOrder.ID, response.Price.Value, PositionExitReason.Closed); return; } // открытие ордера if (!response.Price.HasValue) { response.RejectReason = OrderRejectReason.UnknownOrder; } if (response.RejectReason.HasValue && response.RejectReason.Value != OrderRejectReason.None) { ServerInterface.NotifyClientOnOrderRejected(request.requestedOrder, response.RejectReasonString); Logger.DebugFormat("{0}: order {1} is rejected for reason {2}", DealerCode, request.requestedOrder.ToStringShort(), response.RejectReason); return; } // сравнить запрошенную и итоговые цены if (request.request.RequestedPrice > 0) { // ReSharper disable once PossibleInvalidOperationException var delta = Math.Abs(response.Price.Value - request.request.RequestedPrice); var deltaRel = delta * 100 / Math.Min(response.Price.Value, request.request.RequestedPrice); if (deltaRel > 5) { var errorStr = string.Format("{0}: order {1} is rejected: requested price ({2}) is far beyond the resulted price ({3})", DealerCode, request.requestedOrder.ToStringShort(), request.request.RequestedPrice.ToStringUniformPriceFormat(true), response.Price.Value.ToStringUniformPriceFormat(true)); Logger.Error(errorStr); response.RejectReason = OrderRejectReason.UnknownOrder; response.RejectReasonString = errorStr; ServerInterface.NotifyClientOnOrderRejected(request.requestedOrder, response.RejectReasonString); return; } } var order = request.requestedOrder; order.PriceEnter = (float)response.Price.Value; order.AccountID = request.request.Account; order.TimeEnter = DateTime.Now; order.State = PositionState.Opened; order.MasterOrder = response.Mt4OrderId; int openedOrderId; ServerInterface.SaveOrderAndNotifyClient(order, out openedOrderId); }
/// <summary> /// отдельный класс читает очередь сообщений от провайдеров /// каждый FIX-дилер получает сообщения своей группы /// </summary> public void ProcessExecutionReport(BrokerResponse response, BrokerOrder request) { Logger.InfoFormat("Запрос ({0}), ответ ({1})", request, response); requestWatchdog.OnRequestProcessed(response.RequestId); // сообщить клиенту об отказе обработать ордер // вынимаем ордер из базы MarketOrder order; int orderId; if (request.ClosingPositionID != null && request.ClosingPositionID > 0) { orderId = (int)request.ClosingPositionID; } else { orderId = request.RequestId; Logger.InfoFormat("Запрос GetMarketOrder orderId={0} requestId={1}", orderId, request.RequestId); } Logger.InfoFormat("Запрос GetMarketOrder accountId={0}, orderId={1}", request.AccountID, orderId); var res = ServerInterface.GetMarketOrder(orderId, out order); if (res == false) { errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОтказСервера, string.Format("Дилер {0}: не найдена позиция ID={0} для обработка запроса [{1}]-[счет {2}, пара {3}]", request.RequestId, request.Id, request.AccountID, request.Instrument), null)); ServerInterface.NotifyClientOnOrderRejected(order, "не найден ордер"); return; } if (response.Status == OrderStatus.Отклонен) { var rejectReasonStr = string.IsNullOrEmpty(response.RejectReasonString) ? (response.RejectReason ?? OrderRejectReason.None).ToString() : response.RejectReasonString; ServerInterface.NotifyClientOnOrderRejected(order, rejectReasonStr); errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОтказСервера, string.Format("Дилер {0}: отказ сервера [{1}] на запрос [{2}]-[счет {3}, пара {4}]", DealerCode, rejectReasonStr, request.Id, request.AccountID, request.Instrument), null)); return; } if (!response.Price.HasValue) { errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОтказСервера, string.Format("Дилер {0}: отказ сервера [нет цены] на запрос [{1}]-[счет {2}, пара {3}]", DealerCode, request.Id, request.AccountID, request.Instrument), null)); ServerInterface.NotifyClientOnOrderRejected(order, "Нет цены"); return; } var deltaMarkup = request.MarkupAbs * order.Side; // закрытие позиции - ордер обработан if (request.ClosingPositionID.HasValue) { var reason = exitReasonByOrderId.ReceiveValue(order.ID); // закрыть ордер немедленно ServerInterface.CloseOrder(order.ID, response.Price.Value - (decimal)deltaMarkup, reason); return; } // открытие позы - обработано order.TimeEnter = response.ValueDate; order.PriceEnter = (float)response.Price.Value + deltaMarkup; order.State = PositionState.Opened; ServerInterface.ModifyMarketOrder(order); }