public async Task <ProtoOAReconcileRes> GetAccountOrders(long accountId, bool isLive) { VerifyConnection(); var client = GetClient(isLive); using var cancelationTokenSource = new CancellationTokenSource(); ProtoOAReconcileRes result = null; using var disposable = client.OfType <ProtoOAReconcileRes>().Where(response => response.CtidTraderAccountId == accountId) .Subscribe(response => { result = response; cancelationTokenSource.Cancel(); }); var requestMessage = new ProtoOAReconcileReq { CtidTraderAccountId = accountId }; await SendMessage(requestMessage, ProtoOAPayloadType.ProtoOaReconcileReq, client, cancelationTokenSource, () => result is not null); return(result); }
public ProtoMessage CreateReconcileResponse(string clientMsgId = null) { return(CreateMessage((uint)ProtoOAPayloadType.PROTO_OA_RECONCILE_RES, ProtoOAReconcileRes.CreateBuilder().Build().ToByteString(), clientMsgId)); }
static string OpenApiMessageToString(ProtoMessage msg) { switch ((ProtoOAPayloadType)msg.PayloadType) { case ProtoOAPayloadType.PROTO_OA_APPLICATION_AUTH_REQ: var app_auth_req = ProtoOAApplicationAuthReq.CreateBuilder().MergeFrom(msg.Payload).Build(); return("AppAuthRequest{clientId:" + app_auth_req.ClientId + ", clientSecret:" + app_auth_req.ClientSecret + "}"); case ProtoOAPayloadType.PROTO_OA_APPLICATION_AUTH_RES: return("ApAuthResponse"); case ProtoOAPayloadType.PROTO_OA_ACCOUNT_AUTH_REQ: var acc_auth_req = ProtoOAAccountAuthReq.CreateBuilder().MergeFrom(msg.Payload).Build(); return("AccAuthRequest{CtidTraderAccountId:" + acc_auth_req.CtidTraderAccountId + "}"); case ProtoOAPayloadType.PROTO_OA_ACCOUNT_AUTH_RES: return("AccAuthResponse"); case ProtoOAPayloadType.PROTO_OA_GET_ACCOUNTS_BY_ACCESS_TOKEN_REQ: return("GetAccountsByAccessTokenReq"); case ProtoOAPayloadType.PROTO_OA_GET_ACCOUNTS_BY_ACCESS_TOKEN_RES: var accounts_list = ProtoOAGetAccountListByAccessTokenRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbAccounts = new StringBuilder(); foreach (var account in accounts_list.CtidTraderAccountList) { sbAccounts.Append("ID: " + account.CtidTraderAccountId + (account.IsLive ? " Status: Live" + Environment.NewLine : " Status: Demo " + Environment.NewLine)); } return("GetAccountsByAccessTokenRes{" + sbAccounts.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_TRADER_REQ: return("PotoOATraderReq"); case ProtoOAPayloadType.PROTO_OA_SYMBOLS_LIST_REQ: return("GetSymbolsList"); case ProtoOAPayloadType.PROTO_OA_SYMBOLS_LIST_RES: var symbols_list = ProtoOASymbolsListRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbSymbols = new StringBuilder(); foreach (var symbol in symbols_list.SymbolList) { sbSymbols.Append("ID: " + symbol.SymbolId + Environment.NewLine); sbSymbols.Append("Name: " + symbol.SymbolName + Environment.NewLine); } return("Symbols{" + sbSymbols.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_SYMBOL_BY_ID_REQ: return("GetSymbolsById"); case ProtoOAPayloadType.PROTO_OA_SYMBOL_BY_ID_RES: var symbol_by_id_list = ProtoOASymbolByIdRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbSymbolByID = new StringBuilder(); foreach (var symbol in symbol_by_id_list.SymbolList) { sbSymbolByID.Append("ID: " + symbol.SymbolId + Environment.NewLine); } return("Symbols{" + sbSymbolByID.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_EXECUTION_EVENT: return(OpenApiExecEventsToString(msg)); case ProtoOAPayloadType.PROTO_OA_DEAL_LIST_REQ: return("DealListRequest{}"); case ProtoOAPayloadType.PROTO_OA_DEAL_LIST_RES: var deal_list = ProtoOADealListRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbDeals = new StringBuilder(); foreach (var deal in deal_list.DealList) { sbDeals.Append("ID: " + deal.DealId + Environment.NewLine); sbDeals.Append("Status: " + deal.DealStatus + Environment.NewLine); sbDeals.Append("Volume: " + deal.Volume + Environment.NewLine); } return("DealList{" + sbDeals.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_RECONCILE_REQ: return("ReconcileRequest{}"); case ProtoOAPayloadType.PROTO_OA_RECONCILE_RES: var reconcile_response = ProtoOAReconcileRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbReconcile = new StringBuilder(); foreach (var order in reconcile_response.OrderList) { sbReconcile.Append("ID: " + order.OrderId + Environment.NewLine); sbReconcile.Append("Status: " + order.OrderStatus + Environment.NewLine); sbReconcile.Append("Volume: " + order.TradeData.Volume + Environment.NewLine); } foreach (var position in reconcile_response.PositionList) { sbReconcile.Append("ID: " + position.HasPositionId + Environment.NewLine); sbReconcile.Append("Status: " + position.PositionStatus + Environment.NewLine); sbReconcile.Append("Volume: " + position.TradeData.Volume + Environment.NewLine); } return("ReconcileList{" + sbReconcile.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_CASH_FLOW_HISTORY_LIST_REQ: return("CashFlowHistoryRequest{}"); case ProtoOAPayloadType.PROTO_OA_CASH_FLOW_HISTORY_LIST_RES: var cashflow_history = ProtoOACashFlowHistoryListRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbDCashflow = new StringBuilder(); foreach (var entry in cashflow_history.DepositWithdrawList) { sbDCashflow.Append("ID: " + entry.BalanceHistoryId + Environment.NewLine); sbDCashflow.Append("Type: " + entry.OperationType + Environment.NewLine); sbDCashflow.Append("Delta: " + entry.Delta + Environment.NewLine); } return("CashFlowHistory{" + sbDCashflow.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_GET_TRENDBARS_REQ: return("GetTrendbarsRequest{}"); case ProtoOAPayloadType.PROTO_OA_GET_TRENDBARS_RES: var trendbar = ProtoOAGetTrendbarsRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbTrendbar = new StringBuilder(); foreach (var entry in trendbar.TrendbarList) { sbTrendbar.Append("Open: " + entry.DeltaOpen + Environment.NewLine); sbTrendbar.Append("High: " + entry.DeltaHigh + Environment.NewLine); sbTrendbar.Append("Low: " + entry.Low + Environment.NewLine); sbTrendbar.Append("Close: " + entry.DeltaClose + Environment.NewLine); } return("Trendbars{" + sbTrendbar.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_GET_TICKDATA_REQ: return("GetTickDataRequest{}"); case ProtoOAPayloadType.PROTO_OA_GET_TICKDATA_RES: var tickData = ProtoOAGetTickDataRes.CreateBuilder().MergeFrom(msg.Payload).Build(); var sbTickData = new StringBuilder(); foreach (var entry in tickData.TickDataList) { sbTickData.Append("Tick: " + entry.Tick + Environment.NewLine + " " + msg.ClientMsgId); } return("Tick Data{" + sbTickData.ToString() + "}"); case ProtoOAPayloadType.PROTO_OA_CANCEL_ORDER_REQ: return("CancelOrderRequest{}"); case ProtoOAPayloadType.PROTO_OA_NEW_ORDER_REQ: return("CreateOrderRequest{}"); case ProtoOAPayloadType.PROTO_OA_CLOSE_POSITION_REQ: return("ClosePositionRequest{}"); case ProtoOAPayloadType.PROTO_OA_AMEND_ORDER_REQ: return("AmendOrderRequest{}"); case ProtoOAPayloadType.PROTO_OA_AMEND_POSITION_SLTP_REQ: return("AmendPositionRequest{}"); case ProtoOAPayloadType.PROTO_OA_SUBSCRIBE_SPOTS_REQ: return("SubscribeForSpotsRequest{}"); case ProtoOAPayloadType.PROTO_OA_SUBSCRIBE_SPOTS_RES: return("SubscribeForSpotsResponse{}"); case ProtoOAPayloadType.PROTO_OA_UNSUBSCRIBE_SPOTS_REQ: return("UnsubscribeFromSpotsRequest{}"); case ProtoOAPayloadType.PROTO_OA_UNSUBSCRIBE_SPOTS_RES: return("UnsubscribeFromSpotsResponse{}"); case ProtoOAPayloadType.PROTO_OA_SPOT_EVENT: var _spot_event = ProtoOASpotEvent.CreateBuilder().MergeFrom(msg.Payload).Build(); return("SpotEvent{symbolId:" + _spot_event.SymbolId + ", bidPrice:" + (_spot_event.HasBid ? _spot_event.Bid.ToString() : " ") + ", askPrice:" + (_spot_event.HasAsk ? _spot_event.Ask.ToString() : " ") + "}"); case ProtoOAPayloadType.PROTO_OA_ERROR_RES: var _err = ProtoOAErrorRes.CreateBuilder().MergeFrom(msg.Payload).Build(); return("ErrorResponse{errorCode:" + _err.ErrorCode + (_err.HasDescription ? ", description:" + _err.Description : "") + "}"); case ProtoOAPayloadType.PROTO_OA_ORDER_ERROR_EVENT: var _orderErr = ProtoOAOrderErrorEvent.CreateBuilder().MergeFrom(msg.Payload).Build(); return("OrderErrorResponse{errorCode:" + _orderErr.ErrorCode + (_orderErr.HasDescription ? ", description:" + _orderErr.Description : "") + "}"); default: return("unknown"); } }
// listener thread private void Listen(SslStream sslStream, Queue messagesQueue) { isShutdown = false; while (!isShutdown) { Thread.Sleep(1); byte[] _length = new byte[sizeof(int)]; int readBytes = 0; do { Thread.Sleep(0); readBytes += sslStream.Read(_length, readBytes, _length.Length - readBytes); } while (readBytes < _length.Length); int length = BitConverter.ToInt32(_length.Reverse().ToArray(), 0); if (length <= 0) { continue; } if (length > MaxMessageSize) { string exceptionMsg = "Message length " + length.ToString() + " is out of range (0 - " + MaxMessageSize.ToString() + ")"; throw new System.IndexOutOfRangeException(); } byte[] _message = new byte[length]; readBytes = 0; do { Thread.Sleep(0); readBytes += sslStream.Read(_message, readBytes, _message.Length - readBytes); } while (readBytes < length); var msgFactory = new OpenApiMessagesFactory(); var protoMessage = msgFactory.GetMessage(_message); messagesQueue.Enqueue("Received: " + OpenApiMessagesPresentation.ToString(protoMessage)); switch ((ProtoOAPayloadType)protoMessage.PayloadType) { case ProtoOAPayloadType.PROTO_OA_APPLICATION_AUTH_RES: ProtoOAApplicationAuthRes Res = msgFactory.GetApplicationAuthorizationResponse(_message); Console.WriteLine(Res.ToString()); break; case ProtoOAPayloadType.PROTO_OA_EXECUTION_EVENT: var _payload_msg = msgFactory.GetExecutionEvent(_message); if (_payload_msg.HasOrder) { testOrderId = _payload_msg.Order.OrderId; } if (_payload_msg.HasPosition) { testPositionId = _payload_msg.Position.PositionId; } break; case ProtoOAPayloadType.PROTO_OA_GET_ACCOUNTS_BY_ACCESS_TOKEN_RES: var _accounts_list = ProtoOAGetAccountListByAccessTokenRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); _accounts = _accounts_list.CtidTraderAccountList; break; case ProtoOAPayloadType.PROTO_OA_TRADER_RES: var trader = ProtoOATraderRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); _traders.Add(trader.Trader); break; case ProtoOAPayloadType.PROTO_OA_RECONCILE_RES: var _reconcile_list = ProtoOAReconcileRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); break; default: break; } ; } }
private void OnReconcileResponse(ProtoOAReconcileRes e, string clientMsgId) { var streamMessage = new StreamMessage <ProtoOAReconcileRes>(e, clientMsgId); _reconcileResponseStream.OnNext(streamMessage); }
private void Process_Reconcile_Res() { ProtoOAReconcileRes args = Serializer.Deserialize <ProtoOAReconcileRes>(_processorMemoryStream); Log.Info("ProtoOAReconcileRes:: " + $"ctidTraderAccountId: {args.ctidTraderAccountId}"); TradingAccounts[args.ctidTraderAccountId].Positions.Clear(); foreach (ProtoOAPosition position in args.Positions) { TradingAccounts[args.ctidTraderAccountId].Positions[position.positionId] = position; string item = $"positionId: {position.positionId}; " + $"positionStatus: {position.positionStatus}; " + $"Price: {position.Price}; " + $"stopLoss: {position.stopLoss}; " + $"takeProfit: {position.takeProfit}; " + $"usedMargin: {position.usedMargin}; " + $"marginRate: {position.marginRate}; " + $"Swap: {position.Swap}; " + $"Commission: {position.Commission}; " + $"mirroringCommission: {position.mirroringCommission}; " + $"tradeData.symbolId: {position.tradeData.symbolId} " + $"({TradingAccounts[args.ctidTraderAccountId].TradingSymbols[position.tradeData.symbolId].LightSymbol.symbolName}); " + $"tradeData.tradeSide: {position.tradeData.tradeSide}; " + $"tradeData.Volume: {position.tradeData.Volume}; " + $"tradeData.guaranteedStopLoss: {position.tradeData.guaranteedStopLoss}; " + $"tradeData.openTimestamp: {position.tradeData.openTimestamp} ({EpochToString(position.tradeData.openTimestamp)}; " + $"tradeData.Label: {position.tradeData.Label}; " + $"stopLossTriggerMethod: {position.stopLossTriggerMethod}; " + $"utcLastUpdateTimestamp: {position.utcLastUpdateTimestamp} ({EpochToString(position.utcLastUpdateTimestamp)}"; Log.Info("ProtoOAReconcileRes:: " + $"ctidTraderAccountId: {args.ctidTraderAccountId}; " + $"Position: [{item}]"); } TradingAccounts[args.ctidTraderAccountId].Orders.Clear(); foreach (ProtoOAOrder order in args.Orders) { TradingAccounts[args.ctidTraderAccountId].Orders[order.orderId] = order; string item = $"orderId: {order.orderId}; " + $"orderType: {order.orderType}; " + $"orderStatus: {order.orderStatus}; " + $"positionId: {order.positionId}; " + $"closingOrder: {order.closingOrder}; " + $"executedVolume: {order.executedVolume}; " + $"executionPrice: {order.executionPrice}; " + $"stopLoss: {order.stopLoss}; " + $"takeProfit: {order.takeProfit}; " + $"limitPrice: {order.limitPrice}; " + $"stopPrice: {order.stopPrice}; " + $"expirationTimestamp: {order.expirationTimestamp} ({EpochToString(order.expirationTimestamp)}); " + $"tradeData.Label: {order.tradeData.Label}; " + $"tradeData.openTimestamp: {order.tradeData.openTimestamp} " + $"({EpochToString(order.tradeData.openTimestamp)}); " + $"tradeData.symbolId: {order.tradeData.symbolId} " + $"({TradingAccounts[args.ctidTraderAccountId].TradingSymbols[order.tradeData.symbolId].LightSymbol.symbolName}); " + $"tradeData.tradeSide: {order.tradeData.tradeSide}; " + $"tradeData.Volume: {order.tradeData.Volume}; " + $"tradeData.guaranteedStopLoss: {order.tradeData.guaranteedStopLoss}; " + $"baseSlippagePrice: {order.baseSlippagePrice}; " + $"clientOrderId: {order.clientOrderId}; " + $"isStopOut: {order.isStopOut}; " + $"relativeStopLoss: {order.relativeStopLoss}; " + $"relativeTakeProfit: {order.relativeTakeProfit}; " + $"slippageInPoints: {order.slippageInPoints}; " + $"stopTriggerMethod: {order.stopTriggerMethod}; " + $"timeInForce: {order.timeInForce}; " + $"trailingStopLoss: {order.trailingStopLoss}; " + $"utcLastUpdateTimestamp: {order.utcLastUpdateTimestamp} ({EpochToString(order.utcLastUpdateTimestamp)})"; Log.Info("ProtoOAReconcileRes:: " + $"ctidTraderAccountId: {args.ctidTraderAccountId}; " + $"Order: {item};"); } if (_subscribeAllSymbols) { Send(Subscribe_Spots_Req(args.ctidTraderAccountId, TradingAccounts[args.ctidTraderAccountId].TradingSymbols.Keys.ToArray())); } OnReconcileResReceived?.Invoke(args); }