def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size,
                                  self.start_timestamp, self.end_timestamp)
        self.market: BacktestMarket = BacktestMarket()
        self.book_data: MockOrderBookLoader = MockOrderBookLoader(
            self.trading_pair, self.base_asset, self.quote_asset)
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.book_data.set_balanced_order_book(mid_price=self.mid_price,
                                               min_price=1,
                                               max_price=200,
                                               price_step_size=1,
                                               volume_step_size=10)
        self.market.add_data(self.book_data)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(self.trading_pair, 6, 6, 6, 6))
        self.market_info = MarketTradingPairTuple(self.market,
                                                  self.trading_pair,
                                                  self.base_asset,
                                                  self.quote_asset)
        self.clock.add_iterator(self.market)
        self.order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled,
                                 self.order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled,
                                 self.cancel_order_logger)

        self.ext_market: BacktestMarket = BacktestMarket()
        self.ext_data: MockOrderBookLoader = MockOrderBookLoader(
            self.trading_pair, self.base_asset, self.quote_asset)
        self.ext_market_info: MarketTradingPairTuple = MarketTradingPairTuple(
            self.ext_market, self.trading_pair, self.base_asset,
            self.quote_asset)
        self.ext_data.set_balanced_order_book(mid_price=100,
                                              min_price=1,
                                              max_price=400,
                                              price_step_size=1,
                                              volume_step_size=100)
        self.ext_market.add_data(self.ext_data)
        self.order_book_asset_del = OrderBookAssetPriceDelegate(
            self.ext_market, self.trading_pair)

        self.one_level_strategy = PureMarketMakingStrategy()
        self.one_level_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=3.0,
            filled_order_delay=3.0,
            order_refresh_tolerance_pct=-1,
            minimum_spread=-1,
            asset_price_delegate=self.order_book_asset_del,
            take_if_crossed=True)
Exemple #2
0
    def test_inventory_skew_multiple_orders_status(self):
        strategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5.0,
            filled_order_delay=5.0,
            order_refresh_tolerance_pct=-1,
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_level_amount=Decimal("0.5"),
            inventory_skew_enabled=True,
            inventory_target_base_pct=Decimal("0.9"),
            inventory_range_multiplier=Decimal("0.5"),
            minimum_spread=-1,
        )
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + 1)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))

        status_df: pd.DataFrame = strategy.inventory_skew_stats_data_frame()
        self.assertEqual("50.0%", status_df.iloc[4, 1])
        self.assertEqual("150.0%", status_df.iloc[4, 2])
Exemple #3
0
    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp)
        self.market: BacktestMarket = BacktestMarket()
        self.maker_data: MockOrderBookLoader = MockOrderBookLoader(*self.maker_trading_pairs)
        self.mid_price = 100
        self.maker_data.set_balanced_order_book(mid_price=self.mid_price, min_price=1,
                                                max_price=200, price_step_size=1, volume_step_size=10)
        self.market.add_data(self.maker_data)
        self.market.set_balance("COINALPHA", 500)
        self.market.set_balance("WETH", 5000)
        self.market.set_balance("QETH", 500)
        self.market.set_quantization_param(
            QuantizationParams(
                self.maker_trading_pairs[0], 6, 6, 6, 6
            )
        )
        self.market_info: MarketTradingPairTuple = MarketTradingPairTuple(
            self.market, self.maker_trading_pairs[0],
            self.maker_trading_pairs[1], self.maker_trading_pairs[2]
        )

        self.strategy: PureMarketMakingStrategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal(.05),
            ask_spread=Decimal(.05),
            order_amount=Decimal(1),
            order_refresh_time=30,
            minimum_spread=0,
        )
Exemple #4
0
    def test_basic_one_level_price_type(self):
        strategies = []

        for price_type in ["last_price", "best_bid", "best_ask"]:
            strategy = PureMarketMakingStrategy(
                self.market_info,
                bid_spread=Decimal("0.01"),
                ask_spread=Decimal("0.01"),
                order_amount=Decimal("1"),
                order_refresh_time=5.0,
                filled_order_delay=5.0,
                order_refresh_tolerance_pct=-1,
                minimum_spread=-1,
                price_type=price_type,
            )
            strategies.append(strategy)
            self.clock.add_iterator(strategy)

        last_strategy, bid_strategy, ask_strategy = strategies

        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(last_strategy.active_buys))
        self.assertEqual(1, len(last_strategy.active_sells))
        buy_1 = last_strategy.active_buys[0]
        self.assertEqual(99, buy_1.price)
        self.assertEqual(1, buy_1.quantity)
        sell_1 = last_strategy.active_sells[0]
        self.assertEqual(101, sell_1.price)
        self.assertEqual(1, sell_1.quantity)

        # Simulate buy order filled
        self.simulate_maker_market_trade(False, 100, 98.9)
        self.assertEqual(0, len(last_strategy.active_buys))
        self.assertEqual(1, len(last_strategy.active_sells))

        # After filled_ore
        self.clock.backtest_til(self.start_timestamp + 7)
        buy_1 = last_strategy.active_buys[0]
        self.assertEqual(Decimal('97.911'), buy_1.price)
        self.assertEqual(1, buy_1.quantity)
        sell_1 = last_strategy.active_sells[0]
        self.assertEqual(Decimal('99.889'), sell_1.price)
        self.assertEqual(1, sell_1.quantity)

        buy_bid = bid_strategy.active_buys[0]
        buy_target = self.market_info.get_price_by_type(PriceType.BestBid) * Decimal("0.99")
        self.assertEqual(buy_target, buy_bid.price)
        sell_bid = bid_strategy.active_sells[0]
        sell_target = self.market_info.get_price_by_type(PriceType.BestBid) * Decimal("1.01")
        self.assertEqual(sell_target, sell_bid.price)

        buy_ask = ask_strategy.active_buys[0]
        buy_target = self.market_info.get_price_by_type(PriceType.BestAsk) * Decimal("0.99")
        self.assertEqual(buy_target, buy_ask.price)
        sell_ask = ask_strategy.active_sells[0]
        sell_target = self.market_info.get_price_by_type(PriceType.BestAsk) * Decimal("1.01")
        self.assertEqual(sell_target, sell_ask.price)
    def test_strategy_ping_pong_on_bid_fill(self):
        self.strategy = PureMarketMakingStrategy()
        self.strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5,
            filled_order_delay=5,
            order_refresh_tolerance_pct=-1,
            ping_pong_enabled=True,
        )
        self.clock.add_iterator(self.strategy)

        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.simulate_maker_market_trade(False, Decimal(100), Decimal("98.9"))

        self.clock.backtest_til(
            self.start_timestamp + 2 * self.clock_tick_size
        )
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))
        old_ask = self.strategy.active_sells[0]

        self.clock.backtest_til(
            self.start_timestamp + 7 * self.clock_tick_size
        )
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        # After new order create cycle (after filled_order_delay), check if a new order is created
        self.assertTrue(old_ask.client_order_id != self.strategy.active_sells[0].client_order_id)

        self.simulate_maker_market_trade(True, Decimal(100), Decimal("101.1"))

        self.clock.backtest_til(
            self.start_timestamp + 15 * self.clock_tick_size
        )
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))
Exemple #6
0
    def test_order_quantity_available_balance(self):
        """
        When balance is below the specified order amount, checks if orders created
        use the remaining available balance for the order size.
        """
        strategy = PureMarketMakingStrategy(self.market_info,
                                            bid_spread=Decimal("0.01"),
                                            ask_spread=Decimal("0.01"),
                                            order_refresh_time=5,
                                            order_amount=Decimal("100"),
                                            order_levels=3)

        self.clock.add_iterator(strategy)
        self.market.set_balance("HBOT", Decimal("10"))
        self.market.set_balance("ETH", Decimal("1000"))
        self.clock.backtest_til(self.start_timestamp + 1)

        # Check if order size on both sides is equal to the remaining balance
        self.assertEqual(Decimal("10.1010"), strategy.active_buys[0].quantity)
        self.assertEqual(Decimal("10"), strategy.active_sells[0].quantity)

        # Order levels created
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))

        strategy.cancel_order(strategy.active_buys[0].client_order_id)
        strategy.cancel_order(strategy.active_sells[0].client_order_id)

        # Do not create order on side with 0 balance
        self.market.set_balance("HBOT", 0)
        self.market.set_balance("ETH", Decimal("1000"))
        self.clock.backtest_til(self.start_timestamp + 7)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(0, len(strategy.active_sells))
Exemple #7
0
    def test_basic_one_level_price_type_own_last_trade(self):
        strategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5.0,
            filled_order_delay=5.0,
            order_refresh_tolerance_pct=-1,
            minimum_spread=-1,
            price_type='last_own_trade_price',
        )
        self.clock.add_iterator(strategy)

        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        buy_1 = strategy.active_buys[0]
        self.assertEqual(99, buy_1.price)
        self.assertEqual(1, buy_1.quantity)
        sell_1 = strategy.active_sells[0]
        self.assertEqual(101, sell_1.price)
        self.assertEqual(1, sell_1.quantity)

        # Simulate buy order filled
        self.simulate_maker_market_trade(False, 100, 98.9)
        self.assertEqual(0, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))

        # Order has been filled
        self.clock.backtest_til(self.start_timestamp + 7)
        buy_1 = strategy.active_buys[0]
        self.assertEqual(Decimal('98.01'), buy_1.price)
        self.assertEqual(1, buy_1.quantity)
        sell_1 = strategy.active_sells[0]
        self.assertEqual(Decimal('99.99'), sell_1.price)
        self.assertEqual(1, sell_1.quantity)
Exemple #8
0
class PMMRefreshToleranceUnitTest(unittest.TestCase):
    start: pd.Timestamp = pd.Timestamp("2019-01-01", tz="UTC")
    end: pd.Timestamp = pd.Timestamp("2019-01-01 01:00:00", tz="UTC")
    start_timestamp: float = start.timestamp()
    end_timestamp: float = end.timestamp()
    trading_pair = "HBOT-ETH"
    base_asset = trading_pair.split("-")[0]
    quote_asset = trading_pair.split("-")[1]

    def simulate_maker_market_trade(self, is_buy: bool, quantity: Decimal,
                                    price: Decimal):
        order_book = self.market.get_order_book(self.trading_pair)
        trade_event = OrderBookTradeEvent(
            self.trading_pair, self.clock.current_timestamp,
            TradeType.BUY if is_buy else TradeType.SELL, price, quantity)
        order_book.apply_trade(trade_event)

    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size,
                                  self.start_timestamp, self.end_timestamp)
        self.market: MockPaperExchange = MockPaperExchange()
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.market.set_balanced_order_book(trading_pair=self.trading_pair,
                                            mid_price=self.mid_price,
                                            min_price=1,
                                            max_price=200,
                                            price_step_size=1,
                                            volume_step_size=10)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(self.trading_pair, 6, 6, 6, 6))
        self.market_info = MarketTradingPairTuple(self.market,
                                                  self.trading_pair,
                                                  self.base_asset,
                                                  self.quote_asset)
        self.clock.add_iterator(self.market)
        self.maker_order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled,
                                 self.maker_order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled,
                                 self.cancel_order_logger)

    def test_strategy_ping_pong_on_ask_fill(self):
        self.strategy = PureMarketMakingStrategy()
        self.strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5,
            filled_order_delay=5,
            order_refresh_tolerance_pct=-1,
            ping_pong_enabled=True,
        )
        self.clock.add_iterator(self.strategy)

        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.simulate_maker_market_trade(True, Decimal(100), Decimal("101.1"))

        self.clock.backtest_til(self.start_timestamp +
                                2 * self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(0, len(self.strategy.active_sells))
        old_bid = self.strategy.active_buys[0]

        self.clock.backtest_til(self.start_timestamp +
                                7 * self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(0, len(self.strategy.active_sells))
        # After new order create cycle (after filled_order_delay), check if a new order is created
        self.assertTrue(old_bid.client_order_id !=
                        self.strategy.active_buys[0].client_order_id)

        self.simulate_maker_market_trade(False, Decimal(100), Decimal("98.9"))

        self.clock.backtest_til(self.start_timestamp +
                                15 * self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

    def test_strategy_ping_pong_on_bid_fill(self):
        self.strategy = PureMarketMakingStrategy()
        self.strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5,
            filled_order_delay=5,
            order_refresh_tolerance_pct=-1,
            ping_pong_enabled=True,
        )
        self.clock.add_iterator(self.strategy)

        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.simulate_maker_market_trade(False, Decimal(100), Decimal("98.9"))

        self.clock.backtest_til(self.start_timestamp +
                                2 * self.clock_tick_size)
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))
        old_ask = self.strategy.active_sells[0]

        self.clock.backtest_til(self.start_timestamp +
                                7 * self.clock_tick_size)
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        # After new order create cycle (after filled_order_delay), check if a new order is created
        self.assertTrue(old_ask.client_order_id !=
                        self.strategy.active_sells[0].client_order_id)

        self.simulate_maker_market_trade(True, Decimal(100), Decimal("101.1"))

        self.clock.backtest_til(self.start_timestamp +
                                15 * self.clock_tick_size)
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

    def test_multiple_orders_ping_pong(self):
        self.strategy = PureMarketMakingStrategy()
        self.strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_amount=Decimal("1"),
            order_level_spread=Decimal("0.01"),
            order_refresh_time=5,
            order_refresh_tolerance_pct=-1,
            filled_order_delay=5,
            ping_pong_enabled=True,
        )
        self.clock.add_iterator(self.strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)

        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(5, len(self.strategy.active_sells))

        self.simulate_maker_market_trade(True, Decimal(100), Decimal("102.50"))
        # After market trade happens, 2 of the asks orders are filled.
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        self.clock.backtest_til(self.start_timestamp +
                                2 * self.clock_tick_size)
        # Not refreshing time yet, still same active orders
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        old_bids = self.strategy.active_buys
        old_asks = self.strategy.active_sells
        self.clock.backtest_til(self.start_timestamp +
                                7 * self.clock_tick_size)
        # After order refresh, same numbers of orders but it's a new set.
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        self.assertNotEqual(
            [o.client_order_id for o in old_asks],
            [o.client_order_id for o in self.strategy.active_sells])
        self.assertNotEqual(
            [o.client_order_id for o in old_bids],
            [o.client_order_id for o in self.strategy.active_buys])

        # Simulate sell trade, the first bid gets taken out
        self.simulate_maker_market_trade(False, Decimal(100), Decimal("98.9"))
        self.assertEqual(4, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        self.clock.backtest_til(self.start_timestamp +
                                13 * self.clock_tick_size)

        # After refresh, same numbers of orders
        self.assertEqual(4, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))

        # Another bid order is filled.
        self.simulate_maker_market_trade(False, Decimal(100), Decimal("97.9"))
        self.assertEqual(3, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                20 * self.clock_tick_size)

        # After refresh, numbers of orders back to order_levels of 5
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(5, len(self.strategy.active_sells))
Exemple #9
0
    def test_multiple_orders_ping_pong(self):
        self.strategy = PureMarketMakingStrategy()
        self.strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_amount=Decimal("1"),
            order_level_spread=Decimal("0.01"),
            order_refresh_time=5,
            order_refresh_tolerance_pct=-1,
            filled_order_delay=5,
            ping_pong_enabled=True,
        )
        self.clock.add_iterator(self.strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)

        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(5, len(self.strategy.active_sells))

        self.simulate_maker_market_trade(True, Decimal(100), Decimal("102.50"))
        # After market trade happens, 2 of the asks orders are filled.
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        self.clock.backtest_til(self.start_timestamp +
                                2 * self.clock_tick_size)
        # Not refreshing time yet, still same active orders
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        old_bids = self.strategy.active_buys
        old_asks = self.strategy.active_sells
        self.clock.backtest_til(self.start_timestamp +
                                7 * self.clock_tick_size)
        # After order refresh, same numbers of orders but it's a new set.
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        self.assertNotEqual(
            [o.client_order_id for o in old_asks],
            [o.client_order_id for o in self.strategy.active_sells])
        self.assertNotEqual(
            [o.client_order_id for o in old_bids],
            [o.client_order_id for o in self.strategy.active_buys])

        # Simulate sell trade, the first bid gets taken out
        self.simulate_maker_market_trade(False, Decimal(100), Decimal("98.9"))
        self.assertEqual(4, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))
        self.clock.backtest_til(self.start_timestamp +
                                13 * self.clock_tick_size)

        # After refresh, same numbers of orders
        self.assertEqual(4, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))

        # Another bid order is filled.
        self.simulate_maker_market_trade(False, Decimal(100), Decimal("97.9"))
        self.assertEqual(3, len(self.strategy.active_buys))
        self.assertEqual(3, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                20 * self.clock_tick_size)

        # After refresh, numbers of orders back to order_levels of 5
        self.assertEqual(5, len(self.strategy.active_buys))
        self.assertEqual(5, len(self.strategy.active_sells))
Exemple #10
0
    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp)
        self.market: MockPaperExchange = MockPaperExchange()
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.market.set_balanced_order_book(trading_pair=self.trading_pair,
                                            mid_price=self.mid_price,
                                            min_price=1,
                                            max_price=200,
                                            price_step_size=1,
                                            volume_step_size=10)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(
                self.trading_pair, 6, 6, 6, 6
            )
        )
        self.market_info = MarketTradingPairTuple(self.market, self.trading_pair,
                                                  self.base_asset, self.quote_asset)
        self.clock.add_iterator(self.market)
        self.maker_order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)

        self.one_level_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
        self.one_level_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=4,
            filled_order_delay=8,
            hanging_orders_enabled=True,
            hanging_orders_cancel_pct=0.05,
            order_refresh_tolerance_pct=0
        )
        self.multi_levels_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
        self.multi_levels_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_refresh_time=4,
            filled_order_delay=8,
            order_refresh_tolerance_pct=0
        )
        self.hanging_order_multiple_strategy = PureMarketMakingStrategy()
        self.hanging_order_multiple_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_refresh_time=4,
            filled_order_delay=8,
            order_refresh_tolerance_pct=0,
            hanging_orders_enabled=True
        )
Exemple #11
0
class PMMRefreshToleranceUnitTest(unittest.TestCase):
    start: pd.Timestamp = pd.Timestamp("2019-01-01", tz="UTC")
    end: pd.Timestamp = pd.Timestamp("2019-01-01 01:00:00", tz="UTC")
    start_timestamp: float = start.timestamp()
    end_timestamp: float = end.timestamp()
    trading_pair = "HBOT-ETH"
    base_asset = trading_pair.split("-")[0]
    quote_asset = trading_pair.split("-")[1]

    def simulate_maker_market_trade(self, is_buy: bool, quantity: Decimal, price: Decimal):
        order_book = self.market.get_order_book(self.trading_pair)
        trade_event = OrderBookTradeEvent(
            self.trading_pair,
            self.clock.current_timestamp,
            TradeType.BUY if is_buy else TradeType.SELL,
            price,
            quantity
        )
        order_book.apply_trade(trade_event)

    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp)
        self.market: MockPaperExchange = MockPaperExchange()
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.market.set_balanced_order_book(trading_pair=self.trading_pair,
                                            mid_price=self.mid_price,
                                            min_price=1,
                                            max_price=200,
                                            price_step_size=1,
                                            volume_step_size=10)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(
                self.trading_pair, 6, 6, 6, 6
            )
        )
        self.market_info = MarketTradingPairTuple(self.market, self.trading_pair,
                                                  self.base_asset, self.quote_asset)
        self.clock.add_iterator(self.market)
        self.maker_order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)

        self.one_level_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
        self.one_level_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=4,
            filled_order_delay=8,
            hanging_orders_enabled=True,
            hanging_orders_cancel_pct=0.05,
            order_refresh_tolerance_pct=0
        )
        self.multi_levels_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
        self.multi_levels_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_refresh_time=4,
            filled_order_delay=8,
            order_refresh_tolerance_pct=0
        )
        self.hanging_order_multiple_strategy = PureMarketMakingStrategy()
        self.hanging_order_multiple_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_refresh_time=4,
            filled_order_delay=8,
            order_refresh_tolerance_pct=0,
            hanging_orders_enabled=True
        )

    def test_active_orders_are_cancelled_when_mid_price_moves(self):
        strategy = self.one_level_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        old_bid = strategy.active_buys[0]
        old_ask = strategy.active_sells[0]
        # Not the order refresh time yet, orders should remain the same
        self.clock.backtest_til(self.start_timestamp + 3 * self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        self.assertEqual(old_bid.client_order_id, strategy.active_buys[0].client_order_id)
        self.assertEqual(old_ask.client_order_id, strategy.active_sells[0].client_order_id)
        self.market.order_books[self.trading_pair].apply_diffs([OrderBookRow(99.5, 30, 2)],
                                                               [OrderBookRow(100.1, 30, 2)], 2)
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        new_bid = strategy.active_buys[0]
        new_ask = strategy.active_sells[0]
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        self.assertNotEqual(old_ask, new_ask)
        self.assertNotEqual(old_bid, new_bid)

    def test_active_orders_are_kept_when_within_tolerance(self):
        strategy = self.one_level_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        old_bid = strategy.active_buys[0]
        old_ask = strategy.active_sells[0]
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        new_bid = strategy.active_buys[0]
        new_ask = strategy.active_sells[0]
        self.assertEqual(old_ask, new_ask)
        self.assertEqual(old_bid, new_bid)
        self.clock.backtest_til(self.start_timestamp + 10 * self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        new_bid = strategy.active_buys[0]
        new_ask = strategy.active_sells[0]
        self.assertEqual(old_ask, new_ask)
        self.assertEqual(old_bid, new_bid)

    def test_multi_levels_active_orders_are_cancelled_when_mid_price_moves(self):
        strategy = self.multi_levels_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        old_buys = strategy.active_buys
        old_sells = strategy.active_sells
        self.market.order_books[self.trading_pair].apply_diffs([OrderBookRow(99.5, 30, 2)],
                                                               [OrderBookRow(100.1, 30, 2)], 2)
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        new_buys = strategy.active_buys
        new_sells = strategy.active_sells
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        self.assertNotEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertNotEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])

    def test_multiple_active_orders_are_kept_when_within_tolerance(self):
        strategy = self.multi_levels_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        old_buys = strategy.active_buys
        old_sells = strategy.active_sells
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        new_buys = strategy.active_buys
        new_sells = strategy.active_sells
        self.assertEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])
        self.clock.backtest_til(self.start_timestamp + 10 * self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        new_buys = strategy.active_buys
        new_sells = strategy.active_sells
        self.assertEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])

    def test_hanging_orders_multiple_orders_with_refresh_tolerance(self):
        strategy = self.hanging_order_multiple_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))

        self.simulate_maker_market_trade(True, Decimal("100"), Decimal("101.1"))

        # Before refresh_time hanging orders are not yet created
        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time / 2)
        self.assertEqual(1, len(self.maker_order_fill_logger.event_log))
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(4, len(strategy.active_sells))
        self.assertEqual(0, len(strategy.hanging_order_ids))

        # At order_refresh_time (4 seconds), hanging order are created
        # Ask is filled and due to delay is not replenished immediately
        # Bid orders are now hanging and active
        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time + 1)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(0, len(strategy.active_sells))
        self.assertEqual(1, len(strategy.hanging_order_ids))

        # At filled_order_delay (8 seconds), new sets of bid and ask orders are created
        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time + strategy.filled_order_delay + 1)
        self.assertEqual(6, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        self.assertEqual(1, len(strategy.hanging_order_ids))

        # Check all hanging order ids are indeed in active bids list
        self.assertTrue(all(h in [order.client_order_id for order in strategy.active_buys]
                            for h in strategy.hanging_order_ids))

        old_buys = [o for o in strategy.active_buys if o.client_order_id not in strategy.hanging_order_ids]
        old_sells = [o for o in strategy.active_sells if o.client_order_id not in strategy.hanging_order_ids]

        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time + strategy.filled_order_delay + 1)
        self.assertEqual(6, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))

        new_buys = [o for o in strategy.active_buys if o.client_order_id not in strategy.hanging_order_ids]
        new_sells = [o for o in strategy.active_sells if o.client_order_id not in strategy.hanging_order_ids]
        self.assertEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])
Exemple #12
0
    def test_inventory_skew_multiple_orders(self):
        strategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5.0,
            filled_order_delay=5.0,
            order_refresh_tolerance_pct=-1,
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_level_amount=Decimal("0.5"),
            inventory_skew_enabled=True,
            inventory_target_base_pct=Decimal("0.9"),
            inventory_range_multiplier=Decimal("0.5"),
            minimum_spread=-1,
        )
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + 1)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))

        first_bid_order = strategy.active_buys[0]
        first_ask_order = strategy.active_sells[0]
        self.assertEqual(Decimal("99"), first_bid_order.price)
        self.assertEqual(Decimal("101"), first_ask_order.price)
        self.assertEqual(Decimal("0.5"), first_bid_order.quantity)
        self.assertEqual(Decimal("1.5"), first_ask_order.quantity)

        last_bid_order = strategy.active_buys[-1]
        last_ask_order = strategy.active_sells[-1]
        last_bid_price = Decimal(100 * (1 - 0.01 - (0.01 * 4))).quantize(Decimal("0.001"))
        last_ask_price = Decimal(100 * (1 + 0.01 + (0.01 * 4))).quantize(Decimal("0.001"))
        self.assertAlmostEqual(last_bid_price, last_bid_order.price, 3)
        self.assertAlmostEqual(last_ask_price, last_ask_order.price, 3)
        self.assertEqual(Decimal("1.5"), last_bid_order.quantity)
        self.assertEqual(Decimal("4.5"), last_ask_order.quantity)

        self.simulate_maker_market_trade(True, 5.0, 101.1)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(4, len(strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp + 3)
        self.assertEqual(1, len(self.order_fill_logger.event_log))

        maker_fill = self.order_fill_logger.event_log[0]
        self.assertEqual(TradeType.SELL, maker_fill.trade_type)
        self.assertAlmostEqual(101, maker_fill.price)
        self.assertAlmostEqual(Decimal("1.5"), Decimal(str(maker_fill.amount)), places=4)

        # The default filled_order_delay is 60, so gotta wait 60 + 2 here.
        self.clock.backtest_til(self.start_timestamp + 7 * self.clock_tick_size + 1)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        first_bid_order = strategy.active_buys[0]
        first_ask_order = strategy.active_sells[0]
        last_bid_order = strategy.active_buys[-1]
        last_ask_order = strategy.active_sells[-1]
        self.assertEqual(Decimal("99"), first_bid_order.price)
        self.assertEqual(Decimal("101"), first_ask_order.price)
        self.assertEqual(Decimal("0.651349"), first_bid_order.quantity)
        self.assertEqual(Decimal("1.34865"), first_ask_order.quantity)
        last_bid_price = Decimal(100 * (1 - 0.01 - (0.01 * 4))).quantize(Decimal("0.001"))
        last_ask_price = Decimal(100 * (1 + 0.01 + (0.01 * 4))).quantize(Decimal("0.001"))
        self.assertAlmostEqual(last_bid_price, last_bid_order.price, 3)
        self.assertAlmostEqual(last_ask_price, last_ask_order.price, 3)
        self.assertEqual(Decimal("1.95404"), last_bid_order.quantity)
        self.assertEqual(Decimal("4.04595"), last_ask_order.quantity)
class PureMMTakeIfCrossUnitTest(unittest.TestCase):
    start: pd.Timestamp = pd.Timestamp("2019-01-01", tz="UTC")
    end: pd.Timestamp = pd.Timestamp("2019-01-01 01:00:00", tz="UTC")
    start_timestamp: float = start.timestamp()
    end_timestamp: float = end.timestamp()
    trading_pair = "HBOT-ETH"
    base_asset = trading_pair.split("-")[0]
    quote_asset = trading_pair.split("-")[1]

    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size,
                                  self.start_timestamp, self.end_timestamp)
        self.market: BacktestMarket = BacktestMarket()
        self.book_data: MockOrderBookLoader = MockOrderBookLoader(
            self.trading_pair, self.base_asset, self.quote_asset)
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.book_data.set_balanced_order_book(mid_price=self.mid_price,
                                               min_price=1,
                                               max_price=200,
                                               price_step_size=1,
                                               volume_step_size=10)
        self.market.add_data(self.book_data)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(self.trading_pair, 6, 6, 6, 6))
        self.market_info = MarketTradingPairTuple(self.market,
                                                  self.trading_pair,
                                                  self.base_asset,
                                                  self.quote_asset)
        self.clock.add_iterator(self.market)
        self.order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled,
                                 self.order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled,
                                 self.cancel_order_logger)

        self.ext_market: BacktestMarket = BacktestMarket()
        self.ext_data: MockOrderBookLoader = MockOrderBookLoader(
            self.trading_pair, self.base_asset, self.quote_asset)
        self.ext_market_info: MarketTradingPairTuple = MarketTradingPairTuple(
            self.ext_market, self.trading_pair, self.base_asset,
            self.quote_asset)
        self.ext_data.set_balanced_order_book(mid_price=100,
                                              min_price=1,
                                              max_price=400,
                                              price_step_size=1,
                                              volume_step_size=100)
        self.ext_market.add_data(self.ext_data)
        self.order_book_asset_del = OrderBookAssetPriceDelegate(
            self.ext_market, self.trading_pair)

        self.one_level_strategy = PureMarketMakingStrategy()
        self.one_level_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=3.0,
            filled_order_delay=3.0,
            order_refresh_tolerance_pct=-1,
            minimum_spread=-1,
            asset_price_delegate=self.order_book_asset_del,
            take_if_crossed=True)

    def simulate_maker_market_trade(self, is_buy: bool, quantity: Decimal,
                                    price: Decimal):
        order_book = self.market.get_order_book(self.trading_pair)
        trade_event = OrderBookTradeEvent(
            self.trading_pair, self.clock.current_timestamp,
            TradeType.BUY if is_buy else TradeType.SELL, price, quantity)
        order_book.apply_trade(trade_event)

    def test_strategy_take_if_crossed_bid_order(self):
        simulate_order_book_widening(
            self.ext_market.get_order_book(self.trading_pair), 120.0, 130.0)
        self.strategy = self.one_level_strategy
        self.clock.add_iterator(self.strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(0, len(self.order_fill_logger.event_log))
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                2 * self.clock_tick_size)
        self.assertEqual(1, len(self.order_fill_logger.event_log))
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                7 * self.clock_tick_size)
        self.assertEqual(2, len(self.order_fill_logger.event_log))
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                10 * self.clock_tick_size)
        self.assertEqual(3, len(self.order_fill_logger.event_log))
        self.assertEqual(0, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))
        self.order_fill_logger.clear()

    def test_strategy_take_if_crossed_ask_order(self):
        simulate_order_book_widening(
            self.ext_market.get_order_book(self.trading_pair), 80.0, 90.0)
        self.strategy = self.one_level_strategy
        self.clock.add_iterator(self.strategy)

        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(0, len(self.order_fill_logger.event_log))
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(1, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                2 * self.clock_tick_size)
        self.assertEqual(1, len(self.order_fill_logger.event_log))
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(0, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                6 * self.clock_tick_size)
        self.assertEqual(2, len(self.order_fill_logger.event_log))
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(0, len(self.strategy.active_sells))

        self.clock.backtest_til(self.start_timestamp +
                                10 * self.clock_tick_size)
        self.assertEqual(3, len(self.order_fill_logger.event_log))
        self.assertEqual(1, len(self.strategy.active_buys))
        self.assertEqual(0, len(self.strategy.active_sells))
        self.order_fill_logger.clear()
Exemple #14
0
    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp)
        self.market: BacktestMarket = BacktestMarket()
        self.book_data: MockOrderBookLoader = MockOrderBookLoader(self.trading_pair, self.base_asset, self.quote_asset)
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.book_data.set_balanced_order_book(mid_price=self.mid_price,
                                               min_price=1,
                                               max_price=200,
                                               price_step_size=1,
                                               volume_step_size=10)
        self.market.add_data(self.book_data)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(
                self.trading_pair, 6, 6, 6, 6
            )
        )
        self.market_info = MarketTradingPairTuple(self.market, self.trading_pair,
                                                  self.base_asset, self.quote_asset)
        self.clock.add_iterator(self.market)
        self.order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled, self.order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)

        self.one_level_strategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5.0,
            filled_order_delay=5.0,
            order_refresh_tolerance_pct=-1,
            minimum_spread=-1,
        )

        self.multi_levels_strategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5.0,
            filled_order_delay=5.0,
            order_refresh_tolerance_pct=-1,
            order_levels=3,
            order_level_spread=Decimal("0.01"),
            order_level_amount=Decimal("1"),
            minimum_spread=-1,
        )

        self.order_override_strategy = PureMarketMakingStrategy(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=5.0,
            filled_order_delay=5.0,
            order_refresh_tolerance_pct=-1,
            order_levels=3,
            order_level_spread=Decimal("0.01"),
            order_level_amount=Decimal("1"),
            minimum_spread=-1,
            order_override={"order_one": ["buy", 0.5, 0.7], "order_two": ["buy", 1.3, 1.1], "order_three": ["sell", 1.1, 2]},
        )

        self.ext_market: BacktestMarket = BacktestMarket()
        self.ext_data: MockOrderBookLoader = MockOrderBookLoader(self.trading_pair, self.base_asset, self.quote_asset)
        self.ext_market_info: MarketTradingPairTuple = MarketTradingPairTuple(
            self.ext_market, self.trading_pair, self.base_asset, self.quote_asset
        )
        self.ext_data.set_balanced_order_book(mid_price=50, min_price=1, max_price=400, price_step_size=1,
                                              volume_step_size=10)
        self.ext_market.add_data(self.ext_data)
        self.order_book_asset_del = OrderBookAssetPriceDelegate(self.ext_market, self.trading_pair)
        trade_fill_sql = SQLConnectionManager(
            SQLConnectionType.TRADE_FILLS, db_path=""
        )
        self.inventory_cost_price_del = InventoryCostPriceDelegate(trade_fill_sql, self.trading_pair)