public void OrderFilledEventHandler(object sender, EventArgs args) { OrderUpdateEventArgs filledOrder = null; //if (args is ForcedOrderFilledEventArgs) //{ // filledOrder = (ForcedOrderFilledEventArgs)args; // Dispatcher.Invoke(() => // { // if (filledOrder.side != "UNKNOWN") // { // btnSellAtNow.IsEnabled = false; // btnStartByBuying.IsEnabled = true; // } // }); //} //else //{ // filledOrder = ((OrderUpdateEventArgs)args); //} filledOrder = ((OrderUpdateEventArgs)args); //MessageBox.Show(string.Format("{0} order ({1}) filled @{2} ", filledOrder.side, filledOrder.OrderId, filledOrder.filledAtPrice)); Dispatcher.Invoke(() => btnBuyAtNow.IsEnabled = true); Dispatcher.Invoke(() => btnSellAtNow.IsEnabled = true); this.Dispatcher.Invoke(() => updateListView(filledOrder)); }
public void Properties() { var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const long id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; const bool isWorking = true; var order = new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, time, isWorking); const OrderExecutionType orderExecutionType = OrderExecutionType.New; const string orderRejectedReason = OrderRejectedReason.None; const string newClientOrderId = "new-test-order"; var args = new OrderUpdateEventArgs(time, order, orderExecutionType, orderRejectedReason, newClientOrderId); Assert.Equal(time, args.Time); Assert.Equal(order, args.Order); Assert.Equal(orderExecutionType, args.OrderExecutionType); Assert.Equal(orderRejectedReason, args.OrderRejectedReason); Assert.Equal(newClientOrderId, args.NewClientOrderId); }
public void OrderUpdated(object sender, OrderUpdateEventArgs args) { try { if (stockCode != args.TrdSym) { return; } // just log the update info for debug first Trace(string.Format("[Order Updated] {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15} {16}", args.TrdSym, args.OrderId, args.Status, args.Price, args.Product, args.ExchTime, args.Duration, args.Message, args.Quantity, args.TradedQty, args.ExchId, args.ExchToken, args.InstToken, args.ParentId, args.TransType, args.TimeStamp, args.AvgPrice)); lock (myUpstoxWrapper.lockSingleThreadedUpstoxCall) { latestOrderUpdateInfo = args; } var orderStatus = myUpstoxWrapper.ParseOrderStatus(args.Status); //if (orderStatus == OrderStatus.ORDERED) orderUpdateReceivedEvent.Set(); //return; } catch (Exception ex) { Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace); } }
public void LimitOrder() { var sec = new Security() { Id = 1, Type = SecurityType.Future, Group = "GC", Product = "GC", Contract = "GCZ6" }; var book = new OrderBook(sec); book.SetStatus(SecurityTradingStatus.Open); OrderCreatedEventArgs createdArgs = null; book.OrderCreated += (sender, e) => { createdArgs = e; }; book.CreateLimitOrder(1, TimeInForce.Day, null, Side.Buy, 100, 3); Debug.Assert(createdArgs != null); Debug.Assert(createdArgs.Order.Status == OrderStatus.Created); Debug.Assert(createdArgs.Order.Id == 1); Debug.Assert(createdArgs.Order.Price == 100); Debug.Assert(createdArgs.Order.Quantity == 3); Debug.Assert(createdArgs.Order.FilledQuantity == 0); Debug.Assert(createdArgs.Order.RemainingQuantity == 3); Debug.Assert(createdArgs.Order.Side == Side.Buy); Debug.Assert(createdArgs.Order.Type == OrderType.Limit); Debug.Assert(createdArgs.Order.TimeInForce == TimeInForce.Day); Debug.Assert(createdArgs.Order.Security == sec); OrderUpdateEventArgs updatedArgs = null; book.OrderUpdated += (sender, e) => { updatedArgs = e; }; book.UpdateLimitOrder(1, 105, 5); Debug.Assert(updatedArgs != null); Debug.Assert(updatedArgs.Order.Status == OrderStatus.Updated); Debug.Assert(updatedArgs.Order.Id == 1); Debug.Assert(updatedArgs.Order.Price == 105); Debug.Assert(updatedArgs.Order.Quantity == 5); Debug.Assert(updatedArgs.Order.FilledQuantity == 0); Debug.Assert(updatedArgs.Order.RemainingQuantity == 5); OrderDeletedEventArgs deletedArgs = null; book.OrderDeleted += (sender, e) => { deletedArgs = e; }; book.DeleteOrder(1); Debug.Assert(deletedArgs != null); Debug.Assert(deletedArgs.Order.Status == OrderStatus.Deleted); Debug.Assert(deletedArgs.Order.Id == 1); Debug.Assert(deletedArgs.Order.Price == 105); Debug.Assert(updatedArgs.Order.Quantity == 5); Debug.Assert(deletedArgs.Order.FilledQuantity == 0); Debug.Assert(deletedArgs.Order.RemainingQuantity == 0); Debug.Assert(deletedArgs.Reason == null); }
private static void OnOrderUpdateEvent(object sender, OrderUpdateEventArgs e) { lock (Program.ConsoleSync) { Console.WriteLine(); Console.WriteLine($"Order [{e.Order.Id}] update: {e.OrderExecutionType}"); Program.Display(e.Order); Console.WriteLine(); } }
/// <summary> /// Deserialize JSON and raise <see cref="UserDataEventArgs"/> event. /// </summary> /// <param name="json"></param> /// <param name="token"></param> /// <param name="callback"></param> /// <returns></returns> protected override void DeserializeJsonAndRaiseEvent(string json, CancellationToken token, Action <UserDataEventArgs> callback = null) { Throw.IfNullOrWhiteSpace(json, nameof(json)); Logger?.LogDebug($"{nameof(UserDataWebSocketClient)}: \"{json}\""); try { var jObject = JObject.Parse(json); var eventType = jObject["e"].Value <string>(); var eventTime = jObject["E"].Value <long>(); // ReSharper disable once ConvertIfStatementToSwitchStatement if (eventType == "outboundAccountInfo") { var commissions = new AccountCommissions( jObject["m"].Value <int>(), // maker jObject["t"].Value <int>(), // taker jObject["b"].Value <int>(), // buyer jObject["s"].Value <int>()); // seller var status = new AccountStatus( jObject["T"].Value <bool>(), // can trade jObject["W"].Value <bool>(), // can withdraw jObject["D"].Value <bool>()); // can deposit var balances = jObject["B"] .Select(entry => new AccountBalance( entry["a"].Value <string>(), // asset entry["f"].Value <decimal>(), // free amount entry["l"].Value <decimal>())) // locked amount .ToList(); var eventArgs = new AccountUpdateEventArgs(eventTime, token, new AccountInfo(User, commissions, status, jObject["u"].Value <long>(), balances)); try { callback?.Invoke(eventArgs); AccountUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled account update event handler exception."); } } } else if (eventType == "executionReport") { var order = new Order(User); FillOrder(order, jObject); var executionType = ConvertOrderExecutionType(jObject["x"].Value <string>()); var rejectedReason = ConvertOrderRejectedReason(jObject["r"].Value <string>()); var newClientOrderId = jObject["c"].Value <string>(); if (executionType == OrderExecutionType.Trade) // trade update event. { var trade = new AccountTrade( jObject["s"].Value <string>(), // symbol jObject["t"].Value <long>(), // ID jObject["i"].Value <long>(), // order ID jObject["L"].Value <decimal>(), // price (price of last filled trade) jObject["z"].Value <decimal>(), // quantity (accumulated quantity of filled trades) jObject["n"].Value <decimal>(), // commission jObject["N"].Value <string>(), // commission asset jObject["T"].Value <long>(), // timestamp order.Side == OrderSide.Buy, // is buyer jObject["m"].Value <bool>(), // is buyer maker jObject["M"].Value <bool>()); // is best price var quantityOfLastFilledTrade = jObject["l"].Value <decimal>(); var eventArgs = new AccountTradeUpdateEventArgs(eventTime, token, order, rejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade); try { callback?.Invoke(eventArgs); TradeUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled trade update event handler exception."); } } } else // order update event. { var eventArgs = new OrderUpdateEventArgs(eventTime, token, order, executionType, rejectedReason, newClientOrderId); try { callback?.Invoke(eventArgs); OrderUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled order update event handler exception."); } } } } else { Logger?.LogWarning($"{nameof(UserDataWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}: Unexpected event type ({eventType}) - \"{json}\""); } } catch (OperationCanceledException) { } catch (Exception e) { if (!token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}"); } } }
protected override void OnWebSocketEvent(WebSocketStreamEventArgs args, IEnumerable <Action <UserDataEventArgs> > callbacks) { if (!ListenKeys.ContainsKey(args.StreamName)) { Logger?.LogError($"{nameof(UserDataWebSocketClient)}.{nameof(OnWebSocketEvent)}: Unknown listen key (\"{args.StreamName}\"). [thread: {Thread.CurrentThread.ManagedThreadId}]"); return; // ignore. } var user = ListenKeys[args.StreamName]; Logger?.LogDebug($"{nameof(UserDataWebSocketClient)}: \"{args.Json}\""); try { var jObject = JObject.Parse(args.Json); var eventType = jObject["e"].Value <string>(); var eventTime = jObject["E"].Value <long>().ToDateTimeK(); // ReSharper disable once ConvertIfStatementToSwitchStatement if (eventType == "outboundAccountInfo") { var commissions = new AccountCommissions( jObject["m"].Value <int>(), // maker jObject["t"].Value <int>(), // taker jObject["b"].Value <int>(), // buyer jObject["s"].Value <int>()); // seller var status = new AccountStatus( jObject["T"].Value <bool>(), // can trade jObject["W"].Value <bool>(), // can withdraw jObject["D"].Value <bool>()); // can deposit var balances = jObject["B"] .Select(entry => new AccountBalance( entry["a"].Value <string>(), // asset entry["f"].Value <decimal>(), // free amount entry["l"].Value <decimal>())) // locked amount .ToList(); var eventArgs = new AccountUpdateEventArgs(eventTime, args.Token, new AccountInfo(user, commissions, status, jObject["u"].Value <long>().ToDateTimeK(), balances)); try { if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } AccountUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!args.Token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled account update event handler exception."); } } } else if (eventType == "executionReport") { var order = new Order(user); FillOrder(order, jObject); var executionType = ConvertOrderExecutionType(jObject["x"].Value <string>()); var rejectedReason = ConvertOrderRejectedReason(jObject["r"].Value <string>()); var newClientOrderId = jObject["c"].Value <string>(); if (executionType == OrderExecutionType.Trade) // trade update event. { var trade = new AccountTrade( jObject["s"].Value <string>(), // symbol jObject["t"].Value <long>(), // ID jObject["i"].Value <long>(), // order ID jObject["L"].Value <decimal>(), // price (price of last filled trade) jObject["z"].Value <decimal>(), // quantity (accumulated quantity of filled trades) jObject["n"].Value <decimal>(), // commission jObject["N"].Value <string>(), // commission asset jObject["T"].Value <long>() .ToDateTimeK(), // time order.Side == OrderSide.Buy, // is buyer jObject["m"].Value <bool>(), // is buyer maker jObject["M"].Value <bool>()); // is best price var quantityOfLastFilledTrade = jObject["l"].Value <decimal>(); var eventArgs = new AccountTradeUpdateEventArgs(eventTime, args.Token, order, rejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade); try { if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } TradeUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!args.Token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled trade update event handler exception."); } } } else // order update event. { var eventArgs = new OrderUpdateEventArgs(eventTime, args.Token, order, executionType, rejectedReason, newClientOrderId); try { if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } OrderUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { } catch (Exception e) { if (!args.Token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled order update event handler exception."); } } } } else { Logger?.LogWarning($"{nameof(UserDataWebSocketClient)}.{nameof(OnWebSocketEvent)}: Unexpected event type ({eventType}) - \"{args.Json}\""); } } catch (OperationCanceledException) { } catch (Exception e) { if (!args.Token.IsCancellationRequested) { Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}.{nameof(OnWebSocketEvent)}"); } } }
private void OnOrderUpdate(object sender, OrderUpdateEventArgs args) { _onOrderUpdate?.Invoke(args); }
private void OnOrderUpdate(OrderUpdateEventArgs args) { var symbol = args.Order.Symbol; UpdateOrders(args.Order, symbol); }
private void updateListView(OrderUpdateEventArgs fillData) { if (fillData.side == "buy") { RowItem rowData = new RowItem(); rowData.buyPrice = fillData.filledAtPrice; rowData.buySize = fillData.fillSize; var dt = DateTime.UtcNow.ToLocalTime(); rowData.buyTime = dt.ToShortDateString() + " " + dt.ToLongTimeString(); rowData.buyFee = fillData.fillFee; lstView.Items.Add(rowData); } else { int lastItem = lstView.Items.Count - 1; RowItem rowDataItem; if (lastItem >= 0) //no item in list { rowDataItem = (RowItem)(lstView.Items.GetItemAt(lastItem)); } else { rowDataItem = new RowItem { buyPrice = "0", buyFee = "0", buySize = "0", buyTime = "" }; } rowDataItem.sellPrice = fillData.filledAtPrice; rowDataItem.sellSize = fillData.fillSize; var dt = DateTime.UtcNow.ToLocalTime(); rowDataItem.sellTime = dt.ToShortDateString() + " " + dt.ToLongTimeString(); rowDataItem.sellFee = fillData.fillFee; var feeTotal = (Convert.ToDecimal(rowDataItem.buyFee) + Convert.ToDecimal(rowDataItem.sellFee)); rowDataItem.feeTotal = feeTotal.ToString(); var diff = Convert.ToDecimal(rowDataItem.sellPrice) - Convert.ToDecimal(rowDataItem.buyPrice); var profitLoss = (diff * (Convert.ToDecimal(rowDataItem.sellSize))) - feeTotal; rowDataItem.pl = (profitLoss).ToString(); if (lastItem >= 0) { lstView.Items.RemoveAt(lastItem); lstView.Items.Insert(lastItem, rowDataItem); } else { lstView.Items.Add(rowDataItem); } } // Populate list var gridView = (GridView)lstView.View; gridView.Columns.ToList().ForEach((c) => { c.Width = 0; c.Width = double.NaN; }); }
public BrokerErrorCode ModifyEquityOrder( ref OrderUpdateEventArgs latestOrderUpdatedInfo, AutoResetEvent orderUpdatedEvent, string stockCode, string orderId, OrderPriceType orderPriceType, int quantity, double price, out OrderStatus orderStatus) { //lock (lockSingleThreadedUpstoxCall) { BrokerErrorCode errorCode = BrokerErrorCode.Unknown; orderStatus = OrderStatus.UNKNOWN; var ordType = orderPriceType == OrderPriceType.LIMIT ? "L" : "M"; try { upstox.ModifySimpleOrder(orderId, ordType, quantity, price, quantity); Thread.Sleep(1000); // let the order status update at server errorCode = GetOrderStatus(orderId, stockCode, out orderStatus); if (orderStatus == OrderStatus.EXPIRED || orderStatus == OrderStatus.CANCELLED || orderStatus == OrderStatus.NOTFOUND || orderStatus == OrderStatus.REJECTED || orderStatus == OrderStatus.UNKNOWN) { Trace("ModifyOrder failed with status: " + orderStatus); } } catch (Exception ex) { Trace(string.Format(genericErrorLogFormat, stockCode, GeneralUtils.GetCurrentMethod(), ex.Message, ex.StackTrace)); // wait for orderupdate event signal var orderUpdateWait = orderUpdatedEvent.WaitOne(20 * 1000); lock (lockSingleThreadedUpstoxCall) { if (orderUpdateWait) { if (latestOrderUpdatedInfo != null) { // match the order if (latestOrderUpdatedInfo.OrderId == orderId) { orderStatus = ParseOrderStatus(latestOrderUpdatedInfo.Status); Trace(string.Format("{0} ModifySimpleOrder Reconciliation completed. ErrCode={1}, OrderStatus={2}, OrderId={3}", stockCode, errorCode, orderStatus, orderId)); } else { Trace(string.Format("{0} ModifySimpleOrder Reconciliation failed OrderNotMatched. ErrCode={1}, OrderStatus={2}, OrderId={2}", stockCode, errorCode, orderStatus, orderId)); } } else { Trace(string.Format("{0} ModifySimpleOrder LatestOrderUpdateInfo is null . ErrCode={1}, OrderStatus={2}, OrderId={3}", stockCode, errorCode, orderStatus, orderId)); } } else { Trace(string.Format("{0} ModifySimpleOrder Reconciliation failed NoOrderUpdate. ErrCode={1}, OrderStatus={2}, OrderId={2}", stockCode, errorCode, orderStatus, orderId)); } } } return(errorCode); } }
public BrokerErrorCode PlaceEquityOrder( ref OrderUpdateEventArgs latestOrderUpdatedInfo, AutoResetEvent orderUpdatedEvent, string exchange, string stockCode, OrderDirection orderDirection, OrderPriceType orderPriceType, int quantity, EquityOrderType orderType, double price, out string orderId, out OrderStatus orderStatus) { //lock (lockSingleThreadedUpstoxCall) { BrokerErrorCode errorCode = BrokerErrorCode.Unknown; orderStatus = OrderStatus.UNKNOWN; orderId = ""; if (quantity == 0) { Trace("Not placing order as quantity is 0"); Trace(string.Format("Not placing order: {0} {1} {2} {3}@{4} {5}, as quantity is 0", orderType, stockCode, orderDirection, quantity, price, orderPriceType)); return(errorCode); } if (price == 0 && orderPriceType == OrderPriceType.LIMIT) { Trace(string.Format("Not placing order: {0} {1} {2} {3}@{4} {5}, as price is 0 for limit order", orderType, stockCode, orderDirection, quantity, price, orderPriceType)); return(errorCode); } var transType = orderDirection == OrderDirection.BUY ? "B" : "S"; var ordType = orderPriceType == OrderPriceType.LIMIT ? "L" : "M"; var prodType = orderType == EquityOrderType.DELIVERY ? "D" : "I"; try { orderId = upstox.PlaceSimpleOrder(exchange, stockCode, transType, ordType, quantity, prodType, price); Thread.Sleep(1000); // let the order status update at server errorCode = GetOrderStatus(orderId, stockCode, out orderStatus); mOrderIds[stockCode].Add(orderId); // For unsuccessful placeorder dont send orderId if (orderStatus == OrderStatus.EXPIRED || orderStatus == OrderStatus.CANCELLED || orderStatus == OrderStatus.NOTFOUND || orderStatus == OrderStatus.REJECTED || orderStatus == OrderStatus.UNKNOWN) { orderId = ""; } } catch (Exception ex) { Trace(string.Format(genericErrorLogFormat, stockCode, GeneralUtils.GetCurrentMethod(), ex.Message, ex.StackTrace)); // wait for orderupdate event signal var orderUpdateWait = orderUpdatedEvent.WaitOne(20 * 1000); lock (lockSingleThreadedUpstoxCall) { if (orderUpdateWait) { if (latestOrderUpdatedInfo != null) { // match the order if (latestOrderUpdatedInfo.Price == price && latestOrderUpdatedInfo.Quantity == quantity && latestOrderUpdatedInfo.Product == prodType && transType == latestOrderUpdatedInfo.TransType) { orderStatus = ParseOrderStatus(latestOrderUpdatedInfo.Status); orderId = latestOrderUpdatedInfo.OrderId; if (!string.IsNullOrEmpty(orderId) && !mOrderIds[stockCode].Contains(orderId)) { mOrderIds[stockCode].Add(orderId); } Trace(string.Format("{0} PlaceSimpleOrder Reconciliation completed. ErrCode={1}, OrderStatus={2}, OrderId={3}", stockCode, errorCode, orderStatus, orderId)); } else { Trace(string.Format("{0} PlaceSimpleOrder Reconciliation failed OrderNotMatched. ErrCode={1}, OrderStatus={2}, OrderId={2}", stockCode, errorCode, orderStatus, orderId)); } } else { Trace(string.Format("{0} PlaceSimpleOrder LatestOrderUpdateInfo is null . ErrCode={1}, OrderStatus={2}, OrderId={3}", stockCode, errorCode, orderStatus, orderId)); } } else { Trace(string.Format("{0} PlaceSimpleOrder Reconciliation failed NoOrderUpdate. ErrCode={1}, OrderStatus={2}, OrderId={2}", stockCode, errorCode, orderStatus, orderId)); } } } return(errorCode); } }
private void HandleOrderUpdateAccepted(object sender, OrderUpdateEventArgs args) { ordersToClients[args.Order.Id].Send(new CancelReplaceAck(args.Order, orderInfos[args.Order.Id])); SendBookUpdates(args.Order.Security); }