internal static void Display(AccountTrade trade) { lock (ConsoleSync) { Console.WriteLine($" {trade.Time.ToLocalTime()} - {trade.Symbol.PadLeft(8)} - {(trade.IsBuyer ? "Buy" : "Sell").PadLeft(4)} - {(trade.IsMaker ? "Maker" : "Taker")} - {trade.Quantity:0.00000000} @ {trade.Price:0.00000000}{(trade.IsBestPriceMatch ? "*" : " ")} - Fee: {trade.Commission:0.00000000} {trade.CommissionAsset.PadRight(5)} ID: {trade.Id}"); } }
public void Throws() { var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; var symbol = Symbol.BTC_USDT; const decimal price = 4999; const string orderRejectedReason = OrderRejectedReason.None; const string newClientOrderId = "new-test-order"; const long tradeId = 12345; const long orderId = 54321; const decimal quantity = 1; const decimal commission = 10; const string commissionAsset = "BNB"; const bool isBuyer = true; const bool isMaker = true; const bool isBestPriceMatch = true; var trade = new AccountTrade(symbol, tradeId, orderId, price, quantity, commission, commissionAsset, time, isBuyer, isMaker, isBestPriceMatch); decimal quantityOfLastFilledTrade = 1; Assert.Throws <ArgumentNullException>("order", () => new AccountTradeUpdateEventArgs(time, null, orderRejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade)); }
public void Serialization() { var symbol = Symbol.BTC_USDT; const long id = 12345; const long orderId = 54321; const decimal price = 5000; const decimal quantity = 1; const decimal quoteQuantity = price * quantity; const decimal commission = 10; var commissionAsset = Asset.BNB; var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; const bool isBuyer = true; const bool isMaker = true; const bool isBestPriceMatch = true; var trade = new AccountTrade(symbol, id, orderId, price, quantity, quoteQuantity, commission, commissionAsset, time, isBuyer, isMaker, isBestPriceMatch); var json = JsonConvert.SerializeObject(trade); trade = JsonConvert.DeserializeObject <AccountTrade>(json); Assert.Equal(symbol, trade.Symbol); Assert.Equal(id, trade.Id); Assert.Equal(orderId, trade.OrderId); Assert.Equal(price, trade.Price); Assert.Equal(quantity, trade.Quantity); Assert.Equal(quoteQuantity, trade.QuoteQuantity); Assert.Equal(commission, trade.Commission); Assert.Equal(commissionAsset, trade.CommissionAsset); Assert.Equal(time, trade.Time); Assert.Equal(isBuyer, trade.IsBuyer); Assert.Equal(isMaker, trade.IsMaker); Assert.Equal(isBestPriceMatch, trade.IsBestPriceMatch); }
public void Equality() { var symbol = Symbol.BTC_USDT; const long id = 12345; const long orderId = 54321; const decimal price = 5000; const decimal quantity = 1; const decimal quoteQuantity = price * quantity; const decimal commission = 10; var commissionAsset = Asset.BNB; var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; const bool isBuyer = true; const bool isMaker = true; const bool isBestPriceMatch = true; var trade = new AccountTrade(symbol, id, orderId, price, quantity, quoteQuantity, commission, commissionAsset, time, isBuyer, isMaker, isBestPriceMatch); var serializer = new AccountTradeSerializer(); var json = serializer.Serialize(trade); var other = serializer.Deserialize(json); Assert.True(trade.Equals(other)); }
public void Properties() { var symbol = Symbol.BTC_USDT; const long id = 12345; const long orderId = 54321; const decimal price = 5000; const decimal quantity = 1; const decimal commission = 10; var commissionAsset = Asset.BNB; var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); const bool isBuyer = true; const bool isMaker = true; const bool isBestPriceMatch = true; var trade = new AccountTrade(symbol, id, orderId, price, quantity, commission, commissionAsset, timestamp, isBuyer, isMaker, isBestPriceMatch); Assert.Equal(symbol, trade.Symbol); Assert.Equal(id, trade.Id); Assert.Equal(orderId, trade.OrderId); Assert.Equal(price, trade.Price); Assert.Equal(quantity, trade.Quantity); Assert.Equal(commission, trade.Commission); Assert.Equal(commissionAsset, trade.CommissionAsset); Assert.Equal(timestamp, trade.Timestamp); Assert.Equal(isBuyer, trade.IsBuyer); Assert.Equal(isMaker, trade.IsMaker); Assert.Equal(isBestPriceMatch, trade.IsBestPriceMatch); }
/// <summary> /// Constructor. /// </summary> /// <param name="timestamp">The event time.</param> /// <param name="token">The cancellation token.</param> /// <param name="order">The order.</param> /// <param name="rejectedReason">The order rejected reason.</param> /// <param name="newClientOrderId">The new client order ID.</param> /// <param name="trade">The trade.</param> /// <param name="quantityOfLastFilledTrade">The quantity of last filled trade.</param> public AccountTradeUpdateEventArgs(long timestamp, CancellationToken token, Order order, OrderRejectedReason rejectedReason, string newClientOrderId, AccountTrade trade, decimal quantityOfLastFilledTrade) : base(timestamp, token, order, OrderExecutionType.Trade, rejectedReason, newClientOrderId) { Throw.IfNull(trade, nameof(trade)); Trade = trade; QuantityOfLastFilledTrade = quantityOfLastFilledTrade; }
/// <summary> /// Constructor. /// </summary> /// <param name="time">The event time.</param> /// <param name="order">The order.</param> /// <param name="rejectedReason">The order rejected reason.</param> /// <param name="newClientOrderId">The new client order ID.</param> /// <param name="trade">The trade.</param> /// <param name="quantityOfLastFilledTrade">The quantity of last filled trade.</param> public AccountTradeUpdateEventArgs(DateTime time, Order order, string rejectedReason, string newClientOrderId, AccountTrade trade, decimal quantityOfLastFilledTrade) : base(time, order, OrderExecutionType.Trade, rejectedReason, newClientOrderId) { Throw.IfNull(trade, nameof(trade)); Trade = trade; QuantityOfLastFilledTrade = quantityOfLastFilledTrade; }
public void Properties() { var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const int 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 OrderRejectedReason orderRejectedReason = OrderRejectedReason.None; const string newClientOrderId = "new-test-order"; const long tradeId = 12345; const long orderId = 54321; const decimal quantity = 1; const decimal commission = 10; const string commissionAsset = "BNB"; const bool isBuyer = true; const bool isMaker = true; const bool isBestPriceMatch = true; var trade = new AccountTrade(symbol, tradeId, orderId, price, quantity, commission, commissionAsset, time, isBuyer, isMaker, isBestPriceMatch); const decimal quantityOfLastFilledTrade = 1; using (var cts = new CancellationTokenSource()) { var args = new AccountTradeUpdateEventArgs(time, cts.Token, order, orderRejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade); Assert.Equal(time, args.Time); Assert.Equal(order, args.Order); Assert.Equal(OrderExecutionType.Trade, args.OrderExecutionType); Assert.Equal(orderRejectedReason, args.OrderRejectedReason); Assert.Equal(newClientOrderId, args.NewClientOrderId); Assert.Equal(trade, args.Trade); Assert.Equal(quantityOfLastFilledTrade, args.QuantityOfLastFilledTrade); } }
public void Throws() { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const int 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, timestamp, isWorking); const OrderRejectedReason orderRejectedReason = OrderRejectedReason.None; const string newClientOrderId = "new-test-order"; const long tradeId = 12345; const long orderId = 54321; const decimal quantity = 1; const decimal commission = 10; const string commissionAsset = "BNB"; const bool isBuyer = true; const bool isMaker = true; const bool isBestPriceMatch = true; var trade = new AccountTrade(symbol, tradeId, orderId, price, quantity, commission, commissionAsset, timestamp, isBuyer, isMaker, isBestPriceMatch); decimal quantityOfLastFilledTrade = 1; using (var cts = new CancellationTokenSource()) { Assert.Throws <ArgumentException>("timestamp", () => new AccountTradeUpdateEventArgs(-1, cts.Token, order, orderRejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade)); Assert.Throws <ArgumentException>("timestamp", () => new AccountTradeUpdateEventArgs(0, cts.Token, order, orderRejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade)); Assert.Throws <ArgumentNullException>("order", () => new AccountTradeUpdateEventArgs(timestamp, cts.Token, null, orderRejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade)); } }
private Interface.Model.AccountTrade NewAccountTrade(AccountTrade t) { return(new Interface.Model.AccountTrade { Symbol = t.Symbol, Id = t.Id, Price = t.Price, Quantity = t.Quantity, Time = t.Time, BuyerOrderId = t.BuyerOrderId, SellerOrderId = t.SellerOrderId, IsBuyerMaker = t.IsBuyerMaker, IsBestPriceMatch = t.IsBestPriceMatch, OrderId = t.OrderId, QuoteQuantity = t.QuoteQuantity, Commission = t.Commission, CommissionAsset = t.CommissionAsset, IsBuyer = t.IsBuyer, IsMaker = t.IsMaker }); }
public virtual string Serialize(AccountTrade trade) { Throw.IfNull(trade, nameof(trade)); var jObject = new JObject { new JProperty(Key_Symbol, trade.Symbol), new JProperty(Key_Id, trade.Id), new JProperty(Key_OrderId, trade.OrderId), new JProperty(Key_Price, trade.Price.ToString(CultureInfo.InvariantCulture)), new JProperty(Key_Quantity, trade.Quantity.ToString(CultureInfo.InvariantCulture)), new JProperty(Key_Commission, trade.Commission.ToString(CultureInfo.InvariantCulture)), new JProperty(Key_CommissionAsset, trade.CommissionAsset), new JProperty(Key_Time, trade.Timestamp), new JProperty(Key_IsBuyer, trade.IsBuyer), new JProperty(Key_IsMaker, trade.IsMaker), new JProperty(Key_IsBestPriceMatch, trade.IsBestPriceMatch) }; return(jObject.ToString(Formatting.None)); }
/// <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 HandleMessage(IEnumerable <Action <UserDataEventArgs> > callbacks, string stream, string json) { if (!Users.ContainsKey(stream)) { Logger?.LogError($"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unknown listen key (\"{stream}\"). [thread: {Thread.CurrentThread.ManagedThreadId}]"); return; // ignore. } var user = Users[stream]; try { var jObject = JObject.Parse(json); var eventType = jObject["e"].Value <string>(); var eventTime = jObject["E"].Value <long>().ToDateTime(); // 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, new AccountInfo(user, commissions, status, jObject["u"].Value <long>().ToDateTime(), balances)); try { // ReSharper disable once InconsistentlySynchronizedField if (_accountUpdateSubscribers.TryGetValue(stream, out var subscribers)) { foreach (var subcriber in subscribers) { subcriber(eventArgs); } } if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } AccountUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { /* ignore */ } catch (Exception e) { Logger?.LogWarning(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}: 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 = 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>() .ToDateTime(), // 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, order, rejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade); try { // ReSharper disable once InconsistentlySynchronizedField if (_accountTradeUpdateSubscribers.TryGetValue(stream, out var subscribers)) { foreach (var subcriber in subscribers) { subcriber(eventArgs); } } if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } TradeUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { /* ignore */ } catch (Exception e) { Logger?.LogWarning(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unhandled trade update event handler exception."); } } else // order update event. { var eventArgs = new OrderUpdateEventArgs(eventTime, order, executionType, rejectedReason, newClientOrderId); try { // ReSharper disable once InconsistentlySynchronizedField if (_orderUpdateSubscribers.TryGetValue(stream, out var subscribers)) { foreach (var subcriber in subscribers) { subcriber(eventArgs); } } if (callbacks != null) { foreach (var callback in callbacks) { callback(eventArgs); } } OrderUpdate?.Invoke(this, eventArgs); } catch (OperationCanceledException) { /* ignore */ } catch (Exception e) { Logger?.LogWarning(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unhandled order update event handler exception."); } } } else { Logger?.LogWarning($"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unexpected event type ({eventType})."); } } catch (OperationCanceledException) { /* ignore */ } catch (Exception e) { Logger?.LogError(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}"); } }
static void Main(string[] args) { CX cx = new CX(CX.Production); //Create CX instance. //Subscribe to GetProducts response. cx.OnGetProducts += (sender, e) => { foreach (Product product in e.Products) Console.WriteLine( $"{product.ProductId, -2} " + $"{product.Symbol, -4} " + $"{product.ProductFullName, -20} " + $"{product.ProductType, -20} " + $"{product.DecimalPlaces, -2}" ); }; //Subscribe to GetInstruments response. cx.OnGetInstruments += (sender, e) => { foreach (Instrument instrument in e.Instruments) Console.WriteLine( $"{instrument.InstrumentId, -2} " + $"{instrument.Symbol, -4} " + $"{instrument.Product1, -2} " + $"{instrument.Product1Symbol, -4} " + $"{instrument.Product2, -2} " + $"{instrument.Product2Symbol, -4} " + $"{instrument.InstrumentType, -10}" ); }; //Subscribe to WebAuthenticateuser response. cx.OnWebAuthenticateUser += (sender, e) => { Console.WriteLine(e.Authenticated); Console.WriteLine(e.SessionToken); Console.WriteLine(e.UserId); Console.WriteLine(e.ErrorMessage); }; //Subscribe to GetUserAccounts response. cx.OnGetUserAccounts += (sender, e) => { foreach (var account in e.AccountIds) Console.WriteLine(account); }; //Subscribe to GetAccountTransaction response. cx.OnGetAccountTransactions += (sender, e) => { foreach (AccountTransaction transaction in e.Transactions) Console.WriteLine( $"{transaction.TransactionId, -4} " + $"{transaction.AccountId, -2} " + $"{transaction.Cr, -5} " + $"{transaction.Dr, -5} " + $"{transaction.TransactionType, -6}" + $" {transaction.ReferenceId, -4} " + $"{transaction.ProductId, -2} " + $"{transaction.Balance, -7} " + $"{transaction.ReferenceType, -14} " + $"{transaction.TimeStamp, -15}" ); }; //Subscribe to GetAccountPosition response. cx.OnGetAccountPositions += (sender, e) => { foreach (AccountPosition position in e.Positions) Console.WriteLine( $"{position.AccountId, -2} " + $"{position.ProductId, -2} " + $"{position.ProductSymbol, -4} " + $"{position.Amount, -10} " + $"{position.Hold, -10} " + $"{position.PendingDeposits, -10} " + $"{position.PendingWithdraws, -10}" ); }; //Subscribe to GetAccountTrades response. cx.OnGetAccountTrades += (sender, e) => { foreach (AccountTrade trade in e.Trades) Console.WriteLine( $"{trade.TradeId, -4} " + $"{trade.OrderId, -5} " + $"{trade.AccountId, -2} " + $"{trade.ClientOrderId, -4} " + $"{trade.InstrumentId, -2} " + $"{trade.Side, -5} " + $"{trade.Quantity, -7} " + $"{trade.Price, -7} " + $"{trade.Value, -7} " + $"{trade.TradeTime, -15}" ); }; //Subscribe to SendOrder response. cx.OnSendOrder += (sender, e) => { Console.WriteLine(e.Status); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.OrderId); }; //Send SendOrder request. cx.SendOrder(new Order { AccountId = 4, ClientOrderId = 99, OMSId = 1, UseDisplayQuantity = true, Quantity = 1, DisplayQuantity = 0, LimitPrice = 95, OrderIdOCO = 0, OrderType = 2, // 1 (Market), 2 (Limit), 3 (StopMarket), 4 (StopLimit), 5 (TrailingStopMarket), 6 (TrailingStopLimit) PegPriceType = 1, // 1 (Last), 2 (Bid), 3 (Ask) InstrumentId = 1, TrailingAmount = 1, LimitOffset = 2, Side = 0, // 0 (Buy) or 1 (Sell) StopPrice = 96, TimeInForce = 1, // 1 (Good 'til Canceled), 3 (Immediate or Cancel), 4 (Fill or Kill) }); //Subscribe to CancelOrder response. cx.OnCancelOrder += (sender, e) => { Console.WriteLine(e.Status); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.Detail); Console.WriteLine(e.ErrorCode); }; //Subscribe to GetOrderStatus response. cx.OnGetOrderStatus += (sender, e) => { OrderStatus orderStatus = e.OrderStatus; Console.WriteLine(orderStatus.Account); Console.WriteLine(orderStatus.Quantity); Console.WriteLine(orderStatus.OrderType); Console.WriteLine(orderStatus.Instrument); // 1 (Market), 2 (Limit), 3 (StopMarket), 4 (StopLimit), 5 (TrailingStopMarket), 6 (TrailingStopLimit) Console.WriteLine(orderStatus.Side); Console.WriteLine(orderStatus.OrderId); Console.WriteLine(orderStatus.Price); Console.WriteLine(orderStatus.OrderState); Console.WriteLine(orderStatus.OrigQuantity); Console.WriteLine(orderStatus.QuantityExecuted); Console.WriteLine(orderStatus.RejectReason); Console.WriteLine(orderStatus.OrigOrderId); Console.WriteLine(orderStatus.OrigClOrdId); Console.WriteLine(orderStatus.ReceiveTime); }; //Subscribe to GetOrderFee cx.OnGetOrderFee += (sender, e) => { Console.WriteLine(e.OrderFee); Console.WriteLine(e.ProductId); }; //Subscribe to GetOrderHistory cx.OnGetOrderHistory += (sender, e) => { foreach (OrderStatus order in e.Orders) Console.WriteLine( $"{order.Account, -5} " + $"{order.ClientOrderId, -3} " + $"{order.Quantity, -2} " + $"{order.OrderType, -2} " + $"{order.Instrument, -2} " + $"{order.Side, -5}" + $"{order.OrderId, -4} " + $"{order.Price, -5} " + $"{order.OrderState, -15} " + $"{order.Quantity, -3} " + $"{order.QuantityExecuted, -3}" + $"{order.RejectReason, -10} " + $"{order.OrigOrderId, -5} " + $"{order.OrigClOrdId, -2} " + $"{order.ReceiveTime, -15}" ); }; //Subscribe to GetOpenOrders response. cx.OnGetOpenOrders += (sender, e) => { foreach (OrderStatus order in e.Orders) Console.WriteLine( $"{order.Account, -5} " + $"{order.ClientOrderId, -3} " + $"{order.Quantity, -2} " + $"{order.OrderType, -2} " + $"{order.Instrument, -2} " + $"{order.Side, -5}" + $"{order.OrderId, -4} " + $"{order.Price, -5} " + $"{order.OrderState, -15} " + $"{order.Quantity, -3} " + $"{order.QuantityExecuted, -3}" + $"{order.RejectReason, -10} " + $"{order.OrigOrderId, -5} " + $"{order.OrigClOrdId, -2} " + $"{order.ReceiveTime, -15}" ); }; //Subscribe to CreateWithdrawTicket response. cx.OnCreateWithdrawTicket += (sender, e) => { Console.WriteLine(e.Result); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.ErrorCode); }; //Subscribe to SubscribeLevel 1 response. cx.OnSubscribeLevel1 += (sender, e) => { MarketDataLevel1 marketData = e.MarketData; Console.WriteLine(marketData.InstrumentId); Console.WriteLine(marketData.BestBid); Console.WriteLine(marketData.BestOffer); Console.WriteLine(marketData.LastTradedPx); Console.WriteLine(marketData.LastTradedQty); Console.WriteLine(marketData.LastTradeTime); Console.WriteLine(marketData.SessionOpen); Console.WriteLine(marketData.SessionHigh); Console.WriteLine(marketData.SessionLow); Console.WriteLine(marketData.SessionClose); Console.WriteLine(marketData.Volume); Console.WriteLine(marketData.CurrentDayVolume); Console.WriteLine(marketData.CurrentDayNumTrades); Console.WriteLine(marketData.CurrentDayPxChange); Console.WriteLine(marketData.Rolling24HrVolume); Console.WriteLine(marketData.Rolling24NumTrades); Console.WriteLine(marketData.Rolling24HrPxChange); Console.WriteLine(marketData.TimeStamp); }; //Subscribe to Level1UpdateEvent event. cx.Level1UpdateEvent += (sender, e) => { MarketDataLevel1 marketData = e.MarketData; Console.WriteLine(marketData.InstrumentId); Console.WriteLine(marketData.BestBid); Console.WriteLine(marketData.BestOffer); Console.WriteLine(marketData.LastTradedPx); Console.WriteLine(marketData.LastTradedQty); Console.WriteLine(marketData.LastTradeTime); Console.WriteLine(marketData.SessionOpen); Console.WriteLine(marketData.SessionHigh); Console.WriteLine(marketData.SessionLow); Console.WriteLine(marketData.SessionClose); Console.WriteLine(marketData.Volume); Console.WriteLine(marketData.CurrentDayVolume); Console.WriteLine(marketData.CurrentDayNumTrades); Console.WriteLine(marketData.CurrentDayPxChange); Console.WriteLine(marketData.Rolling24HrVolume); Console.WriteLine(marketData.Rolling24NumTrades); Console.WriteLine(marketData.Rolling24HrPxChange); Console.WriteLine(marketData.TimeStamp); }; //Subscribe to UnsubscribeLevel1 response. cx.OnUnsubscribeLevel1 += (sender, e) => { Console.WriteLine(e.Result); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.ErrorCode); Console.WriteLine(e.Detail); }; //Subscribe to Subscribelevel2 response. cx.OnSubscribeLevel2 += (sender, e) => { foreach (MarketDataLevel2 marketData in e.MarketData) { Console.WriteLine( $"{marketData.SequenceNumber,-7} " + $"{marketData.NumTraders - 7} " + $"{marketData.Timestamp,-15} " + $"{marketData.ChangeType,-7} " + // 0 (New), 1 (Update), 2 (Delete) $"{marketData.LastTradedPx,-7} " + $"{marketData.NumOrders,-7} " + $"{marketData.Price,-7} " + $"{marketData.InstrumenId,-2} " + $"{marketData.Quantity,-7} " + $"{marketData.Side,-5} " // 0 (Buy), 1 (Sell) ); } }; //Subscribe to Level2UpdateEvent event. cx.Level2UpdateEvent += (sender, e) => { foreach (MarketDataLevel2 marketData in e.MarketData) { Console.WriteLine( $"{marketData.SequenceNumber, -7} " + $"{marketData.NumTraders -7} " + $"{marketData.Timestamp, -15} " + $"{marketData.ChangeType, -7} " + // 0 (New), 1 (Update), 2 (Delete) $"{marketData.LastTradedPx, -7} " + $"{marketData.NumOrders, -7} " + $"{marketData.Price, -7} " + $"{marketData.InstrumenId, -2} " + $"{marketData.Quantity, -7} " + $"{marketData.Side, -5} " // 0 (Buy), 1 (Sell) ); } }; //Subscribe to UnsubscribeLevel2 response. cx.OnUnsubscribeLevel2 += (sender, e) => { Console.WriteLine(e.Result); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.ErrorCode); Console.WriteLine(e.Detail); }; //Subscribe to SubscribeTrades response. cx.OnSubscribeTrades += (sender, e) => { foreach (MarketTrade trade in e.MarketTrades) { Console.WriteLine( $"{trade.TradeId, -4} " + $"{trade.InstrumentId, -2} " + $"{trade.Quantity, -7} " + $"{trade.Price, -7} " + $"{trade.Timestamp, -15} " + $"{trade.Direction, -10} " + //0 (NoChange), 1 (Uptick), 2 (Downtick) $"{trade.TakerSide, -7} " ); } }; //Subscribe to TradeDataUpdateEvent event. cx.TradeDataUpdateEvent += (sender, e) => { foreach (MarketTrade trade in e.MarketTrades) { Console.WriteLine( $"{trade.TradeId,-4} " + $"{trade.InstrumentId,-2} " + $"{trade.Quantity,-7} " + $"{trade.Price,-7} " + $"{trade.Timestamp,-15} " + $"{trade.Direction,-10} " + //0 (NoChange), 1 (Uptick), 2 (Downtick) $"{trade.TakerSide,-7} " ); } }; //Subscribe to UnsubscribeTrades response. cx.OnUnsubscribeTrades += (sender, e) => { Console.WriteLine(e.Result); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.ErrorCode); Console.WriteLine(e.Detail); }; //Subscribe to AccountPositionEvent cx.AccountPositionEvent += (sender, e) => { AccountPosition position = e.Position; Console.WriteLine( $"{position.AccountId, -2} " + $"{position.ProductId, -2} " + $"{position.ProductSymbol, -4} " + $"{position.Amount, -7} " + $"{position.Hold, -7} " + $"{position.PendingDeposits, -7} " + $"{position.PendingWithdraws, -7} " + $"{position.TotalDayDeposits, -7} " + $"{position.TotalDayWithdraws , -7} " ); }; //Subscribe to OrderStateEvent cx.OrderStateEvent += (sender, e) => { OrderStatus order = e.OrderStatus; Console.WriteLine( $"{order.Account, -2} " + $"{order.ClientOrderId, -2} " + $"{order.Quantity, -7} " + $"{order.OrderType, -15}" + // 1 (Market), 2 (Limit), 3 (StopMarket), 4 (StopLimit), 5 (TrailingStopMarket), 6 (TrailingStopLimit) $"{order.Instrument, -2} " + $"{order.Side, -5} " + $"{order.OrderId, -4} " + $"{order.Price, -4} " + $"{order.OrderState, -14} " + $"{order.QuantityExecuted, -7} " + $"{order.ChangeReason, -42} " + $"{order.ReceiveTime, -15} " ); }; //Subscribe OrderTradeEvent cx.OrderTradeEvent += (sender, e) => { AccountTrade trade = e.Trade; Console.WriteLine( $"{trade.TradeId, -4} " + $"{trade.OrderId, -5} " + $"{trade.AccountId, -2} " + $"{trade.ClientOrderId, -4} " + $"{trade.InstrumentId, -2} " + $"{trade.Side, -5} " + $"{trade.Quantity, -7} " + $"{trade.Price, -7} " + $"{trade.Value, -7} " + $"{trade.TradeTime, -15}" ); }; //Subscribe NewOrderRejectEvent cx.NewOrderRejectEvent += (sender, e) => { Console.WriteLine(e.AccountId); Console.WriteLine(e.ClientOrderId); Console.WriteLine(e.Status); Console.WriteLine(e.RejectReason); }; //Subscribe CancelOrderRejectEvent cx.CancelOrderRejectEvent += (sender, e) => { Console.WriteLine(e.AccountId); Console.WriteLine(e.OrderId); Console.WriteLine(e.OrderRevision); Console.WriteLine(e.OrderType); Console.WriteLine(e.InstrumentId); Console.WriteLine(e.Status); Console.WriteLine(e.RejectReason); }; //Subscribe MarketStateUpdate cx.MarketStateUpdate += (sender, e) => { Console.WriteLine(e.EchangeId); Console.WriteLine(e.VenueAdapterId); Console.WriteLine(e.Action); Console.WriteLine(e.PreviousStatus); Console.WriteLine(e.NewStatus); Console.WriteLine(e.ExchangeDateTime); }; //Subscribe to SubscribeAccountEvents response. cx.OnSubscribeAccountEvents += (sender, e) => { Console.WriteLine(e.Result); Console.WriteLine(e.ErrorMessage); Console.WriteLine(e.ErrorCode); Console.WriteLine(e.Detail); }; while (true) { var command = Console.ReadLine(); switch (command) { case "get products": cx.GetProducts(); break; case "get instruments": cx.GetInstruments(); break; case "web authenticate user": Console.Write("web authenticate user > enter username : "******"web authenticate user > enter password : "******"get user accounts": cx.GetUserAccounts(); break; case "get account transactions": Console.Write("get account transactions > account id : "); int accountId = int.Parse(Console.ReadLine()); cx.GetAccountTransactions(accountId, 10); break; case "help": case "/?": default: Console.WriteLine("C# Coins Pro Command Line 0.0.1"); Console.WriteLine(); Console.WriteLine($"{"help",-25} {"Prints the help."}"); Console.WriteLine($"{"/?",-25} {"Prints the help."}"); Console.WriteLine($"{"get products",-25} {"Send request to get products."}"); Console.WriteLine($"{"get instruments",-25} {"Send request to get instruments."}"); Console.WriteLine($"{"web authenticate user",-25} {"Send request to log in to API."}"); Console.WriteLine($"{"get user accounts",-25} {"Send request to get user accounts."}"); break; } } }