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: BacktestMarket = BacktestMarket() self.taker_market: BacktestMarket = BacktestMarket() self.maker_data: MockOrderBookLoader = MockOrderBookLoader( *self.maker_trading_pairs) self.taker_data: MockOrderBookLoader = MockOrderBookLoader( *self.taker_trading_pairs) self.maker_data.set_balanced_order_book(1.0, 0.5, 1.5, 0.01, 10) self.taker_data.set_balanced_order_book(1.0, 0.5, 1.5, 0.001, 4) self.maker_market.add_data(self.maker_data) self.taker_market.add_data(self.taker_data) 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.market_pair], order_size_portfolio_ratio_limit=Decimal("0.3"), min_profitability=Decimal(self.min_profitbality), logging_options=logging_options, ) self.strategy_with_top_depth_tolerance: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy( [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) 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: BacktestMarket = BacktestMarket() self.maker_data: MockOrderBookLoader = MockOrderBookLoader( trading_pair=self.trading_pair, base_currency=self.base_asset, quote_currency=self.quote_asset, ) self.mid_price = 100 self.time_delay = 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", 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_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)
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.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.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.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.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: Clock = Clock(ClockMode.BACKTEST, 60.0, self.start_timestamp, self.end_timestamp) self.clock_tick_size = 60 self.maker_market: BacktestMarket = BacktestMarket() self.maker_data: MockOrderBookLoader = MockOrderBookLoader(*self.maker_symbols) self.mid_price = 100 self.bid_threshold = 0.01 self.ask_threshold = 0.01 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.filter_delegate = PassThroughFilterDelegate() self.constant_pricing_delegate = ConstantSpreadPricingDelegate(self.bid_threshold, self.ask_threshold) self.constant_sizing_delegate = ConstantSizeSizingDelegate(1.0) self.equal_strategy_sizing_delegate = StaggeredMultipleSizeSizingDelegate( order_start_size=1.0, order_step_size=0, number_of_orders=5 ) self.staggered_strategy_sizing_delegate = StaggeredMultipleSizeSizingDelegate( order_start_size=1.0, order_step_size=0.5, number_of_orders=5 ) self.multiple_order_strategy_pricing_delegate = ConstantMultipleSpreadPricingDelegate( bid_spread=self.bid_threshold, ask_spread=self.ask_threshold, order_interval_size=0.01, number_of_orders=5 ) self.maker_market.add_data(self.maker_data) self.maker_market.set_balance("COINALPHA", 500) self.maker_market.set_balance("WETH", 5000) self.maker_market.set_balance("QETH", 500) self.maker_market.set_quantization_param( QuantizationParams( self.maker_symbols[0], 6, 6, 6, 6 ) ) self.market_info: MarketSymbolPair = MarketSymbolPair( *( [self.maker_market] + self.maker_symbols ) ) logging_options: int = (PureMarketMakingStrategyV2.OPTION_LOG_ALL & (~PureMarketMakingStrategyV2.OPTION_LOG_NULL_ORDER_SIZE)) self.strategy: PureMarketMakingStrategyV2 = PureMarketMakingStrategyV2( [self.market_info], filter_delegate=self.filter_delegate, sizing_delegate=self.constant_sizing_delegate, pricing_delegate=self.constant_pricing_delegate, cancel_order_wait_time=45, logging_options=logging_options ) self.multi_order_equal_strategy: PureMarketMakingStrategyV2 = PureMarketMakingStrategyV2( [self.market_info], filter_delegate=self.filter_delegate, pricing_delegate=self.multiple_order_strategy_pricing_delegate, sizing_delegate=self.equal_strategy_sizing_delegate, cancel_order_wait_time=45, logging_options=logging_options ) self.multi_order_staggered_strategy: PureMarketMakingStrategyV2 = PureMarketMakingStrategyV2( [self.market_info], filter_delegate=self.filter_delegate, pricing_delegate=self.multiple_order_strategy_pricing_delegate, sizing_delegate=self.staggered_strategy_sizing_delegate, cancel_order_wait_time=45, logging_options=logging_options ) self.logging_options = logging_options self.clock.add_iterator(self.maker_market) self.clock.add_iterator(self.strategy) self.maker_order_fill_logger: EventLogger = EventLogger() self.cancel_order_logger: EventLogger = EventLogger() self.maker_market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger) self.maker_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: BacktestMarket = BacktestMarket() self.maker_data: MockOrderBookLoader = MockOrderBookLoader(*self.maker_symbols) self.mid_price = 100 self.time_delay = 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", 5000) 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 ) ) 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=99, cancel_order_wait_time=self.cancel_order_wait_time, is_buy=True, time_delay=self.time_delay, order_amount=1.0, logging_options=logging_options ) self.limit_sell_strategy: SimpleTradeStrategy = SimpleTradeStrategy( [self.market_info], order_type="limit", order_price=101, cancel_order_wait_time=self.cancel_order_wait_time, is_buy=False, time_delay=self.time_delay, order_amount=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=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=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, 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.time_delay = 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", 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)) # Define strategies to test self.limit_buy_strategy: Dev4TwapTradeStrategy = Dev4TwapTradeStrategy( [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, num_individual_orders=2, order_amount=Decimal("2.0")) self.limit_sell_strategy: Dev4TwapTradeStrategy = Dev4TwapTradeStrategy( [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, num_individual_orders=3, order_amount=Decimal("5.0")) self.market_buy_strategy: Dev4TwapTradeStrategy = Dev4TwapTradeStrategy( [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, num_individual_orders=4, order_amount=Decimal("1.0")) self.market_sell_strategy: Dev4TwapTradeStrategy = Dev4TwapTradeStrategy( [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, num_individual_orders=4, order_amount=Decimal("1.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.clock_tick_size = 1 self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp) self.maker_market: BacktestMarket = BacktestMarket() self.maker_data: MockOrderBookLoader = MockOrderBookLoader( *self.maker_trading_pairs) self.mid_price = 100 self.bid_spread = 0.01 self.ask_spread = 0.01 self.order_refresh_time = 30 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.constant_pricing_delegate = ConstantSpreadPricingDelegate( Decimal(self.bid_spread), Decimal(self.ask_spread)) self.constant_sizing_delegate = ConstantSizeSizingDelegate( Decimal("1.0")) self.filter_delegate = PassThroughFilterDelegate() self.maker_market.add_data(self.maker_data) self.maker_market.set_balance("COINALPHA", 500) self.maker_market.set_balance("WETH", 5000) self.maker_market.set_balance("QETH", 500) self.maker_market.set_quantization_param( QuantizationParams(self.maker_trading_pairs[0], 6, 6, 6, 6)) self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( *([self.maker_market] + self.maker_trading_pairs)) logging_options: int = ( PureMarketMakingStrategyV2.OPTION_LOG_ALL & (~PureMarketMakingStrategyV2.OPTION_LOG_NULL_ORDER_SIZE)) self.one_level_strategy: PureMarketMakingStrategyV2 = PureMarketMakingStrategyV2( [self.market_info], filter_delegate=self.filter_delegate, pricing_delegate=self.constant_pricing_delegate, sizing_delegate=self.constant_sizing_delegate, order_refresh_time=4, filled_order_delay=8, hanging_orders_enabled=True, logging_options=logging_options, hanging_orders_cancel_pct=0.05, order_refresh_tolerance_pct=0) self.multiple_order_pricing_delegate = ConstantMultipleSpreadPricingDelegate( bid_spread=Decimal(self.bid_spread), ask_spread=Decimal(self.ask_spread), order_level_spread=Decimal("0.01"), order_levels=Decimal("5")) self.equal_sizing_delegate = StaggeredMultipleSizeSizingDelegate( order_start_size=Decimal("1.0"), order_step_size=Decimal("0"), order_levels=Decimal("5")) self.multi_levels_strategy: PureMarketMakingStrategyV2 = PureMarketMakingStrategyV2( [self.market_info], filter_delegate=self.filter_delegate, pricing_delegate=self.multiple_order_pricing_delegate, sizing_delegate=self.equal_sizing_delegate, order_refresh_time=4, filled_order_delay=8, hanging_orders_enabled=True, logging_options=logging_options, hanging_orders_cancel_pct=0.1, order_refresh_tolerance_pct=0) self.hanging_order_multiple_strategy: PureMarketMakingStrategyV2 = PureMarketMakingStrategyV2( [self.market_info], filter_delegate=self.filter_delegate, pricing_delegate=self.multiple_order_pricing_delegate, sizing_delegate=self.equal_sizing_delegate, order_refresh_time=4, filled_order_delay=8, hanging_orders_enabled=True, logging_options=logging_options, order_refresh_tolerance_pct=0) self.logging_options = logging_options self.clock.add_iterator(self.maker_market) self.maker_order_fill_logger: EventLogger = EventLogger() self.cancel_order_logger: EventLogger = EventLogger() self.maker_market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger) self.maker_market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
class CeloArbUnitTest(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 = "CGLD-CUSD" base_asset = trading_pair.split("-")[0] quote_asset = trading_pair.split("-")[1] @classmethod def setUpClass(cls): if MOCK_CELO_COMMANDS: cls._patcher = mock.patch( "hummingbot.market.celo.celo_cli.command") cls._mock = cls._patcher.start() cls._mock.side_effect = mock_command @classmethod def tearDownClass(cls) -> None: if MOCK_CELO_COMMANDS: cls._patcher.stop() def setUp(self): self.maxDiff = None self.clock: Clock = Clock(ClockMode.BACKTEST, 1.0, self.start_timestamp, self.end_timestamp) self.market: BacktestMarket = BacktestMarket() self.market_data = MockOrderBookLoader(self.trading_pair, self.base_asset, self.quote_asset) self.market_data.set_balanced_order_book(10, 5, 15, 0.1, 1) self.market.add_data(self.market_data) 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.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_get_trade_profits(self): """ Order book bids price amount update_id 0 9.95 1 1 1 9.85 2 1 2 9.75 3 1 3 9.65 4 1 4 9.55 5 1 Order book asks price amount update_id 0 10.05 1 1 1 10.15 2 1 2 10.25 3 1 3 10.35 4 1 4 10.45 5 1 """ order_amount = 1 trade_profits = get_trade_profits(self.market, self.trading_pair, order_amount) # Sell price at CTP (counter party) 1 CGLD is 9.95 CUSD # At Celo 9.95 CUSD will get you 1 CGLD, so the profit is 0% celo_buy_trade = trade_profits[0] self.assertTrue(celo_buy_trade.is_celo_buy) # Can sell at CTP at 9.95 self.assertEqual(celo_buy_trade.ctp_price, Decimal("9.95")) # Can buy at celo for 9.95 self.assertEqual(celo_buy_trade.celo_price, Decimal("9.95")) # profit is 0 self.assertEqual(celo_buy_trade.profit, Decimal("0")) # Buy price at CTP (counter party) 1 CGLD at 10.05 USD # at Celo 1 CGLD will get you 10.5 USD, so the profit is (10.5 - 10.05)/10.05 = 0.0447761194 celo_sell_trade = trade_profits[1] self.assertFalse(celo_sell_trade.is_celo_buy) # Can buy price at CTP for 10.05 self.assertEqual(celo_sell_trade.ctp_price, Decimal("10.05")) # vwap price is 10.05 self.assertEqual(celo_sell_trade.ctp_vwap, Decimal("10.05")) # Can sell price celo at 10.w self.assertEqual(celo_sell_trade.celo_price, Decimal("10.5")) self.assertAlmostEqual(celo_sell_trade.profit, Decimal("0.0447761194")) order_amount = 5 trade_profits = get_trade_profits(self.market, self.trading_pair, order_amount) celo_buy_trade = trade_profits[0] self.assertTrue(celo_buy_trade.is_celo_buy) # VWAP Sell price (5 CGLD) at CTP is ((9.95 * 1) + (9.85 * 2) + (9.75 * 2))/5 = 9.83 self.assertEqual(celo_buy_trade.ctp_vwap, Decimal("9.83")) self.assertEqual(celo_buy_trade.ctp_price, Decimal("9.75")) # for 9.83 * 5 USD, you can get 0.99 * 5 CGLD at Celo, so the price is 9.83/0.99 = 9.92929292929 self.assertAlmostEqual(celo_buy_trade.celo_price, Decimal("9.92929292929")) # profit is -0.00999999999 self.assertAlmostEqual(celo_buy_trade.profit, Decimal("-0.00999999999")) celo_sell_trade = trade_profits[1] self.assertFalse(celo_sell_trade.is_celo_buy) # VWAP Buy price (5 CGLD) at CTP is ((10.05 * 1) + (10.15 * 2) + (10.25 * 2))/5 = 10.17 self.assertEqual(celo_sell_trade.ctp_vwap, Decimal("10.17")) self.assertEqual(celo_sell_trade.ctp_price, Decimal("10.25")) # Can sell price celo at 10.1 each self.assertEqual(celo_sell_trade.celo_price, Decimal("10.1")) # profit = (10.1 - 10.17)/10.17 = -0.00688298918 self.assertAlmostEqual(celo_sell_trade.profit, Decimal("-0.00688298918")) def test_profitable_celo_sell_trade(self): order_amount = 1 self.strategy.order_amount = order_amount trade_profits = get_trade_profits(self.market, self.trading_pair, order_amount) celo_sell_trade = [t for t in trade_profits if not t.is_celo_buy][0] self.clock.backtest_til(self.start_timestamp + 1) ctp_active_orders = self.strategy.market_info_to_active_orders[ self.market_info] self.assertEqual(len(ctp_active_orders), 1) self.assertTrue(ctp_active_orders[0].is_buy) self.assertEqual(ctp_active_orders[0].price, celo_sell_trade.ctp_price) self.assertEqual(ctp_active_orders[0].quantity, order_amount) self.assertEqual(len(self.strategy.celo_orders), 1) self.assertFalse(self.strategy.celo_orders[0].is_buy) self.assertEqual(self.strategy.celo_orders[0].price, celo_sell_trade.celo_price) self.assertEqual(self.strategy.celo_orders[0].amount, order_amount) def test_profitable_celo_buy_trade(self): order_amount = 2 self.strategy.order_amount = order_amount trade_profits = get_trade_profits(self.market, self.trading_pair, order_amount) celo_buy_trade = [t for t in trade_profits if t.is_celo_buy][0] self.clock.backtest_til(self.start_timestamp + 1) ctp_active_orders = self.strategy.market_info_to_active_orders[ self.market_info] self.assertEqual(len(ctp_active_orders), 1) self.assertFalse(ctp_active_orders[0].is_buy) self.assertEqual(ctp_active_orders[0].price, celo_buy_trade.ctp_price) self.assertEqual(ctp_active_orders[0].quantity, order_amount) self.assertEqual(len(self.strategy.celo_orders), 1) self.assertTrue(self.strategy.celo_orders[0].is_buy) self.assertEqual(self.strategy.celo_orders[0].price, celo_buy_trade.celo_price) self.assertEqual(self.strategy.celo_orders[0].amount, order_amount) def test_profitable_but_insufficient_balance(self): order_amount = 2 trade_profits = get_trade_profits(self.market, self.trading_pair, order_amount) celo_buy_trade = [t for t in trade_profits if t.is_celo_buy][0] self.assertTrue( celo_buy_trade.profit > self.strategy.min_profitability) self.market.set_balance(self.base_asset, 1) self.market.set_balance(self.quote_asset, 1) self.strategy.order_amount = order_amount self.clock.backtest_til(self.start_timestamp + 1) self.assertEqual(len(self.strategy.market_info_to_active_orders), 0) self.assertEqual(len(self.strategy.celo_orders), 0) def test_no_profitable_trade(self): order_amount = 5 trade_profits = get_trade_profits(self.market, self.trading_pair, order_amount) profitables = [ t for t in trade_profits if t.profit >= self.strategy.min_profitability ] self.assertEqual(len(profitables), 0) self.strategy.order_amount = order_amount self.clock.backtest_til(self.start_timestamp + 1) self.assertEqual(len(self.strategy.market_info_to_active_orders), 0) self.assertEqual(len(self.strategy.celo_orders), 0)
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: BacktestMarket = BacktestMarket() self.spot_obook: MockOrderBookLoader = MockOrderBookLoader(trading_pair, base_asset, quote_asset) self.spot_obook.set_balanced_order_book(mid_price=100, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.spot_connector.add_data(self.spot_obook) 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() self.perp_connector.set_leverage(trading_pair, 5) self.perp_obook: MockOrderBookLoader = MockOrderBookLoader(trading_pair, base_asset, quote_asset) self.perp_obook.set_balanced_order_book(mid_price=110, min_price=1, max_price=200, price_step_size=1, volume_step_size=10) self.perp_connector.add_data(self.perp_obook) 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