コード例 #1
0
def convert_snapshot_message_to_order_book_row(
    message: OrderBookMessage
) -> Tuple[List[OrderBookRow], List[OrderBookRow]]:
    update_id = message.update_id
    data = []
    if "data" in message.content:  # From REST API
        data: List[Dict[str, Any]] = message.content["data"]
    elif "order_books" in message.content:  # From Websocket API
        data: List[Dict[str, Any]] = message.content["order_books"]
    bids, asks = [], []

    for entry in data:
        order_row = OrderBookRow(float(entry["price"]),
                                 float(entry["quantity"]), update_id)
        if entry["side"] == "buy":
            bids.append(order_row)
        else:  # entry["type"] == "Sell":
            asks.append(order_row)

    return bids, asks
コード例 #2
0
    def test_asset_limit(self):
        self.market_2.order_books[self.market_2_trading_pairs[0]].apply_diffs(
            [OrderBookRow(1.1, 30, 2)],
            [],
            2
        )
        self.market_1.set_balance("COINALPHA", 40)
        self.market_2.set_balance("COINALPHA", 20)
        amount, profitability, bid_price, ask_price = self.strategy.find_best_profitable_amount(self.market_trading_pair_tuple_1,
                                                                                                self.market_trading_pair_tuple_2)

        self.assertEqual(20.0, amount)
        self.assertAlmostEqual(Decimal("1.0330510429366988"), profitability)

        self.market_2.set_balance("COINALPHA", 0)
        amount, profitability, bid_price, ask_price = self.strategy.find_best_profitable_amount(self.market_trading_pair_tuple_1,
                                                                                                self.market_trading_pair_tuple_2)

        self.assertEqual(Decimal("0"), amount)
        self.assertAlmostEqual(Decimal("1.0399044681062792"), profitability)
コード例 #3
0
    async def _test_spreads_adjusted_on_volatility_async(self):
        try:
            script_file = realpath(join(__file__, "../../scripts/spreads_adjusted_on_volatility_script.py"))
            self._script_iterator = ScriptIterator(script_file, [self.market], self.one_level_strategy, 0.01, True)
            self.clock.add_iterator(self._script_iterator)

            strategy = self.one_level_strategy
            self.clock.add_iterator(strategy)
            await self.turn_clock(1)

            self.assertEqual(1, len(strategy.active_buys))
            self.assertEqual(1, len(strategy.active_sells))
            self.assertEqual(Decimal("0.01"), strategy.bid_spread)
            self.assertEqual(Decimal("0.01"), strategy.ask_spread)
            await self.turn_clock(155)
            self.assertEqual(1, len(strategy.active_buys))
            self.assertEqual(1, len(strategy.active_sells))
            simulate_order_book_widening(self.book_data.order_book, 100, 105)
            self.book_data.order_book.apply_diffs([OrderBookRow(100, 30, 2)], [], 2)
            await self.turn_clock(160)
            mid_price = self.market.get_mid_price(self.trading_pair)
            print(mid_price)
            # The median volatility over the long period is at 0
            # The average volatility over the short period is now at 0.00916
            # So the adjustment is 0.0075 (rounded by 0.0025 increment)
            # await self.turn_clock(161)
            self.assertEqual(Decimal("0.0175"), strategy.bid_spread)
            self.assertEqual(Decimal("0.0175"), strategy.ask_spread)
            self.assertEqual(1, len(strategy.active_buys))
            self.assertEqual(1, len(strategy.active_sells))
            await self.turn_clock(185)
            # No more further price movement, which means volatility is now back to 0.
            # Spreads are adjusted back to the originals
            self.assertEqual(Decimal("0.01"), strategy.bid_spread)
            self.assertEqual(Decimal("0.01"), strategy.ask_spread)
            self.assertEqual(1, len(strategy.active_buys))
            self.assertEqual(1, len(strategy.active_sells))
        finally:
            self._script_iterator.stop(self.clock)
    def _parse_raw_update(self, pair: str,
                          raw_response: str) -> OrderBookMessage:
        """
        Parses raw update, if price for a tracked order identified by ID is 0, then order is deleted
        Returns OrderBookMessage
        """
        _, content = ujson.loads(raw_response)

        if isinstance(content, list) and len(content) == 3:
            order_id = content[0]
            price = content[1]
            amount = content[2]

            os = self._get_tracked_order_by_id(order_id)
            order = os["order"]
            side = os["side"]

            if order is not None:
                # this is not a new order. Either update it or delete it
                if price == 0:
                    self._untrack_order(order_id)
                    # print("-------------- Deleted order %d" % (order_id))
                    return self._generate_delete_message(
                        pair, order.price, side)
                else:
                    self._track_order(
                        order_id,
                        OrderBookRow(price, abs(amount), order.update_id),
                        side)
                    return None
            else:
                # this is a new order unless the price is 0, just track it and create message that
                # will add it to the order book
                if price != 0:
                    # print("-------------- Add order %d" % (order_id))
                    return self._generate_add_message(pair, price, amount)
        return None
コード例 #5
0
 def bids(self) -> List[OrderBookRow]:
     # raise NotImplementedError("Dexfin order book messages have different semantics.")
     return [
         OrderBookRow(float(price), float(amount), self.update_id)
         for price, amount, *trash in self.content.get("bids", [])
     ]
コード例 #6
0
 def asks(self) -> (List[OrderBookRow]):
     return [
         OrderBookRow(float(ask["price"]), float(ask["quantity"]), self.update_id)
         for ask in self.content.get("asks", [])
     ]
コード例 #7
0
 def bids(self) -> (List[OrderBookRow]):
     return [
         OrderBookRow(float(bid["price"]), float(bid["quantity"]), self.update_id)
         for bid in self.content.get("bids", [])
     ]
コード例 #8
0
 def asks(self) -> List[OrderBookRow]:
     results = [
         OrderBookRow(float(ask[0]), float(ask[1]), self.update_id) for ask in self.content["asks"]
     ]
     sorted(results, key=lambda a: a.price)
     return results
    def test_buy_diff_message(self):
        order_books: Dict[str, OrderBook] = self.order_book_tracker.order_books
        test_order_book: OrderBook = order_books[test_trading_pair]
        test_active_order_tracker = self.order_book_tracker._active_order_trackers[
            test_trading_pair]

        # 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_trading_pair,
            "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_trading_pair,
            "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_trading_pair,
            "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_trading_pair,
            "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)])
コード例 #10
0
ファイル: test_pmm.py プロジェクト: vyfirm/hummingbot
 def test_minimum_spread_param(self):
     strategy = self.strategy
     self.clock.add_iterator(strategy)
     self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
     self.assertEqual(1, len(strategy.active_buys))
     self.assertEqual(1, len(strategy.active_sells))
     old_bid = strategy.active_buys[0]
     old_ask = strategy.active_sells[0]
     # t = 2, No Change => orders should stay the same
     self.clock.backtest_til(self.start_timestamp +
                             2 * self.clock_tick_size)
     self.assertEqual(1, len(strategy.active_buys))
     self.assertEqual(1, len(strategy.active_sells))
     self.assertEqual(old_bid.client_order_id,
                      strategy.active_buys[0].client_order_id)
     self.assertEqual(old_ask.client_order_id,
                      strategy.active_sells[0].client_order_id)
     # Minimum Spread Threshold Cancellation
     # t = 3, Mid Market Price Moves Down - Below Min Spread (Old Bid) => Buy Order Cancelled
     self.maker_data.order_book.apply_diffs([OrderBookRow(50, 1000, 2)],
                                            [OrderBookRow(50, 1000, 2)], 2)
     self.clock.backtest_til(self.start_timestamp +
                             3 * self.clock_tick_size)
     self.assertEqual(0, len(strategy.active_buys))
     self.assertEqual(1, len(strategy.active_sells))
     # t = 30, New Set of Orders
     self.clock.backtest_til(self.start_timestamp +
                             32 * self.clock_tick_size)
     self.assertEqual(1, len(strategy.active_buys))
     self.assertEqual(1, len(strategy.active_sells))
     new_bid = strategy.active_buys[0]
     new_ask = strategy.active_sells[0]
     self.assertNotEqual(old_bid.client_order_id, new_bid.client_order_id)
     self.assertNotEqual(old_ask.client_order_id, new_ask.client_order_id)
     old_ask = new_ask
     old_bid = new_bid
     # t = 35, No Change
     self.clock.backtest_til(self.start_timestamp +
                             36 * self.clock_tick_size)
     self.assertEqual(1, len(strategy.active_buys))
     self.assertEqual(1, len(strategy.active_sells))
     self.assertEqual(old_bid.client_order_id,
                      strategy.active_buys[0].client_order_id)
     self.assertEqual(old_ask.client_order_id,
                      strategy.active_sells[0].client_order_id)
     # t = 36, Mid Market Price Moves Up - Below Min Spread (Old Ask) => Sell Order Cancelled
     # Clear Order Book (setting all orders above price 0, to quantity 0)
     simulate_order_book_widening(self.maker_data.order_book, 0, 0)
     # New Mid-Market Price
     self.maker_data.order_book.apply_diffs([OrderBookRow(99, 1000, 3)],
                                            [OrderBookRow(101, 1000, 3)], 3)
     # Check That Order Book Manipulations Didn't Affect Strategy Orders Yet
     self.assertEqual(1, len(strategy.active_buys))
     self.assertEqual(1, len(strategy.active_sells))
     self.assertEqual(old_bid.client_order_id,
                      strategy.active_buys[0].client_order_id)
     self.assertEqual(old_ask.client_order_id,
                      strategy.active_sells[0].client_order_id)
     # Simulate Minimum Spread Threshold Cancellation
     self.clock.backtest_til(self.start_timestamp +
                             40 * self.clock_tick_size)
     self.assertEqual(1, len(strategy.active_buys))
     self.assertEqual(0, len(strategy.active_sells))
コード例 #11
0
    def test_buy_diff_message(self):
        order_books: Dict[str, OrderBook] = self.order_book_tracker.order_books
        test_order_book: OrderBook = order_books[test_trading_pair]
        test_active_order_tracker = self.order_book_tracker._active_order_trackers[
            test_trading_pair]

        # receive open buy message to be added to active orders
        order_id = "abc"
        side = 1
        price = 1337.0
        open_size = 100.0
        market_id = 51
        open_sequence = int(datetime.now().timestamp() * 1000)
        open_message_dict: Dict[str, Any] = {
            "type": "o_placed",
            "timestamp": open_sequence,
            "marketId": market_id,
            "orderId": order_id,
            "limitPrice": str(price),
            "qty": str(open_size),
            "oType": 2,
            "side": side
        }
        open_message: EterbaseOrderBookMessage = 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 match message
        match_size = 30.0
        match_sequence = int(datetime.now().timestamp() * 1000)
        match_message_dict: Dict[str, Any] = {
            "type": "o_fill",
            "tradeId": 10,
            "orderId": order_id,
            "timestamp": match_sequence,
            "marketId": market_id,
            "qty": str(match_size),
            "remainingQty": str(open_size - match_size),
            "limitPrice": str(price),
            "side": side
        }
        match_message: EterbaseOrderBookMessage = 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, open_size - match_size, match_sequence)])

        # receive done message
        done_size = 0.0
        done_sequence = int(datetime.now().timestamp() * 1000)
        done_message_dict: Dict[str, Any] = {
            "type": "o_closed",
            "timestamp": done_sequence,
            "marketId": market_id,
            "price": str(price),
            "orderId": order_id,
            "closeReason": "FILLED",
            "side": side,
            "remainingQty": "0"
        }
        done_message: EterbaseOrderBookMessage = 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)])
コード例 #12
0
 def bids(self) -> List[OrderBookRow]:
     results = [
         OrderBookRow(float(bid[0]), float(bid[1]), self.update_id) for bid in self.content["bids"]
     ]
     sorted(results, key=lambda a: a.price)
     return results
コード例 #13
0
 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))
コード例 #14
0
 def bids(self) -> List[OrderBookRow]:
     return [
         OrderBookRow(float(price), float(size), self.update_id)
         for price, size, *trash in self.content["bid"]
     ]
コード例 #15
0
 def bids(self) -> List[OrderBookRow]:
     return [
         OrderBookRow(float(price), float(amount), self.update_id,
                      self.timestamp)
         for price, amount, *trash in self.content["bids"]
     ]
コード例 #16
0
    def bids(self) -> List[OrderBookRow]:
        bids = map(self.content["bids"], lambda bid: {"price": bid[0], "amount": bid[1]})

        return [
            OrderBookRow(float(price), float(amount), self.update_id) for price, amount in bids
        ]
コード例 #17
0
    def asks(self) -> List[OrderBookRow]:
        asks = map(self.content["asks"], lambda ask: {"price": ask[0], "amount": ask[1]})

        return [
            OrderBookRow(float(price), float(amount), self.update_id) for price, amount in asks
        ]
コード例 #18
0
 def bids(self) -> (List[OrderBookRow]):
     return [
         OrderBookRow(float(price), float(amount), self.update_id)
         for price, amount, *trash in self.content.get("bids", [])
     ]
コード例 #19
0
    def test_insert_update_delete_messages(self):
        active_tracker = BeaxyActiveOrderTracker()

        # receive INSERT message to be added to active orders
        side = "BID"
        price = 1337.4423423404
        quantity: float = 1
        update_id = 123
        message_dict: Dict[str, Any] = {
            "action": "INSERT",
            "quantity": quantity,
            "price": price,
            "side": side,
            "sequenceNumber": update_id,
            "sequrity": test_trading_pair
        }
        insert_message = BeaxyOrderBook.diff_message_from_exchange(
            message_dict, float(12345))
        insert_ob_row: OrderBookRow = active_tracker.convert_diff_message_to_order_book_row(
            insert_message)
        self.assertEqual(insert_ob_row[0],
                         [OrderBookRow(price, quantity, update_id)])

        # receive UPDATE message
        updated_quantity: float = 3.2
        update_message_dict: Dict[str, Any] = {
            "action": "UPDATE",
            "quantity": updated_quantity,
            "price": price,
            "side": side,
            "sequenceNumber": update_id + 1,
            "sequrity": test_trading_pair
        }
        change_message = BeaxyOrderBook.diff_message_from_exchange(
            update_message_dict, float(12345))
        change_ob_row: OrderBookRow = active_tracker.convert_diff_message_to_order_book_row(
            change_message)
        self.assertEqual(
            change_ob_row[0],
            [OrderBookRow(price, float(updated_quantity), update_id + 1)])

        # receive DELETE message
        delete_quantity = 1
        delete_message_dict: Dict[str, Any] = {
            "action": "DELETE",
            "quantity": delete_quantity,
            "price": price,
            "side": side,
            "sequenceNumber": update_id + 1 + 1,
            "sequrity": test_trading_pair
        }

        delete_message: BeaxyOrderBookMessage = BeaxyOrderBook.diff_message_from_exchange(
            delete_message_dict, float(12345))
        delete_ob_row: OrderBookRow = active_tracker.convert_diff_message_to_order_book_row(
            delete_message)
        self.assertEqual(delete_ob_row[0], [
            OrderBookRow(price,
                         float(updated_quantity) - float(delete_quantity),
                         update_id + 1 + 1)
        ])
コード例 #20
0
 def test_arbitrage_not_profitable(self):
     self.market_2_data.order_book.apply_diffs([OrderBookRow(1.05, 1.0, 2)],
                                               [], 2)
     self.clock.backtest_til(self.start_timestamp + 1)
     taker_orders = self.strategy.tracked_limit_orders + self.strategy.tracked_market_orders
     self.assertTrue(len(taker_orders) == 0)
コード例 #21
0
    async def _test_dynamic_price_band_price_async(self):
        try:
            script_file = realpath(
                join(__file__,
                     "../../../../scripts/dynamic_price_band_script.py"))
            self._script_iterator = ScriptIterator(script_file, [self.market],
                                                   self.multi_levels_strategy,
                                                   0.01, True)
            self.clock.add_iterator(self._script_iterator)

            strategy = self.multi_levels_strategy
            self.clock.add_iterator(strategy)
            await self.turn_clock(1)

            self.assertEqual(3, len(strategy.active_buys))
            self.assertEqual(3, len(strategy.active_sells))

            await self.turn_clock(4)
            # self.book_data.order_book.apply_diffs([OrderBookRow(99.97, 30, 2)], [OrderBookRow(100.3, 30, 2)], 2)
            simulate_order_book_widening(self.book_data.order_book, 85,
                                         self.mid_price)
            mid_price = self.market.get_mid_price(self.trading_pair)
            await self.turn_clock(10)
            mid_price = self.market.get_mid_price(self.trading_pair)
            print(mid_price)
            self.assertLess(mid_price, Decimal(100 * 0.97))
            # mid_price is now below 3% from the original (at 92.5), but band script won't kick in until at least 50s
            self.assertEqual(3, len(strategy.active_buys))
            self.assertEqual(3, len(strategy.active_sells))
            await self.turn_clock(55)
            self.assertEqual(3, len(strategy.active_buys))
            self.assertEqual(3, len(strategy.active_sells))
            simulate_order_book_widening(self.book_data.order_book, 75,
                                         self.mid_price)
            self.book_data.order_book.apply_diffs([],
                                                  [OrderBookRow(76, 30, 2)], 2)
            mid_price = self.market.get_mid_price(self.trading_pair)
            print(mid_price)
            await self.turn_clock(80)
            self.assertEqual(3, len(strategy.active_buys))
            self.assertEqual(0, len(strategy.active_sells))
            # after another 40 ticks, the mid price avg is now at 75.25, both buys and sells back on the market
            await self.turn_clock(110)
            self.assertEqual(3, len(strategy.active_buys))
            self.assertEqual(3, len(strategy.active_sells))

            simulate_order_book_widening(self.book_data.order_book, 76, 90)
            self.book_data.order_book.apply_diffs([OrderBookRow(85, 30, 2)],
                                                  [OrderBookRow(86, 30, 2)], 3)
            mid_price = self.market.get_mid_price(self.trading_pair)
            print(mid_price)
            # Market now move up over 10%
            await self.turn_clock(120)
            self.assertEqual(0, len(strategy.active_buys))
            self.assertEqual(3, len(strategy.active_sells))
            # As no further movement in market prices, avg starts to catch up to the mid price
            await self.turn_clock(160)
            self.assertEqual(3, len(strategy.active_buys))
            self.assertEqual(3, len(strategy.active_sells))
        finally:
            self._script_iterator.stop(self.clock)
コード例 #22
0
 def asks(self) -> List[OrderBookRow]:
     return [OrderBookRow(float(price), float(amount), self.update_id)
             for price, amount, *trash in self.content["asks"]]