Пример #1
0
 def test_update_trading_rules(self, mock_api):
     self.exchange._trading_pairs.append("XBT-USDT")
     url = web_utils.rest_url(CONSTANTS.EXCHANGE_INFO_URL,
                              domain=self.domain)
     regex_url = re.compile(f"^{url}".replace(".",
                                              r"\.").replace("?", r"\?"))
     mock_response: Dict[str, Any] = [
         {
             "symbol": "COINALPHA_HBOT",
             "rootSymbol": "COINALPHA",
             "quoteCurrency": "HBOT",
             "settlCurrency": "HBOT",
             "lotSize": 1.0,
             "tickSize": 0.0001,
             "minProvideSize": 0.001,
             "maxOrderQty": 1000000
         },
         {
             "symbol": "XBT_USDT",
             "rootSymbol": "XBT",
             "quoteCurrency": "USDT",
             "lotSize": 100,
             "tickSize": 0.5,
             "settlCurrency": "XBt",
             "maxOrderQty": 10000000
         },
     ]
     mock_api.get(regex_url, status=200, body=json.dumps(mock_response))
     url_2 = web_utils.rest_url(CONSTANTS.TICKER_PRICE_URL,
                                domain=self.domain)
     regex_url_2 = re.compile(f"^{url_2}".replace(".", r"\.").replace(
         "?", r"\?"))
     mock_response_2: List[Dict[str, Any]] = [{
         "symbol": "COINALPHA_HBOT",
         "lastPrice": 1000.0
     }]
     mock_api.get(regex_url_2, body=json.dumps(mock_response_2))
     url_3 = web_utils.rest_url(CONSTANTS.TICKER_PRICE_URL,
                                domain=self.domain)
     regex_url_3 = re.compile(f"^{url_3}".replace(".", r"\.").replace(
         "?", r"\?"))
     mock_response_3: List[Dict[str, Any]] = [{
         "symbol": "XBT_USDT",
         "lastPrice": 1000.0
     }]
     mock_api.get(regex_url_3, body=json.dumps(mock_response_3))
     self.async_run_with_timeout(self.exchange._update_trading_rules())
     self.assertTrue(len(self.exchange._trading_rules) > 0)
     quant_amount = self.exchange.quantize_order_amount(
         'XBT-USDT', Decimal('0.00001'), Decimal('10000'))
     self.assertEqual(quant_amount, Decimal('0.000010'))
     quant_price = self.exchange.quantize_order_price(
         'COINALPHA-HBOT', Decimal('1'))
     self.assertEqual(quant_price, Decimal('1.0'))
     quant_amount = self.exchange.quantize_order_amount(
         'COINALPHA-HBOT', Decimal('0.00001'), Decimal('10000'))
     self.assertEqual(quant_amount, Decimal('0.000010'))
     self.exchange._trading_pairs.remove("XBT-USDT")
    def test_listen_for_order_book_snapshots_successful(self, mock_api):
        url = web_utils.rest_url(
            CONSTANTS.SNAPSHOT_REST_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))
        mock_response = [{
            'symbol': 'ETH_USDT',
            'side': 'Sell',
            'size': 348,
            'price': 3127.4,
            'id': 33337777
        }]
        mock_api.get(regex_url, status=200, body=json.dumps(mock_response))

        msg_queue: asyncio.Queue = asyncio.Queue()
        self.listening_task = self.ev_loop.create_task(
            self.data_source.listen_for_order_book_snapshots(self.ev_loop, msg_queue)
        )

        result = self.async_run_with_timeout(msg_queue.get())

        self.assertIsInstance(result, OrderBookMessage)
        self.assertEqual(OrderBookMessageType.SNAPSHOT, result.type)
        self.assertTrue(result.has_update_id)
        self.assertEqual(self.trading_pair, result.content["trading_pair"])
    def test_rest_url_testnet_domain(self):
        path_url = "/TEST_PATH_URL"

        expected_url = f"{CONSTANTS.TESTNET_BASE_URL}{path_url}"
        self.assertEqual(
            expected_url,
            web_utils.rest_url(path_url=path_url, domain="testnet"))
Пример #4
0
    def test_update_order_status_failure_old_order(self, req_mock,
                                                   mock_timestamp):
        self.exchange._last_poll_timestamp = 0
        mock_timestamp.return_value = 1

        self.exchange.start_tracking_order(order_side=TradeType.SELL,
                                           client_order_id="OID1",
                                           order_type=OrderType.LIMIT,
                                           created_at=0,
                                           hash="8886774",
                                           trading_pair=self.trading_pair,
                                           price=Decimal("10000"),
                                           amount=Decimal("1"))

        order = [{
            "clOrdID": "OID2",
            "leavesQty": 0.5,
            "ordStatus": "PartiallyFilled",
            "avgPx": 10001,
        }]

        url = web_utils.rest_url(CONSTANTS.ORDER_URL, domain=self.domain)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        req_mock.get(regex_url, body=json.dumps(order))

        self.async_run_with_timeout(self.exchange._update_order_status())
        self.assertEqual(len(self.exchange.in_flight_orders), 0)
Пример #5
0
    def test_create_order_exception(self, req_mock):
        url = web_utils.rest_url(CONSTANTS.ORDER_URL, domain=self.domain)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        create_response = {
            "updateTime": int(self.start_timestamp),
            "ordStatus": "Canceled",
            "orderID": "8886774"
        }

        req_mock.post(regex_url, body=json.dumps(create_response))

        margin_asset = self.quote_asset
        mocked_response = self._get_exchange_info_mock_response(margin_asset)
        trading_rules = self.async_run_with_timeout(
            self.exchange._format_trading_rules(mocked_response))
        self.exchange._trading_rules[self.trading_pair] = trading_rules[0]

        self.async_run_with_timeout(
            self.exchange.execute_sell(order_id="OID1",
                                       trading_pair=self.trading_pair,
                                       amount=Decimal("10000"),
                                       order_type=OrderType.LIMIT,
                                       price=Decimal("1010")))

        self.assertTrue("OID1" not in self.exchange._in_flight_orders)
Пример #6
0
    def test_update_balances(self, mock_api):
        url = web_utils.rest_url(CONSTANTS.ACCOUNT_INFO_URL,
                                 domain=self.domain)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        response = [{
            "currency": "USDT",
            "amount": 100000000,
            "pendingCredit": 2000000,
            "pendingDebit": 0
        }, {
            "currency": "XBT",
            "amount": 1000000000,
            "pendingCredit": 20000000,
            "pendingDebit": 0
        }]

        mock_api.get(regex_url, body=json.dumps(response))

        url_2 = web_utils.rest_url(CONSTANTS.TOKEN_INFO_URL,
                                   domain=self.domain)
        regex_url_2 = re.compile(f"^{url_2}".replace(".", r"\.").replace(
            "?", r"\?"))

        response_2 = [{
            "asset": "USDT",
            "scale": 6
        }, {
            "asset": "XBT",
            "scale": 8,
        }]

        mock_api.get(regex_url_2, body=json.dumps(response_2))
        self.async_run_with_timeout(self.exchange._update_balances())

        available_balances = self.exchange.available_balances
        total_balances = self.exchange.get_all_balances()

        self.assertEqual(Decimal("98"), available_balances["USDT"])
        self.assertEqual(Decimal("9.8"), available_balances["XBT"])
        self.assertEqual(Decimal("100"), total_balances["USDT"])
        self.assertEqual(Decimal("10"), total_balances["XBT"])
    def test_init_trading_pair_symbols_failure(self, mock_api):
        BitmexAPIOrderBookDataSource._trading_pair_symbol_map = {}
        url = web_utils.rest_url(
            CONSTANTS.EXCHANGE_INFO_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))

        mock_api.get(regex_url, status=400, body=json.dumps(["ERROR"]))

        map = self.async_run_with_timeout(self.data_source.trading_pair_symbol_map(domain=self.domain))
        self.assertEqual(0, len(map))
    def test_get_snapshot_exception_raised(self, mock_api):
        url = web_utils.rest_url(
            CONSTANTS.SNAPSHOT_REST_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))
        mock_api.get(regex_url, status=400, body=json.dumps(["ERROR"]))

        with self.assertRaises(IOError) as context:
            self.async_run_with_timeout(
                self.data_source.get_snapshot(trading_pair=self.trading_pair, domain=self.domain)
            )

        self.assertEqual(str(context.exception), "Error executing request GET /orderBook/L2. HTTP status is 400. Error: [\"ERROR\"]")
 def test_init_trading_pair_symbols_successful(self, mock_api):
     url = web_utils.rest_url(
         CONSTANTS.EXCHANGE_INFO_URL, domain=self.domain
     )
     regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))
     mock_response: List[Dict[str, Any]] = [
         {
             "symbol": "ETH_USDT",
             "rootSymbol": "ETH",
             "quoteCurrency": "USDT"
         },
     ]
     mock_api.get(regex_url, status=200, body=json.dumps(mock_response))
     self.async_run_with_timeout(self.data_source.init_trading_pair_symbols(domain=self.domain))
     self.assertEqual(1, len(self.data_source._trading_pair_symbol_map))
    def test_get_last_traded_prices(self, mock_api):
        url = web_utils.rest_url(
            CONSTANTS.TICKER_PRICE_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))
        mock_response: List[Dict[str, Any]] = [{
            "symbol": "ETH_USDT",
            "lastPrice": 100.0
        }]
        mock_api.get(regex_url, body=json.dumps(mock_response))

        result: Dict[str, Any] = self.async_run_with_timeout(
            self.data_source.get_last_traded_prices(trading_pairs=[self.trading_pair], domain=self.domain)
        )
        self.assertTrue(self.trading_pair in result)
        self.assertEqual(100.0, result[self.trading_pair])
Пример #11
0
    def test_update_order_status_successful(self, req_mock, mock_timestamp):
        self.exchange._last_poll_timestamp = 0
        mock_timestamp.return_value = 1

        self.exchange.start_tracking_order(order_side=TradeType.SELL,
                                           client_order_id="OID1",
                                           order_type=OrderType.LIMIT,
                                           created_at=time.time(),
                                           hash="8886774",
                                           trading_pair=self.trading_pair,
                                           price=Decimal("10000"),
                                           amount=Decimal("1"))

        order = [{
            "clOrdID": "OID1",
            "leavesQty": 500000000,
            "ordStatus": "PartiallyFilled",
            "avgPx": 10001,
        }]

        url = web_utils.rest_url(CONSTANTS.ORDER_URL, domain=self.domain)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        req_mock.get(regex_url, body=json.dumps(order))

        self.async_run_with_timeout(self.exchange._update_order_status())

        in_flight_orders = self.exchange._in_flight_orders

        self.assertTrue("OID1" in in_flight_orders)

        self.assertEqual("OID1", in_flight_orders["OID1"].client_order_id)
        self.assertEqual(f"{self.base_asset}-{self.quote_asset}",
                         in_flight_orders["OID1"].trading_pair)
        self.assertEqual(OrderType.LIMIT, in_flight_orders["OID1"].order_type)
        self.assertEqual(TradeType.SELL, in_flight_orders["OID1"].trade_type)
        self.assertEqual(10000, in_flight_orders["OID1"].price)
        self.assertEqual(1, in_flight_orders["OID1"].amount)
        self.assertEqual(BitmexOrderStatus.PartiallyFilled,
                         in_flight_orders["OID1"].state)
        # Processing an order update should not impact trade fill information
        self.assertEqual(Decimal("0.5"),
                         in_flight_orders["OID1"].executed_amount_base)
        self.assertEqual(Decimal("5000.5"),
                         in_flight_orders["OID1"].executed_amount_quote)
    def test_listen_for_order_book_snapshots_cancelled_error_raised(self, mock_api):
        url = web_utils.rest_url(
            CONSTANTS.SNAPSHOT_REST_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))

        mock_api.get(regex_url, exception=asyncio.CancelledError)

        msg_queue: asyncio.Queue = asyncio.Queue()

        with self.assertRaises(asyncio.CancelledError):
            self.listening_task = self.ev_loop.create_task(
                self.data_source.listen_for_order_book_snapshots(self.ev_loop, msg_queue)
            )
            self.async_run_with_timeout(self.listening_task)

        self.assertEqual(0, msg_queue.qsize())
    def test_get_snapshot_successful(self, mock_api):
        url = web_utils.rest_url(
            CONSTANTS.SNAPSHOT_REST_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))
        mock_response = [{
            'symbol': 'ETH_USDT',
            'side': 'Sell',
            'size': 348,
            'price': 3127.4
        }]
        mock_api.get(regex_url, status=200, body=json.dumps(mock_response))

        result: Dict[str, Any] = self.async_run_with_timeout(
            self.data_source.get_snapshot(trading_pair=self.trading_pair, domain=self.domain)
        )
        self.assertEqual(mock_response, result)
Пример #14
0
    def test_cancel_all_successful(self, mocked_api, mock_wait):
        mock_wait.return_value = True
        url = web_utils.rest_url(CONSTANTS.ORDER_URL, domain=self.domain)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        cancel_response = {"code": 200, "msg": "success"}
        mocked_api.delete(regex_url, body=json.dumps(cancel_response))

        self.exchange.start_tracking_order(order_side=TradeType.BUY,
                                           client_order_id="OID1",
                                           order_type=OrderType.LIMIT,
                                           created_at=time.time(),
                                           hash="8886774",
                                           trading_pair=self.trading_pair,
                                           price=Decimal("10000"),
                                           amount=Decimal("1"))

        self.exchange.start_tracking_order(order_side=TradeType.SELL,
                                           client_order_id="OID2",
                                           order_type=OrderType.LIMIT,
                                           created_at=time.time(),
                                           hash="8886774",
                                           trading_pair=self.trading_pair,
                                           price=Decimal("10000"),
                                           amount=Decimal("1"))

        self.assertTrue("OID1" in self.exchange._in_flight_orders)
        self.assertTrue("OID2" in self.exchange._in_flight_orders)

        cancellation_results = self.async_run_with_timeout(
            self.exchange.cancel_all(timeout_seconds=1))

        order_cancelled_events = self.order_cancelled_logger.event_log

        self.assertEqual(0, len(order_cancelled_events))
        self.assertEqual(2, len(cancellation_results))
        self.assertEqual("OID1", cancellation_results[0].order_id)
        self.assertEqual("OID2", cancellation_results[1].order_id)
    def test_listen_for_order_book_snapshots_logs_exception_error_with_response(self, mock_api):
        url = web_utils.rest_url(
            CONSTANTS.SNAPSHOT_REST_URL, domain=self.domain
        )
        regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))

        mock_response = {
            "m": 1,
            "i": 2,
        }
        mock_api.get(regex_url, body=json.dumps(mock_response), callback=self.resume_test_callback)

        msg_queue: asyncio.Queue = asyncio.Queue()

        self.listening_task = self.ev_loop.create_task(
            self.data_source.listen_for_order_book_snapshots(self.ev_loop, msg_queue)
        )

        self.async_run_with_timeout(self.resume_test_event.wait())

        self.assertTrue(
            self._is_logged("ERROR", "Unexpected error occurred fetching orderbook snapshots. Retrying in 5 seconds...")
        )
Пример #16
0
    def test_cancel_unknown_old_order(self, req_mock):
        url = web_utils.rest_url(CONSTANTS.ORDER_URL, domain=self.domain)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        cancel_response = {
            "error": {
                "message": "order not found",
                "name": "Not Found"
            }
        }
        req_mock.delete(regex_url,
                        status=400,
                        body=json.dumps(cancel_response))

        self.exchange.start_tracking_order(order_side=TradeType.BUY,
                                           client_order_id="OID1",
                                           order_type=OrderType.LIMIT,
                                           created_at=0.0,
                                           hash="8886774",
                                           trading_pair=self.trading_pair,
                                           price=Decimal("10000"),
                                           amount=Decimal("1"))

        tracked_order = self.exchange.in_flight_orders.get("OID1")
        tracked_order.state = BitmexOrderStatus.New

        self.assertTrue("OID1" in self.exchange._in_flight_orders)
        try:
            cancellation_result = self.async_run_with_timeout(
                self.exchange.cancel_order("OID1"))
        except Exception:
            pass

        self.assertFalse(cancellation_result)

        self.assertTrue("OID1" not in self.exchange._in_flight_orders)
 def test_get_trading_pair_multipliers(self, mock_api):
     url = web_utils.rest_url(CONSTANTS.EXCHANGE_INFO_URL,
                              domain="bitmex_perpetual")
     regex_url = re.compile(f"^{url}".replace(".",
                                              r"\.").replace("?", r"\?"))
     mock_response: Dict[str, Any] = [
         {
             "symbol": "COINALPHA_HBOT",
             "rootSymbol": "COINALPHA",
             "quoteCurrency": "HBOT",
             "settlCurrency": "HBOT",
             "lotSize": 1.0,
             "tickSize": 0.0001,
             "minProvideSize": 0.001,
             "maxOrderQty": 1000000,
             "underlyingToPositionMultiplier": 100,
             "quoteToSettleMultiplier": 1000,
             "positionCurrency": "COINALPHA"
         },
     ]
     mock_api.get(regex_url, status=200, body=json.dumps(mock_response))
     tp_multipliers = self._ev_loop.run_until_complete(
         utils.get_trading_pair_multipliers("COINALPHA_HBOT"))
     self.assertTrue(tp_multipliers.base_multiplier > 0)
 def test_get_new_order_book(self, mock_api):
     url = web_utils.rest_url(
         CONSTANTS.SNAPSHOT_REST_URL, domain=self.domain
     )
     regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?"))
     mock_response = [
         {
             'symbol': 'ETH_USDT',
             'side': 'Sell',
             'size': 348,
             'price': 3127.4,
             'id': 2543
         },
         {
             'symbol': 'ETH_USDT',
             'side': 'Buy',
             'size': 100,
             'price': 3000.1,
             'id': 2555
         }
     ]
     mock_api.get(regex_url, status=200, body=json.dumps(mock_response))
     result = self.async_run_with_timeout(self.data_source.get_new_order_book(trading_pair=self.trading_pair))
     self.assertIsInstance(result, OrderBook)
    def test_rest_url_main_domain(self):
        path_url = "/TEST_PATH_URL"

        expected_url = f"{CONSTANTS.BASE_URL}{path_url}"
        self.assertEqual(expected_url, web_utils.rest_url(path_url))
        self.assertEqual(expected_url, web_utils.rest_url(path_url))