Esempio n. 1
0
        public void CancelOrder(Order order, OrderOperationCallback callback = null)
        {
            string     endPoint = "https://www.okcoin.com/api/v1/cancel_order.do";
            RestClient client   = new RestClient(endPoint, RestClient.HttpVerb.POST);

            Dictionary <string, string> param = new Dictionary <string, string>();

            param["api_key"]  = APIKey;
            param["symbol"]   = TradeSymbolString;
            param["order_id"] = order.OrderID;

            var reqMsg = BuildSignedMessage(param);
            var json   = client.MakeRequest(reqMsg);

            var response = (JObject)JsonConvert.DeserializeObject(json);

            if ((bool)response["result"])
            {
                Log.Write($"Cancel {order}", 2);
            }
            else
            {
                Log.Write($"Cancel order error: {response["error_code"]}", 0);
            }
            callback?.Invoke(!(bool)response["result"]);
        }
Esempio n. 2
0
        public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
        {
            OrderSubmitCallback = callback;
            var msg = new NewOrderMessage(TradeSymbol, price, volume, side, type);

            SocketTerminal.Send(JsonConvert.SerializeObject(msg));
            NewOrderWaitHandle.WaitOne();
            if (NewOrderID > 0)
            {
                var order = new Order()
                {
                    Price     = price,
                    Volume    = volume,
                    Side      = side,
                    OrderType = type,
                    Time      = DateTime.Now
                };
                order.ClientOrderID = NewOrderID;
                order.OrderID       = NewOrderID.ToString();
                CurrentOrders.Add(order);
                Log.Write($"Submit {order}$", 2);
                return(order);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 3
0
        public OKCMarketFIXAPI(string keyfile, string symbol, bool orderbook, bool livetrade)
        {
            SessionSettings settings     = new SessionSettings("config/quickfix-client.cfg");
            var             storeFactory = new FileStoreFactory(settings);
            var             logFactory   = new ScreenLogFactory(settings);

            Initiator = new QuickFix.Transport.SocketInitiator(this, storeFactory, settings, logFactory);
            Initiator.Start();

            OrderCancelCallback = null;
            OrderSubmitCallback = null;

            AccountUtil.ReadKeyFile(keyfile);
            TradeSymbolString               = symbol;
            TradeSymbol                     = new Symbol(symbol);
            OKTradingRequest.TradeSymbol    = TradeSymbol;
            OKMarketDataRequest.TradeSymbol = TradeSymbol;
            CurrentOrders                   = new List <Order>();
            if (orderbook)
            {
                CurrentOrderBook = new OrderBook();
            }

            LastTrade      = null;
            TrackOrderBook = orderbook;
            TrackLiveTrade = livetrade;
        }
Esempio n. 4
0
        public OKCMarketWSAPI(string keyfile, string symbol, bool orderbook, bool livetrade)
        {
            PrivateMessage.LoadKeyfile(keyfile);

            TradeSymbol   = symbol;
            CurrentOrders = new List <Order>();
            if (orderbook)
            {
                CurrentOrderBook = new OrderBook();
            }

            SocketTerminal                  = new WebSocket(ConnectionString);
            SocketTerminal.Opened          += SocketTerminal_Opened;
            SocketTerminal.Closed          += SocketTerminal_Closed;
            SocketTerminal.MessageReceived += SocketTerminal_MessageReceived;
            SocketTerminal.Error           += SocketTerminal_Error;
            SocketTerminal.Open();

            NewOrderWaitHandle  = new AutoResetEvent(false);
            OrderCancelCallback = null;
            OrderSubmitCallback = null;

            TrackOrderBook = orderbook;
            TrackLiveTrade = livetrade;
        }
Esempio n. 5
0
        public void CancelOrder(Order order, OrderOperationCallback callback = null)
        {
            string endPoint = "https://api.bitfinex.com/v1/order/cancel";
            var    client   = new RestClient(endPoint, RestClient.HttpVerb.POST);

            string[] headers;
            string[] param = new string[]
            {
                $"\"order_id\":\"{order.OrderID}\""
            };
            BuildSignedMessage("/v1/order/cancel", param, out headers);

            try
            {
                var json     = client.MakeRequest("", headers, false);
                var response = (JObject)JsonConvert.DeserializeObject(json);
                Log.Write($"Cancelled {order}", 2);
                callback?.Invoke(false);
            }
            catch (Exception e)
            {
                Log.Write($"Failed to cancel {order}", 0);
                Log.Write($"Exception: {e}", 0);
                callback?.Invoke(true);
            }
        }
Esempio n. 6
0
        public void CancelOrder(Order order, OrderOperationCallback callback = null)
        {
            OrderCancelCallback = callback;
            var msg = JsonConvert.SerializeObject(new CancelOrderMessage(TradeSymbol, order.OrderID));

            SocketTerminal.Send(msg);
            Log.Write($"Cancel {order}", 2);
        }
Esempio n. 7
0
        public void CancelOrder(Order order, OrderOperationCallback callback = null)
        {
            OrderCancelCallback = callback;
            var subCancelOrder     = new CancelOrderMessage(order);
            var cancelOrderMessage = BuildRequestMsg(subCancelOrder, "oc");

            SocketTerminal.Send(cancelOrderMessage);
        }
Esempio n. 8
0
        public void CancelOrder(Order order, OrderOperationCallback callback = null)
        {
            OrderCancelCallback = callback;
            var request = OKTradingRequest.CreateOrderCancelRequest(order);

            CurrentSession.Send(request);
            Log.Write($"Cancel order {order.Volume} at {order.Price.ToString("N3")}", 1);
        }
Esempio n. 9
0
        public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
        {
            string endPoint = "https://api.bitfinex.com/v1/order/new";
            var    client   = new RestClient(endPoint, RestClient.HttpVerb.POST);

            string[] headers;
            string[] param = new string[]
            {
                $"\"symbol\":\"{TradeSymbol}\"",
                $"\"amount\":\"{volume}\"",
                $"\"price\":\"{price}\"",
                $"\"side\":\"{(side.Equals(Side.BUY) ? "buy" : "sell")}\"",
                $"\"type\":\"exchange {(type.Equals(OrdType.LIMIT) ? "limit" : "market")}\"",
                "\"is_hidden\":false",
                "\"is_postonly\":false",
                "\"use_all_available\":false",
                "\"ocoorder\":false",
                "\"buy_price_oco\":\"0\"",
                "\"sell_price_oco\":\"0\"",
            };
            BuildSignedMessage("/v1/order/new", param, out headers);

            try
            {
                var json     = client.MakeRequest("", headers, false);
                var response = (JObject)JsonConvert.DeserializeObject(json);

                Order order = new Order()
                {
                    OrderID       = response["id"].ToString(),
                    ClientOrderID = (long)response["id"],
                    Price         = price,
                    Volume        = volume,
                    Side          = side,
                    OrderType     = type,
                    Time          = new DateTime(1970, 1, 1).AddMilliseconds((double)response["timestamp"])
                };
                Log.Write($"Submitted {order}", 2);

                callback?.Invoke(false);
                return(order);
            }
            catch (Exception e)
            {
                Log.Write($"Failed to submit order", 0);
                Log.Write($"Exception: {e}", 0);
                callback?.Invoke(true);
                return(null);
            }
        }
Esempio n. 10
0
        public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
        {
            string     endPoint = "https://www.okcoin.com/api/v1/trade.do";
            RestClient client   = new RestClient(endPoint, RestClient.HttpVerb.POST);

            Dictionary <string, string> param = new Dictionary <string, string>();

            param["api_key"] = APIKey;
            param["symbol"]  = TradeSymbolString;
            param["type"]    = side == Side.BUY ? "buy" : "sell";
            if (type == OrdType.MARKET)
            {
                param["type"] += "_market";
            }
            param["price"]  = price.ToString();
            param["amount"] = volume.ToString();

            var reqMsg = BuildSignedMessage(param);
            var json   = client.MakeRequest(reqMsg);

            var response = (JObject)JsonConvert.DeserializeObject(json);
            var result   = (bool)response["result"];

            Order order = null;

            if (result)
            {
                order = new Order()
                {
                    Price         = price,
                    Volume        = volume,
                    Time          = DateTime.Now,
                    Side          = side,
                    OrderType     = type,
                    OrderID       = response["order_id"].ToString(),
                    ClientOrderID = (long)response["order_id"]
                };
                Log.Write($"Submit {order}", 2);
            }
            else
            {
                Log.Write($"Submit order error: {response["errorcode"]}", 0);
            }
            callback?.Invoke(!result);

            return(order);
        }
Esempio n. 11
0
        public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
        {
            OrderSubmitCallback = callback;
            var request = OKTradingRequest.CreateNewOrderRequest(volume, price, side, type);

            CurrentSession.Send(request);
            var order = new Order()
            {
                Price         = price,
                Volume        = volume,
                Side          = side,
                OrderType     = type,
                ClientOrderID = request.GetInt(Tags.ClOrdID),
                Time          = request.GetDateTime(Tags.TransactTime)
            };

            Log.Write($"Submit {order}", 2);
            return(order);
        }
Esempio n. 12
0
        public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
        {
            switch (side)
            {
            case Side.BUY:
                if (price * volume > BalanceFiat)
                {
                    return(null);
                }
                break;

            case Side.SELL:
                if (volume > BalanceSecurity)
                {
                    return(null);
                }
                break;

            default:
                break;
            }

            if (type.Equals(OrdType.MARKET))
            {
                ExecuteOrder(volume, side);
                return(new Order()
                {
                    Price = price, Volume = volume, Side = side, OrderType = type, ClientOrderID = GetFreeID
                });
            }
            var newOrder = new Order()
            {
                Price = price, Volume = volume, Side = side, OrderType = type, ClientOrderID = GetFreeID
            };

            OrderLock.WaitOne();
            CurrentOrders.Add(newOrder);
            OrderLock.ReleaseMutex();

            return(newOrder);
        }
Esempio n. 13
0
        public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
        {
            OrderSubmitCallback = callback;

            var subOrderMsg = new NewOrderMessage(TradeSymbol, price, volume, side, type);
            var orderMsg    = BuildRequestMsg(subOrderMsg, "on");

            Log.Write($"Submitted order msg: {orderMsg.ToString()}", 3);

            SocketTerminal.Send(orderMsg.ToString());
            var order = new Order()
            {
                Price         = price,
                Volume        = volume,
                Side          = side,
                OrderType     = type,
                Time          = DateTime.Now,
                ClientOrderID = subOrderMsg.ClientID
            };

            return(order);
        }
Esempio n. 14
0
 public void CancelOrder(Order order, OrderOperationCallback callback = null)
 {
     throw new NotImplementedException();
 }
Esempio n. 15
0
        private void SocketTerminal_MessageReceived(object sender, MessageReceivedEventArgs e)
        {
            var dataArray = (JArray)JsonConvert.DeserializeObject(e.Message);

            for (int i = 0; i < dataArray.Count; i++)
            {
                Log.Write($"Message received: {dataArray[i]}\n", 3);

                var channel = dataArray[i]["channel"].ToString();

                // wallet info
                if (channel.Equals("ok_sub_spotusd_userinfo"))
                {
                    BalanceUSD = (double)dataArray[i]["data"]["info"]["free"]["usd"];
                    BalanceBTC = (double)dataArray[i]["data"]["info"]["free"]["btc"];
                    BalanceLTC = (double)dataArray[i]["data"]["info"]["free"]["ltc"];
                }
                // wallet info
                else if (channel.Equals("ok_spotusd_userinfo"))
                {
                    BalanceUSD = (double)dataArray[i]["data"]["info"]["funds"]["free"]["usd"];
                    BalanceBTC = (double)dataArray[i]["data"]["info"]["funds"]["free"]["btc"];
                    BalanceLTC = (double)dataArray[i]["data"]["info"]["funds"]["free"]["ltc"];
                }
                // new order response
                else if (channel.Equals("ok_spotusd_trade"))
                {
                    var result = (bool)dataArray[i]["data"]["result"];
                    if (result)
                    {
                        NewOrderID = (int)dataArray[i]["data"]["order_id"];
                    }
                    else
                    {
                        NewOrderID = -1;
                        Log.Write($"Submit order error: {dataArray[i]["data"]["error_code"]}", 0);
                    }
                    NewOrderWaitHandle.Set();
                    OrderSubmitCallback?.Invoke(!result);
                    OrderSubmitCallback = null;
                }
                //cancel order response
                else if (channel.Equals("ok_spotusd_cancel_order"))
                {
                    var result = (bool)dataArray[i]["data"]["result"];
                    if (result)
                    {
                        CurrentOrders.RemoveAll(o => o.OrderID.Equals(dataArray[i]["data"]["order_id"].ToString()));
                    }
                    else
                    {
                        Log.Write($"Cancel order error: {dataArray[i]["data"]["error_code"]}", 0);
                    }
                    NewOrderWaitHandle.Set();
                    OrderCancelCallback?.Invoke(!result);
                    OrderSubmitCallback = null;
                }
                // order book data
                else if (channel.Equals("ok_sub_spot_btc_depth") || channel.Equals("ok_sub_spot_ltc_depth"))
                {
                    var bids = (JArray)dataArray[i]["data"]["bids"];
                    foreach (JArray bid in bids)
                    {
                        if ((double)bid[1] > 0.0001)
                        {
                            CurrentOrderBook.ChangeOrder((double)bid[0], (double)bid[1], MDEntryType.BID);
                        }
                        else
                        {
                            CurrentOrderBook.RemoveOrder((double)bid[0], MDEntryType.BID);
                        }
                    }
                    var asks = (JArray)dataArray[i]["data"]["asks"];
                    foreach (JArray ask in asks)
                    {
                        if ((double)ask[1] > 0.0001)
                        {
                            CurrentOrderBook.ChangeOrder((double)ask[0], (double)ask[1], MDEntryType.OFFER);
                        }
                        else
                        {
                            CurrentOrderBook.RemoveOrder((double)ask[0], MDEntryType.OFFER);
                        }
                    }
                }
                // live trade data
                else if (channel.Equals("ok_sub_spotusd_btc_trades") || channel.Equals("ok_sub_spotusd_ltc_trades"))
                {
                    var trade = (JArray)dataArray[i]["data"];
                    LastTrade = new Trade()
                    {
                        Price  = (double)trade.Last[1],
                        Volume = (double)trade.Last[2]
                    };
                }
                // order info
                else if (channel.Equals("ok_spotusd_orderinfo"))
                {
                    if ((bool)dataArray[i]["data"]["result"])
                    {
                        var orders = (JArray)dataArray[i]["data"]["orders"];
                        foreach (var order in orders)
                        {
                            // add to existing order if it's not already there
                            if (!CurrentOrders.Exists(o => o.OrderID.Equals(order["order_id"].ToString())) && ((int)order["status"] == 0) || (int)order["status"] == 1)
                            {
                                CurrentOrders.Add(new Order()
                                {
                                    OrderID   = order["order_id"].ToString(),
                                    Time      = (DateTime)order["create_date"],
                                    Price     = (double)order["price"],
                                    Volume    = (double)order["amount"],
                                    Side      = order["type"].ToString().Contains("buy") ? Side.BUY : Side.SELL,
                                    OrderType = order["type"].ToString().Contains("market") ? OrdType.MARKET : OrdType.LIMIT
                                });
                            }
                        }
                    }
                    else
                    {
                        Log.Write($"Error in requesting order info: {dataArray[i]["data"]}", 0);
                    }
                }
                // sub order/trade info
                else if (channel.Equals("ok_sub_spotusd_trades"))
                {
                    var status = (int)dataArray[i]["data"]["status"];
                    switch (status)
                    {
                    case -1:        // cancelled
                    case 2:         // filled
                        CurrentOrders.First(o => o.OrderID.Equals(dataArray[i]["data"]["orderId"])).FilledVolume = (double)dataArray[i]["data"]["completedTradeAmount"];
                        //CurrentOrders.RemoveAll(o => o.OrderID.Equals(dataArray[i]["data"]["orderId"]));
                        break;

                    case 1:         // partial fill
                        CurrentOrders.First(o => o.OrderID.Equals(dataArray[i]["data"]["orderId"])).FilledVolume = (double)dataArray[i]["data"]["completedTradeAmount"];
                        break;
                    }
                }
            }
        }
Esempio n. 16
0
 public Order SubmitOrder(double price, double volume, char side, char type, OrderOperationCallback callback = null)
 {
     throw new NotImplementedException();
 }
Esempio n. 17
0
 public void OnMessage(QuickFix.FIX44.OrderCancelReject msg, SessionID sessionID)
 {
     OrderCancelCallback?.Invoke(true);
     OrderCancelCallback = null;
     Log.Write($"Order cancel error: {msg.GetString(Tags.Text)}", 1);
 }
Esempio n. 18
0
        /// <summary>
        /// Report after a request about orders is made
        /// Possible cause:
        /// - New order
        /// - Cancel order
        /// - Rejected order
        /// - Requested order info
        /// - Order filled or partially filled
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="sessionID"></param>
        public void OnMessage(QuickFix.FIX44.ExecutionReport msg, SessionID sessionID)
        {
            char executionReportType = msg.GetChar(Tags.ExecType);
            int  clientOrderID       = msg.GetInt(Tags.ClOrdID);

            switch (executionReportType)
            {
            case ExecType.NEW:
            {
                // New order execution report
                string avgPrice = msg.GetString(Tags.AvgPx);
                char   side     = msg.GetChar(Tags.Side);
                var    order    = new Order()
                {
                    OrderID       = msg.GetString(Tags.ExecID),
                    ClientOrderID = clientOrderID,
                    Price         = double.Parse(avgPrice),
                    Side          = side
                };
                CurrentOrders.Add(order);
                OrderSubmitCallback?.Invoke(false);
                OrderSubmitCallback = null;
                Log.Write($"Submission confirmed {order}", 2);
                break;
            }

            case ExecType.PARTIAL_FILL:
            {
                // Order executed
                double executionPrice = (double)msg.GetDecimal(Tags.AvgPx);
                int    orderStatus    = msg.GetInt(Tags.OrdStatus);
                char   side           = msg.GetChar(Tags.Side);

                double remainingQty = (double)msg.GetDecimal(Tags.LeavesQty);
                var    order        = CurrentOrders.First(o => o.ClientOrderID == clientOrderID);
                order.FilledVolume = order.Volume - remainingQty;
                Log.Write($"Partial fill {order}", 2);
                break;
            }

            case ExecType.FILL:
            {
                // Order executed
                double executionPrice = (double)msg.GetDecimal(Tags.AvgPx);
                int    orderStatus    = msg.GetInt(Tags.OrdStatus);
                char   side           = msg.GetChar(Tags.Side);
                var    order          = CurrentOrders.First(o => o.ClientOrderID == clientOrderID);
                order.FilledVolume = order.Volume;
                //CurrentOrders.Remove(order);
                Log.Write($"Fill {order}", 2);
                break;
            }

            case ExecType.CANCELED:
            {
                // Order cancel report
                string orderID = msg.GetString(Tags.ExecID);
                CurrentOrders.RemoveAll(o => o.ClientOrderID == clientOrderID);
                OrderCancelCallback?.Invoke(false);
                OrderCancelCallback = null;
                break;
            }

            case ExecType.REJECTED:
            {
                // Rejected order execution report
                OrderSubmitCallback?.Invoke(true);
                OrderSubmitCallback = null;
                string orderStatus = msg.GetString(Tags.OrdStatus);
                string text        = msg.GetString(Tags.Text);
                Log.Write($"Order rejected | status: {orderStatus} | reason: {text}", 1);
                break;
            }

            case ExecType.PENDING_NEW:
            {
                // Requested Order info
                int numReports = msg.GetInt(Tags.TotNumReports);
                if (!CurrentOrders.Exists(o => o.ClientOrderID.Equals(clientOrderID)))
                {
                    CurrentOrders.Add(new Order()
                        {
                            OrderID       = msg.GetString(Tags.OrderID),
                            ClientOrderID = clientOrderID,
                            Price         = (double)msg.GetDecimal(Tags.AvgPx),
                            Side          = msg.GetChar(Tags.Side)
                        });
                }
                break;
            }

            default:
                Log.Write($"Unknown execution report type {executionReportType}", 0);
                break;
            }
        }
Esempio n. 19
0
        private void SocketTerminal_OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            Log.Write($"Message received: {e.Message}", 3);

            var data = JsonConvert.DeserializeObject(e.Message);

            if (data is JObject)
            {
                var dataObject = (JObject)data;
                var eventType  = dataObject["event"].ToString();
                if (eventType.Equals("subscribed"))
                {
                    ChannelID.Add(dataObject["channel"].ToString(), (int)dataObject["chanId"]);
                }
                else if (eventType.Equals("auth"))
                {
                    var errorCode = dataObject["code"];
                    if (errorCode != null)
                    {
                        Log.Write($"Authentication failure with code {errorCode} | msg: {dataObject["msg"]}", 0);
                    }
                }
                else if (eventType.Equals("error"))
                {
                    Log.Write($"Error code: {dataObject["code"]} | msg: {dataObject["msg"]}", 0);
                }
            }
            else if (data is JArray)
            {
                var dataArray = (JArray)data;
                var channelID = (int)dataArray[0];
                if (channelID == ChannelID["auth"])
                {
                    var msgType = dataArray[1].ToString();
                    if (msgType.Equals("ws"))   // wallet snapshot
                    {
                        var wallets = dataArray[2];
                        for (var wal = wallets.First; wal != null; wal = wal.Next)
                        {
                            if (wal[0].ToString().Equals("exchange"))
                            {
                                var currency = wal[1].ToString();
                                if (currency.Equals("USD"))
                                {
                                    BalanceFiat = (double)wal[2];
                                }
                                else if (currency.Equals(Symbol))
                                {
                                    BalanceSecurity = (double)wal[2];
                                }
                            }
                        }
                    }
                    else if (msgType.Equals("wu"))  // wallet update
                    {
                        // Only consider exchange wallets
                        if (dataArray[2][0].ToString().Equals("exchange"))
                        {
                            var currency = dataArray[2][1].ToString();
                            if (currency.Equals("USD"))
                            {
                                BalanceFiat = (double)dataArray[2][2];
                            }
                            else if (currency.Equals(Symbol))
                            {
                                BalanceSecurity = (double)dataArray[2][2];
                            }
                        }
                    }
                    else if (msgType.Equals("on"))  // new order confirmation
                    {
                        string symbol = dataArray[2][3].ToString();
                        if (symbol.Equals(TradeSymbol))
                        {
                            var order = new Order()
                            {
                                OrderID       = dataArray[2][0].ToString(),
                                ClientOrderID = (long)dataArray[2][2],
                                Price         = (double)dataArray[2][16],
                                Time          = new DateTime(1970, 1, 1).AddMilliseconds((double)dataArray[2][4]),
                                Volume        = Math.Abs((double)dataArray[2][7]),
                                FilledVolume  = Math.Abs((double)dataArray[2][6] - (double)dataArray[2][7]),
                                Side          = (double)dataArray[2][6] > 0 ? Side.BUY : Side.SELL,
                                OrderType     = dataArray[2][8].ToString().Contains("LIMIT") ? OrdType.LIMIT : OrdType.MARKET
                            };
                            CurrentOrders.Add(order);
                            OrderSubmitCallback?.Invoke(false);
                            OrderSubmitCallback = null;
                            Log.Write($"Submitted {order}", 2);
                        }
                    }
                    else if (msgType.Equals("oc"))  // cancel order confirmation
                    {
                        string symbol = dataArray[2][3].ToString();
                        if (symbol.Equals(TradeSymbol))
                        {
                            string status  = dataArray[2][13].ToString();
                            string orderId = dataArray[2][0].ToString();
                            var    order   = CurrentOrders.FirstOrDefault(o => o.OrderID.Equals(orderId));

                            if (order != null)
                            {
                                if (status.Contains("EXECUTED")) // executed
                                {
                                    order.FilledVolume = Math.Abs((double)dataArray[2][6] - (double)dataArray[2][7]);
                                    Log.Write($"Executed {order}", 2);
                                }
                                else if (status.Contains("PARTIALLY FILLED"))
                                {
                                    order.FilledVolume = Math.Abs((double)dataArray[2][6] - (double)dataArray[2][7]);
                                    Log.Write($"Partial fill {order}", 2);
                                }
                                else // cancelled
                                {
                                    CurrentOrders.Remove(order);
                                    OrderCancelCallback?.Invoke(false);
                                    OrderCancelCallback = null;
                                    Log.Write($"Cancelled {order}", 2);
                                }
                            }
                            else
                            {
                                // unregistered
                                order = new Order()
                                {
                                    OrderID       = dataArray[2][0].ToString(),
                                    ClientOrderID = (long)dataArray[2][2],
                                    Price         = (double)dataArray[2][16],
                                    Time          = new DateTime(1970, 1, 1).AddMilliseconds((double)dataArray[2][4]),
                                    Volume        = Math.Abs((double)dataArray[2][7]),
                                    FilledVolume  = Math.Abs((double)dataArray[2][6] - (double)dataArray[2][7]),
                                    Side          = (double)dataArray[2][6] > 0 ? Side.BUY : Side.SELL,
                                    OrderType     = dataArray[2][8].ToString().Contains("LIMIT") ? OrdType.LIMIT : OrdType.MARKET
                                };

                                if (status.Contains("EXECUTED"))
                                {
                                    Log.Write($"Executed unregistered {orderId} (This should happen VERY rarily)", 2);
                                }
                                else
                                {
                                    Log.Write($"Cancelled unregistered {orderId}", 2);
                                }
                            }
                        }
                    }
                    else if (msgType.Equals("os"))  // order info snapshot
                    {
                        var orders = dataArray[2];
                        foreach (var order in orders)
                        {
                            string symbol  = order[3].ToString();
                            string orderId = order[0].ToString();
                            // If order is not yet registered locally
                            if (symbol.Equals(TradeSymbol) && !CurrentOrders.Any(o => o.OrderID.Equals(orderId)))
                            {
                                CurrentOrders.Add(new Order()
                                {
                                    OrderID       = orderId,
                                    ClientOrderID = (long)order[2],
                                    Price         = (double)order[12],
                                    Volume        = Math.Abs((double)order[7]),
                                    FilledVolume  = Math.Abs((double)order[6] - (double)order[7]),
                                    Side          = (double)order[6] > 0 ? Side.BUY : Side.SELL,
                                    OrderType     = order[8].ToString().Contains("LIMIT") ? OrdType.LIMIT : OrdType.MARKET,
                                    Time          = new DateTime(1970, 1, 1).AddMilliseconds((double)order[4]),
                                });
                            }
                        }
                    }
                    else if (msgType.Equals("ou"))  // order info update
                    {
                        string symbol  = dataArray[2][3].ToString();
                        string orderId = dataArray[2][0].ToString();
                        if (symbol.Equals(TradeSymbol))
                        {
                            var order = CurrentOrders.FirstOrDefault(o => o.OrderID.Equals(orderId));
                            if (order == null)
                            {
                                order = new Order()
                                {
                                    OrderID       = dataArray[2][0].ToString(),
                                    ClientOrderID = (int)dataArray[2][2],
                                    Time          = new DateTime(1970, 1, 1).AddMilliseconds((double)dataArray[2][4]),
                                    Volume        = Math.Abs((double)dataArray[2][7]),
                                    FilledVolume  = Math.Abs((double)dataArray[2][6] - (double)dataArray[2][7]),
                                    Side          = (double)dataArray[2][6] > 0 ? Side.BUY : Side.SELL,
                                    OrderType     = dataArray[2][8].ToString().Contains("LIMIT") ? OrdType.LIMIT : OrdType.MARKET
                                };
                                CurrentOrders.Add(order);
                            }
                            else
                            {
                                order.FilledVolume = Math.Abs((double)dataArray[2][6] - (double)dataArray[2][7]);
                                Log.Write($"Update {order}", 2);
                            }
                        }
                    }
                    else if (msgType.Equals("tu"))  // trades
                    {
                        string symbol = dataArray[2][1].ToString();
                        if (TradeSymbol.Contains(symbol))
                        {
                            string orderId = dataArray[2][3].ToString();
                            var    order   = CurrentOrders.FirstOrDefault(o => o.OrderID.Equals(orderId));
                            if (order != null)
                            {
                                order.FilledVolume = Math.Abs((double)dataArray[2][4]);
                                Log.Write($"Trade info about {order}", 2);
                                if (order.FilledVolume >= order.Volume)
                                {
                                    CurrentOrders.Remove(order);
                                }
                            }
                            else
                            {
                                Log.Write($"Trade info about unregistered order", 1);
                            }
                        }
                    }
                    else if (msgType.Equals("n"))   // notification
                    {
                        string status = dataArray[2][6].ToString();
                        if (status.Equals("ERROR"))
                        {
                            Log.Write($"Error: {dataArray[2][7].ToString()}", 0);
                            string req = dataArray[2][1].ToString();
                            if (req.Equals("on-req"))   // new order error
                            {
                                OrderSubmitCallback?.Invoke(true);
                            }
                            else if (req.Equals("oc-req"))  // cancel order error
                            {
                                OrderCancelCallback?.Invoke(true);
                            }
                        }
                        else if (status.Equals("FAILURE"))
                        {
                            Log.Write($"Failure: {dataArray[2][7].ToString()}", 0);
                        }
                        else if (status.Equals("SUCCESS"))
                        {
                            Log.Write($"Notification: {dataArray[2][7].ToString()}", 2);
                        }
                        else if (status.Equals("INFO"))
                        {
                            Log.Write($"Information: {dataArray[2][7].ToString()}", 2);
                        }
                    }
                }
                else if (ChannelID.ContainsKey("trades") && channelID == ChannelID["trades"])
                {
                    if (dataArray[1] is JArray) // snapshot
                    {
                        var trades    = dataArray[1];
                        var lastTrade = trades.First;
                        LastTrade = new Trade()
                        {
                            Price  = (double)lastTrade[3],
                            Volume = (double)lastTrade[2]
                        };
                    }
                    else // update
                    {
                        if (dataArray[1].ToString().Equals("te"))
                        {
                            LastTrade = new Trade()
                            {
                                Price  = (double)dataArray[2][3],
                                Volume = (double)dataArray[2][2]
                            };
                        }
                    }
                }
                else if (ChannelID.ContainsKey("book") && channelID == ChannelID["book"])
                {
                    // heartbeat
                    if (dataArray[1].ToString().Equals("hb"))
                    {
                    }
                    // Snapshot
                    else if (dataArray[1][0] is JArray)
                    {
                        foreach (var entry in dataArray[1])
                        {
                            int count = (int)entry[1];
                            if (count == 0)
                            {
                                Log.Write("Error: zero count in order book snapshot", 0);
                            }
                            else
                            {
                                double volume = (double)entry[2];
                                CurrentOrderBook.AddOrder((double)entry[0], volume, volume > 0 ? MDEntryType.BID : MDEntryType.OFFER);
                            }
                        }
                    }
                    // Update
                    else
                    {
                        int count = (int)dataArray[1][1];
                        if (count > 0)  // change bid
                        {
                            CurrentOrderBook.ChangeOrder((double)dataArray[1][0], (double)dataArray[1][2], (double)dataArray[1][2] > 0 ? MDEntryType.BID : MDEntryType.OFFER);
                        }
                        else // remove
                        {
                            CurrentOrderBook.RemoveOrder((double)dataArray[1][0], (double)dataArray[1][2] > 0 ? MDEntryType.BID : MDEntryType.OFFER);
                        }
                    }
                }
            }
            else
            {
                Log.Write($"Unknown message json type: {data.GetType()}", 0);
            }
        }
Esempio n. 20
0
 public void CancelOrder(Order order, OrderOperationCallback callback = null)
 {
     OrderLock.WaitOne();
     CurrentOrders.RemoveAll(o => o.ClientOrderID == order.ClientOrderID || o.OrderID == order.OrderID);
     OrderLock.ReleaseMutex();
 }