Esempio n. 1
0
        private async void HandleNonFilledOrder(ExchangeOrderResult orderResult, Candle candle)
        {
            ExchangeOrderResult result = null;

            Ticker ticker;

            switch (orderResult.Result)
            {
            case ExchangeAPIOrderResult.FilledPartially:

                Log($"Partially filled order quantity filled {orderResult.AmountFilled} of {orderResult.Amount}");

                /*
                 *
                 * PARTIALLY FILLED
                 *
                 * 1. Save the initial order and what was filled
                 * 2. Check in thrity seconds for any more filling of it
                 * 3. Add a new order against this position
                 * 4. If not filled after two more queries, cancel it
                 *
                 */

                // 1. Save

                SavePosition(SaveOrder(orderResult, GetTimeStamp(candle.Timestamp)));

                // 2. Check in 30 seconds twice

                int counter = 0;

                while (counter < 3)
                {
                    Log("Waiting 30 seconds..");

                    Pause(30);
                    ++counter;

                    result = await CheckOrderStatus(orderResult.OrderId);

                    if (result.Result == ExchangeAPIOrderResult.Filled)     // if status now is now filled great
                    {
                        Log($"Remaining quanity of order filled");
                        SaveOrder(orderResult, GetTimeStamp(candle.Timestamp));
                        UpdatePositionQuantity();
                        return;
                    }
                    else
                    {
                        if (counter == 2)     // this is the last time & it wasn't filled
                        {
                            Log($"Remaining quanity of order not filled after waiting 90 seconds, cancelling the order, exchange order id {orderResult.OrderId}, message: {orderResult.Message}");

                            _trader.CancelOrder(orderResult.OrderId);

                            // TODO: Could look at putting in another order for the outstanding quantity
                            // Get the minimum quantity for the currency
                            // if the outstanding quantity is more than the minimum quantity
                            // get the current price
                            // create a new order for the remaining quantity
                            // update the position with the new quantity received
                        }
                    }
                }


                break;

            case ExchangeAPIOrderResult.Canceled:

                /*
                 *
                 * CANCELLED by exchange
                 *
                 * 1. Wait 10 seconds
                 * 3. Check price now
                 * 4. Issue a new Buy
                 *
                 */

                Log($"Order cancelled by exchange for orderId {orderResult.OrderId}, waiting 10 seconds and retrying, message: {orderResult.Message}");

                Log("Waiting 10 seconds");
                Pause(10);

                ticker = _trader.GetLatestTicker(_inMemoryBot.BaseCoin, _inMemoryBot.Coin);

                if (orderResult.IsBuy)
                {
                    Buy(new Candle()
                    {
                        Timestamp = DateTime.Now, ClosePrice = ticker.Ask
                    });
                }
                else
                {
                    Sell(new Candle()
                    {
                        Timestamp = DateTime.Now, ClosePrice = ticker.Bid
                    });
                }

                break;


            case ExchangeAPIOrderResult.Error:

                /*
                 *
                 * ERROR
                 *
                 * 1. Wait 10 seconds and check again
                 * 2. If still error, cancel it
                 * 3. Check price now
                 * 4. Issue a new Buy
                 *
                 */

                Log($"Error reported on exchange for orderId {orderResult.OrderId}, message: {orderResult.Message}");
                Log("Waiting 10 seconds to check again");
                Pause(10);

                result = await CheckOrderStatus(orderResult.OrderId);

                Log($"Result.. {result.Result}");

                // 2. If not filled, cancel it

                if (result.Result != ExchangeAPIOrderResult.Filled)
                {
                    Log($"Not filled, cancelling order {orderResult.OrderId}");
                    _trader.CancelOrder(orderResult.OrderId);

                    // 3. Check the price now
                    ticker = _trader.GetLatestTicker(_inMemoryBot.BaseCoin, _inMemoryBot.Coin);
                    Log($"Going to order again, latest ticker {JsonConvert.SerializeObject(ticker)} ");

                    if (orderResult.IsBuy)
                    {
                        Buy(new Candle()
                        {
                            Timestamp = DateTime.Now, ClosePrice = ticker.Ask
                        });
                    }
                    else
                    {
                        Sell(new Candle()
                        {
                            Timestamp = DateTime.Now, ClosePrice = ticker.Bid
                        });
                    }
                }

                break;


            case ExchangeAPIOrderResult.Pending:

                /*
                 *
                 * PENDING
                 *
                 * 1. Wait 30 seconds and check again
                 * 2. If still pending, cancel it
                 * 3. Check price now
                 * 4. Issue a new Buy
                 *
                 */

                Log($"Pending reported on exchange for orderId {orderResult.OrderId}, message: {orderResult.Message}");

                // 1. Wait thirty seconds & check

                Pause(30);

                result = await CheckOrderStatus(orderResult.OrderId);

                // 2. If not filled, cancel it

                if (result.Result == ExchangeAPIOrderResult.Pending)
                {
                    _trader.CancelOrder(orderResult.OrderId);

                    // 3. Check the price now
                    ticker = _trader.GetLatestTicker(_inMemoryBot.BaseCoin, _inMemoryBot.Coin);

                    Log($"Order still pending after 30 seconds for orderId {orderResult.OrderId}, cancelling and re-ordering at new price {ticker.Ask}");

                    if (orderResult.IsBuy)
                    {
                        Buy(new Candle()
                        {
                            Timestamp = DateTime.Now, ClosePrice = ticker.Ask
                        });
                    }
                    else
                    {
                        Sell(new Candle()
                        {
                            Timestamp = DateTime.Now, ClosePrice = ticker.Bid
                        });
                    }
                }


                break;


            case ExchangeAPIOrderResult.Unknown:

                /*
                 *
                 * UNKNOWN
                 *
                 * 1. Wait thirty seconds and check again
                 * 2. If still unknow, cancel it
                 * 3. Check price now
                 * 4. Issue a new Buy
                 *
                 */

                Log($"UNKNOWN reported by exchange for orderId {orderResult.OrderId}, message: {orderResult.Message}. Waiting 30 seconds to try again");

                // 1. Wait thirty seconds & check

                Pause(30);

                result = await CheckOrderStatus(orderResult.OrderId);

                // 2. If not filled, cancel it

                if (result.Result == ExchangeAPIOrderResult.Unknown)
                {
                    _trader.CancelOrder(orderResult.OrderId);

                    // 3. Check the price now
                    ticker = _trader.GetLatestTicker(_inMemoryBot.BaseCoin, _inMemoryBot.Coin);

                    Log($"Order still UNKNOWN after 30 seconds for orderId {orderResult.OrderId}, cancelling and re-ordering at new price {ticker.Ask}");

                    if (orderResult.IsBuy)
                    {
                        Buy(new Candle()
                        {
                            Timestamp = DateTime.Now, ClosePrice = ticker.Ask
                        });
                    }
                    else
                    {
                        Sell(new Candle()
                        {
                            Timestamp = DateTime.Now, ClosePrice = ticker.Bid
                        });
                    }
                }

                break;
            }
        }