def setUp(self): self.clock: Clock = Clock(ClockMode.BACKTEST, 1.0, self.start_timestamp, self.end_timestamp) self.min_profitbality = Decimal("0.005") self.maker_market: MockPaperExchange = MockPaperExchange() self.taker_market: MockPaperExchange = MockPaperExchange() self.maker_market.set_balanced_order_book(self.maker_trading_pairs[0], 1.0, 0.5, 1.5, 0.01, 10) self.taker_market.set_balanced_order_book(self.taker_trading_pairs[0], 1.0, 0.5, 1.5, 0.001, 4) self.maker_market.set_balance("COINALPHA", 5) self.maker_market.set_balance("WETH", 5) self.maker_market.set_balance("QETH", 5) self.taker_market.set_balance("COINALPHA", 5) self.taker_market.set_balance("ETH", 5) self.maker_market.set_quantization_param(QuantizationParams(self.maker_trading_pairs[0], 5, 5, 5, 5)) self.taker_market.set_quantization_param(QuantizationParams(self.taker_trading_pairs[0], 5, 5, 5, 5)) self.market_pair: CrossExchangeMarketPair = CrossExchangeMarketPair( MarketTradingPairTuple(self.maker_market, *self.maker_trading_pairs), MarketTradingPairTuple(self.taker_market, *self.taker_trading_pairs), ) logging_options: int = ( CrossExchangeMarketMakingStrategy.OPTION_LOG_ALL & (~CrossExchangeMarketMakingStrategy.OPTION_LOG_NULL_ORDER_SIZE) ) self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy() self.strategy.init_params( [self.market_pair], order_size_portfolio_ratio_limit=Decimal("0.3"), min_profitability=Decimal(self.min_profitbality), logging_options=logging_options, slippage_buffer=Decimal("0"), ) self.strategy_with_top_depth_tolerance: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy() self.strategy_with_top_depth_tolerance.init_params( [self.market_pair], order_size_portfolio_ratio_limit=Decimal("0.3"), min_profitability=Decimal(self.min_profitbality), logging_options=logging_options, top_depth_tolerance=1, slippage_buffer=Decimal("0"), ) self.logging_options = logging_options self.clock.add_iterator(self.maker_market) self.clock.add_iterator(self.taker_market) self.clock.add_iterator(self.strategy) self.maker_order_fill_logger: EventLogger = EventLogger() self.taker_order_fill_logger: EventLogger = EventLogger() self.cancel_order_logger: EventLogger = EventLogger() self.maker_order_created_logger: EventLogger = EventLogger() self.taker_order_created_logger: EventLogger = EventLogger() self.maker_market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger) self.taker_market.add_listener(MarketEvent.OrderFilled, self.taker_order_fill_logger) self.maker_market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger) self.maker_market.add_listener(MarketEvent.BuyOrderCreated, self.maker_order_created_logger) self.maker_market.add_listener(MarketEvent.SellOrderCreated, self.maker_order_created_logger) self.taker_market.add_listener(MarketEvent.BuyOrderCreated, self.taker_order_created_logger) self.taker_market.add_listener(MarketEvent.SellOrderCreated, self.taker_order_created_logger)
def setUp(self): self.maxDiff = None self.clock: Clock = Clock(ClockMode.BACKTEST, 1.0, self.start_timestamp, self.end_timestamp) self.market_1: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.market_2: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.market_1.set_balanced_order_book(self.market_1_trading_pairs[0], 1.0, 0.5, 1.5, 0.01, 10) self.market_2.set_balanced_order_book(self.market_2_trading_pairs[0], 1.0, 0.5, 1.5, 0.005, 5) self.market_1.set_balance("COINALPHA", 500) self.market_1.set_balance("WETH", 500) self.market_2.set_balance("COINALPHA", 500) self.market_2.set_balance("ETH", 500) self.market_1.set_quantization_param( QuantizationParams(self.market_1_trading_pairs[0], 5, 5, 5, 5)) self.market_2.set_quantization_param( QuantizationParams(self.market_2_trading_pairs[0], 5, 5, 5, 5)) self.market_trading_pair_tuple_1 = MarketTradingPairTuple( *([self.market_1] + self.market_1_trading_pairs)) self.market_trading_pair_tuple_2 = MarketTradingPairTuple( *([self.market_2] + self.market_2_trading_pairs)) self.market_pair: ArbitrageMarketPair = ArbitrageMarketPair( self.market_trading_pair_tuple_1, self.market_trading_pair_tuple_2) self.logging_options: int = ArbitrageStrategy.OPTION_LOG_ALL self.strategy: ArbitrageStrategy = ArbitrageStrategy() self.strategy.init_params( [self.market_pair], min_profitability=Decimal("0.03"), logging_options=self.logging_options, secondary_to_primary_quote_conversion_rate=Decimal("0.95")) self.clock.add_iterator(self.market_1) self.clock.add_iterator(self.market_2) self.clock.add_iterator(self.strategy) self.market_1_order_fill_logger: EventLogger = EventLogger() self.market_2_order_fill_logger: EventLogger = EventLogger() self.market_1.add_listener(MarketEvent.OrderFilled, self.market_1_order_fill_logger) self.market_2.add_listener(MarketEvent.OrderFilled, self.market_2_order_fill_logger)
def create_market( trading_pairs: List[str], mid_price, balances: Dict[str, int] ) -> (MockPaperExchange, Dict[str, MarketTradingPairTuple]): """ Create a BacktestMarket and marketinfo dictionary to be used by the liquidity mining strategy """ market: ExtendedMockPaperExchange = ExtendedMockPaperExchange() market_infos: Dict[str, MarketTradingPairTuple] = {} for trading_pair in trading_pairs: base_asset = trading_pair.split("-")[0] quote_asset = trading_pair.split("-")[1] market.set_balanced_order_book(trading_pair=trading_pair, mid_price=mid_price, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) market.set_quantization_param( QuantizationParams(trading_pair, 6, 6, 6, 6)) market_infos[trading_pair] = MarketTradingPairTuple( market, trading_pair, base_asset, quote_asset) for asset, value in balances.items(): market.set_balance(asset, value) return market, market_infos
def test_with_adjust_orders_disabled(self): self.clock.remove_iterator(self.strategy) self.clock.remove_iterator(self.maker_market) self.maker_market: MockPaperExchange = MockPaperExchange() self.maker_market.set_balanced_order_book(self.maker_trading_pairs[0], 1.0, 0.5, 1.5, 0.1, 10) self.taker_market.set_balanced_order_book(self.taker_trading_pairs[0], 1.0, 0.5, 1.5, 0.001, 20) self.market_pair: CrossExchangeMarketPair = CrossExchangeMarketPair( MarketTradingPairTuple(self.maker_market, *self.maker_trading_pairs), MarketTradingPairTuple(self.taker_market, *self.taker_trading_pairs), ) self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy() self.strategy.init_params( [self.market_pair], order_size_portfolio_ratio_limit=Decimal("0.3"), min_profitability=Decimal("0.005"), logging_options=self.logging_options, adjust_order_enabled=False ) self.maker_market.set_balance("COINALPHA", 5) self.maker_market.set_balance("WETH", 5) self.maker_market.set_balance("QETH", 5) self.maker_market.set_quantization_param(QuantizationParams(self.maker_trading_pairs[0], 4, 4, 4, 4)) self.clock.add_iterator(self.strategy) self.clock.add_iterator(self.maker_market) self.clock.backtest_til(self.start_timestamp + 5) self.assertEqual(1, len(self.strategy.active_bids)) self.assertEqual(1, len(self.strategy.active_asks)) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] self.assertEqual(Decimal("0.9945"), bid_order.price) self.assertEqual(Decimal("1.006"), ask_order.price) self.assertAlmostEqual(Decimal("3"), round(bid_order.quantity, 4)) self.assertAlmostEqual(Decimal("3"), round(ask_order.quantity, 4))
def setUp(self): self.maxDiff = None self.clock: Clock = Clock(ClockMode.BACKTEST, 1.0, self.start_timestamp, self.end_timestamp) self.market: MockPaperExchange = MockPaperExchange() self.market.set_balanced_order_book(self.trading_pair, 10, 5, 15, 0.1, 1) self.market.set_balance(self.base_asset, 500) self.market.set_balance(self.quote_asset, 500) self.market.set_quantization_param( QuantizationParams(self.trading_pair, 5, 5, 5, 5)) self.market_info = MarketTradingPairTuple(self.market, self.trading_pair, self.base_asset, self.quote_asset) self.logging_options: int = CeloArbStrategy.OPTION_LOG_ALL self.strategy = CeloArbStrategy() self.strategy.init_params(self.market_info, min_profitability=Decimal("0.01"), order_amount=Decimal("1"), celo_slippage_buffer=Decimal("0.001"), logging_options=self.logging_options, hb_app_notification=False, mock_celo_cli_mode=True) self.clock.add_iterator(self.market) self.clock.add_iterator(self.strategy) self.market_order_fill_logger: EventLogger = EventLogger() self.market.add_listener(MarketEvent.OrderFilled, self.market_order_fill_logger) CeloCLI.unlock_account(TEST_ADDRESS, TEST_PASSWORD)
def test_market_ready(self): # Simulate Order Book being populated quote_balance = 5000 self.mid_price = 100 self.time_delay = 15 self.cancel_order_wait_time = 45 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("COINALPHA", 500) self.market.set_balance("HBOT", quote_balance) self.market.set_quantization_param( QuantizationParams(self.trading_pair, 6, 6, 6, 6)) self.clock.add_iterator(self.market) self.clock.add_iterator(self.strategy) self.clock.backtest_til(self.start_timestamp + self.tick_size) # Check status output when market is ready status_msg_output: str = self.ev_loop.run_until_complete( self.strategy.format_status()) self.assertTrue("Assets:" in status_msg_output) self.assertTrue(f"HBOT {quote_balance}" in status_msg_output)
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 setUp(self): self.log_records = [] self.start: pd.Timestamp = pd.Timestamp("2019-01-01", tz="UTC") self.end: pd.Timestamp = pd.Timestamp("2019-01-01 01:00:00", tz="UTC") self.start_timestamp: float = self.start.timestamp() self.end_timestamp: float = self.end.timestamp() self.connector_name: str = "mock_paper_exchange" self.trading_pair: str = "HBOT-USDT" self.base_asset, self.quote_asset = self.trading_pair.split("-") self.base_balance: int = 500 self.quote_balance: int = 5000 self.initial_mid_price: int = 100 self.clock_tick_size = 1 self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp) self.connector: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.connector.set_balanced_order_book(trading_pair=self.trading_pair, mid_price=100, min_price=50, max_price=150, price_step_size=1, volume_step_size=10) self.connector.set_balance(self.base_asset, self.base_balance) self.connector.set_balance(self.quote_asset, self.quote_balance) self.connector.set_quantization_param( QuantizationParams(self.trading_pair, 6, 6, 6, 6)) self.clock.add_iterator(self.connector) ScriptStrategyBase.markets = {self.connector_name: {self.trading_pair}} self.strategy = ScriptStrategyBase( {self.connector_name: self.connector}) self.strategy.logger().setLevel(1) self.strategy.logger().addHandler(self)
def setUp(self) -> None: np.random.seed(self.INITIAL_RANDOM_SEED) trade_fee_schema = TradeFeeSchema( maker_percent_fee_decimal=Decimal("0.25"), taker_percent_fee_decimal=Decimal("0.25")) client_config_map = ClientConfigAdapter(ClientConfigMap()) self.market: MockPaperExchange = MockPaperExchange( client_config_map, trade_fee_schema) self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.market, self.trading_pair, *self.trading_pair.split("-")) self.market.set_balanced_order_book(trading_pair=self.trading_pair, mid_price=self.initial_mid_price, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.market.set_balance("COINALPHA", 1) self.market.set_balance("HBOT", 500) self.market.set_quantization_param( QuantizationParams(self.trading_pair.split("-")[0], 6, 6, 6, 6)) self.price_delegate = OrderBookAssetPriceDelegate( self.market_info.market, self.trading_pair) self.indicator = TradingIntensityIndicator( order_book=self.market_info.order_book, price_delegate=self.price_delegate, sampling_length=self.BUFFER_LENGTH)
def test_adjust_candidate_buy_insufficient_funds_partial_adjustment_allowed(self): q_params = QuantizationParams( trading_pair=self.trading_pair, price_precision=8, price_decimals=2, order_size_precision=8, order_size_decimals=2, ) self.exchange.set_quantization_param(q_params) self.exchange.set_balance(self.quote_asset, Decimal("10")) order_candidate = OrderCandidate( trading_pair=self.trading_pair, is_maker=True, order_type=OrderType.LIMIT, order_side=TradeType.BUY, amount=Decimal("10"), price=Decimal("2"), ) adjusted_candidate = self.budget_checker.adjust_candidate(order_candidate, all_or_none=False) # order amount quantized to two decimal places self.assertEqual(Decimal("4.95"), adjusted_candidate.amount) # 5 * .99 self.assertEqual(self.quote_asset, adjusted_candidate.order_collateral.token) self.assertEqual(Decimal("9.9"), adjusted_candidate.order_collateral.amount) # 4.95 * 2 self.assertEqual(self.quote_asset, adjusted_candidate.percent_fee_collateral.token) self.assertEqual(Decimal("0.099"), adjusted_candidate.percent_fee_collateral.amount) # 9.9 * 0.01 self.assertEqual(self.quote_asset, adjusted_candidate.percent_fee_value.token) self.assertEqual(Decimal("0.099"), adjusted_candidate.percent_fee_value.amount) # 9.9 * 0.01 self.assertEqual(0, len(adjusted_candidate.fixed_fee_collaterals)) self.assertEqual(self.base_asset, adjusted_candidate.potential_returns.token) self.assertEqual(Decimal("4.95"), adjusted_candidate.potential_returns.amount)
def test_empty_maker_orderbook(self): self.clock.remove_iterator(self.strategy) self.clock.remove_iterator(self.maker_market) self.maker_market: MockPaperExchange = MockPaperExchange() # Orderbook is empty self.maker_market.new_empty_order_book(self.maker_trading_pairs[0]) self.market_pair: CrossExchangeMarketPair = CrossExchangeMarketPair( MarketTradingPairTuple(self.maker_market, *self.maker_trading_pairs), MarketTradingPairTuple(self.taker_market, *self.taker_trading_pairs), ) self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy() self.strategy.init_params( [self.market_pair], order_amount=1, min_profitability=Decimal("0.005"), logging_options=self.logging_options, adjust_order_enabled=False ) self.maker_market.set_balance("COINALPHA", 5) self.maker_market.set_balance("WETH", 5) self.maker_market.set_balance("QETH", 5) self.maker_market.set_quantization_param(QuantizationParams(self.maker_trading_pairs[0], 4, 4, 4, 4)) self.clock.add_iterator(self.strategy) self.clock.add_iterator(self.maker_market) self.clock.backtest_til(self.start_timestamp + 5) self.assertEqual(1, len(self.strategy.active_bids)) self.assertEqual(1, len(self.strategy.active_asks)) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] # Places orders based on taker orderbook self.assertEqual(Decimal("0.9945"), bid_order.price) self.assertEqual(Decimal("1.006"), ask_order.price) self.assertAlmostEqual(Decimal("1"), round(bid_order.quantity, 4)) self.assertAlmostEqual(Decimal("1"), round(ask_order.quantity, 4))
def test_market_ready(self): # Simulate Order Book being populated quote_balance = 5000 self.mid_price = 100 self.time_delay = 15 self.cancel_order_wait_time = 45 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("COINALPHA", 500) self.market.set_balance("HBOT", quote_balance) self.market.set_quantization_param( QuantizationParams( self.trading_pair, 6, 6, 6, 6 ) ) expected_best_ask = min([row.price for row in self.market.order_book_ask_entries(self.trading_pair)]) expected_best_bid = max([row.price for row in self.market.order_book_bid_entries(self.trading_pair)]) self.clock.add_iterator(self.market) self.clock.add_iterator(self.strategy) self.clock.backtest_til(self.start_timestamp + self.tick_size) # Check status output when market is ready status_msg_output: str = self.ev_loop.run_until_complete(self.strategy.format_status()) curr_best_bid, curr_best_ask = [Decimal(item) for item in status_msg_output.split('\n')[2].split(' ') if item != ''] self.assertEqual(expected_best_bid, curr_best_bid) self.assertEqual(expected_best_ask, curr_best_ask)
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: MockPaperExchange = MockPaperExchange() self.mid_price = 100 self.order_delay_time = 15 self.cancel_order_wait_time = 45 self.market.set_balanced_order_book( trading_pair=self.maker_trading_pairs[0], mid_price=self.mid_price, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) 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)
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.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: MockPaperExchange = MockPaperExchange() self.ext_market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.ext_market, self.trading_pair, self.base_asset, self.quote_asset) self.ext_market.set_balanced_order_book(trading_pair=self.trading_pair, mid_price=100, min_price=1, max_price=400, price_step_size=1, volume_step_size=100) 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 setUp(self): super().setUp() self.log_records = [] self.market: MockPerpConnector = MockPerpConnector( client_config_map=ClientConfigAdapter(ClientConfigMap()), trade_fee_schema=self.trade_fee_schema) self.market.set_quantization_param( QuantizationParams( self.trading_pair, price_precision=6, price_decimals=2, order_size_precision=6, order_size_decimals=2, ) ) self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.market, self.trading_pair, self.base_asset, self.quote_asset ) self.market.set_balanced_order_book(trading_pair=self.trading_pair, mid_price=self.initial_mid_price, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.market.set_balance("COINALPHA", 1000) self.market.set_balance("HBOT", 50000) new_strategy = PerpetualMarketMakingStrategy() new_strategy.init_params( market_info=self.market_info, leverage=10, position_mode=PositionMode.ONEWAY.name.title(), bid_spread=Decimal("0.5"), ask_spread=Decimal("0.4"), order_amount=Decimal("100"), long_profit_taking_spread=self.long_profit_taking_spread, short_profit_taking_spread=self.short_profit_taking_spread, stop_loss_spread=self.stop_loss_spread, time_between_stop_loss_orders=10.0, stop_loss_slippage_buffer=self.stop_loss_slippage_buffer, ) new_strategy._position_mode_ready = True self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp) self.clock.add_iterator(self.market) self._configure_strategy(new_strategy) self.clock.backtest_til(self.start_timestamp) self.cancel_order_logger: EventLogger = EventLogger() self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
def test_with_adjust_orders_enabled(self): self.clock.remove_iterator(self.strategy) self.clock.remove_iterator(self.maker_market) self.maker_market: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.maker_market.set_balanced_order_book(self.trading_pairs_maker[0], 1.0, 0.5, 1.5, 0.1, 10) self.market_pair: CrossExchangeMarketPair = CrossExchangeMarketPair( MarketTradingPairTuple(self.maker_market, *self.trading_pairs_maker), MarketTradingPairTuple(self.taker_market, *self.trading_pairs_taker), ) config_map_raw = deepcopy(self.config_map_raw) config_map_raw.order_size_portfolio_ratio_limit = Decimal("30") config_map_raw.min_profitability = Decimal("0.5") config_map_raw.adjust_order_enabled = True config_map = ClientConfigAdapter(config_map_raw) self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy( ) self.strategy.init_params( config_map=config_map, market_pairs=[self.market_pair], logging_options=self.logging_options, ) self.maker_market.set_balance("COINALPHA", 5) self.maker_market.set_balance("WETH", 5) self.maker_market.set_balance("QETH", 5) self.maker_market.set_quantization_param( QuantizationParams(self.trading_pairs_maker[0], 4, 4, 4, 4)) self.clock.add_iterator(self.strategy) self.clock.add_iterator(self.maker_market) self.clock.backtest_til(self.start_timestamp + 5) self.assertEqual(1, len(self.strategy.active_bids)) self.assertEqual(1, len(self.strategy.active_asks)) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] # place above top bid (at 0.95) self.assertAlmostEqual(Decimal("0.9501"), bid_order.price) # place below top ask (at 1.05) self.assertAlmostEqual(Decimal("1.049"), ask_order.price) self.assertAlmostEqual(Decimal("3"), round(bid_order.quantity, 4)) self.assertAlmostEqual(Decimal("3"), round(ask_order.quantity, 4))
def setUp(self): self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp) self.market: MockPaperExchange = MockPaperExchange() self.market.set_balanced_order_book(trading_pair=self.trading_pair, mid_price=100, min_price=50, max_price=150, price_step_size=1, volume_step_size=10) self.market.set_balance("COINALPHA", self.base_balance) self.market.set_balance("HBOT", self.quote_balance) 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)
def setUp(self): self.market: ExtendedMockPaperExchange = ExtendedMockPaperExchange() self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.market, self.trading_pair, *self.trading_pair.split("-")) self.mid_price = 100 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("COINALPHA", 500) self.market.set_balance("WETH", 5000) self.market.set_balance("QETH", 500) self.market.set_quantization_param( QuantizationParams(self.trading_pair.split("-")[0], 6, 6, 6, 6)) self.strategy: StrategyBase = MockStrategy() self.strategy.add_markets([self.market])
def setUp(self): self.market: ExtendedMockPaperExchange = ExtendedMockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.market, self.trading_pair, *self.trading_pair.split("-")) self.mid_price = 100 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("COINALPHA", 500) self.market.set_balance("WETH", 5000) self.market.set_balance("QETH", 500) self.market.set_quantization_param( QuantizationParams(self.trading_pair.split("-")[0], 6, 6, 6, 6)) self.strategy: StrategyBase = MockStrategy() self.strategy.add_markets([self.market]) self.strategy.order_tracker._set_current_timestamp(1640001112.223)
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( client_config_map=ClientConfigAdapter(ClientConfigMap())) 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 setUp(self): self.clock_tick_size = 1 self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp) self.client_config_map = ClientConfigAdapter(ClientConfigMap()) self.market: MockPaperExchange = MockPaperExchange(self.client_config_map) self.mid_price = 100 self.start_order_spread = 0.01 self.order_refresh_time = 30 self.n_levels = 10 self.grid_price_ceiling = 200 self.grid_price_floor = 20 self.market.set_balanced_order_book(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.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.quote_required_strategy = FixedGridStrategy() self.quote_required_strategy.init_params( self.market_info, n_levels=10, grid_price_floor = Decimal("20"), grid_price_ceiling = Decimal("200"), start_order_spread=Decimal("0.01"), order_amount=Decimal("52"), order_refresh_time=30.0 ) self.base_required_strategy = FixedGridStrategy() self.base_required_strategy.init_params( self.market_info, n_levels=10, grid_price_floor = Decimal("110"), grid_price_ceiling = Decimal("200"), start_order_spread=Decimal("0.01"), order_amount=Decimal("60"), order_refresh_time=30.0 ) self.no_rebalance_strategy = FixedGridStrategy() self.no_rebalance_strategy.init_params( self.market_info, n_levels=10, grid_price_floor = Decimal("40"), grid_price_ceiling = Decimal("130"), start_order_spread=Decimal("0.01"), order_amount=Decimal("5"), order_refresh_time=10.0 )
def setUp(self): self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp) self.mid_price = 100 self.time_delay = 15 self.cancel_order_wait_time = 45 self.market: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) 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("COINALPHA", 500) self.market.set_balance("WETH", 5000) self.market.set_quantization_param( QuantizationParams(self.trading_pair, 6, 6, 6, 6)) self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.market, self.trading_pair, self.base_asset, self.quote_asset) # Define strategies to test self.buy_mid_price_strategy: PerformTradeStrategy = PerformTradeStrategy( exchange=self.market, trading_pair=self.trading_pair, is_buy=True, spread=self.spread, order_amount=Decimal("1.0"), price_type=PriceType.MidPrice) self.sell_mid_price_strategy: PerformTradeStrategy = PerformTradeStrategy( exchange=self.market, trading_pair=self.trading_pair, is_buy=False, spread=self.spread, order_amount=Decimal("1.0"), price_type=PriceType.MidPrice) self.buy_last_price_strategy: PerformTradeStrategy = PerformTradeStrategy( exchange=self.market, trading_pair=self.trading_pair, is_buy=True, spread=self.spread, order_amount=Decimal("1.0"), price_type=PriceType.LastTrade) self.sell_last_price_strategy: PerformTradeStrategy = PerformTradeStrategy( exchange=self.market, trading_pair=self.trading_pair, is_buy=False, spread=self.spread, order_amount=Decimal("1.0"), price_type=PriceType.LastTrade) self.buy_last_own_trade_price_strategy: PerformTradeStrategy = PerformTradeStrategy( exchange=self.market, trading_pair=self.trading_pair, is_buy=True, spread=self.spread, order_amount=Decimal("1.0"), price_type=PriceType.LastOwnTrade) self.sell_last_own_trade_price_strategy: PerformTradeStrategy = PerformTradeStrategy( exchange=self.market, trading_pair=self.trading_pair, is_buy=False, spread=self.spread, order_amount=Decimal("1.0"), price_type=PriceType.LastOwnTrade) 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)
def setUp(self): 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.time_delay = 15 self.cancel_order_wait_time = 45 self.market.set_balanced_order_book(self.maker_trading_pairs[0], mid_price=self.mid_price, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) 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)) logging_options: int = ( SimpleTradeStrategy.OPTION_LOG_ALL & (~SimpleTradeStrategy.OPTION_LOG_NULL_ORDER_SIZE)) # Define strategies to test self.limit_buy_strategy: SimpleTradeStrategy = SimpleTradeStrategy( [self.market_info], order_type="limit", order_price=Decimal("99"), cancel_order_wait_time=self.cancel_order_wait_time, is_buy=True, time_delay=self.time_delay, order_amount=Decimal("1.0"), logging_options=logging_options) self.limit_sell_strategy: SimpleTradeStrategy = SimpleTradeStrategy( [self.market_info], order_type="limit", order_price=Decimal("101"), cancel_order_wait_time=self.cancel_order_wait_time, is_buy=False, time_delay=self.time_delay, order_amount=Decimal("1.0"), logging_options=logging_options) self.market_buy_strategy: SimpleTradeStrategy = SimpleTradeStrategy( [self.market_info], order_type="market", order_price=None, cancel_order_wait_time=self.cancel_order_wait_time, is_buy=True, time_delay=self.time_delay, order_amount=Decimal("1.0"), logging_options=logging_options) self.market_sell_strategy: SimpleTradeStrategy = SimpleTradeStrategy( [self.market_info], order_type="market", order_price=None, cancel_order_wait_time=self.cancel_order_wait_time, is_buy=False, time_delay=self.time_delay, order_amount=Decimal("1.0"), logging_options=logging_options) self.logging_options = logging_options 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)
def setUp(self): self.clock: Clock = Clock(ClockMode.BACKTEST, 1.0, self.start_timestamp, self.end_timestamp) self.min_profitability = Decimal("0.005") self.maker_market: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.taker_market: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.maker_market.set_balanced_order_book(self.trading_pairs_maker[0], 1.0, 0.5, 1.5, 0.01, 10) self.taker_market.set_balanced_order_book(self.trading_pairs_taker[0], 1.0, 0.5, 1.5, 0.001, 4) self.maker_market.set_balance("COINALPHA", 5) self.maker_market.set_balance("WETH", 5) self.maker_market.set_balance("QETH", 5) self.taker_market.set_balance("COINALPHA", 5) self.taker_market.set_balance("ETH", 5) self.maker_market.set_quantization_param( QuantizationParams(self.trading_pairs_maker[0], 5, 5, 5, 5)) self.taker_market.set_quantization_param( QuantizationParams(self.trading_pairs_taker[0], 5, 5, 5, 5)) self.market_pair: CrossExchangeMarketPair = CrossExchangeMarketPair( MarketTradingPairTuple(self.maker_market, *self.trading_pairs_maker), MarketTradingPairTuple(self.taker_market, *self.trading_pairs_taker), ) self.config_map_raw = CrossExchangeMarketMakingConfigMap( maker_market=self.exchange_name_maker, taker_market=self.exchange_name_taker, maker_market_trading_pair=self.trading_pairs_maker[0], taker_market_trading_pair=self.trading_pairs_taker[0], min_profitability=Decimal(self.min_profitability), slippage_buffer=Decimal("0"), order_amount=Decimal("0"), # Default values folllow order_size_taker_volume_factor=Decimal("25"), order_size_taker_balance_factor=Decimal("99.5"), order_size_portfolio_ratio_limit=Decimal("30"), adjust_order_enabled=True, anti_hysteresis_duration=60.0, order_refresh_mode=ActiveOrderRefreshMode(), top_depth_tolerance=Decimal(0), conversion_rate_mode=TakerToMakerConversionRateMode(), ) self.config_map_raw.conversion_rate_mode.taker_to_maker_base_conversion_rate = Decimal( "1.0") self.config_map_raw.conversion_rate_mode.taker_to_maker_quote_conversion_rate = Decimal( "1.0") self.config_map = ClientConfigAdapter(self.config_map_raw) config_map_with_top_depth_tolerance_raw = deepcopy(self.config_map_raw) config_map_with_top_depth_tolerance_raw.top_depth_tolerance = Decimal( "1") config_map_with_top_depth_tolerance = ClientConfigAdapter( config_map_with_top_depth_tolerance_raw) logging_options: int = ( CrossExchangeMarketMakingStrategy.OPTION_LOG_ALL & (~CrossExchangeMarketMakingStrategy.OPTION_LOG_NULL_ORDER_SIZE)) self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy( ) self.strategy.init_params( config_map=self.config_map, market_pairs=[self.market_pair], logging_options=logging_options, ) self.strategy_with_top_depth_tolerance: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy( ) self.strategy_with_top_depth_tolerance.init_params( config_map=config_map_with_top_depth_tolerance, market_pairs=[self.market_pair], logging_options=logging_options, ) self.logging_options = logging_options self.clock.add_iterator(self.maker_market) self.clock.add_iterator(self.taker_market) self.clock.add_iterator(self.strategy) self.maker_order_fill_logger: EventLogger = EventLogger() self.taker_order_fill_logger: EventLogger = EventLogger() self.cancel_order_logger: EventLogger = EventLogger() self.maker_order_created_logger: EventLogger = EventLogger() self.taker_order_created_logger: EventLogger = EventLogger() self.maker_market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger) self.taker_market.add_listener(MarketEvent.OrderFilled, self.taker_order_fill_logger) self.maker_market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger) self.maker_market.add_listener(MarketEvent.BuyOrderCreated, self.maker_order_created_logger) self.maker_market.add_listener(MarketEvent.SellOrderCreated, self.maker_order_created_logger) self.taker_market.add_listener(MarketEvent.BuyOrderCreated, self.taker_order_created_logger) self.taker_market.add_listener(MarketEvent.SellOrderCreated, self.taker_order_created_logger)
def setUp(self): 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.time_delay = 15 self.cancel_order_wait_time = 45 self.market.set_balanced_order_book(self.maker_symbols[0], mid_price=self.mid_price, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.market.set_balance("COINALPHA", 500) self.market.set_balance("WETH", 500000000000) self.market.set_balance("QETH", 500) self.market.set_quantization_param( QuantizationParams(self.maker_symbols[0], 6, 6, 6, 6)) self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( *([self.market] + self.maker_symbols)) # Define strategies to test self.limit_buy_strategy: Dev5TwapTradeStrategy = Dev5TwapTradeStrategy( [self.market_info], order_type="limit", order_price=Decimal("99"), cancel_order_wait_time=self.cancel_order_wait_time, is_buy=True, time_delay=self.time_delay, is_vwap=True, percent_slippage=50.0, order_percent_of_volume=0.5, order_amount=Decimal("100.0")) self.limit_sell_strategy: Dev5TwapTradeStrategy = Dev5TwapTradeStrategy( [self.market_info], order_type="limit", order_price=Decimal("101"), cancel_order_wait_time=self.cancel_order_wait_time, is_buy=False, time_delay=self.time_delay, is_vwap=True, percent_slippage=50.0, order_percent_of_volume=0.5, order_amount=Decimal("100.0")) self.market_buy_strategy: Dev5TwapTradeStrategy = Dev5TwapTradeStrategy( [self.market_info], order_type="market", order_price=None, cancel_order_wait_time=self.cancel_order_wait_time, is_buy=True, time_delay=self.time_delay, is_vwap=True, percent_slippage=50.0, order_percent_of_volume=0.5, order_amount=Decimal("100.0")) self.market_sell_strategy: Dev5TwapTradeStrategy = Dev5TwapTradeStrategy( [self.market_info], order_type="market", order_price=None, cancel_order_wait_time=self.cancel_order_wait_time, is_buy=False, time_delay=self.time_delay, is_vwap=True, percent_slippage=50.0, order_percent_of_volume=0.5, order_amount=Decimal("100.0")) 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)
def setUp(self): self.log_records = [] self.order_fill_logger: EventLogger = EventLogger() self.cancel_order_logger: EventLogger = EventLogger() self.clock: Clock = Clock(ClockMode.BACKTEST, 1, self.start_timestamp, self.end_timestamp) self.spot_connector: MockPaperExchange = MockPaperExchange( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.spot_connector.set_balanced_order_book(trading_pair=trading_pair, mid_price=100, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.spot_connector.set_balance(base_asset, 5) self.spot_connector.set_balance(quote_asset, 500) self.spot_connector.set_quantization_param( QuantizationParams(trading_pair, 6, 6, 6, 6)) self.spot_market_info = MarketTradingPairTuple(self.spot_connector, trading_pair, base_asset, quote_asset) self.perp_connector: MockPerpConnector = MockPerpConnector( client_config_map=ClientConfigAdapter(ClientConfigMap())) self.perp_connector.set_leverage(trading_pair, 5) self.perp_connector.set_balanced_order_book(trading_pair=trading_pair, mid_price=110, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.perp_connector.set_balance(base_asset, 5) self.perp_connector.set_balance(quote_asset, 500) self.perp_connector.set_quantization_param( QuantizationParams(trading_pair, 6, 6, 6, 6)) self.perp_market_info = MarketTradingPairTuple(self.perp_connector, trading_pair, base_asset, quote_asset) self.clock.add_iterator(self.spot_connector) self.clock.add_iterator(self.perp_connector) self.spot_connector.add_listener(MarketEvent.OrderFilled, self.order_fill_logger) self.spot_connector.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger) self.perp_connector.add_listener(MarketEvent.OrderFilled, self.order_fill_logger) self.perp_connector.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger) self.strategy = SpotPerpetualArbitrageStrategy() self.strategy.init_params( spot_market_info=self.spot_market_info, perp_market_info=self.perp_market_info, order_amount=Decimal("1"), perp_leverage=5, min_opening_arbitrage_pct=Decimal("0.05"), min_closing_arbitrage_pct=Decimal("0.01"), next_arbitrage_opening_delay=10, ) self.strategy.logger().setLevel(1) self.strategy.logger().addHandler(self) self._last_tick = 0