/// <summary> /// sent order to execution in the trading systme /// выслать ордер на исполнение в торговую систему /// </summary> /// <param name="order">order / ордер</param> public void SendOrder(Order order) { var guid = Guid.NewGuid().ToString().Replace('-', '0'); var needId = guid.Remove(0, guid.Length - 32); _couplers.Add(new OrderCoupler() { OsOrderNumberUser = order.NumberUser, OrderNumberMarket = needId, }); _client.SendOrder(order, needId); Task t = new Task(async() => { await Task.Delay(7000); if (_incominOrders.Find(o => o.NumberUser == order.NumberUser) == null) { order.State = OrderStateType.Fail; MyOrderEvent?.Invoke(order); SendLogMessage("Order miss. Id: " + order.NumberUser, LogMessageType.Error); } }); t.Start(); }
private void HandleAllNeedEvents(long id) { foreach (var ev in _orderEvents) { if (ev.Id == id) { var needNumberUser = _myOrders.First(o => o.Value == id); MyOrderEvent?.Invoke(needNumberUser.Key, GetPortfolioName(), ev); _handledOrderEvents.Add(ev); } } foreach (var tr in _queueMyTradeEvents) { if (tr.OrderBuyId == id) { MyTradeEvent?.Invoke(tr.OrderBuyId.ToString(), tr); _handledMyTradeEvents.Add(tr); } if (tr.OrderSellId == id) { MyTradeEvent?.Invoke(tr.OrderSellId.ToString(), tr); _handledMyTradeEvents.Add(tr); } } CheckAndDelOrders(); CheckAndDelTrades(); }
/// <summary> /// cancel order /// отозвать ордер /// </summary> public void CanselOrder(Order order) { var guid = Guid.NewGuid().ToString().Replace('-', '0'); var needId = guid.Remove(0, guid.Length - 32); var result = _client.CancelOrder(order, needId); if (result.code == 0) { var needCoupler = _couplers.Find(c => c.OrderNumberMarket == order.NumberMarket); if (needCoupler != null) { needCoupler.OrderCancelId = needId; } else { SendLogMessage($"Order cancellation error № {result.code} : {result.message}", LogMessageType.Error); } } else { SendLogMessage($"Order cancellation error № {result.code} : {result.message}", LogMessageType.Error); order.State = OrderStateType.Cancel; MyOrderEvent?.Invoke(order); } }
private void Client_MyOrderEvent(int numUser, string portfolio, PrivateOrderRawEvent orderInfo) { lock (_orderLocker) { var needOrder = _myOrders.Find(o => o.NumberUser == numUser); if (needOrder == null) { return; } var order = new OsEngine.Entity.Order(); order.NumberUser = numUser; order.PortfolioNumber = portfolio; order.SecurityNameCode = needOrder.SecurityNameCode; if (orderInfo.Id == -1) { order.State = OrderStateType.Fail; order.Price = needOrder.Price; order.Volume = needOrder.Volume; order.Side = needOrder.Side; order.NumberMarket = needOrder.NumberMarket; MyOrderEvent?.Invoke(order); return; } order.NumberMarket = orderInfo.Id.ToString(); order.Price = ParseDecimal(orderInfo.Price); order.TimeCallBack = new DateTime(1970, 1, 1).AddMilliseconds(Convert.ToDouble(orderInfo.Timestamp)); order.Volume = needOrder.Volume; order.Side = orderInfo.order_type == PrivateOrderRawEvent.OrderType.Bid ? Side.Buy : Side.Sell; decimal quantity = ParseDecimal(orderInfo.Quantity); decimal cancelVolume = ParseDecimal(orderInfo.QuantityLeftBeforeCancellation); if (quantity == 0 && cancelVolume == needOrder.Volume) { order.State = OrderStateType.Cancel; DelOrder(needOrder); } else if (quantity == 0 && cancelVolume == 0) { order.State = OrderStateType.Done; DelOrder(needOrder); } else if (quantity == order.Volume) { order.State = OrderStateType.Activ; } else if (needOrder.Volume != quantity && quantity != 0) { order.State = OrderStateType.Patrial; } MyOrderEvent?.Invoke(order); } }
/// <summary> /// send order /// исполнить ордер /// </summary> public void SendOrder(Order order) { var guid = Guid.NewGuid().ToString().Replace('-', '0'); var needId = guid.Remove(0, guid.Length - 32); var result = _client.SendOrder(order, needId); if (result.code == 0) { _couplers.Add(new OrderCoupler() { OsOrderNumberUser = order.NumberUser, OrderNumberMarket = needId, }); } else { order.State = OrderStateType.Fail; MyOrderEvent?.Invoke(order); SendLogMessage($"Order placement error № {result.code} : {result.message}", LogMessageType.Error); } }
public string Get() { var ev = new MyOrderEvent(3); myApi1IntegrationEventService.PublishThroughEventBusAsync(ev); return("Ok"); }
/// <summary> /// send order /// исполнить ордер /// </summary> public void SendOrder(Order order) { var guid = Guid.NewGuid().ToString().Replace('-', '0'); string needId = guid; while (needId.Length > 32) { needId = needId.Remove(needId.Length - 1); } var result = _client.SendOrder(order, needId); if (result == null || result.Code != 0) { order.State = OrderStateType.Fail; MyOrderEvent?.Invoke(order); SendLogMessage($"Order placement error № {result?.Code}.", LogMessageType.Error); } else if (result.Data.Status == "Ack") { var newCoupler = new OrderCoupler() { OsOrderNumberUser = order.NumberUser, OrderNumberMarket = result.Data.Info.OrderId, }; _couplers.Add(newCoupler); order.State = OrderStateType.Activ; order.NumberMarket = result.Data.Info.OrderId; MyOrderEvent?.Invoke(order); } else if (result.Data.Status == "DONE") { var newCoupler = new OrderCoupler() { OsOrderNumberUser = order.NumberUser, OrderNumberMarket = result.Data.Info.OrderId, }; _couplers.Add(newCoupler); order.State = OrderStateType.Done; order.NumberMarket = result.Data.Info.OrderId; MyOrderEvent?.Invoke(order); } }
/// <summary> /// send order to exchange /// выслать ордер на биржу /// </summary> public void SendOrder(Order order) { string side = order.Side == Side.Buy ? "B" : "S"; var needSec = _securities.Find(s => s.Name == order.SecurityNameCode); string cmd = "<command id=\"neworder\">"; cmd += "<security>"; cmd += "<board>" + needSec.NameClass + "</board>"; cmd += "<seccode>" + needSec.Name + "</seccode>"; cmd += "</security>"; cmd += "<union>" + _clients[0].Union + "</union>"; cmd += "<price>" + order.Price + "</price>"; cmd += "<quantity>" + order.Volume + "</quantity>"; cmd += "<buysell>" + side + "</buysell>"; cmd += "<brokerref>" + order.NumberUser + "</brokerref>"; cmd += "<unfilled> PutInQueue </unfilled>"; cmd += "</command>"; // sending command / отправка команды string res = _client.ConnectorSendCommand(cmd); Result data; var formatter = new XmlSerializer(typeof(Result)); using (StringReader fs = new StringReader(res)) { data = (Result)formatter.Deserialize(fs); } //<result success="true" transactionid="12445626"/> if (data.Success != "true") { order.State = OrderStateType.Fail; } else { order.NumberUser = int.Parse(data.Transactionid); order.State = OrderStateType.Pending; } order.TimeCallBack = ServerTime; MyOrderEvent?.Invoke(order); }
/// <summary> /// обработчик отчета об ошибках отмены моих ордеров /// </summary> private void OrderCancelRejectHandler(FixEntity entity) { try { string rej = entity.GetFieldByTag((int)Tags.CxlRejReason); if (rej == "1") { Order order = new Order(); order.ServerType = ServerType.Lmax; order.NumberMarket = entity.GetFieldByTag((int)Tags.ClOrdID); order.TimeCallBack = DateTime.UtcNow; var numUser = entity.GetFieldByTag((int)Tags.OrigClOrdID); try { order.NumberUser = Convert.ToInt32(numUser); } catch (Exception e) { return; } order.State = OrderStateType.Fail; MyOrderEvent?.Invoke(order); return; } SendLogMessage("Ошибка отмены ордера. Причина: " + _errorDictionary.CxlRejReason[rej] + "-" + entity.GetFieldByTag((int)Tags.Text), LogMessageType.Trade); } catch (ArgumentException e) { SendLogMessage(e.Message, LogMessageType.Error); } catch (Exception e) { SendLogMessage("OrderCancelRejectHandlerError " + e.Message, LogMessageType.Error); } }
/// <summary> /// takes messages from the shared queue, converts them to C# classes, and sends them to up /// берет сообщения из общей очереди, конвертирует их в классы C# и отправляет на верх /// </summary> public void Converter() { while (true) { try { if (_isDisposed) { return; } if (!_newMessage.IsEmpty) { string data; if (_newMessage.TryDequeue(out data)) { if (data.StartsWith("<pits>") || data.StartsWith("<sec_info")) { continue; } if (data.StartsWith("<server_status")) { ServerStatus status = Deserialize <ServerStatus>(data); if (status.Connected == "true") { IsConnected = true; Connected?.Invoke(); } else if (status.Connected == "false") { IsConnected = false; Disconnected?.Invoke(); } else if (status.Connected == "error") { SendLogMessage(status.Text, LogMessageType.Error); } } else if (data.StartsWith("<securities>")) { var securities = _deserializer.Deserialize <List <Security> >(new RestResponse() { Content = data }); UpdatePairs?.Invoke(securities); } else if (data.StartsWith("<united_portfolio")) { UnitedPortfolio unitedPortfolio = Deserialize <UnitedPortfolio>(data); UpdatePortfolio?.Invoke(unitedPortfolio); } else if (data.StartsWith("<positions")) { var positions = Deserialize <TransaqPositions>(data); UpdatePositions?.Invoke(positions); } else if (data.StartsWith("<clientlimits")) { var limits = Deserialize <Clientlimits>(data); UpdateMonoPortfolio?.Invoke(limits); } else if (data.StartsWith("<client")) { var clientInfo = _deserializer.Deserialize <Client>(new RestResponse() { Content = data }); ClientsInfo?.Invoke(clientInfo); } else if (data.StartsWith("<alltrades>")) { var allTrades = _deserializer.Deserialize <List <Trade> >(new RestResponse() { Content = data }); NewTradesEvent?.Invoke(allTrades); } else if (data.StartsWith("<quotes>")) { var quotes = _deserializer.Deserialize <List <Quote> >(new RestResponse() { Content = data }); UpdateMarketDepth?.Invoke(quotes); } else if (data.StartsWith("<orders>")) { var orders = _deserializer.Deserialize <List <Order> >(new RestResponse() { Content = data }); MyOrderEvent?.Invoke(orders); } else if (data.StartsWith("<trades>")) { var myTrades = _deserializer.Deserialize <List <Trade> >(new RestResponse() { Content = data }); MyTradeEvent?.Invoke(myTrades); } else if (data.StartsWith("<candles")) { Candles newCandles = Deserialize <Candles>(data); NewCandles?.Invoke(newCandles); } else if (data.StartsWith("<messages>")) { if (data.Contains("Время действия Вашего пароля истекло")) { NeedChangePassword?.Invoke(); } } } } } catch (Exception exception) { SendLogMessage(exception.ToString(), LogMessageType.Error); } Thread.Sleep(1); } }
/// <summary> /// takes messages from the common queue, converts them to C # classes and sends them to up /// берет сообщения из общей очереди, конвертирует их в классы C# и отправляет на верх /// </summary> public void Converter() { while (true) { if (_isDisposed) { return; } if (!_newMessage.IsEmpty) { protobuf.ws.WsResponse response; if (_newMessage.TryDequeue(out response)) { try { if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.TradeChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.TradeChannelSubscribedResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.TradeChannelSubscribedResponse>(messageStream); SendLogMessage("Успешная подписка на все сделки", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.TradeNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { try { protobuf.ws.TradeNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.TradeNotification>(messageStream); message.CurrencyPair = message.CurrencyPair.Replace('/', '_'); NewTradesEvent?.Invoke(message); } catch { // ignore } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.Error) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.ErrorResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.ErrorResponse>(messageStream); var token = response.Meta.Token; if (message.Message.StartsWith("Channel already subscribed")) { continue; } if (token.StartsWith("NewOrder")) { var order = new PrivateOrderRawEvent(); order.Id = -1; MyOrderEvent?.Invoke(Convert.ToInt32(token.Split('_')[1]), GetPortfolioName(), order); } if (message.Message.StartsWith("insufficient funds")) { continue; } SendLogMessage("WsClient error : " + message.Message, LogMessageType.Error); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.ChannelUnsubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.ChannelUnsubscribedResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.ChannelUnsubscribedResponse>(messageStream); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.LoginResponse) { IsConnected = true; if (Connected != null) { Connected(); } // SendLogMessage("Соединение через вебсокет успешно установлено", LogMessageType.System); } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.BalanceChangeChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateSubscribeBalanceChangeChannelRequest message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateSubscribeBalanceChangeChannelRequest>(messageStream); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.BalanceChangeNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateChangeBalanceNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateChangeBalanceNotification>(messageStream); if (UpdatePortfolio != null) { UpdatePortfolio(GetPortfolioName(), message); } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.OrderBookNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.OrderBookNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.OrderBookNotification>(messageStream); message.CurrencyPair = message.CurrencyPair.Replace('/', '_'); if (UpdateMarketDepth != null) { UpdateMarketDepth(message); } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.OrderBookChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.OrderBookChannelSubscribedResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.OrderBookChannelSubscribedResponse>(messageStream); // SendLogMessage("Успешная подписка на стакан котировок", LogMessageType.System); message.CurrencyPair = message.CurrencyPair.Replace('/', '_'); if (NewMarketDepth != null) { NewMarketDepth(message); } } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateOrderRawChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { //SendLogMessage("Успешная подписка на мои ордера", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateOrderRawNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateOrderRawNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateOrderRawNotification>(messageStream); foreach (var ev in message.Datas) { if (!_myOrders.ContainsValue(ev.Id)) { ev.CurrencyPair = ev.CurrencyPair.Replace('/', '_'); _orderEvents.Add(ev); } else { var needNumberUser = _myOrders.First(o => o.Value == ev.Id); ev.CurrencyPair = ev.CurrencyPair.Replace('/', '_'); MyOrderEvent?.Invoke(needNumberUser.Key, GetPortfolioName(), ev); } } //SendLogMessage("Пришла информацияпо ордеру", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateTradeChannelSubscribed) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { //SendLogMessage("Успешная подписка на мои сделки", LogMessageType.System); } } else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PrivateTradeNotify) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PrivateTradeNotification message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PrivateTradeNotification>(messageStream); //SendLogMessage("Пришла моя сделка", LogMessageType.System); foreach (var t in message.Datas) { t.CurrencyPair = t.CurrencyPair.Replace('/', '_'); if (!_myOrders.ContainsValue(t.OrderBuyId)) { _queueMyTradeEvents.Add(t); } else { MyTradeEvent?.Invoke(t.OrderBuyId.ToString(), t); } if (!_myOrders.ContainsValue(t.OrderSellId)) { _queueMyTradeEvents.Add(t); } else { MyTradeEvent?.Invoke(t.OrderSellId.ToString(), t); } } } }//PUT_LIMIT_ORDER_RESPONSE else if (response.Meta.ResponseType == protobuf.ws.WsResponseMetaData.WsResponseMsgType.PutLimitOrderResponse) { using (MemoryStream messageStream = new MemoryStream(response.Msg)) { protobuf.ws.PutLimitOrderResponse message = ProtoBuf.Serializer.Deserialize <protobuf.ws.PutLimitOrderResponse>(messageStream); var orderData = response.Meta.Token.Split('_'); int id = Convert.ToInt32(orderData[1]); _myOrders.Add(id, message.OrderId); HandleAllNeedEvents(message.OrderId); } } } catch (Exception exception) { SendLogMessage(exception.Message, LogMessageType.Error); SendLogMessage("Message type " + response.Meta.ResponseType, LogMessageType.Error); } } } else { Thread.Sleep(1); } } }
private void _client_MyOrderEvent(Result result) { OrderCoupler needCoupler; needCoupler = _couplers.Find(c => c.OrderNumberMarket == result.clientOrderId); if (needCoupler == null) { return; } if (result.status == "partiallyFilled" || result.status == "filled") { var partialVolume = result.quantity.ToDecimal(); var tradeVolume = partialVolume - needCoupler.CurrentVolume; needCoupler.CurrentVolume += tradeVolume; MyTrade myTrade = new MyTrade() { NumberOrderParent = result.clientOrderId, Side = result.side == "sell" ? Side.Sell : Side.Buy, NumberPosition = Convert.ToString(needCoupler.OsOrderNumberUser), SecurityNameCode = result.symbol, Price = result.price.ToDecimal() , Volume = tradeVolume, NumberTrade = result.id, Time = result.updatedAt, }; MyTradeEvent?.Invoke(myTrade); } Order order = new Order(); order.NumberUser = needCoupler.OsOrderNumberUser; order.NumberMarket = result.clientOrderId; order.PortfolioNumber = result.symbol.Substring(result.symbol.Length - 3); order.Price = result.price.ToDecimal(); order.Volume = result.quantity.ToDecimal(); order.Side = result.side == "sell" ? Side.Sell : Side.Buy; order.SecurityNameCode = result.symbol; order.ServerType = ServerType; order.TimeCallBack = Convert.ToDateTime(result.createdAt); order.TypeOrder = result.type == "limit" ? OrderPriceType.Limit : OrderPriceType.Market; if (result.status == "new") { order.State = OrderStateType.Activ; } else if (result.status == "partiallyFilled") { order.State = OrderStateType.Patrial; } else if (result.status == "filled") { order.State = OrderStateType.Done; _couplers.Remove(needCoupler); } else if (result.status == "canceled") { order.State = OrderStateType.Cancel; _couplers.Remove(needCoupler); } else if (result.status == "expired") { order.State = OrderStateType.Fail; } MyOrderEvent?.Invoke(order); _incominOrders.Add(order); _client.GetBalance(); }
protected void OnOrderEvent(Order order) { MyOrderEvent?.Invoke(order); }
/// <summary> /// обработчик отчета о моих ордерах и сделках /// </summary> private void ExecutionReportHandler(FixEntity entity) { try { string type = entity.GetFieldByTag((int)Tags.ExecType); if (type != "F") { Order order = new Order(); order.ServerType = ServerType.Lmax; var time = entity.GetFieldByTag((int)Tags.TransactTime); order.TimeCallBack = DateTime.ParseExact(time, "yyyyMMdd-HH:mm:ss.fff", CultureInfo.CurrentCulture); order.SecurityNameCode = entity.GetFieldByTag((int)Tags.SecurityID); var numUser = entity.GetFieldByTag((int)Tags.ClOrdID); if (type == "0") { try { // если пришел сигнал о новом ордере, но ClOrdID не может быть конвертирован в int, значит ордер создавался не в OsEngine, игнорим его order.NumberUser = Convert.ToInt32(numUser); } catch (Exception e) { return; } order.State = OrderStateType.Activ; order.NumberMarket = entity.GetFieldByTag((int)Tags.OrderID); order.Side = entity.GetFieldByTag((int)Tags.Side) == "1" ? Side.Buy : Side.Sell; order.Volume = Convert.ToDecimal(entity.GetFieldByTag((int)Tags.OrderQty), CultureInfo.InvariantCulture); if (entity.GetFieldByTag((int)Tags.OrdType) == "2") { order.Price = Convert.ToDecimal(entity.GetFieldByTag((int)Tags.Price), CultureInfo.InvariantCulture); } MyOrderEvent?.Invoke(order); return; } if (type == "8") { try { order.NumberUser = Convert.ToInt32(numUser); } catch (Exception e) { return; } order.State = OrderStateType.Fail; string rej = entity.GetFieldByTag((int)Tags.OrdRejReason); SendLogMessage( "Ошибка выставления ордера: " + _errorDictionary.OrdRejReason[rej] + "-" + entity.GetFieldByTag((int)Tags.Text), LogMessageType.System); MyOrderEvent?.Invoke(order); return; } if (type == "4") { order.State = OrderStateType.Cancel; order.TimeCancel = order.TimeCallBack; var oldNumUser = entity.GetFieldByTag((int)Tags.OrigClOrdID); try { order.NumberUser = Convert.ToInt32(oldNumUser); } catch (Exception e) { return; } order.NumberMarket = entity.GetFieldByTag((int)Tags.OrderID); order.Side = entity.GetFieldByTag((int)Tags.Side) == "1" ? Side.Buy : Side.Sell; order.Volume = Convert.ToDecimal(entity.GetFieldByTag((int)Tags.OrderQty), CultureInfo.InvariantCulture); if (entity.GetFieldByTag((int)Tags.OrdType) == "2") { order.Price = Convert.ToDecimal(entity.GetFieldByTag((int)Tags.Price), CultureInfo.InvariantCulture); } MyOrderEvent?.Invoke(order); } else if (type == "I") { } } else { MyTrade trade = new MyTrade(); trade.Time = DateTime.ParseExact(entity.GetFieldByTag((int)Tags.TransactTime), "yyyyMMdd-HH:mm:ss.fff", CultureInfo.CurrentCulture); trade.NumberOrderParent = entity.GetFieldByTag((int)Tags.OrderID); trade.NumberTrade = entity.GetFieldByTag((int)Tags.ExecID); trade.Volume = Convert.ToDecimal(entity.GetFieldByTag((int)Tags.LastQty), CultureInfo.InvariantCulture); trade.Price = Convert.ToDecimal(entity.GetFieldByTag((int)Tags.LastPx), CultureInfo.InvariantCulture); trade.SecurityNameCode = entity.GetFieldByTag((int)Tags.SecurityID); MyTradeEvent?.Invoke(trade); } } catch (ArgumentException e) { SendLogMessage(e.Message, LogMessageType.Error); } catch (Exception e) { SendLogMessage("ExecutionReportHandlerError " + e.Message, LogMessageType.Error); } }
/// <summary> /// order and trade came /// пришел ордер и трейд /// </summary> /// <param name="bitMaxOrder"></param> private void ClientMyOrderEvent(OrderState bitMaxOrder) { var data = bitMaxOrder.Data; OrderCoupler needCoupler = _couplers.Find(c => c.OrderNumberMarket == data.OrderId); if (needCoupler == null) { return; } Order order = new Order(); order.NumberUser = needCoupler.OsOrderNumberUser; order.NumberMarket = data.OrderId; order.PortfolioNumber = data.S.Split('/')[1]; order.Price = data.P.ToDecimal(); order.Volume = data.Q.ToDecimal(); order.Side = data.Sd == "Buy" ? Side.Buy : Side.Sell; order.SecurityNameCode = data.S; order.ServerType = ServerType; order.TimeCallBack = TimeManager.GetDateTimeFromTimeStamp(Convert.ToInt64(data.T)); order.TypeOrder = OrderPriceType.Limit; if (data.St == "New") { order.State = OrderStateType.Activ; } else if (data.St == "Canceled") { order.State = OrderStateType.Cancel; _couplers.Remove(needCoupler); } else if (data.St == "PartiallyFilled") { order.State = OrderStateType.Patrial; } else if (data.St == "Filled") { order.State = OrderStateType.Done; _couplers.Remove(needCoupler); } else if (data.St == "Rejected") { order.State = OrderStateType.Fail; } if (bitMaxOrder.Data.St == "PartiallyFilled" || bitMaxOrder.Data.St == "Filled") { var cumVolume = data.Cfq.ToDecimal(); var tradeVolume = cumVolume - needCoupler.CurrentVolume; needCoupler.CurrentVolume += tradeVolume; MyTrade myTrade = new MyTrade { NumberOrderParent = data.OrderId, Side = data.Sd == "Buy" ? Side.Buy : Side.Sell, SecurityNameCode = data.S, Price = data.Ap.ToDecimal(), Volume = tradeVolume, NumberTrade = data.Sn.ToString(), Time = TimeManager.GetDateTimeFromTimeStamp(Convert.ToInt64(data.T)), }; MyTradeEvent?.Invoke(myTrade); } MyOrderEvent?.Invoke(order); }
/// <summary> /// order and trade came /// пришел ордер и трейд /// </summary> /// <param name="bitMaxOrder"></param> private void ClientMyOrderEvent(BitMaxOrder bitMaxOrder) { OrderCoupler needCoupler; if (bitMaxOrder.status == "Canceled") { needCoupler = _couplers.Find(c => c.OrderCancelId == bitMaxOrder.coid); } else { needCoupler = _couplers.Find(c => c.OrderNumberMarket == bitMaxOrder.coid); } if (needCoupler == null) { return; } if (bitMaxOrder.status == "PartiallyFilled" || bitMaxOrder.status == "Filled") { var partialVolume = bitMaxOrder.f.ToDecimal(); var tradeVolume = partialVolume - needCoupler.CurrentVolume; needCoupler.CurrentVolume += tradeVolume; MyTrade myTrade = new MyTrade() { NumberOrderParent = bitMaxOrder.coid, Side = bitMaxOrder.side == "Sell" ? Side.Sell : Side.Buy, NumberPosition = bitMaxOrder.coid, SecurityNameCode = bitMaxOrder.s.Replace('/', '-'), Price = bitMaxOrder.p.ToDecimal() , Volume = tradeVolume, NumberTrade = Guid.NewGuid().ToString(), Time = TimeManager.GetDateTimeFromTimeStamp(Convert.ToInt64(bitMaxOrder.t)), }; MyTradeEvent?.Invoke(myTrade); } Order order = new Order(); order.NumberUser = needCoupler.OsOrderNumberUser; order.NumberMarket = bitMaxOrder.coid; order.PortfolioNumber = bitMaxOrder.s.Split('/')[1]; order.Price = bitMaxOrder.p.ToDecimal(); order.Volume = bitMaxOrder.q.ToDecimal(); order.Side = bitMaxOrder.side == "Sell" ? Side.Sell : Side.Buy; order.SecurityNameCode = bitMaxOrder.s.Replace('/', '-'); order.ServerType = ServerType; order.TimeCallBack = TimeManager.GetDateTimeFromTimeStamp(Convert.ToInt64(bitMaxOrder.t)); order.TypeOrder = OrderPriceType.Limit; if (bitMaxOrder.status == "New") { order.State = OrderStateType.Activ; } else if (bitMaxOrder.status == "PartiallyFilled") { order.State = OrderStateType.Patrial; } else if (bitMaxOrder.status == "Filled") { order.State = OrderStateType.Done; _couplers.Remove(needCoupler); } else if (bitMaxOrder.status == "Canceled") { order.State = OrderStateType.Cancel; _couplers.Remove(needCoupler); } else if (bitMaxOrder.status == "Rejected") { order.State = OrderStateType.Fail; } MyOrderEvent?.Invoke(order); }