Esempio n. 1
0
        public async Task Execute()
        {
            var spreadMiddle = 0M;
            var lastUpdate   = new DateTime();

            // BEGIN EXECUTION LOOP:
            while (true)
            {
                // Place new/Replace tiered orders, then pause
                if (DateTime.Now - lastUpdate > SETTINGS.OrderExecDelay)
                {
                    spreadMiddle = await ReplaceSpreadOrders("XLMUSDT", spreadMiddle);

                    lastUpdate = DateTime.Now;
                }
                else if (userDATA.UserUpdateQueue.IsEmpty)
                {
                    Thread.Sleep(100);
                }


                // PROCESS ORDER UPDATES, MAKE DECISIONS BASED ON ExecutionType:
                while (!userDATA.UserUpdateQueue.IsEmpty)
                {
                    // DeQueue next order update:
                    bool tryDQ   = false;
                    var  userMsg = new UserDataUpdate();
                    do
                    {
                        tryDQ = userDATA.UserUpdateQueue.TryDequeue(out userMsg);
                    } while (!tryDQ);

                    if (userMsg.TradeOrderData != null) // (!= balance update msg)
                    {
                        var clientID = userMsg.TradeOrderData.NewClientOrderId.Split('_');
                        if (clientID[0] == "bin2")
                        {
                            await StrategyP2.HandleTradeMsg(userMsg.TradeOrderData, clientID);

                            continue;
                        }
                        else if (clientID[0] != "bina")
                        {
                            continue;
                        }

                        switch (userMsg.TradeOrderData.ExecutionType)
                        {
                        case ExecutionType.New:
                            // UPDATE UNCONFIRMED BUY/SELL OrderInfo in openOrders LIST:
                            var orderInfo = new OrderInfo(userMsg.TradeOrderData);

                            if (clientID[1] == "Buy")
                            {
                                OpenBUYorders[OpenBUYorders.IndexOf(OpenBUYorders.First(o => o.ClientID == userMsg.TradeOrderData.NewClientOrderId))] = orderInfo;
                            }
                            else if (clientID[1] == "Sell")
                            {
                                OpenSELLorders[OpenSELLorders.IndexOf(OpenSELLorders.First(o => o.ClientID == userMsg.TradeOrderData.NewClientOrderId))] = orderInfo;
                            }

                            break;

                        case ExecutionType.Trade:
                            if (userMsg.TradeOrderData.OrderStatus == OrderStatus.Filled)
                            {
                                // UPDATE ORDERS StratStatus in OpenDATAorders:
                                var order = new OrderInfo(userMsg.TradeOrderData);

                                if (clientID[1] == "Buy")
                                {
                                    // HANDLE RAPID TP-ORDER HERE
                                    if (order.StratState == StrategyState.OPEN_FILLED)
                                    {
                                        // place TP order, update to TP_ENTERED
                                        var tpPrice = Math.Round(order.Price * (1 + SETTINGS.TakeProfitMargin), PriceRoundDigits);
                                        var tpQty   = order.Qty;
                                        var ord     = new CreateOrderRequest()
                                        {
                                            Side             = OrderSide.Sell,
                                            Symbol           = order.Symbol,
                                            Price            = tpPrice,
                                            Quantity         = tpQty,
                                            NewClientOrderId = order.ClientID
                                        };
                                        var resp = await BinaREST.CreateLimitOrder(ord);

                                        if (resp != null)
                                        {
                                            Log.Debug($">>> [BUY] Take-Profit submitted");
                                        }

                                        // update order info
                                        order = new OrderInfo(ord, StrategyState.TP_UNCONFIRMED);
                                    }

                                    OpenBUYorders[OpenBUYorders.IndexOf(OpenBUYorders.First(o => o.ClientID == userMsg.TradeOrderData.NewClientOrderId))] = order;
                                }
                                else if (clientID[1] == "Sell")
                                {
                                    // HANDLE RAPID TP-ORDER HERE
                                    if (order.StratState == StrategyState.OPEN_FILLED)
                                    {
                                        // place TP order, update to TP_ENTERED
                                        var tpPrice = Math.Round(order.Price * (1 - SETTINGS.TakeProfitMargin), PriceRoundDigits);
                                        var tpQty   = Math.Round(Convert.ToDecimal(order.BaseCurrReturn) / (tpPrice * (1 + SETTINGS.FeePercentage)), QtyRoundDigits);
                                        var ord     = new CreateOrderRequest()
                                        {
                                            Side             = OrderSide.Buy,
                                            Symbol           = order.Symbol,
                                            Price            = tpPrice,
                                            Quantity         = tpQty,
                                            NewClientOrderId = order.ClientID
                                        };
                                        var resp = await BinaREST.CreateLimitOrder(ord);

                                        if (resp != null)
                                        {
                                            Log.Debug($">>> [SELL] Take-Profit submitted");
                                        }

                                        // update order info
                                        order = new OrderInfo(ord, StrategyState.TP_UNCONFIRMED);
                                    }

                                    OpenSELLorders[OpenSELLorders.IndexOf(OpenSELLorders.First(o => o.ClientID == userMsg.TradeOrderData.NewClientOrderId))] = order;
                                }
                            }
                            else if (userMsg.TradeOrderData.OrderStatus == OrderStatus.PartiallyFilled)
                            {
                                // HANDLE PARTIAL FILLS (ANCHOR UNTIL FILLED)
                                var order = new OrderInfo(userMsg.TradeOrderData);
                                if (order.StratState == StrategyState.PARTIAL_FILL)
                                {
                                    if (clientID[1] == "Buy")
                                    {
                                        OpenBUYorders[OpenBUYorders.IndexOf(OpenBUYorders.First(o => o.ClientID == userMsg.TradeOrderData.NewClientOrderId))] = order;
                                    }
                                    else if (clientID[1] == "Sell")
                                    {
                                        OpenSELLorders[OpenSELLorders.IndexOf(OpenSELLorders.First(o => o.ClientID == userMsg.TradeOrderData.NewClientOrderId))] = order;
                                    }
                                }
                            }

                            break;

                        case ExecutionType.Cancelled:
                            break;

                        case ExecutionType.Rejected:
                            LogOrderMessage(userMsg.TradeOrderData);
                            break;

                        default:
                            LogOrderMessage(userMsg.TradeOrderData);
                            break;
                        }
                    }
                }

                if (OpenBUYorders.Where(o => o.StratState == StrategyState.TP_ENTERED).Count() == SETTINGS.Tiers &&
                    OpenSELLorders.Where(o => o.StratState == StrategyState.TP_ENTERED).Count() == SETTINGS.Tiers &&
                    !SETTINGS.MutePhase2)
                {
                    var window_top    = OpenBUYorders.Min(tp => tp.Price);
                    var window_bottom = OpenSELLorders.Max(tp => tp.Price);
                    await StrategyP2.Activate(depthDATA.GetSpreadMiddle(SETTINGS.SubSpecificSymbols[0]), window_top, window_bottom);
                }
                else
                {
                    await StrategyP2.Deactivate();
                }
            }
        }