Esempio n. 1
0
 def place_order(self, is_buy, trading_pair, amount, order_type, price,
                 nonce, post_resp, ws_resp):
     global EXCHANGE_ORDER_ID
     order_id, exch_order_id = None, None
     if API_MOCK_ENABLED:
         exch_order_id = f"BITTREX_{EXCHANGE_ORDER_ID}"
         EXCHANGE_ORDER_ID += 1
         self._t_nonce_mock.return_value = nonce
         resp = post_resp.copy()
         resp["id"] = exch_order_id
         side = 'buy' if is_buy else 'sell'
         resp["direction"] = side.upper()
         resp["type"] = order_type.name.upper()
         if order_type == OrderType.LIMIT:
             del resp["limit"]
         self.web_app.update_response("post", API_BASE_URL, "/v3/orders",
                                      resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type,
                                     price)
     if API_MOCK_ENABLED:
         resp = ws_resp.copy()
         resp["content"]["o"]["OU"] = exch_order_id
         HummingWsServerFactory.send_json_threadsafe(WS_BASE_URL,
                                                     resp,
                                                     delay=1.0)
     return order_id, exch_order_id
    def test_cancel_all(self):
        trading_pair = "ETH-USDC"
        bid_price: Decimal = self.market.get_price(trading_pair, True) * Decimal("0.5")
        ask_price: Decimal = self.market.get_price(trading_pair, False) * 2
        amount: Decimal = 10 / bid_price
        quantized_amount: Decimal = self.market.quantize_order_amount(trading_pair, amount)

        # Intentionally setting invalid price to prevent getting filled
        quantize_bid_price: Decimal = self.market.quantize_order_price(trading_pair, bid_price * Decimal("0.7"))
        quantize_ask_price: Decimal = self.market.quantize_order_price(trading_pair, ask_price * Decimal("1.5"))

        _, exch_order_id = self.place_order(True, trading_pair, quantized_amount, OrderType.LIMIT_MAKER, quantize_bid_price,
                                            10001, FixtureCoinbasePro.OPEN_BUY_LIMIT_ORDER, FixtureCoinbasePro.WS_ORDER_OPEN)
        _, exch_order_id_2 = self.place_order(False, trading_pair, quantized_amount, OrderType.LIMIT_MAKER,
                                              quantize_ask_price, 10002, FixtureCoinbasePro.OPEN_SELL_LIMIT_ORDER,
                                              FixtureCoinbasePro.WS_ORDER_OPEN)
        self.run_parallel(asyncio.sleep(1))

        if API_MOCK_ENABLED:
            self.web_app.update_response("delete", API_BASE_URL, f"/orders/{exch_order_id}", exch_order_id)
            self.web_app.update_response("delete", API_BASE_URL, f"/orders/{exch_order_id_2}", exch_order_id_2)
        [cancellation_results] = self.run_parallel(self.market.cancel_all(5))
        if API_MOCK_ENABLED:
            resp = FixtureCoinbasePro.WS_ORDER_CANCELLED.copy()
            resp["order_id"] = exch_order_id
            HummingWsServerFactory.send_json_threadsafe(WS_BASE_URL, resp, delay=0.1)
            resp = FixtureCoinbasePro.WS_ORDER_CANCELLED.copy()
            resp["order_id"] = exch_order_id_2
            HummingWsServerFactory.send_json_threadsafe(WS_BASE_URL, resp, delay=0.11)
        for cr in cancellation_results:
            self.assertEqual(cr.success, True)
Esempio n. 3
0
    def test_cancel_order(self):
        self.assertGreater(self.market.get_balance("USDC"), 16000)
        trading_pair = "WETH-USDC"
        bid_price: Decimal = self.market.get_price(trading_pair, True)
        amount: Decimal = Decimal("40.0")

        # Intentionally setting price far away from best ask
        client_order_id = self.place_order(True, "WETH-USDC", amount,
                                           OrderType.LIMIT_MAKER,
                                           bid_price * Decimal('0.5'), 10001,
                                           FixtureDydx.BUY_LIMIT_ORDER,
                                           FixtureDydx.WS_AFTER_BUY_1)
        self.run_parallel(asyncio.sleep(1.0))
        self.market.cancel(trading_pair, client_order_id)
        if API_MOCK_ENABLED:
            HummingWsServerFactory.send_json_threadsafe(
                self._ws_user_url, FixtureDydx.WS_AFTER_CANCEL_BUY, delay=0.1)
        [order_cancelled_event] = self.run_parallel(
            self.market_logger.wait_for(OrderCancelledEvent))

        order_cancelled_event: OrderCancelledEvent = order_cancelled_event

        self.run_parallel(asyncio.sleep(6.0))
        self.assertEqual(0, len(self.market.limit_orders))
        self.assertEqual(client_order_id, order_cancelled_event.order_id)
Esempio n. 4
0
 def place_order(self,
                 is_buy,
                 trading_pair,
                 amount,
                 order_type,
                 price,
                 nonce,
                 fixture_resp,
                 fixture_ws_1=None,
                 fixture_ws_2=None):
     order_id = None
     if API_MOCK_ENABLED:
         resp = self.order_response(fixture_resp, nonce,
                                    'buy' if is_buy else 'sell',
                                    trading_pair)
         self.web_app.update_response("post", self.base_api_url,
                                      "/api/v3/order", resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type,
                                     price)
     if API_MOCK_ENABLED and fixture_ws_1 is not None and fixture_ws_2 is not None:
         data = self.fixture(fixture_ws_1, c=order_id)
         HummingWsServerFactory.send_json_threadsafe(self._ws_user_url,
                                                     data,
                                                     delay=0.1)
         data = self.fixture(fixture_ws_2, c=order_id)
         HummingWsServerFactory.send_json_threadsafe(self._ws_user_url,
                                                     data,
                                                     delay=0.11)
     return order_id
Esempio n. 5
0
    def setUpClass(cls):
        global MAINNET_RPC_URL

        cls.ev_loop = asyncio.get_event_loop()

        if API_MOCK_ENABLED:
            cls.web_app = HummingWebApp.get_instance()
            cls.web_app.add_host_to_mock(BASE_API_URL, [])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", BASE_API_URL,
                                        "/v2/public/get-ticker",
                                        fixture.TICKERS)
            cls.web_app.update_response("get", BASE_API_URL,
                                        "/v2/public/get-instruments",
                                        fixture.INSTRUMENTS)
            cls.web_app.update_response("get", BASE_API_URL,
                                        "/v2/public/get-book",
                                        fixture.GET_BOOK)
            cls.web_app.update_response("post", BASE_API_URL,
                                        "/v2/private/get-account-summary",
                                        fixture.BALANCES)
            cls.web_app.update_response("post", BASE_API_URL,
                                        "/v2/private/cancel-order",
                                        fixture.CANCEL)

            HummingWsServerFactory.start_new_server(WSS_PRIVATE_URL)
            HummingWsServerFactory.start_new_server(WSS_PUBLIC_URL)
            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = HummingWsServerFactory.reroute_ws_connect

        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.connector: CryptoComExchange = CryptoComExchange(
            crypto_com_api_key=API_KEY,
            crypto_com_api_secret=API_SECRET,
            trading_pairs=[cls.trading_pair],
            trading_required=True)
        print(
            "Initializing CryptoCom market... this will take about a minute.")
        cls.clock.add_iterator(cls.connector)
        cls.stack: contextlib.ExitStack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        if API_MOCK_ENABLED:
            HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                        fixture.WS_INITIATED,
                                                        delay=0.5)
            HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                        fixture.WS_SUBSCRIBE,
                                                        delay=0.51)
            HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                        fixture.WS_HEARTBEAT,
                                                        delay=0.52)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
 def cancel_order(self, trading_pair, order_id, exchange_order_id, fixture_ws):
     if API_MOCK_ENABLED:
         self.web_app.update_response("delete", API_BASE_URL, f"/orders/{exchange_order_id}", exchange_order_id)
     self.market.cancel(trading_pair, order_id)
     if API_MOCK_ENABLED:
         resp = fixture_ws.copy()
         resp["order_id"] = exchange_order_id
         HummingWsServerFactory.send_json_threadsafe(WS_BASE_URL, resp, delay=0.1)
Esempio n. 7
0
 def _cancel_order(self, cl_order_id):
     self.connector.cancel(self.trading_pair, cl_order_id)
     if API_MOCK_ENABLED:
         data = fixture.WS_ORDER_CANCELLED.copy()
         data["result"]["data"][0]["client_oid"] = cl_order_id
         HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                     data,
                                                     delay=0.1)
Esempio n. 8
0
 def _mock_ws_bal_update(self, token, available):
     if API_MOCK_ENABLED:
         available = float(available)
         data = fixture.WS_BALANCE.copy()
         data["result"]["data"][0]["currency"] = token
         data["result"]["data"][0]["available"] = available
         HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                     fixture.WS_BALANCE,
                                                     delay=0.1)
Esempio n. 9
0
    def setUpClass(cls):
        global MAINNET_RPC_URL

        cls.ev_loop = asyncio.get_event_loop()

        if API_MOCK_ENABLED:
            cls.web_app = HummingWebApp.get_instance()
            cls.web_app.add_host_to_mock(cls.base_api_url, ["/api/v1/ping", "/api/v1/time", "/api/v1/ticker/24hr"])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local

            cls._req_patcher = unittest.mock.patch.object(requests.Session, "request", autospec=True)
            cls._req_url_mock = cls._req_patcher.start()
            cls._req_url_mock.side_effect = HummingWebApp.reroute_request
            cls.web_app.update_response("get", cls.base_api_url, "/api/v3/account", FixtureBinance.BALANCES)
            cls.web_app.update_response("get", cls.base_api_url, "/api/v1/exchangeInfo",
                                        FixtureBinance.MARKETS)
            cls.web_app.update_response("get", cls.base_api_url, "/wapi/v3/tradeFee.html",
                                        FixtureBinance.TRADE_FEES)
            cls.web_app.update_response("post", cls.base_api_url, "/api/v1/userDataStream",
                                        FixtureBinance.LISTEN_KEY)
            cls.web_app.update_response("put", cls.base_api_url, "/api/v1/userDataStream",
                                        FixtureBinance.LISTEN_KEY)
            cls.web_app.update_response("get", cls.base_api_url, "/api/v1/depth",
                                        FixtureBinance.LINKETH_SNAP, params={'symbol': 'LINKETH'})
            cls.web_app.update_response("get", cls.base_api_url, "/api/v1/depth",
                                        FixtureBinance.ZRXETH_SNAP, params={'symbol': 'ZRXETH'})
            cls.web_app.update_response("get", cls.base_api_url, "/api/v3/myTrades",
                                        {}, params={'symbol': 'ZRXETH'})
            cls.web_app.update_response("get", cls.base_api_url, "/api/v3/myTrades",
                                        {}, params={'symbol': 'LINKETH'})
            ws_base_url = "wss://stream.binance.com:9443/ws"
            cls._ws_user_url = f"{ws_base_url}/{FixtureBinance.LISTEN_KEY['listenKey']}"
            HummingWsServerFactory.start_new_server(cls._ws_user_url)
            HummingWsServerFactory.start_new_server(f"{ws_base_url}/linketh@depth/zrxeth@depth")
            cls._ws_patcher = unittest.mock.patch("websockets.connect", autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = HummingWsServerFactory.reroute_ws_connect

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.binance.binance_exchange.get_tracking_nonce")
            cls._t_nonce_mock = cls._t_nonce_patcher.start()
        cls.current_nonce = 1000000000000000
        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: BinanceExchange = BinanceExchange(API_KEY, API_SECRET, ["LINK-ETH", "ZRX-ETH"], True)
        print("Initializing Binance market... this will take about a minute.")
        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
        cls.clock.add_iterator(cls.market)
        cls.stack: contextlib.ExitStack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Esempio n. 10
0
    def test_prevent_duplicated_orders(self):
        config_path: str = "test_config"
        strategy_name: str = "test_strategy"
        sql: SQLConnectionManager = SQLConnectionManager(SQLConnectionType.TRADE_FILLS, db_path=self.db_path)
        buy_id: Optional[str] = None
        recorder: MarketsRecorder = MarketsRecorder(sql, [self.market], config_path, strategy_name)
        recorder.start()

        try:
            # Perform the same order twice which should produce the same exchange_order_id
            # Try to buy 1 LINK from the exchange, and watch for completion event.
            bid_price: Decimal = self.market.get_price("LINK-ETH", True)
            amount: Decimal = 1
            buy_id = self.place_order(True, "LINK-ETH", amount, OrderType.LIMIT, bid_price, self.get_current_nonce(),
                                      FixtureBinance.BUY_LIMIT_ORDER, FixtureBinance.WS_AFTER_BUY_1,
                                      FixtureBinance.WS_AFTER_BUY_2)
            [buy_order_completed_event] = self.run_parallel(self.market_logger.wait_for(BuyOrderCompletedEvent))

            self.market_logger.clear()

            # Simulate that order is still in in_flight_orders
            order_json = {"client_order_id": buy_id,
                          "exchange_order_id": str(FixtureBinance.WS_AFTER_BUY_2['t']),
                          "trading_pair": "LINK-ETH",
                          "order_type": "MARKET",
                          "trade_type": "BUY",
                          "price": bid_price,
                          "amount": amount,
                          "last_state": "NEW",
                          "executed_amount_base": "0",
                          "executed_amount_quote": "0",
                          "fee_asset": "LINK",
                          "fee_paid": "0.0"}
            self.market.restore_tracking_states({buy_id: order_json})
            self.market.in_flight_orders.get(buy_id).trade_id_set.add(str(FixtureBinance.WS_AFTER_BUY_2['t']))
            # Simulate incoming responses as if buy_id is executed again
            data = self.fixture(FixtureBinance.WS_AFTER_BUY_2, c=buy_id)
            HummingWsServerFactory.send_json_threadsafe(self._ws_user_url, data, delay=0.11)
            # Will wait, but no order filled event should be triggered because order is ignored
            self.run_parallel(asyncio.sleep(1))
            # Query the persisted trade logs
            trade_fills: List[TradeFill] = recorder.get_trades_for_config(config_path)
            buy_fills: List[TradeFill] = [t for t in trade_fills if t.trade_type == "BUY"]
            exchange_trade_id = FixtureBinance.WS_AFTER_BUY_2['t']
            self.assertEqual(len([bf for bf in buy_fills if int(bf.exchange_trade_id) == exchange_trade_id]), 1)

            buy_id = None

        finally:
            if buy_id is not None:
                self.market.cancel("LINK-ETH", buy_id)
                self.run_parallel(self.market_logger.wait_for(OrderCancelledEvent))

            recorder.stop()
            os.unlink(self.db_path)
Esempio n. 11
0
    def test_limit_makers_unfilled(self):
        self.assertGreater(self.market.get_balance("USDC"), 16000)
        trading_pair = "WETH-USDC"
        amount: Decimal = Decimal("40.0")
        bid_price: Decimal = self.market.get_price(trading_pair, True)
        buy_order_id: str = self.place_order(True, "WETH-USDC", amount,
                                             OrderType.LIMIT_MAKER,
                                             bid_price * Decimal('0.5'), 10001,
                                             FixtureDydx.BUY_LIMIT_MAKER_ORDER,
                                             FixtureDydx.WS_AFTER_BUY_1)
        self.run_parallel(asyncio.sleep(6.0))
        self.market.cancel(trading_pair, buy_order_id)

        if API_MOCK_ENABLED:
            HummingWsServerFactory.send_json_threadsafe(
                self._ws_user_url, FixtureDydx.WS_AFTER_CANCEL_BUY, delay=0.1)
        [order_cancelled_event] = self.run_parallel(
            self.market_logger.wait_for(OrderCancelledEvent))
 def place_order(self, is_buy, trading_pair, amount, order_type, price, nonce, fixture_resp, fixture_ws):
     order_id, exch_order_id = None, None
     if API_MOCK_ENABLED:
         self._t_nonce_mock.return_value = nonce
         side = 'buy' if is_buy else 'sell'
         resp = fixture_resp.copy()
         exch_order_id = resp["id"]
         resp["side"] = side
         self.web_app.update_response("post", API_BASE_URL, "/orders", resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type, price)
     if API_MOCK_ENABLED:
         resp = fixture_ws.copy()
         resp["order_id"] = exch_order_id
         resp["side"] = side
         HummingWsServerFactory.send_json_threadsafe(WS_BASE_URL, resp, delay=0.1)
     return order_id, exch_order_id
Esempio n. 13
0
 def _place_order(self,
                  is_buy,
                  amount,
                  order_type,
                  price,
                  ex_order_id,
                  get_order_fixture=None,
                  ws_trade_fixture=None,
                  ws_order_fixture=None) -> str:
     if API_MOCK_ENABLED:
         data = fixture.PLACE_ORDER.copy()
         data["result"]["order_id"] = str(ex_order_id)
         self.web_app.update_response("post", BASE_API_URL,
                                      "/v2/private/create-order", data)
     if is_buy:
         cl_order_id = self.connector.buy(self.trading_pair, amount,
                                          order_type, price)
     else:
         cl_order_id = self.connector.sell(self.trading_pair, amount,
                                           order_type, price)
     if API_MOCK_ENABLED:
         if get_order_fixture is not None:
             data = get_order_fixture.copy()
             data["result"]["order_info"]["client_oid"] = cl_order_id
             data["result"]["order_info"]["order_id"] = ex_order_id
             self.web_app.update_response("post", BASE_API_URL,
                                          "/v2/private/get-order-detail",
                                          data)
         if ws_trade_fixture is not None:
             data = ws_trade_fixture.copy()
             data["result"]["data"][0]["order_id"] = str(ex_order_id)
             HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                         data,
                                                         delay=0.1)
         if ws_order_fixture is not None:
             data = ws_order_fixture.copy()
             data["result"]["data"][0]["order_id"] = str(ex_order_id)
             data["result"]["data"][0]["client_oid"] = cl_order_id
             HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                         data,
                                                         delay=0.12)
     return cl_order_id
Esempio n. 14
0
    def setUpClass(cls):
        cls.ev_loop = asyncio.get_event_loop()
        trading_pair = "ETH-USDC"
        if API_MOCK_ENABLED:
            cls.web_app = HummingWebApp.get_instance()
            cls.web_app.add_host_to_mock(
                API_BASE_URL,
                ["/time", "/products", f"/products/{trading_pair}/book"])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", API_BASE_URL, "/accounts",
                                        FixtureCoinbasePro.ACCOUNTS_GET)
            cls.web_app.update_response("get", API_BASE_URL, "/fees",
                                        FixtureCoinbasePro.FEES_GET)
            cls.web_app.update_response("get", API_BASE_URL, "/orders",
                                        FixtureCoinbasePro.ORDERS_STATUS)

            HummingWsServerFactory.start_new_server(WS_BASE_URL)
            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = HummingWsServerFactory.reroute_ws_connect

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.market.coinbase_pro.coinbase_pro_market.get_tracking_nonce"
            )
            cls._t_nonce_mock = cls._t_nonce_patcher.start()
        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: CoinbaseProMarket = CoinbaseProMarket(
            API_KEY, API_SECRET, API_PASSPHRASE, trading_pairs=[trading_pair])
        print(
            "Initializing Coinbase Pro market... this will take about a minute."
        )
        cls.clock.add_iterator(cls.market)
        cls.stack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Esempio n. 15
0
    def place_order(self,
                    is_buy,
                    trading_pair,
                    amount,
                    order_type,
                    price,
                    ws_resps=[]):
        global EXCHANGE_ORDER_ID
        order_id, exch_order_id = None, None

        if is_buy:
            order_id = self.market.buy(trading_pair, amount, order_type, price)
        else:
            order_id = self.market.sell(trading_pair, amount, order_type,
                                        price)
        if API_MOCK_ENABLED:
            for delay, ws_resp in ws_resps:
                HummingWsServerFactory.send_str_threadsafe(
                    BeaxyConstants.TradingApi.WS_BASE_URL,
                    ws_resp,
                    delay=delay)
        return order_id, exch_order_id
Esempio n. 16
0
    def test_cancel_order(self):

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL,
                                         "/api/v2/orders",
                                         FixtureBeaxy.TEST_CANCEL_BUY_ORDER)

            self.web_app.update_response(
                "delete", PRIVET_API_BASE_URL,
                "/api/v2/orders/open/435118B0-A7F7-40D2-A409-820E8FC342A2", '')

        amount: Decimal = Decimal("0.01")

        self.assertGreater(self.market.get_balance("BTC"), 0.00005)
        trading_pair = "DASH-BTC"

        # make worst price so order wont be executed
        price: Decimal = self.market.get_price(trading_pair,
                                               True) * Decimal('0.5')
        quantized_amount: Decimal = self.market.quantize_order_amount(
            trading_pair, amount)

        order_id, exch_order_id = self.place_order(
            True, trading_pair, quantized_amount, OrderType.LIMIT, price,
            [(3, FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER_COMPLETED)])
        [order_completed_event] = self.run_parallel(
            self.market_logger.wait_for(BuyOrderCreatedEvent))

        if API_MOCK_ENABLED:
            HummingWsServerFactory.send_str_threadsafe(
                BeaxyConstants.TradingApi.WS_BASE_URL,
                FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER_CANCELED,
                delay=3)

        self.cancel_order(trading_pair, order_id, exch_order_id)
        [order_cancelled_event] = self.run_parallel(
            self.market_logger.wait_for(OrderCancelledEvent))
        order_cancelled_event: OrderCancelledEvent = order_cancelled_event
        self.assertEqual(order_cancelled_event.order_id, order_id)
Esempio n. 17
0
    def test_cancel_all(self):
        bid_price = self.connector.get_price(self.trading_pair, True)
        ask_price = self.connector.get_price(self.trading_pair, False)
        bid_price = self.connector.quantize_order_price(
            self.trading_pair, bid_price * Decimal("0.7"))
        ask_price = self.connector.quantize_order_price(
            self.trading_pair, ask_price * Decimal("1.5"))
        amount = self.connector.quantize_order_amount(self.trading_pair,
                                                      Decimal("0.0001"))

        buy_id = self._place_order(True, amount, OrderType.LIMIT, bid_price, 1)
        sell_id = self._place_order(False, amount, OrderType.LIMIT, ask_price,
                                    2)

        self.ev_loop.run_until_complete(asyncio.sleep(1))
        asyncio.ensure_future(self.connector.cancel_all(3))
        if API_MOCK_ENABLED:
            data = fixture.WS_ORDER_CANCELLED.copy()
            data["result"]["data"][0]["client_oid"] = buy_id
            data["result"]["data"][0]["order_id"] = 1
            HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                        data,
                                                        delay=0.1)
            self.ev_loop.run_until_complete(asyncio.sleep(1))
            data = fixture.WS_ORDER_CANCELLED.copy()
            data["result"]["data"][0]["client_oid"] = sell_id
            data["result"]["data"][0]["order_id"] = 2
            HummingWsServerFactory.send_json_threadsafe(WSS_PRIVATE_URL,
                                                        data,
                                                        delay=0.11)
        self.ev_loop.run_until_complete(asyncio.sleep(3))
        cancel_events = [
            t for t in self.event_logger.event_log
            if isinstance(t, OrderCancelledEvent)
        ]
        self.assertEqual({buy_id, sell_id},
                         {o.order_id
                          for o in cancel_events})
Esempio n. 18
0
    def setUpClass(cls):
        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
        if API_MOCK_ENABLED:
            cls.web_app = HummingWebApp.get_instance()
            cls.web_app.add_host_to_mock(API_BASE_URL, [])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", API_BASE_URL, "/v3/ping", FixtureBittrex.PING)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/markets", FixtureBittrex.MARKETS)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/markets/tickers", FixtureBittrex.MARKETS_TICKERS)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/balances", FixtureBittrex.BALANCES)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/orders/open", FixtureBittrex.ORDERS_OPEN)
            cls._t_nonce_patcher = unittest.mock.patch("hummingbot.market.bittrex.bittrex_market.get_tracking_nonce")
            cls._t_nonce_mock = cls._t_nonce_patcher.start()

            cls._us_patcher = unittest.mock.patch("hummingbot.market.bittrex.bittrex_api_user_stream_data_source."
                                                  "BittrexAPIUserStreamDataSource._transform_raw_message",
                                                  autospec=True)
            cls._us_mock = cls._us_patcher.start()
            cls._us_mock.side_effect = _transform_raw_message_patch

            cls._ob_patcher = unittest.mock.patch("hummingbot.market.bittrex.bittrex_api_order_book_data_source."
                                                  "BittrexAPIOrderBookDataSource._transform_raw_message",
                                                  autospec=True)
            cls._ob_mock = cls._ob_patcher.start()
            cls._ob_mock.side_effect = _transform_raw_message_patch

            HummingWsServerFactory.url_host_only = True
            ws_server = HummingWsServerFactory.start_new_server(WS_BASE_URL)
            cls._ws_patcher = unittest.mock.patch("websockets.connect", autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = HummingWsServerFactory.reroute_ws_connect
            ws_server.add_stock_response("queryExchangeState", FixtureBittrex.WS_ORDER_BOOK_SNAPSHOT.copy())

        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: BittrexMarket = BittrexMarket(
            bittrex_api_key=API_KEY,
            bittrex_secret_key=API_SECRET,
            trading_pairs=["ETH-USDT"]
        )

        print("Initializing Bittrex market... this will take about a minute. ")
        cls.clock.add_iterator(cls.market)
        cls.stack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Esempio n. 19
0
 def place_order(self,
                 is_buy,
                 trading_pair,
                 amount,
                 order_type,
                 price,
                 nonce,
                 fixture_resp,
                 fixture_ws_1=None,
                 fixture_ws_2=None,
                 fixture_ws_3=None):
     order_id = None
     if API_MOCK_ENABLED:
         resp = self.order_response(fixture_resp, nonce,
                                    'buy' if is_buy else 'sell',
                                    trading_pair)
         self.web_app.update_response("post", self.base_api_url,
                                      "/v2/orders", resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type,
                                     price)
     if API_MOCK_ENABLED and fixture_ws_1 is not None:
         self.web_app.update_response("get",
                                      self.base_api_url,
                                      "/v2/fills",
                                      FixtureDydx.FILLS,
                                      params={
                                          "orderId": order_id,
                                          "limit": 100
                                      })
         data = self.fixture(fixture_ws_1, id=order_id)
         HummingWsServerFactory.send_json_threadsafe(self._ws_user_url,
                                                     data,
                                                     delay=0.1)
         if fixture_ws_2 is not None:
             data = self.fixture(fixture_ws_2, id=order_id)
             HummingWsServerFactory.send_json_threadsafe(self._ws_user_url,
                                                         data,
                                                         delay=0.11)
         if fixture_ws_3 is not None:
             HummingWsServerFactory.send_json_threadsafe(self._ws_user_url,
                                                         fixture_ws_3,
                                                         delay=0.1)
     return order_id
Esempio n. 20
0
    def test_order_saving_and_restoration(self):
        config_path: str = "test_config"
        strategy_name: str = "test_strategy"
        sql: SQLConnectionManager = SQLConnectionManager(
            SQLConnectionType.TRADE_FILLS, db_path=self.db_path)
        order_id: Optional[str] = None
        trading_pair: str = "WETH-USDC"

        recorder: MarketsRecorder = MarketsRecorder(sql, [self.market],
                                                    config_path, strategy_name)
        recorder.start()
        try:
            self.assertEqual(0, len(self.market.tracking_states))
            self.assertGreater(self.market.get_balance("USDC"), 16000)
            amount: Decimal = Decimal("40.0")
            current_bid_price: Decimal = self.market.get_price(
                trading_pair, True)
            bid_price: Decimal = Decimal("0.5") * current_bid_price
            quantize_bid_price: Decimal = self.market.quantize_order_price(
                trading_pair, bid_price)
            order_id = self.place_order(True, trading_pair, amount,
                                        OrderType.LIMIT, quantize_bid_price,
                                        10001, FixtureDydx.BUY_LIMIT_ORDER,
                                        FixtureDydx.WS_AFTER_BUY_1)

            [order_created_event] = self.run_parallel(
                self.market_logger.wait_for(BuyOrderCreatedEvent))
            order_created_event: BuyOrderCreatedEvent = order_created_event

            self.assertEqual(order_id, order_created_event.order_id)

            # Verify tracking states
            self.assertEqual(1, len(self.market.tracking_states))
            self.assertEqual(order_id,
                             list(self.market.tracking_states.keys())[0])

            # Verify orders from recorder
            recorded_orders: List[
                Order] = recorder.get_orders_for_config_and_market(
                    config_path, self.market)
            self.assertEqual(1, len(recorded_orders))
            self.assertEqual(order_id, recorded_orders[0].id)

            # Verify saved market states
            saved_market_states: MarketState = recorder.get_market_states(
                config_path, self.market)
            self.assertIsNotNone(saved_market_states)
            self.assertIsInstance(saved_market_states.saved_state, dict)
            self.assertGreater(len(saved_market_states.saved_state), 0)

            # Close out the current market and start another market.
            self.clock.remove_iterator(self.market)

            for event_tag in self.market_events:
                self.market.remove_listener(event_tag, self.market_logger)

            self.market: DydxExchange = DydxExchange(
                dydx_eth_private_key=PRIVATE_KEY,
                dydx_node_address=NODE_ADDRESS,
                poll_interval=10.0,
                trading_pairs=[trading_pair],
                trading_required=True)
            for event_tag in self.market_events:
                self.market.add_listener(event_tag, self.market_logger)
            recorder.stop()
            recorder = MarketsRecorder(sql, [self.market], config_path,
                                       strategy_name)
            recorder.start()
            saved_market_states = recorder.get_market_states(
                config_path, self.market)
            self.clock.add_iterator(self.market)
            self.assertEqual(0, len(self.market.limit_orders))
            self.assertEqual(0, len(self.market.tracking_states))
            self.market.restore_tracking_states(
                saved_market_states.saved_state)
            self.assertEqual(1, len(self.market.limit_orders))
            self.assertEqual(1, len(self.market.tracking_states))

            # Cancel the order and verify that the change is saved.
            self.run_parallel(asyncio.sleep(5.0))
            self.market.cancel(trading_pair, order_id)
            if API_MOCK_ENABLED:
                HummingWsServerFactory.send_json_threadsafe(
                    self._ws_user_url,
                    FixtureDydx.WS_AFTER_CANCEL_BUY,
                    delay=0.1)
            self.run_parallel(self.market_logger.wait_for(OrderCancelledEvent))
            order_id = None
            self.assertEqual(0, len(self.market.limit_orders))
            self.assertEqual(0, len(self.market.tracking_states))
            saved_market_states = recorder.get_market_states(
                config_path, self.market)
            self.assertEqual(0, len(saved_market_states.saved_state))
        finally:
            if order_id is not None:
                self.market.cancel(trading_pair, order_id)
                if API_MOCK_ENABLED:
                    HummingWsServerFactory.send_json_threadsafe(
                        self._ws_user_url,
                        FixtureDydx.WS_AFTER_CANCEL_BUY,
                        delay=0.1)
                self.run_parallel(
                    self.market_logger.wait_for(OrderCancelledEvent))

            recorder.stop()
Esempio n. 21
0
    def setUpClass(cls):
        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
        if API_MOCK_ENABLED:

            cls.web_app = HummingWebApp.get_instance()
            cls.web_app.add_host_to_mock(cls.base_api_url, [])

            cls.web_app.start()

            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())

            cls._req_patcher = mock.patch.object(requests.Session,
                                                 "request",
                                                 autospec=True)
            cls._req_url_mock = cls._req_patcher.start()
            cls._req_url_mock.side_effect = HummingWebApp.reroute_request

            cls.web_app.update_response("get",
                                        cls.base_api_url,
                                        f"/v1/accounts/{WALLET_ADDRESS}",
                                        FixtureDydx.BALANCES,
                                        params={'number': f'{ACCOUNT_NUMBER}'})

            cls.web_app.update_response("get", cls.base_api_url, "/v2/markets",
                                        FixtureDydx.MARKETS)
            cls.web_app.update_response("get", cls.base_api_url,
                                        "/v1/orderbook/WETH-USDC",
                                        FixtureDydx.WETHUSDC_SNAP)
            cls._buy_order_exchange_id = "0xb0751a113c759779ff5fd6a53b37b26211a9\
              f8845d443323b9f877f32d9aafd9"

            cls._sell_order_exchange_id = "0x03dfd18edc2f26fc9298edcd28ca6cad4971\
              bd1f44d40253d5154b0d1f217680"

            cls.web_app.update_response(
                "delete", cls.base_api_url,
                f"/v2/orders/{cls._buy_order_exchange_id}",
                FixtureDydx.CANCEL_ORDER_BUY)
            cls.web_app.update_response(
                "delete", cls.base_api_url,
                f"/v2/orders/{cls._sell_order_exchange_id}",
                FixtureDydx.CANCEL_ORDER_SELL)
            ws_base_url = "wss://api.dydx.exchange/v1/ws"
            cls._ws_user_url = f"{ws_base_url}"
            HummingWsServerFactory.start_new_server(cls._ws_user_url)
            HummingWsServerFactory.start_new_server(f"{ws_base_url}")
            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = HummingWsServerFactory.reroute_ws_connect

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.dydx.\
                dydx_exchange.get_tracking_nonce")
            cls._t_nonce_mock = cls._t_nonce_patcher.start()

        cls.market: DydxExchange = DydxExchange(
            dydx_eth_private_key=PRIVATE_KEY,
            dydx_node_address=NODE_ADDRESS,
            poll_interval=10.0,
            trading_pairs=['WETH-USDC'],
            trading_required=True)

        print("Initializing Dydx market... ")
        cls.clock.add_iterator(cls.market)
        cls.stack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Esempio n. 22
0
    def test_limit_makers_unfilled(self):

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL,
                                         "/api/v2/orders",
                                         FixtureBeaxy.TEST_UNFILLED_ORDER1)

        self.assertGreater(self.market.get_balance("BTC"), 0.00005)
        trading_pair = "DASH-BTC"

        current_bid_price: Decimal = self.market.get_price(
            trading_pair, True) * Decimal('0.8')
        quantize_bid_price: Decimal = self.market.quantize_order_price(
            trading_pair, current_bid_price)
        bid_amount: Decimal = Decimal('0.01')
        quantized_bid_amount: Decimal = self.market.quantize_order_amount(
            trading_pair, bid_amount)

        current_ask_price: Decimal = self.market.get_price(trading_pair, False)
        quantize_ask_price: Decimal = self.market.quantize_order_price(
            trading_pair, current_ask_price)
        ask_amount: Decimal = Decimal('0.01')
        quantized_ask_amount: Decimal = self.market.quantize_order_amount(
            trading_pair, ask_amount)

        order_id1, exch_order_id_1 = self.place_order(
            True, trading_pair, quantized_bid_amount, OrderType.LIMIT,
            quantize_bid_price,
            [(3, FixtureBeaxy.TEST_UNFILLED_ORDER1_WS_ORDER_CREATED)])
        [order_created_event] = self.run_parallel(
            self.market_logger.wait_for(BuyOrderCreatedEvent))
        order_created_event: BuyOrderCreatedEvent = order_created_event
        self.assertEqual(order_id1, order_created_event.order_id)

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL,
                                         "/api/v2/orders",
                                         FixtureBeaxy.TEST_UNFILLED_ORDER2)

        order_id2, exch_order_id_2 = self.place_order(
            False, trading_pair, quantized_ask_amount, OrderType.LIMIT,
            quantize_ask_price,
            [(3, FixtureBeaxy.TEST_UNFILLED_ORDER2_WS_ORDER_CREATED)])
        [order_created_event] = self.run_parallel(
            self.market_logger.wait_for(SellOrderCreatedEvent))
        order_created_event: BuyOrderCreatedEvent = order_created_event
        self.assertEqual(order_id2, order_created_event.order_id)

        if API_MOCK_ENABLED:
            HummingWsServerFactory.send_str_threadsafe(
                BeaxyConstants.TradingApi.WS_BASE_URL,
                FixtureBeaxy.TEST_UNFILLED_ORDER1_WS_ORDER_CANCELED,
                delay=3)
            HummingWsServerFactory.send_str_threadsafe(
                BeaxyConstants.TradingApi.WS_BASE_URL,
                FixtureBeaxy.TEST_UNFILLED_ORDER2_WS_ORDER_CANCELED,
                delay=3)

            self.web_app.update_response("delete", PRIVET_API_BASE_URL,
                                         "/api/v1/orders", "")

        self.run_parallel(asyncio.sleep(1))
        [cancellation_results] = self.run_parallel(self.market.cancel_all(5))
        for cr in cancellation_results:
            self.assertEqual(cr.success, True)
Esempio n. 23
0
    def test_cancel_all(self):

        if API_MOCK_ENABLED:
            self.web_app.update_response(
                "delete", PRIVET_API_BASE_URL,
                "/api/v2/orders/open/435118B0-A7F7-40D2-A409-820E8FC342A2", '')

        self.assertGreater(self.market.get_balance("BTC"), 0.00005)
        self.assertGreater(self.market.get_balance("DASH"), 0.01)
        trading_pair = "DASH-BTC"

        # make worst price so order wont be executed
        current_bid_price: Decimal = self.market.get_price(
            trading_pair, True) * Decimal('0.5')
        quantize_bid_price: Decimal = self.market.quantize_order_price(
            trading_pair, current_bid_price)
        bid_amount: Decimal = Decimal('0.01')
        quantized_bid_amount: Decimal = self.market.quantize_order_amount(
            trading_pair, bid_amount)

        # make worst price so order wont be executed
        current_ask_price: Decimal = self.market.get_price(
            trading_pair, False) * Decimal('2')
        quantize_ask_price: Decimal = self.market.quantize_order_price(
            trading_pair, current_ask_price)
        ask_amount: Decimal = Decimal('0.01')
        quantized_ask_amount: Decimal = self.market.quantize_order_amount(
            trading_pair, ask_amount)

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL,
                                         "/api/v2/orders",
                                         FixtureBeaxy.TEST_CANCEL_ALL_ORDER1)

        _, exch_order_id_1 = self.place_order(True, trading_pair,
                                              quantized_bid_amount,
                                              OrderType.LIMIT_MAKER,
                                              quantize_bid_price)

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL,
                                         "/api/v2/orders",
                                         FixtureBeaxy.TEST_CANCEL_ALL_ORDER2)

        _, exch_order_id_2 = self.place_order(False, trading_pair,
                                              quantized_ask_amount,
                                              OrderType.LIMIT_MAKER,
                                              quantize_ask_price)
        self.run_parallel(asyncio.sleep(1))

        [cancellation_results] = self.run_parallel(self.market.cancel_all(5))

        if API_MOCK_ENABLED:
            HummingWsServerFactory.send_str_threadsafe(
                BeaxyConstants.TradingApi.WS_BASE_URL,
                FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER1_CANCELED,
                delay=3)
            HummingWsServerFactory.send_str_threadsafe(
                BeaxyConstants.TradingApi.WS_BASE_URL,
                FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER2_CANCELED,
                delay=3)

        for cr in cancellation_results:
            self.assertEqual(cr.success, True)
Esempio n. 24
0
    def setUpClass(cls):

        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()

        if API_MOCK_ENABLED:

            cls.web_app = HummingWebApp.get_instance()
            cls.web_app.add_host_to_mock(PRIVET_API_BASE_URL, [])
            cls.web_app.add_host_to_mock(PUBLIC_API_BASE_URL, [])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", PUBLIC_API_BASE_URL,
                                        "/api/v2/symbols",
                                        FixtureBeaxy.SYMBOLS)
            cls.web_app.update_response("get", PUBLIC_API_BASE_URL,
                                        "/api/v2/symbols/DASHBTC/book",
                                        FixtureBeaxy.TRADE_BOOK)
            cls.web_app.update_response("get", PUBLIC_API_BASE_URL,
                                        "/api/v2/symbols/DASHBTC/rate",
                                        FixtureBeaxy.EXCHANGE_RATE)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/health", FixtureBeaxy.HEALTH)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/wallets",
                                        FixtureBeaxy.BALANCES)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/tradingsettings",
                                        FixtureBeaxy.TRADE_SETTINGS)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/orders/open",
                                        FixtureBeaxy.ORDERS_OPEN_EMPTY)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/orders/closed",
                                        FixtureBeaxy.ORDERS_CLOSED_EMPTY)

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_exchange.get_tracking_nonce"
            )
            cls._t_nonce_mock = cls._t_nonce_patcher.start()

            HummingWsServerFactory.url_host_only = True
            HummingWsServerFactory.start_new_server(
                BeaxyConstants.TradingApi.WS_BASE_URL)
            HummingWsServerFactory.start_new_server(
                BeaxyConstants.PublicApi.WS_BASE_URL)

            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = HummingWsServerFactory.reroute_ws_connect

            cls._auth_confirm_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth._BeaxyAuth__login_confirm"
            )
            cls._auth_confirm_mock = cls._auth_confirm_patcher.start()
            cls._auth_session_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth._BeaxyAuth__get_session_data"
            )
            cls._auth_session_mock = cls._auth_session_patcher.start()
            cls._auth_session_mock.return_value = {
                "sign_key": 123,
                "session_id": '123'
            }
            cls._auth_headers_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth.get_token"
            )
            cls._auth_headers_mock = cls._auth_headers_patcher.start()
            cls._auth_headers_mock.return_value = '123'
            cls._auth_poll_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth._auth_token_polling_loop"
            )
            cls._auth_poll_mock = cls._auth_poll_patcher.start()

        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: BeaxyExchange = BeaxyExchange(API_KEY,
                                                  API_SECRET,
                                                  trading_pairs=["DASH-BTC"])

        if API_MOCK_ENABLED:

            async def mock_status_polling_task():
                pass

            # disable status polling as it will make orders update inconsistent from mock view
            cls.market._status_polling_task = asyncio.ensure_future(
                mock_status_polling_task())
            cls.ev_loop.run_until_complete(cls.market._update_balances())

        print("Initializing Beaxy market... this will take about a minute.")
        cls.clock.add_iterator(cls.market)
        cls.stack: contextlib.ExitStack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")