def test_order_fills_after_cancellation(self): self.clock.backtest_til(self.start_timestamp + 5) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] self.assertEqual(Decimal("0.99501"), bid_order.price) self.assertEqual(Decimal("1.0049"), ask_order.price) self.assertEqual(Decimal("3.0"), bid_order.quantity) self.assertEqual(Decimal("3.0"), ask_order.quantity) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] self.maker_data.order_book.apply_diffs([OrderBookRow(0.996, 30, 2)], [OrderBookRow(1.004, 30, 2)], 2) self.clock.backtest_til(self.start_timestamp + 10) self.assertEqual(2, len(self.cancel_order_logger.event_log)) self.assertEqual(Decimal("0.99601"), self.strategy.active_bids[0][1].price) self.assertEqual(Decimal("1.0039"), self.strategy.active_asks[0][1].price) self.assertEqual(0, len(self.taker_order_fill_logger.event_log)) self.clock.backtest_til(self.start_timestamp + 20) self.simulate_limit_order_fill(self.maker_market, bid_order) self.simulate_limit_order_fill(self.maker_market, ask_order) self.clock.backtest_til(self.start_timestamp + 25) fill_events: List[OrderFilledEvent] = self.taker_order_fill_logger.event_log bid_hedges: List[OrderFilledEvent] = [evt for evt in fill_events if evt.trade_type is TradeType.SELL] ask_hedges: List[OrderFilledEvent] = [evt for evt in fill_events if evt.trade_type is TradeType.BUY] self.assertEqual(1, len(bid_hedges)) self.assertEqual(1, len(ask_hedges)) self.assertGreater( self.maker_market.get_balance(self.maker_symbols[2]) + self.taker_market.get_balance(self.taker_symbols[2]), 10 )
def simulate_order_book_widening(order_book: OrderBook, top_bid: float, top_ask: float): bid_diffs: List[OrderBookRow] = [] ask_diffs: List[OrderBookRow] = [] update_id: int = order_book.last_diff_uid + 1 for row in order_book.bid_entries(): if row.price > top_bid: bid_diffs.append(OrderBookRow(row.price, 0, update_id)) else: break for row in order_book.ask_entries(): if row.price < top_ask: ask_diffs.append(OrderBookRow(row.price, 0, update_id)) else: break order_book.apply_diffs(bid_diffs, ask_diffs, update_id)
def test_top_depth_tolerance(self): self.maker_data.order_book.apply_diffs([OrderBookRow(0.999, 0.1, 2), OrderBookRow(0.998, 0.1, 2)], [OrderBookRow(1.001, 0.1, 2), OrderBookRow(1.002, 0.1, 2)], 2) self.clock.backtest_til(self.start_timestamp + 5) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] self.assertEqual(Decimal("0.99501"), bid_order.price) self.assertEqual(Decimal("1.0049"), ask_order.price) self.assertEqual(Decimal("3.0"), bid_order.quantity) self.assertEqual(Decimal("3.0"), ask_order.quantity) self.maker_data.order_book.apply_diffs([OrderBookRow(0.996, 30, 3)], [], 3) self.clock.backtest_til(self.start_timestamp + 10) self.assertEqual(1, len(self.cancel_order_logger.event_log)) bid_order: LimitOrder = self.strategy.active_bids[0][1] self.assertEqual(Decimal("0.99601"), bid_order.price)
def test_market_became_narrower(self): self.clock.backtest_til(self.start_timestamp + 5) bid_order: LimitOrder = self.strategy.active_bids[0][1] ask_order: LimitOrder = self.strategy.active_asks[0][1] self.assertEqual(Decimal("0.99501"), bid_order.price) self.assertEqual(Decimal("1.0049"), ask_order.price) self.assertEqual(Decimal("3.0"), bid_order.quantity) self.assertEqual(Decimal("3.0"), ask_order.quantity) self.maker_data.order_book.apply_diffs([OrderBookRow(0.996, 30, 2)], [OrderBookRow(1.004, 30, 2)], 2) self.clock.backtest_til(self.start_timestamp + 10) self.assertEqual(2, len(self.cancel_order_logger.event_log)) self.assertEqual(1, len(self.strategy.active_bids)) self.assertEqual(1, len(self.strategy.active_asks)) bid_order = self.strategy.active_bids[0][1] ask_order = self.strategy.active_asks[0][1] self.assertEqual(Decimal("0.99601"), bid_order.price) self.assertEqual(Decimal("1.0039"), ask_order.price)
def test_market_changed_to_unprofitable(self): self.clock.backtest_til(self.start_timestamp + 5) self.assertEqual(1, len(self.strategy.active_bids)) self.assertEqual(1, len(self.strategy.active_asks)) self.assertEqual(0, len(self.cancel_order_logger.event_log)) self.maker_data.order_book.apply_diffs([], [OrderBookRow(1.0, 15, 2)], 2) self.clock.backtest_til(self.start_timestamp + 10) self.assertEqual(1, len(self.strategy.active_bids)) self.assertEqual(0, len(self.strategy.active_asks)) self.assertEqual(1, len(self.cancel_order_logger.event_log))
def bids(self) -> List[OrderBookRow]: return [ OrderBookRow(float(price), float(amount), self.update_id) for price, amount, *trash in self.content["bids"] ]
def test_ask_side_profitable(self): self.maker_data.order_book.apply_diffs([OrderBookRow(1.0, 5, 2)], [], 2) self.clock.backtest_til(self.start_timestamp + 5) self.assertEqual(0, len(self.strategy.active_bids)) self.assertEqual(1, len(self.strategy.active_asks))
def test_buy_diff_message(self): order_books: Dict[str, OrderBook] = self.order_book_tracker.order_books test_order_book: OrderBook = order_books[test_symbol] test_active_order_tracker = self.order_book_tracker._active_order_trackers[ test_symbol] # receive open buy message to be added to active orders order_id = "abc" side = "buy" price = 1337.0 open_size = 100.0 open_sequence = 1 open_message_dict: Dict[str, Any] = { "type": "open", "time": "2014-11-07T08:19:27.028459Z", "product_id": test_symbol, "sequence": open_sequence, "order_id": order_id, "price": str(price), "remaining_size": str(open_size), "side": side } open_message: CoinbaseProOrderBookMessage = test_order_book.diff_message_from_exchange( open_message_dict) open_ob_row: OrderBookRow = test_active_order_tracker.convert_diff_message_to_order_book_row( open_message) self.assertEqual(open_ob_row[0], [OrderBookRow(price, open_size, open_sequence)]) # receive change message change_size = 50.0 change_sequence = 2 change_message_dict: Dict[str, Any] = { "type": "change", "time": "2014-11-07T08:19:27.028459Z", "sequence": change_sequence, "order_id": order_id, "product_id": test_symbol, "new_size": str(change_size), "old_size": "100.0", "price": str(price), "side": side } change_message: CoinbaseProOrderBookMessage = test_order_book.diff_message_from_exchange( change_message_dict) change_ob_row: OrderBookRow = test_active_order_tracker.convert_diff_message_to_order_book_row( change_message) self.assertEqual(change_ob_row[0], [OrderBookRow(price, change_size, change_sequence)]) # receive match message match_size = 30.0 match_sequence = 3 match_message_dict: Dict[str, Any] = { "type": "match", "trade_id": 10, "sequence": match_sequence, "maker_order_id": order_id, "taker_order_id": "132fb6ae-456b-4654-b4e0-d681ac05cea1", "time": "2014-11-07T08:19:27.028459Z", "product_id": test_symbol, "size": str(match_size), "price": str(price), "side": side } match_message: CoinbaseProOrderBookMessage = test_order_book.diff_message_from_exchange( match_message_dict) match_ob_row: OrderBookRow = test_active_order_tracker.convert_diff_message_to_order_book_row( match_message) self.assertEqual( match_ob_row[0], [OrderBookRow(price, change_size - match_size, match_sequence)]) # receive done message done_size = 0.0 done_sequence = 4 done_message_dict: Dict[str, Any] = { "type": "done", "time": "2014-11-07T08:19:27.028459Z", "product_id": test_symbol, "sequence": done_sequence, "price": str(price), "order_id": order_id, "reason": "filled", "side": side, "remaining_size": "0" } done_message: CoinbaseProOrderBookMessage = test_order_book.diff_message_from_exchange( done_message_dict) done_ob_row: OrderBookRow = test_active_order_tracker.convert_diff_message_to_order_book_row( done_message) self.assertEqual(done_ob_row[0], [OrderBookRow(price, done_size, done_sequence)])