Exemplo n.º 1
0
        private void SetInitialPrices()
        {
            var ordList     = new List <OrderInfo>();
            var changedList = new List <OrderInfo>();

            foreach (var tp in P2_BuyOrders.Where(o => o.StratState == StrategyState.TP_ENTERED))
            {
                if (tp.InitialPrice == 0M || !grid_values.Any(x => x == tp.InitialPrice))
                {
                    changedList.Add(new OrderInfo(tp));
                    var initPrice = tp.Price * (1 - SETTINGS.TakeProfitMargin);
                    tp.InitialPrice = grid_values.Aggregate((x, y) => Math.Abs(x - initPrice) < Math.Abs(y - initPrice) ? x : y);
                    ordList.Add(tp);
                }
            }
            P2_BuyOrders = P2_BuyOrders.Except(changedList).ToList();
            P2_BuyOrders.AddRange(ordList);

            ordList.Clear();
            changedList.Clear();
            foreach (var tp in P2_SellOrders.Where(o => o.StratState == StrategyState.TP_ENTERED))
            {
                if (tp.InitialPrice == 0M || !grid_values.Any(x => x == tp.InitialPrice))
                {
                    changedList.Add(new OrderInfo(tp));
                    var initPrice = tp.Price * (1 + SETTINGS.TakeProfitMargin);
                    tp.InitialPrice = grid_values.Aggregate((x, y) => Math.Abs(x - initPrice) < Math.Abs(y - initPrice) ? x : y);
                    ordList.Add(tp);
                }
            }
            P2_SellOrders = P2_SellOrders.Except(changedList).ToList();
            P2_SellOrders.AddRange(ordList);
        }
Exemplo n.º 2
0
        public async Task Deactivate()
        {
            if (!P2_Active)
            {
                return;
            }

            // Cancel all OPEN orders, leave TakeProfits open
            var canceledOrds = new List <OrderInfo>();

            foreach (var ord in P2_BuyOrders.Where(o => o.StratState == StrategyState.OPEN))
            {
                var cancelResp = await BinaREST.CancelOrder(ord.Symbol, ord.ClientID);

                if (cancelResp != null)
                {
                    Log.Debug($">>> [P2_BUY] CANCELED - Price: {ord.Price}");
                }

                canceledOrds.Add(ord);
            }
            P2_BuyOrders = P2_BuyOrders.Except(canceledOrds).ToList();

            canceledOrds.Clear();
            foreach (var ord in P2_SellOrders.Where(o => o.StratState == StrategyState.OPEN))
            {
                var cancelResp = await BinaREST.CancelOrder(ord.Symbol, ord.ClientID);

                if (cancelResp != null)
                {
                    Log.Debug($">>> [P2_BUY] CANCELED - Price: {ord.Price}");
                }

                canceledOrds.Add(ord);
            }
            P2_SellOrders = P2_SellOrders.Except(canceledOrds).ToList();

            P2_Active = false;
        }
Exemplo n.º 3
0
        public async Task Activate(decimal middle, decimal top, decimal bottom)
        {
            // populate grid values if necessary
            PopulateGridVals(bottom);

            // snap existing P2 TakeProfit orders to an initial grid price
            SetInitialPrices();

            // narrow down grid_values to only possible order placements
            var middleRound     = Math.Round(middle, PriceRoundDigits);
            var possibleBuyVals = grid_values.Where(x => x >= middle * (1 - (SETTINGS.grid_interval * SETTINGS.MaxOrdsPerSide)) &&
                                                    x <middleRound && // Within range, and not impeding the phase1 TP boundary
                                                       x> bottom &&
                                                    x * (1 + SETTINGS.TakeProfitMargin) < top).ToList();

            var possibleSellVals = grid_values.Where(x => x <= middle * (1 + (SETTINGS.grid_interval * SETTINGS.MaxOrdsPerSide)) &&
                                                     x > middleRound &&
                                                     x <top &&
                                                        x * (1 - SETTINGS.TakeProfitMargin)> bottom).ToList();

            // further filter possibleVals and cancel any OPEN orders that fall outside:
            var canceledOrds = new List <OrderInfo>();

            foreach (var order in P2_BuyOrders)
            {
                // remove already placed orders from possibleVals
                if (order.StratState == StrategyState.OPEN ||
                    order.StratState == StrategyState.OPEN_UNCONFIRMED ||
                    order.StratState == StrategyState.OPEN_FILLED ||
                    order.StratState == StrategyState.PARTIAL_FILL)
                {
                    possibleBuyVals.Remove(order.Price);
                }
                // cancel any OPEN status orders outside the possibleVals
                else if (order.StratState == StrategyState.OPEN && !possibleBuyVals.Any(x => x == order.Price))
                {
                    var cancelResp = await BinaREST.CancelOrder(order.Symbol, order.ClientID);

                    if (cancelResp != null)
                    {
                        Log.Debug($">>> [P2_BUY] CANCELED - Price: {order.Price}");
                    }
                    canceledOrds.Add(order);
                }
                // and remove possibleVals that already have corresponding TakeProfit.InitPrice open
                else if (order.StratState == StrategyState.TP_ENTERED ||
                         order.StratState == StrategyState.TP_UNCONFIRMED ||
                         order.StratState == StrategyState.TP_FILLED)
                {
                    possibleBuyVals.Remove(order.InitialPrice);
                }
            }
            P2_BuyOrders = P2_BuyOrders.Except(canceledOrds).ToList();

            // Same as above for Sell side:
            canceledOrds.Clear();
            foreach (var order in P2_SellOrders)
            {
                if (order.StratState == StrategyState.OPEN ||
                    order.StratState == StrategyState.OPEN_UNCONFIRMED ||
                    order.StratState == StrategyState.OPEN_FILLED ||
                    order.StratState == StrategyState.PARTIAL_FILL)
                {
                    possibleSellVals.Remove(order.Price);
                }
                else if (order.StratState == StrategyState.OPEN && !possibleSellVals.Any(x => x == order.Price))
                {
                    var cancelResp = await BinaREST.CancelOrder(order.Symbol, order.ClientID);

                    if (cancelResp != null)
                    {
                        Log.Debug($">>> [P2_SELL] CANCELED - Price: {order.Price}");
                    }
                    canceledOrds.Add(order);
                }
                else if (order.StratState == StrategyState.TP_ENTERED ||
                         order.StratState == StrategyState.TP_UNCONFIRMED ||
                         order.StratState == StrategyState.TP_FILLED)
                {
                    possibleSellVals.Remove(order.InitialPrice);
                }
            }
            P2_SellOrders = P2_SellOrders.Except(canceledOrds).ToList();

            possibleBuyVals  = possibleBuyVals.Distinct().ToList();
            possibleSellVals = possibleSellVals.Distinct().ToList();

            // place orders on remaining values, add to orderInfo Lists
            possibleBuyVals.OrderByDescending(v => v);
            foreach (var p in possibleBuyVals)
            {
                // FIRST REPLACE ANY 'TP_FILLED' WITH COMPOUNDED GAINS
                var filledTP = P2_BuyOrders.FirstOrDefault(o => o.StratState == StrategyState.TP_FILLED);
                if (filledTP != null)
                {
                    var buyQty = Math.Round(Convert.ToDecimal(filledTP.BaseCurrReturn) / (p * (1 + SETTINGS.FeePercentage)), QtyRoundDigits);
                    var order  = new CreateOrderRequest()
                    {
                        Side             = OrderSide.Buy,
                        Symbol           = MarketSymbol,
                        Price            = p,
                        Quantity         = buyQty,
                        NewClientOrderId = filledTP.ClientID
                    };
                    var response = await BinaREST.CreateLimitOrder(order);

                    if (response != null)
                    {
                        Log.Debug($">>> [BUY] (RE)ORDER PLACED - Price: {p}");
                    }

                    // update order info
                    var newOrd = new OrderInfo(order, StrategyState.OPEN_UNCONFIRMED);
                    newOrd.InitialPrice = p;
                    P2_BuyOrders[P2_BuyOrders.IndexOf(P2_BuyOrders.First(o => o.ClientID == filledTP.ClientID))] = newOrd;
                }
                //Place remaining available OPEN order slots
                else if (P2_BuyOrders.Count() < SETTINGS.MaxOrdsPerSide)
                {
                    var buyQty = Math.Round(SETTINGS.PrimaryWager / (p * (1 + SETTINGS.FeePercentage)), QtyRoundDigits);
                    var order  = new CreateOrderRequest()
                    {
                        Side             = OrderSide.Buy,
                        Symbol           = MarketSymbol,
                        Price            = p,
                        Quantity         = buyQty,
                        NewClientOrderId = "bin2_Buy_" + UniqueString()
                    };
                    var response = await BinaREST.CreateLimitOrder(order);

                    if (response != null)
                    {
                        Log.Debug($">>> [P2_BUY] ORDER PLACED - Price: {p}");
                    }

                    // add order status to prevent repeat order
                    var newOrd = new OrderInfo(order, StrategyState.OPEN_UNCONFIRMED);
                    newOrd.InitialPrice = p;
                    P2_BuyOrders.Add(newOrd);
                }
                // MOVE UP LOWER BUY ORDERS
                else if (P2_BuyOrders.Any(o => o.StratState == StrategyState.OPEN && o.Price < p))
                {
                    // Cancel lowest buy order
                    var minPrice = P2_BuyOrders.Where(o => o.StratState == StrategyState.OPEN).Min(o => o.Price);
                    var oldOrder = P2_BuyOrders.First(o => o.Price == minPrice);

                    var baseReturn = 0M;
                    if (oldOrder.BaseCurrReturn != null)
                    {
                        baseReturn = Convert.ToDecimal(oldOrder.BaseCurrReturn);
                    }

                    var cancelResp = await BinaREST.CancelOrder(oldOrder.Symbol, oldOrder.ClientID);

                    if (cancelResp != null)
                    {
                        Log.Debug($">>> [P2_SELL] CANCELED - Price: {oldOrder.Price}");
                    }
                    P2_BuyOrders.Remove(oldOrder);

                    // Place order at correct price
                    // If baseCurr != 0, use this to calc QTY, else primary wager
                    var buyQty = Math.Round(SETTINGS.PrimaryWager / (p * (1 + SETTINGS.FeePercentage)), QtyRoundDigits);
                    if (baseReturn != 0)
                    {
                        buyQty = Math.Round(Convert.ToDecimal(baseReturn) / (p * (1 + SETTINGS.FeePercentage)), QtyRoundDigits);
                    }

                    var order = new CreateOrderRequest()
                    {
                        Side             = OrderSide.Buy,
                        Symbol           = MarketSymbol,
                        Price            = p,
                        Quantity         = buyQty,
                        NewClientOrderId = "bin2_Buy_" + UniqueString()
                    };
                    var response = await BinaREST.CreateLimitOrder(order);

                    if (response != null)
                    {
                        Log.Debug($">>> [P2_BUY] ORDER PLACED - Price: {p}");
                    }

                    // add order status to prevent repeat order
                    var newOrd = new OrderInfo(order, StrategyState.OPEN_UNCONFIRMED);
                    newOrd.InitialPrice = p;
                    P2_BuyOrders.Add(newOrd);
                }
            }

            // Same as above for sell side:
            possibleSellVals.OrderBy(v => v);
            foreach (var p in possibleSellVals)
            {
                // FIRST REPLACE ANY 'TP_FILLED' WITH COMPOUNDED GAINS
                var filledTP = P2_SellOrders.FirstOrDefault(o => o.StratState == StrategyState.TP_FILLED);
                if (filledTP != null)
                {
                    var sellQty = filledTP.Qty;
                    var order   = new CreateOrderRequest()
                    {
                        Side             = OrderSide.Sell,
                        Symbol           = MarketSymbol,
                        Price            = p,
                        Quantity         = sellQty,
                        NewClientOrderId = filledTP.ClientID
                    };
                    var response = await BinaREST.CreateLimitOrder(order);

                    if (response != null)
                    {
                        Log.Debug($">>> [SELL] ORDER (RE)PLACED - Price: {p}");
                    }

                    // update order info
                    var newOrd = new OrderInfo(order, StrategyState.OPEN_UNCONFIRMED);
                    newOrd.InitialPrice = p;
                    P2_SellOrders[P2_SellOrders.IndexOf(P2_SellOrders.First(o => o.ClientID == filledTP.ClientID))] = newOrd;
                }
                //Place remaining available OPEN order slots
                else if (P2_SellOrders.Count() < SETTINGS.MaxOrdsPerSide)
                {
                    var sellQty = Math.Round(SETTINGS.PrimaryWager / (p * (1 - SETTINGS.FeePercentage)), QtyRoundDigits);
                    var order   = new CreateOrderRequest()
                    {
                        Side             = OrderSide.Sell,
                        Symbol           = MarketSymbol,
                        Price            = p,
                        Quantity         = sellQty,
                        NewClientOrderId = "bin2_Sell_" + UniqueString()
                    };
                    var response = await BinaREST.CreateLimitOrder(order);

                    if (response != null)
                    {
                        Log.Debug($">>> [P2_SELL] ORDER PLACED - Price: {p}");
                    }

                    // add order status to prevent repeat order
                    var newOrd = new OrderInfo(order, StrategyState.OPEN_UNCONFIRMED);
                    newOrd.InitialPrice = p;
                    P2_SellOrders.Add(newOrd);
                }
                // MOVE DOWN ANY HIGHER SELL ORDERS
                else if (P2_SellOrders.Any(o => o.StratState == StrategyState.OPEN && o.Price > p))
                {
                    // Cancel order
                    var maxPrice = P2_SellOrders.Where(o => o.StratState == StrategyState.OPEN).Max(o => o.Price);
                    var oldOrder = P2_SellOrders.First(o => o.Price == maxPrice);

                    var baseCurr = (oldOrder.Price * (1 - SETTINGS.FeePercentage)) * oldOrder.Qty;

                    var cancelResp = await BinaREST.CancelOrder(oldOrder.Symbol, oldOrder.ClientID);

                    if (cancelResp != null)
                    {
                        Log.Debug($">>> [P2_SELL] CANCELED - Price: {oldOrder.Price}");
                    }
                    P2_SellOrders.Remove(oldOrder);

                    // Place order at correct price
                    // use same BaseCurr wager amount
                    var sellQty = Math.Round(baseCurr / (p * (1 - SETTINGS.FeePercentage)), QtyRoundDigits);
                    var order   = new CreateOrderRequest()
                    {
                        Side             = OrderSide.Sell,
                        Symbol           = MarketSymbol,
                        Price            = p,
                        Quantity         = sellQty,
                        NewClientOrderId = "bin2_Sell_" + UniqueString()
                    };
                    var response = await BinaREST.CreateLimitOrder(order);

                    if (response != null)
                    {
                        Log.Debug($">>> [P2_SELL] ORDER PLACED - Price: {p}");
                    }

                    // add order status to prevent repeat order
                    var newOrd = new OrderInfo(order, StrategyState.OPEN_UNCONFIRMED);
                    newOrd.InitialPrice = p;
                    P2_SellOrders.Add(newOrd);
                }
            }

            P2_Active = true;
        }