public void DOMMidprice()
        {
            // Arrange
            const decimal BUY_PRICE         = 6004.5m;
            const decimal SELL_PRICE        = 6016.0m;
            const decimal EXPECTED_MIDPRICE = 6010.25m;
            const decimal LOTS = 100m;

            var bids = new List <Tuple <decimal, decimal> >();

            bids.Add(new Tuple <decimal, decimal>(BUY_PRICE - 10m, LOTS));
            bids.Add(new Tuple <decimal, decimal>(BUY_PRICE, LOTS));
            bids.Add(new Tuple <decimal, decimal>(BUY_PRICE - 100m, LOTS));

            var asks = new List <Tuple <decimal, decimal> >();

            asks.Add(new Tuple <decimal, decimal>(SELL_PRICE + 45m, LOTS));
            asks.Add(new Tuple <decimal, decimal>(SELL_PRICE, LOTS));
            asks.Add(new Tuple <decimal, decimal>(SELL_PRICE + 167m, LOTS));
            var dom = new SimpleDOM(bids, asks);
            // Act
            var d = new DOMBalance(Instrument.XBTUSD(), dom, 0.1, 100m);

            // Asert
            Assert.AreEqual(EXPECTED_MIDPRICE, d.MidPrice, $"Incorrect mid-price for spread {BUY_PRICE}..{SELL_PRICE}");
        }
Example #2
0
        public void FilterOutFarOrders()
        {
            // Arrange
            const decimal EXPECTED_MIDPRICE            = 4510.25m;
            const double  RADIUS_FROM_MIDPRICE_PERCENT = 0.5;                                                                        // 50% from mid price
            const decimal BUY_PRICE          = EXPECTED_MIDPRICE - EXPECTED_MIDPRICE * (decimal)(RADIUS_FROM_MIDPRICE_PERCENT)-0.5m; // 0.5 ticks below lower border
            const decimal SELL_PRICE         = EXPECTED_MIDPRICE + EXPECTED_MIDPRICE * (decimal)(RADIUS_FROM_MIDPRICE_PERCENT)+0.5m; // 0.5 ticks over upper border
            const decimal EXPECTED_LIQUIDITY = 47m;
            const decimal LOTS = 100m;

            var bids = new List <Tuple <decimal, decimal> >();

            bids.Add(new Tuple <decimal, decimal>(BUY_PRICE, LOTS));
            var asks = new List <Tuple <decimal, decimal> >();

            asks.Add(new Tuple <decimal, decimal>(SELL_PRICE, LOTS));
            var dom = new SimpleDOM(bids, asks);
            // Act
            var d = new DOMBalance(Instrument.XBTUSD(), dom, RADIUS_FROM_MIDPRICE_PERCENT, EXPECTED_LIQUIDITY);

            // Asert
            Assert.AreEqual(EXPECTED_MIDPRICE, d.MidPrice, $"Incorrect mid-price for spread {BUY_PRICE}..{SELL_PRICE}");

            // Since all far orders are filtered out, so we need to create buy and sell orders to make liquidity
            Assert.AreEqual(0m, d.SellAmount, "Sell not filtered out");
            Assert.AreEqual(0m, d.BuyAmount, "Buy not filtered out");
            Assert.AreEqual(EXPECTED_LIQUIDITY / 2.0m, d.BuyDisbalance, "Expected to buy");
            Assert.AreEqual(EXPECTED_LIQUIDITY / 2.0m, d.SellDisbalance, "Expected to sell");
        }
        public void EmptyDOMTest()
        {
            // Arrange & Act
            var empty = new List <Tuple <decimal, decimal> >();
            var d     = new DOMBalance(Instrument.XBTUSD(), new SimpleDOM(empty, empty), 0.1, 100m);

            // Asert
            Assert.IsNull(d.MidPrice, "Mid price shall be null");

            Assert.AreEqual(0m, d.BuyDisbalance, "Shall not change buy side");
            Assert.AreEqual(0m, d.BuyDisbalance, "Shall not change buy side");

            Assert.AreEqual(0m, d.BuyAmount, "Buy side shall be equal to 0");
            Assert.AreEqual(0m, d.BuyAmount, "Sell side shall be equal to 0");
        }
        public void SingleSellMidprice()
        {
            // Arrange
            const decimal PRICE = 1.2345m;
            const decimal LOTS  = 100m;

            var bids = new List <Tuple <decimal, decimal> >();
            var asks = new List <Tuple <decimal, decimal> >();

            asks.Add(new Tuple <decimal, decimal>(PRICE, LOTS));
            var dom = new SimpleDOM(bids, asks);
            // Act
            var d = new DOMBalance(Instrument.XBTUSD(), dom, 0.1, 100m);

            // Asert
            Assert.AreEqual(PRICE, d.MidPrice, "Incorrect mid-price");
        }
Example #5
0
        protected override void Do()
        {
            var bba     = _exec.GetBBA(Instrument.ETHUSD()).Result;
            var kethusd = 1m;

            if (bba != null)
            {
                kethusd          = (bba.Item1 + bba.Item2) / 2.0m;
                _settings.ETHUSD = kethusd; // Update ETHUSD quote in settings
                kethusd         *= 1000.0m;
            }

            var dom = _exec.GetDOM(_settings.Instrument).Result;
            //TODO: Remove own orders from DOM before calcs

            var balance = new DOMBalance(_settings.Instrument, dom, _settings.RadiusPercent, _settings.RequiredLiquidityUSD);

            Console.WriteLine($"midPrice=${balance.MidPrice:0.#} low=${balance.MidPrice - balance.MidPrice * (decimal)_settings.RadiusPercent:0.#} high=${balance.MidPrice + balance.MidPrice * (decimal)_settings.RadiusPercent:0.#}");
            Console.WriteLine($"buyAmount={balance.BuyAmount / balance.MidPrice / 1000.0m:0.#}K XBT sellAmount={balance.SellAmount / balance.MidPrice / 1000.0m:0.#}K XBT "
                              + $"buyDisb={balance.BuyDisbalance / kethusd:0.#}K ETH sellDisb={balance.SellDisbalance / kethusd:0.#}K ETH");

            // If buy side volume is more than expected then fill some orders
            if (balance.BuyDisbalance < 0)
            {
                _om.EatBidSide(-balance.BuyDisbalance);
            }

            // If sell side volume is more than expected then fill some orders
            if (balance.SellDisbalance < 0)
            {
                _om.EatAskSide(-balance.SellDisbalance);
            }

            var buyPrice  = balance.MidPrice - balance.MidPrice * (decimal)_settings.RadiusPercent;
            var sellPrice = balance.MidPrice + balance.MidPrice * (decimal)_settings.RadiusPercent;

            if (balance.MidPrice.HasValue)
            {
                _om.AmendMMOrders(buyPrice ?? 0, balance.BuyDisbalance, sellPrice ?? 0, balance.SellDisbalance);
            }
        }
Example #6
0
        public void OppositeOrderToSingleSell()
        {
            // Arrange
            const decimal PRICE    = 6056.0m;
            const int     LOT_SIZE = 2;
            const decimal REQUIRED_LIQUIDITY_IN_DOM = PRICE * LOT_SIZE * 2; // 2 orders with the same price*vol

            var bids = new List <Tuple <decimal, decimal> >();
            var asks = new List <Tuple <decimal, decimal> >();

            asks.Add(new Tuple <decimal, decimal>(PRICE, LOT_SIZE));
            var dom = new SimpleDOM(bids, asks);
            // Act
            var d = new DOMBalance(Instrument.XBTUSD(), dom, 1, REQUIRED_LIQUIDITY_IN_DOM);

            // Asert
            Assert.AreEqual(PRICE, d.MidPrice, "Incorrect mid-price");
            Assert.AreEqual(0m, d.BuyAmount, "Incorrect buy amount");
            Assert.AreEqual(0m, d.SellDisbalance, "Not expected to sell");

            Assert.AreEqual(PRICE * LOT_SIZE, d.SellAmount, "Incorrect sell amount");
            Assert.AreEqual(PRICE * LOT_SIZE, d.BuyDisbalance, "Expected to buy");
        }
Example #7
0
        public void SingleLargeSell()
        {
            // Arrange
            const decimal PRICE = 6056.0m;
            const int     LOTS  = 2;
            const decimal REQUIRED_LIQUIDITY_IN_DOM = PRICE * LOTS * 0.8m;

            var bids = new List <Tuple <decimal, decimal> >();
            var asks = new List <Tuple <decimal, decimal> >();

            asks.Add(new Tuple <decimal, decimal>(PRICE, LOTS));
            var dom = new SimpleDOM(bids, asks);
            // Act
            var d = new DOMBalance(Instrument.XBTUSD(), dom, 1, REQUIRED_LIQUIDITY_IN_DOM);

            // Asert
            Assert.AreEqual(PRICE, d.MidPrice, "Incorrect mid-price");
            Assert.AreEqual(0m, d.BuyAmount, "Incorrect buy amount");
            Assert.Less(d.SellDisbalance, 0m, "Sell disbalance shall be negative (need close/eat some sell LMTs)");

            Assert.AreEqual(PRICE * LOTS, d.SellAmount, "Incorrect sell amount");
            Assert.AreEqual(REQUIRED_LIQUIDITY_IN_DOM / 2.0m, d.BuyDisbalance, "Expected to buy");
        }