示例#1
0
    def setUp(self):

        super().setUp()
        self.log_records = []

        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.order_delay_time = 15
        self.cancel_order_wait_time = 45
        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", 50000)
        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))

        # Define strategies to test
        self.limit_buy_strategy: TwapTradeStrategy = TwapTradeStrategy(
            [self.market_info],
            order_price=Decimal("99"),
            cancel_order_wait_time=self.cancel_order_wait_time,
            is_buy=True,
            order_delay_time=self.order_delay_time,
            target_asset_amount=Decimal("2.0"),
            order_step_size=Decimal("1.0"))
        self.limit_sell_strategy: TwapTradeStrategy = TwapTradeStrategy(
            [self.market_info],
            order_price=Decimal("101"),
            cancel_order_wait_time=self.cancel_order_wait_time,
            is_buy=False,
            order_delay_time=self.order_delay_time,
            target_asset_amount=Decimal("5.0"),
            order_step_size=Decimal("1.67"))

        self.clock.add_iterator(self.market)
        self.maker_order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.buy_order_completed_logger: EventLogger = EventLogger()
        self.sell_order_completed_logger: EventLogger = EventLogger()

        self.market.add_listener(MarketEvent.BuyOrderCompleted,
                                 self.buy_order_completed_logger)
        self.market.add_listener(MarketEvent.SellOrderCompleted,
                                 self.sell_order_completed_logger)
        self.market.add_listener(MarketEvent.OrderFilled,
                                 self.maker_order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled,
                                 self.cancel_order_logger)
示例#2
0
    def test_strategy_time_span_execution(self):
        span_start_time = self.start_timestamp + (self.clock_tick_size * 5)
        span_end_time = self.start_timestamp + (self.clock_tick_size * 7)
        strategy = TwapTradeStrategy(
            [self.market_info],
            order_price=Decimal("99"),
            cancel_order_wait_time=self.cancel_order_wait_time,
            is_buy=True,
            order_delay_time=self.order_delay_time,
            target_asset_amount=Decimal("100.0"),
            order_step_size=Decimal("1.0"),
            execution_state=RunInTimeConditionalExecutionState(
                start_timestamp=datetime.fromtimestamp(span_start_time),
                end_timestamp=datetime.fromtimestamp(span_end_time)))

        self.clock.add_iterator(strategy)
        # check no orders are placed before span start
        self.clock.backtest_til(span_start_time - self.clock_tick_size)
        self.assertEqual(0, len(self.limit_sell_strategy.active_asks))

        order_time_1 = span_start_time + self.clock_tick_size
        self.clock.backtest_til(order_time_1)
        self.assertEqual(1, len(strategy.active_bids))
        first_bid_order: LimitOrder = strategy.active_bids[0][1]
        self.assertEqual(Decimal("99"), first_bid_order.price)
        self.assertEqual(1, first_bid_order.quantity)

        # check no orders are placed after span end
        order_time_2 = span_end_time + (self.clock_tick_size * 10)
        self.clock.backtest_til(order_time_2)
        self.assertEqual(1, len(strategy.active_bids))
    def test_status_with_time_span_execution(self):
        exchange = MockExchange(
            client_config_map=ClientConfigAdapter(ClientConfigMap()))
        exchange.buy_price = Decimal("25100")
        exchange.sell_price = Decimal("24900")
        exchange.update_account_balance({
            "ETH": Decimal("100000"),
            "USDT": Decimal(10000)
        })
        exchange.update_account_available_balance({
            "ETH": Decimal("100000"),
            "USDT": Decimal(10000)
        })
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        start_time_string = "2021-06-24 10:00:00"
        end_time_string = "2021-06-24 10:30:00"
        execution_type = RunInTimeConditionalExecutionState(
            start_timestamp=datetime.fromisoformat(start_time_string),
            end_timestamp=datetime.fromisoformat(end_time_string))
        strategy = TwapTradeStrategy(market_infos=[marketTuple],
                                     is_buy=True,
                                     target_asset_amount=Decimal(100),
                                     order_step_size=Decimal(10),
                                     order_price=Decimal(25000),
                                     execution_state=execution_type)

        status = strategy.format_status()
        expected_status = (
            "\n  Configuration:\n"
            "    Total amount: 100 ETH    Order price: 25000 USDT    Order size: 10.00 ETH\n"
            f"    Execution type: run between {start_time_string} and {end_time_string}\n\n"
            "  Markets:\n"
            "           Exchange    Market  Best Bid Price  Best Ask Price  Mid Price\n"
            "    0  MockExchange  ETH-USDT           24900           25100      25000\n\n"
            "  Assets:\n"
            "           Exchange Asset  Total Balance  Available Balance\n"
            "    0  MockExchange   ETH         100000             100000\n"
            "    1  MockExchange  USDT          10000              10000\n\n"
            "  No active maker orders.\n\n"
            "  Average filled orders price: 0 USDT\n"
            "  Pending amount: 100 ETH\n\n"
            "*** WARNINGS ***\n"
            "  Markets are offline for the ETH-USDT pair. "
            "Continued trading with these markets may be dangerous.\n")

        self.assertEqual(expected_status, status)
示例#4
0
    def test_tick_logs_warning_when_market_not_connected(self):
        exchange = MockExchange()
        exchange.ready = True
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        strategy = TwapTradeStrategy(market_infos=[marketTuple])
        strategy.logger().setLevel(1)
        strategy.logger().addHandler(self)

        start_timestamp = time.time()
        strategy.start(Clock(ClockMode.BACKTEST), start_timestamp)
        strategy.tick(start_timestamp + 1000)

        self.assertTrue(
            self._is_logged('WARNING', (
                "WARNING: Some markets are not connected or are down at the moment. "
                "Market making may be dangerous when markets or networks are unstable."
            )))
示例#5
0
    def test_tick_logs_warning_when_market_not_ready(self):
        exchange = MockExchange()
        exchange.ready = False
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        strategy = TwapTradeStrategy(market_infos=[marketTuple])
        strategy.logger().setLevel(1)
        strategy.logger().addHandler(self)

        start_timestamp = time.time()
        strategy.start(Clock(ClockMode.BACKTEST), start_timestamp)
        strategy.tick(start_timestamp + 1000)

        self.assertTrue(
            self._is_logged(
                'WARNING',
                "Markets are not ready. No market making trades are permitted."
            ))
    def test_creation_without_market_info_fails(self):
        with self.assertRaises(ValueError) as ex_context:
            TwapTradeStrategy(market_infos=[],
                              is_buy=True,
                              target_asset_amount=1,
                              order_step_size=1,
                              order_price=1)

        self.assertEqual(str(ex_context.exception),
                         "market_infos must not be empty.")
示例#7
0
    def test_start(self):
        exchange = MockExchange()
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        strategy = TwapTradeStrategy(market_infos=[marketTuple])
        strategy.logger().setLevel(1)
        strategy.logger().addHandler(self)

        start_timestamp = time.time()
        strategy.start(Clock(ClockMode.BACKTEST), start_timestamp)

        self.assertTrue(
            self._is_logged('INFO', 'Waiting for 10.0 to place orders'))
示例#8
0
    def test_status(self):
        exchange = MockExchange()
        exchange.buy_price = Decimal("25100")
        exchange.sell_price = Decimal("24900")
        exchange.update_account_balance({
            "ETH": Decimal("100000"),
            "USDT": Decimal(10000)
        })
        exchange.update_account_available_balance({
            "ETH": Decimal("100000"),
            "USDT": Decimal(10000)
        })
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        strategy = TwapTradeStrategy(market_infos=[marketTuple],
                                     is_buy=True,
                                     target_asset_amount=Decimal(100),
                                     order_step_size=Decimal(10),
                                     order_price=Decimal(25000))

        status = strategy.format_status()
        expected_status = (
            "\n  Configuration:\n"
            "    Total amount: 100 ETH    Order price: 25000 USDT    Order size: 10.00 ETH\n"
            "    Execution type: run continuously\n\n"
            "  Markets:\n"
            "           Exchange    Market  Best Bid Price  Best Ask Price  Mid Price\n"
            "    0  MockExchange  ETH-USDT           24900           25100      25000\n\n"
            "  Assets:\n"
            "           Exchange Asset  Total Balance  Available Balance\n"
            "    0  MockExchange   ETH         100000             100000\n"
            "    1  MockExchange  USDT          10000              10000\n\n"
            "  No active maker orders.\n\n"
            "  Average filled orders price: 0 USDT\n"
            "  Pending amount: 100 ETH\n\n"
            "*** WARNINGS ***\n"
            "  Markets are offline for the ETH-USDT pair. "
            "Continued trading with these markets may be dangerous.\n")

        self.assertEqual(expected_status, status)
    def test_tick_logs_warning_when_market_not_ready(self):
        exchange = MockExchange(
            client_config_map=ClientConfigAdapter(ClientConfigMap()))
        exchange.ready = False
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        strategy = TwapTradeStrategy(market_infos=[marketTuple],
                                     is_buy=True,
                                     target_asset_amount=1,
                                     order_step_size=1,
                                     order_price=1)
        strategy.logger().setLevel(1)
        strategy.logger().addHandler(self)

        start_timestamp = time.time()
        strategy.start(Clock(ClockMode.BACKTEST), start_timestamp)
        strategy.tick(start_timestamp + 1000)

        self.assertTrue(
            self._is_logged(
                'WARNING',
                "Markets are not ready. No market making trades are permitted."
            ))
    def test_start(self):
        exchange = MockExchange(
            client_config_map=ClientConfigAdapter(ClientConfigMap()))
        marketTuple = MarketTradingPairTuple(exchange, "ETH-USDT", "ETH",
                                             "USDT")
        strategy = TwapTradeStrategy(market_infos=[marketTuple],
                                     is_buy=True,
                                     target_asset_amount=1,
                                     order_step_size=1,
                                     order_price=1)
        strategy.logger().setLevel(1)
        strategy.logger().addHandler(self)

        start_timestamp = time.time()
        strategy.start(Clock(ClockMode.BACKTEST), start_timestamp)

        self.assertTrue(
            self._is_logged('INFO', 'Waiting for 10.0 to place orders'))
示例#11
0
    def test_creation_without_market_info_fails(self):
        with self.assertRaises(ValueError) as ex_context:
            TwapTradeStrategy([])

        self.assertEqual(str(ex_context.exception),
                         "market_infos must not be empty.")