def simulate_maker_market_trade(self, is_buy: bool, quantity: Decimal, price: Decimal): order_book = self.market.get_order_book(self.trading_pair) trade_event = OrderBookTradeEvent( self.trading_pair, self.clock.current_timestamp, TradeType.BUY if is_buy else TradeType.SELL, price, quantity) order_book.apply_trade(trade_event)
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, base_currency_traded, quote_currency_traded, 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, base_currency_traded, quote_currency_traded, OrderType.LIMIT ))
async def delay_trigger_event1(): await asyncio.sleep(1) trade_event1 = OrderBookTradeEvent(trading_pair="ETH-USDT", timestamp=time.time(), type=TradeType.SELL, price=best_bid_price + 1, amount=1.0) self.market.order_books['ETH-USDT'].apply_trade(trade_event1)
def simulate_maker_market_trade(self, is_buy: bool, quantity: Decimal, price: Decimal): maker_symbol: str = self.maker_symbols[0] order_book: OrderBook = self.maker_market.get_order_book(maker_symbol) trade_event: OrderBookTradeEvent = OrderBookTradeEvent( maker_symbol, self.clock.current_timestamp, TradeType.BUY if is_buy else TradeType.SELL, price, quantity) order_book.apply_trade(trade_event)
async def delay_trigger_event2(): await asyncio.sleep(1) trade_event = OrderBookTradeEvent(symbol=trading_pair.trading_pair, timestamp=time.time(), type=TradeType.BUY, price=best_ask_price - 1, amount=base_quantity) self.market.order_books[trading_pair.trading_pair].apply_trade( trade_event)
def simulate_maker_market_trade(self, is_buy: bool, quantity: float): maker_symbol: str = self.maker_symbols[0] order_book: OrderBook = self.maker_market.get_order_book(maker_symbol) trade_event: OrderBookTradeEvent = OrderBookTradeEvent( maker_symbol, self.clock.current_timestamp, TradeType.BUY if is_buy else TradeType.SELL, (self.mid_price * (1 - self.bid_threshold - 0.01) if not is_buy else self.mid_price * (1 + self.ask_threshold + 0.01)), quantity) order_book.apply_trade(trade_event)
def simulate_maker_market_trade( self, is_buy: bool, quantity: Decimal, price: Decimal, market: Optional[BacktestMarket] = None, ): if market is None: market = self.market order_book = market.get_order_book(self.trading_pair) trade_event = OrderBookTradeEvent( self.trading_pair, self.clock.current_timestamp, TradeType.BUY if is_buy else TradeType.SELL, price, quantity ) order_book.apply_trade(trade_event)
async def _emit_trade_event_loop(self): last_message_timestamp: float = time.time() messages_accepted: int = 0 messages_rejected: int = 0 await self._order_books_initialized.wait() while True: try: trade_message: OrderBookMessage = await self._order_book_trade_stream.get( ) trading_pair: str = trade_message.trading_pair if trading_pair not in self._order_books: messages_rejected += 1 continue order_book: OrderBook = self._order_books[trading_pair] order_book.apply_trade( OrderBookTradeEvent( trading_pair=trade_message.trading_pair, timestamp=trade_message.timestamp, price=float(trade_message.content["price"]), amount=float(trade_message.content["amount"]), type=TradeType.SELL if trade_message.content["trade_type"] == float( TradeType.SELL.value) else TradeType.BUY)) messages_accepted += 1 # Log some statistics. now: float = time.time() if int(now / 60.0) > int(last_message_timestamp / 60.0): self.logger().debug( f"Trade messages processed: {messages_accepted}, rejected: {messages_rejected}" ) messages_accepted = 0 messages_rejected = 0 last_message_timestamp = now except asyncio.CancelledError: raise except Exception: self.logger().network( "Unexpected error routing order book messages.", exc_info=True, app_warning_msg= "Unexpected error routing order book messages. Retrying after 5 seconds." ) await asyncio.sleep(5.0)
def simulate_maker_market_trade( self, is_buy: bool, quantity: Decimal, price: Decimal, trading_pair: str, market: Optional[MockPaperExchange] = None, ): """ simulate making a trade, broadcasts a trade event """ if market is None: market = self.market order_book: OrderBook = market.get_order_book(trading_pair) trade_event = OrderBookTradeEvent( trading_pair, self.clock.current_timestamp, TradeType.BUY if is_buy else TradeType.SELL, price, quantity ) order_book.apply_trade(trade_event)
def test_calculate_trading_intensity_deterministic(self): def curve_fn( t_, a_, b_ ): # see curve fit in `TradingIntensityIndicator.c_estimate_intensity` return a_ * np.exp(-b_ * t_) last_price = 1 trade_price_levels = [2, 3, 4, 5] a = 2 b = 0.1 ts = [curve_fn(p - last_price, a, b) for p in trade_price_levels] timestamp = self.start_timestamp trading_intensity_indicator = TradingIntensityIndicator( OrderBook(), self.price_delegate, 1) trading_intensity_indicator.last_quotes = [{ "timestamp": timestamp, "price": last_price }] timestamp += 1 for p, t in zip(trade_price_levels, ts): new_trade = OrderBookTradeEvent( trading_pair="COINALPHAHBOT", timestamp=timestamp, price=p, amount=t, type=TradeType.SELL, ) trading_intensity_indicator.register_trade(new_trade) trading_intensity_indicator.calculate(timestamp) alpha, kappa = trading_intensity_indicator.current_value self.assertAlmostEqual(a, alpha, 10) self.assertAlmostEqual(b, kappa, 10)
def simulate_limit_order_fill(market: Market, 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 config: MarketConfig = market.config 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, 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 )) 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 ))
def make_trades(bids_df, asks_df): # Estimate market orders that happened # Assume every movement in the BBO is caused by a market order and its size is the volume differential bid_df_prev = None ask_df_prev = None bid_prev = None ask_prev = None price_prev = None trades = [] start = pd.Timestamp("2019-01-01", tz="UTC") start_timestamp = start.timestamp() timestamp = start_timestamp for bid_df, ask_df in zip(bids_df, asks_df): trades += [[]] bid = bid_df["price"].iloc[0] ask = ask_df["price"].iloc[0] if bid_prev is not None and ask_prev is not None and price_prev is not None: # Higher bids were filled - someone matched them - a determined seller # Equal bids - if amount lower - partially filled for index, row in bid_df_prev[ bid_df_prev['price'] >= bid].iterrows(): if row['price'] == bid: if bid_df["amount"].iloc[0] < row['amount']: amount = row['amount'] - bid_df["amount"].iloc[0] new_trade = OrderBookTradeEvent( trading_pair="COINALPHAHBOT", timestamp=timestamp, price=row['price'], amount=amount, type=TradeType.SELL) trades[-1] += [new_trade] else: amount = row['amount'] new_trade = OrderBookTradeEvent( trading_pair="COINALPHAHBOT", timestamp=timestamp, price=row['price'], amount=amount, type=TradeType.SELL) trades[-1] += [new_trade] # Lower asks were filled - someone matched them - a determined buyer # Equal asks - if amount lower - partially filled for index, row in ask_df_prev[ ask_df_prev['price'] <= ask].iterrows(): if row['price'] == ask: if ask_df["amount"].iloc[0] < row['amount']: amount = row['amount'] - ask_df["amount"].iloc[0] new_trade = OrderBookTradeEvent( trading_pair="COINALPHAHBOT", timestamp=timestamp, price=row['price'], amount=amount, type=TradeType.BUY) trades[-1] += [new_trade] else: amount = row['amount'] new_trade = OrderBookTradeEvent( trading_pair="COINALPHAHBOT", timestamp=timestamp, price=row['price'], amount=amount, type=TradeType.BUY) trades[-1] += [new_trade] # Store previous values bid_df_prev = bid_df ask_df_prev = ask_df bid_prev = bid_df["price"].iloc[0] ask_prev = ask_df["price"].iloc[0] price_prev = (bid_prev + ask_prev) / 2 timestamp += 1 return trades