def test_show_ticker(self, notify_mock): global_config_map["tables_format"].value = "psql" captures = [] notify_mock.side_effect = lambda s: captures.append(s) exchange_name = "paper" exchange = MockPaperExchange() self.app.markets[exchange_name] = exchange trading_pair = "BTC-USDT" exchange.set_balanced_order_book( trading_pair, mid_price=10, min_price=8.5, max_price=11.5, price_step_size=1, volume_step_size=1, ) self.async_run_with_timeout( self.app.show_ticker(exchange=exchange_name, live=False)) self.assertEqual(1, len(captures)) df_str_expected = ( " Market: MockPaperExchange" "\n+------------+------------+-------------+--------------+" "\n| Best Bid | Best Ask | Mid Price | Last Trade |" "\n|------------+------------+-------------+--------------|" "\n| 9.5 | 10.5 | 10 | nan |" "\n+------------+------------+-------------+--------------+") self.assertEqual(df_str_expected, captures[0])
def test_adjust_candidate_insufficient_funds_for_flat_fees_and_percent_fees(self): trade_fee_schema = TradeFeeSchema( maker_percent_fee_decimal=Decimal("0.1"), maker_fixed_fees=[TokenAmount(self.quote_asset, Decimal("1"))], ) exchange = MockPaperExchange(trade_fee_schema) budget_checker: BudgetChecker = exchange.budget_checker exchange.set_balance(self.quote_asset, Decimal("12")) 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 = budget_checker.adjust_candidate(order_candidate, all_or_none=False) self.assertEqual(Decimal("5"), adjusted_candidate.amount) self.assertEqual(self.quote_asset, adjusted_candidate.order_collateral.token) self.assertEqual(Decimal("10"), adjusted_candidate.order_collateral.amount) self.assertEqual(self.quote_asset, adjusted_candidate.percent_fee_collateral.token) self.assertEqual(Decimal("1"), adjusted_candidate.percent_fee_collateral.amount) self.assertEqual(self.quote_asset, adjusted_candidate.percent_fee_value.token) self.assertEqual(Decimal("1"), adjusted_candidate.percent_fee_value.amount) self.assertEqual(1, len(adjusted_candidate.fixed_fee_collaterals)) fixed_fee_collateral = adjusted_candidate.fixed_fee_collaterals[0] self.assertEqual(self.quote_asset, fixed_fee_collateral.token) self.assertEqual(Decimal("1"), fixed_fee_collateral.amount) self.assertEqual(self.base_asset, adjusted_candidate.potential_returns.token) self.assertEqual(Decimal("5"), adjusted_candidate.potential_returns.amount)
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 emit_order_created_event(market: MockPaperExchange, order: LimitOrder): event_cls = BuyOrderCreatedEvent if order.is_buy else SellOrderCreatedEvent event_tag = MarketEvent.BuyOrderCreated if order.is_buy else MarketEvent.SellOrderCreated market.trigger_event( event_tag, message=event_cls(order.creation_timestamp, OrderType.LIMIT, order.trading_pair, order.quantity, order.price, order.client_order_id, order.creation_timestamp * 1e-6))
def setUp(self) -> None: super().setUp() self.base_asset = "COINALPHA" self.quote_asset = "HBOT" self.trading_pair = f"{self.base_asset}-{self.quote_asset}" trade_fee_schema = TradeFeeSchema( maker_percent_fee_decimal=Decimal("0.01"), taker_percent_fee_decimal=Decimal("0.02") ) self.exchange = MockPaperExchange(trade_fee_schema) self.budget_checker: BudgetChecker = self.exchange.budget_checker
def __init__( self, trade_fee_schema: Optional[TradeFeeSchema] = None, buy_collateral_token: Optional[str] = None, sell_collateral_token: Optional[str] = None, ): MockPaperExchange.__init__(self, trade_fee_schema) PerpetualTrading.__init__(self) self._budget_checker = PerpetualBudgetChecker(exchange=self) self._funding_payment_span = [0, 10] self._buy_collateral_token = buy_collateral_token self._sell_collateral_token = sell_collateral_token
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 test_populate_collateral_fields_percent_fees_in_third_token(self): pfc_token = "PFC" trade_fee_schema = TradeFeeSchema( percent_fee_token=pfc_token, maker_percent_fee_decimal=Decimal("0.01"), taker_percent_fee_decimal=Decimal("0.01"), ) exchange = MockPaperExchange(trade_fee_schema) pfc_quote_pair = combine_to_hb_trading_pair(self.quote_asset, pfc_token) exchange.set_balanced_order_book( # the quote to pfc price will be 1:2 trading_pair=pfc_quote_pair, mid_price=1.5, min_price=1, max_price=2, price_step_size=1, volume_step_size=1, ) budget_checker: BudgetChecker = exchange.budget_checker 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"), ) populated_candidate = budget_checker.populate_collateral_entries( order_candidate) self.assertEqual(self.quote_asset, populated_candidate.order_collateral.token) self.assertEqual(Decimal("20"), populated_candidate.order_collateral.amount) self.assertEqual(pfc_token, populated_candidate.percent_fee_collateral.token) self.assertEqual(Decimal("0.4"), populated_candidate.percent_fee_collateral.amount) self.assertEqual(pfc_token, populated_candidate.percent_fee_value.token) self.assertEqual(Decimal("0.4"), populated_candidate.percent_fee_value.amount) self.assertEqual(0, len(populated_candidate.fixed_fee_collaterals)) self.assertEqual(self.base_asset, populated_candidate.potential_returns.token) self.assertEqual(Decimal("10"), populated_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_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 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: MockPaperExchange = MockPaperExchange() 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 setUp(self): self.market: MockPaperExchange = MockPaperExchange() self.market_info: MarketTradingPairTuple = MarketTradingPairTuple( self.market, self.trading_pair, *self.trading_pair.split("-")) self.strategy: StrategyPyBase = MockPyStrategy() self.strategy.add_markets([self.market])
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 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_populate_collateral_fields_buy_order_percent_fee_from_returns(self): trade_fee_schema = TradeFeeSchema( maker_percent_fee_decimal=Decimal("0.01"), taker_percent_fee_decimal=Decimal("0.01"), buy_percent_fee_deducted_from_returns=True, ) exchange = MockPaperExchange(trade_fee_schema) budget_checker: BudgetChecker = exchange.budget_checker 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"), ) populated_candidate = budget_checker.populate_collateral_entries(order_candidate) self.assertEqual(self.quote_asset, populated_candidate.order_collateral.token) self.assertEqual(Decimal("20"), populated_candidate.order_collateral.amount) self.assertIsNone(populated_candidate.percent_fee_collateral) self.assertEqual(self.base_asset, populated_candidate.percent_fee_value.token) self.assertEqual(Decimal("0.1"), populated_candidate.percent_fee_value.amount) self.assertEqual(0, len(populated_candidate.fixed_fee_collaterals)) self.assertEqual(self.base_asset, populated_candidate.potential_returns.token) self.assertEqual(Decimal("9.90"), populated_candidate.potential_returns.amount)
def setUpClass(cls): cls.ev_loop = asyncio.get_event_loop() cls.trading_pair = "COINALPHA-HBOT" cls.limit_orders: List[LimitOrder] = [ LimitOrder(client_order_id=f"LIMIT//-{i}-{int(time.time()*1e6)}", trading_pair=cls.trading_pair, is_buy=True if i % 2 == 0 else False, base_currency=cls.trading_pair.split("-")[0], quote_currency=cls.trading_pair.split("-")[1], price=Decimal(f"{100 - i}") if i % 2 == 0 else Decimal(f"{100 + i}"), quantity=Decimal(f"{10 * (i + 1)}"), creation_timestamp=int(time.time() * 1e6)) for i in range(20) ] cls.market_orders: List[MarketOrder] = [ MarketOrder(order_id=f"MARKET//-{i}-{int(time.time()*1e3)}", trading_pair=cls.trading_pair, is_buy=True if i % 2 == 0 else False, base_asset=cls.trading_pair.split("-")[0], quote_asset=cls.trading_pair.split("-")[1], amount=float(f"{10 * (i + 1)}"), timestamp=time.time()) for i in range(20) ] cls.market: MockPaperExchange = MockPaperExchange() cls.market_info: MarketTradingPairTuple = MarketTradingPairTuple( cls.market, cls.trading_pair, *cls.trading_pair.split("-"))
def test_populate_collateral_fields_fixed_fees_in_quote_token(self): trade_fee_schema = TradeFeeSchema( maker_fixed_fees=[TokenAmount(self.quote_asset, Decimal("1"))], taker_fixed_fees=[TokenAmount(self.base_asset, Decimal("2"))], ) exchange = MockPaperExchange(trade_fee_schema) budget_checker: BudgetChecker = exchange.budget_checker 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"), ) populated_candidate = budget_checker.populate_collateral_entries(order_candidate) self.assertEqual(self.quote_asset, populated_candidate.order_collateral.token) self.assertEqual(Decimal("20"), populated_candidate.order_collateral.amount) self.assertIsNone(populated_candidate.percent_fee_collateral) self.assertIsNone(populated_candidate.percent_fee_value) self.assertEqual(1, len(populated_candidate.fixed_fee_collaterals)) fixed_fee_collateral = populated_candidate.fixed_fee_collaterals[0] self.assertEqual(self.quote_asset, fixed_fee_collateral.token) self.assertEqual(Decimal("1"), fixed_fee_collateral.amount) self.assertEqual(self.base_asset, populated_candidate.potential_returns.token) self.assertEqual(Decimal("10"), populated_candidate.potential_returns.amount)
def test_adjust_candidate_insufficient_funds_for_flat_fees_and_percent_fees_third_token( self): fc_token = "PFC" trade_fee_schema = TradeFeeSchema( percent_fee_token=fc_token, maker_percent_fee_decimal=Decimal("0.01"), taker_percent_fee_decimal=Decimal("0.01"), maker_fixed_fees=[TokenAmount(fc_token, Decimal("1"))]) exchange = MockPaperExchange(trade_fee_schema) pfc_quote_pair = combine_to_hb_trading_pair(self.quote_asset, fc_token) exchange.set_balanced_order_book( # the quote to pfc price will be 1:2 trading_pair=pfc_quote_pair, mid_price=1.5, min_price=1, max_price=2, price_step_size=1, volume_step_size=1, ) budget_checker: BudgetChecker = exchange.budget_checker exchange.set_balance(self.quote_asset, Decimal("20")) exchange.set_balance( fc_token, Decimal("1.2") ) # 0.2 less than required; will result in 50% order reduction 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 = budget_checker.adjust_candidate(order_candidate, all_or_none=False) self.assertEqual(Decimal("5"), adjusted_candidate.amount) self.assertEqual(self.quote_asset, adjusted_candidate.order_collateral.token) self.assertEqual(Decimal("10"), adjusted_candidate.order_collateral.amount) self.assertEqual(fc_token, adjusted_candidate.percent_fee_collateral.token) self.assertEqual(Decimal("0.2"), adjusted_candidate.percent_fee_collateral.amount) self.assertEqual(fc_token, adjusted_candidate.percent_fee_value.token) self.assertEqual(Decimal("0.2"), adjusted_candidate.percent_fee_value.amount) self.assertEqual(1, len(adjusted_candidate.fixed_fee_collaterals)) fixed_fee_collateral = adjusted_candidate.fixed_fee_collaterals[0] self.assertEqual(fc_token, fixed_fee_collateral.token) self.assertEqual(Decimal("1"), fixed_fee_collateral.amount) self.assertEqual(self.base_asset, adjusted_candidate.potential_returns.token) self.assertEqual(Decimal("5"), adjusted_candidate.potential_returns.amount)
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() self.market_2: MockPaperExchange = MockPaperExchange() 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 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 setUpClass(cls): cls.ev_loop = asyncio.get_event_loop() cls.clock: Clock = Clock(ClockMode.BACKTEST, cls.tick_size, cls.start_timestamp, cls.end_timestamp) cls.market: MockPaperExchange = MockPaperExchange() cls.strategy: GetOrderBookStrategy = GetOrderBookStrategy( exchange=cls.market, trading_pair=cls.trading_pair, )
def test_add_markets(self): self.assertEqual(1, len(self.strategy.active_markets)) new_market: MockPaperExchange = MockPaperExchange() self.strategy.add_markets([new_market]) self.assertEqual(2, len(self.strategy.active_markets))
def setUpClass(cls): cls.ev_loop = asyncio.get_event_loop() cls.clock: Clock = Clock(ClockMode.BACKTEST, cls.tick_size, cls.start_timestamp, cls.end_timestamp) cls.market: MockPaperExchange = MockPaperExchange() cls.strategy: HelloWorldStrategy = HelloWorldStrategy( exchange=cls.market, trading_pair=cls.trading_pair, asset=cls.quote_asset, )
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 test_adjust_candidate_insufficient_funds_for_flat_fees_third_token(self): fee_asset = "FEE" trade_fee_schema = TradeFeeSchema( maker_fixed_fees=[TokenAmount(fee_asset, Decimal("11"))], ) exchange = MockPaperExchange(trade_fee_schema) budget_checker: BudgetChecker = exchange.budget_checker exchange.set_balance(self.quote_asset, Decimal("100")) exchange.set_balance(fee_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 = budget_checker.adjust_candidate(order_candidate, all_or_none=False) self.assertTrue(adjusted_candidate.is_zero_order)
def simulate_limit_order_fill(market: MockPaperExchange, limit_order: LimitOrder): quote_currency_traded: Decimal = limit_order.price * limit_order.quantity base_currency_traded: Decimal = limit_order.quantity quote_currency: str = limit_order.quote_currency base_currency: str = limit_order.base_currency if limit_order.is_buy: market.set_balance( quote_currency, market.get_balance(quote_currency) - quote_currency_traded) market.set_balance( base_currency, market.get_balance(base_currency) + base_currency_traded) else: market.set_balance( quote_currency, market.get_balance(quote_currency) + quote_currency_traded) market.set_balance( base_currency, market.get_balance(base_currency) - base_currency_traded) market.trigger_event( MarketEvent.OrderFilled, OrderFilledEvent( market.current_timestamp, limit_order.client_order_id, limit_order.trading_pair, TradeType.BUY if limit_order.is_buy else TradeType.SELL, OrderType.LIMIT, limit_order.price, limit_order.quantity, AddedToCostTradeFee(Decimal("0")))) event_type = MarketEvent.BuyOrderCompleted if limit_order.is_buy else MarketEvent.SellOrderCompleted event_class = BuyOrderCompletedEvent if limit_order.is_buy else SellOrderCompletedEvent market.trigger_event( event_type, event_class(market.current_timestamp, limit_order.client_order_id, base_currency, quote_currency, base_currency_traded, quote_currency_traded, OrderType.LIMIT))
def simulate_limit_order_fill(market: MockPaperExchange, limit_order: LimitOrder, timestamp: float = 0): quote_currency_traded: Decimal = limit_order.price * limit_order.quantity base_currency_traded: Decimal = limit_order.quantity quote_currency: str = limit_order.quote_currency base_currency: str = limit_order.base_currency trade_event: OrderBookTradeEvent = OrderBookTradeEvent( trading_pair=limit_order.trading_pair, timestamp=timestamp, type=TradeType.BUY if limit_order.is_buy else TradeType.SELL, price=limit_order.price, amount=limit_order.quantity) market.get_order_book( limit_order.trading_pair).apply_trade(trade_event) if limit_order.is_buy: market.set_balance( quote_currency, market.get_balance(quote_currency) - quote_currency_traded) market.set_balance( base_currency, market.get_balance(base_currency) + base_currency_traded) market.trigger_event( MarketEvent.OrderFilled, OrderFilledEvent(market.current_timestamp, limit_order.client_order_id, limit_order.trading_pair, TradeType.BUY, OrderType.LIMIT, limit_order.price, limit_order.quantity, AddedToCostTradeFee(Decimal(0.0)))) market.trigger_event( MarketEvent.BuyOrderCompleted, BuyOrderCompletedEvent(market.current_timestamp, limit_order.client_order_id, base_currency, quote_currency, quote_currency, base_currency_traded, quote_currency_traded, Decimal(0.0), OrderType.LIMIT)) else: market.set_balance( quote_currency, market.get_balance(quote_currency) + quote_currency_traded) market.set_balance( base_currency, market.get_balance(base_currency) - base_currency_traded) market.trigger_event( MarketEvent.OrderFilled, OrderFilledEvent(market.current_timestamp, limit_order.client_order_id, limit_order.trading_pair, TradeType.SELL, OrderType.LIMIT, limit_order.price, limit_order.quantity, AddedToCostTradeFee(Decimal(0.0)))) market.trigger_event( MarketEvent.SellOrderCompleted, SellOrderCompletedEvent(market.current_timestamp, limit_order.client_order_id, base_currency, quote_currency, quote_currency, base_currency_traded, quote_currency_traded, Decimal(0.0), OrderType.LIMIT))
def simulate_limit_order_fill(market: MockPaperExchange, limit_order: LimitOrder, timestamp: float): quote_currency_traded: Decimal = limit_order.price * limit_order.quantity base_currency_traded: Decimal = limit_order.quantity quote_currency: str = limit_order.quote_currency base_currency: str = limit_order.base_currency config: MarketConfig = market.config trade_event = OrderBookTradeEvent( trading_pair=limit_order.trading_pair, timestamp=timestamp, type=TradeType.BUY if limit_order.is_buy else TradeType.SELL, price=limit_order.price, amount=limit_order.quantity, ) if limit_order.is_buy: market.set_balance( quote_currency, market.get_balance(quote_currency) - quote_currency_traded) market.set_balance( base_currency, market.get_balance(base_currency) + base_currency_traded) market.trigger_event( MarketEvent.OrderFilled, OrderFilledEvent(market.current_timestamp, limit_order.client_order_id, limit_order.trading_pair, TradeType.BUY, OrderType.LIMIT, limit_order.price, limit_order.quantity, TradeFee(Decimal(0.0)))) market.trigger_event( MarketEvent.BuyOrderCompleted, BuyOrderCompletedEvent( market.current_timestamp, limit_order.client_order_id, base_currency, quote_currency, base_currency if config.buy_fees_asset is AssetType.BASE_CURRENCY else quote_currency, base_currency_traded, quote_currency_traded, Decimal(0.0), OrderType.LIMIT)) market.order_books[limit_order.trading_pair].apply_trade( trade_event) else: market.set_balance( quote_currency, market.get_balance(quote_currency) + quote_currency_traded) market.set_balance( base_currency, market.get_balance(base_currency) - base_currency_traded) market.trigger_event( MarketEvent.OrderFilled, OrderFilledEvent(market.current_timestamp, limit_order.client_order_id, limit_order.trading_pair, TradeType.SELL, OrderType.LIMIT, limit_order.price, limit_order.quantity, TradeFee(Decimal(0.0)))) market.trigger_event( MarketEvent.SellOrderCompleted, SellOrderCompletedEvent( market.current_timestamp, limit_order.client_order_id, base_currency, quote_currency, base_currency if config.sell_fees_asset is AssetType.BASE_CURRENCY else quote_currency, base_currency_traded, quote_currency_traded, Decimal(0.0), OrderType.LIMIT)) market.order_books[limit_order.trading_pair].apply_trade( trade_event)
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() 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)