def test_execute_cancel_success(self, mock_cancel): order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0, initial_state="Working", ) self.exchange._in_flight_orders.update({ order.client_order_id: order }) mock_response = { "code": 200, "data": {"123": "success"} } url = CONSTANTS.MEXC_BASE_URL + CONSTANTS.MEXC_ORDER_CANCEL regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?")) mock_cancel.delete(regex_url, body=json.dumps(mock_response)) self.mocking_assistant.configure_http_request_mock(mock_cancel) self.mocking_assistant.add_http_response(mock_cancel, 200, mock_response, "") result = self.async_run_with_timeout( self.exchange.execute_cancel(self.trading_pair, order.client_order_id) ) self.assertIsNone(result)
def test_update_order_status_error_response(self, mock_api, mock_ts): # Simulates order being tracked order: MexcInFlightOrder = MexcInFlightOrder( "0", "2628", self.trading_pair, OrderType.LIMIT, TradeType.SELL, Decimal(str(41720.83)), Decimal("1"), creation_timestamp=1640001112.0) self.exchange._in_flight_orders.update({ order.client_order_id: order }) self.assertTrue(1, len(self.exchange.in_flight_orders)) ts: float = time.time() mock_ts.return_value = ts self.exchange._current_timestamp = ts # Add TradeHistory API Response url = CONSTANTS.MEXC_BASE_URL + CONSTANTS.MEXC_ORDER_DETAILS_URL regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?")) mock_response = { "result": False, "errormsg": "Invalid Request", "errorcode": 100, "detail": None } mock_api.get(regex_url, body=json.dumps(mock_response)) self.async_run_with_timeout(self.exchange._update_order_status()) self.assertEqual(1, len(self.exchange.in_flight_orders))
def test_execute_cancel_all_success(self, mock_post_request): order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0) self.exchange._in_flight_orders.update({ order.client_order_id: order }) mock_response = { "code": 200, "data": { "0": "success" } } url = CONSTANTS.MEXC_BASE_URL + CONSTANTS.MEXC_ORDER_CANCEL regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?")) mock_post_request.delete(regex_url, body=json.dumps(mock_response)) cancellation_results = self.async_run_with_timeout( self.exchange.cancel_all(10) ) self.assertEqual(1, len(cancellation_results)) self.assertEqual("0", cancellation_results[0].order_id) self.assertTrue(cancellation_results[0].success)
def test_execute_cancel_fail(self, mock_cancel, mock_main_app): order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0, initial_state="Working", ) self.exchange._in_flight_orders.update({ order.client_order_id: order }) mock_response = { "code": 100, "data": {"123": "success"} } url = CONSTANTS.MEXC_BASE_URL + CONSTANTS.MEXC_ORDER_CANCEL regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?")) mock_cancel.delete(regex_url, body=json.dumps(mock_response)) self.async_run_with_timeout( self.exchange.execute_cancel(self.trading_pair, order.client_order_id) ) self._is_logged("NETWORK", "Failed to cancel order 0 : MexcAPIError('Order could not be canceled')")
def test_is_done(self): order = MexcInFlightOrder.from_json(self._example_json()) self.assertFalse(order.is_done) for status in ["FILLED", "CANCELED", "PARTIALLY_CANCELED"]: order.last_state = status self.assertTrue(order.is_done)
def start_tracking_order(self, order_id: str, exchange_order_id: Optional[str], trading_pair: str, trade_type: TradeType, price: Decimal, amount: Decimal, order_type: OrderType): self._in_flight_orders[order_id] = MexcInFlightOrder( client_order_id=order_id, exchange_order_id=exchange_order_id, trading_pair=trading_pair, order_type=order_type, trade_type=trade_type, price=price, amount=amount)
def test_tracking_states_order_done(self): order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0, initial_state="FILLED") self.exchange._in_flight_orders.update({order.client_order_id: order}) self.assertEqual(0, len(self.exchange.tracking_states))
def test_create_from_json(self): order = MexcInFlightOrder.from_json(self._example_json()) self.assertEqual("C1", order.client_order_id) self.assertEqual("1", order.exchange_order_id) self.assertEqual("BTC-USDT", order.trading_pair) self.assertEqual(OrderType.LIMIT, order.order_type) self.assertEqual(TradeType.BUY, order.trade_type) self.assertEqual(Decimal("35000"), order.price) self.assertEqual(Decimal("1.1"), order.amount) self.assertEqual(Decimal("0.5"), order.executed_amount_base) self.assertEqual(Decimal("15000"), order.executed_amount_quote) self.assertEqual(order.base_asset, order.fee_asset) self.assertEqual(Decimal("0"), order.fee_paid) self.assertEqual("Working", order.last_state)
def test_limit_orders(self): self.assertEqual(0, len(self.exchange.limit_orders)) # Simulate orders being placed and tracked order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0) self.exchange._in_flight_orders.update({order.client_order_id: order}) self.assertEqual(1, len(self.exchange.limit_orders))
def test_restore_tracking_states(self): order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0) order_json = order.to_json() self.exchange.restore_tracking_states({order.client_order_id: order_json}) self.assertEqual(1, len(self.exchange.in_flight_orders)) self.assertEqual(str(self.exchange.in_flight_orders[order.client_order_id]), str(order))
def test_update_order_status(self, mock_api, mock_ts): # Simulates order being tracked order: MexcInFlightOrder = MexcInFlightOrder( "0", "2628", self.trading_pair, OrderType.LIMIT, TradeType.SELL, Decimal(str(41720.83)), Decimal("1"), 1640001112.0, "Working", ) self.exchange._in_flight_orders.update({ order.client_order_id: order }) self.exchange._last_poll_timestamp = 10 ts: float = time.time() mock_ts.return_value = ts self.exchange._current_timestamp = ts self.assertTrue(1, len(self.exchange.in_flight_orders)) # Add TradeHistory API Response url = CONSTANTS.MEXC_BASE_URL + CONSTANTS.MEXC_ORDER_DETAILS_URL regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?")) mock_response = { "code": 200, "data": [ { "id": "504feca6ba6349e39c82262caf0be3f4", "symbol": "MX_USDT", "price": "3.001", "quantity": "30", "state": "CANCELED", "type": "BID", "deal_quantity": "0", "deal_amount": "0", "create_time": 1573117266000 } ] } mock_api.get(regex_url, body=json.dumps(mock_response)) self.async_run_with_timeout(self.exchange._update_order_status()) self.assertEqual(0, len(self.exchange.in_flight_orders))
def test_instance_creation(self): order = MexcInFlightOrder(client_order_id="C1", exchange_order_id="1", trading_pair="BTC-USDT", order_type=OrderType.LIMIT, trade_type=TradeType.SELL, price=Decimal("35000"), amount=Decimal("1.1")) self.assertEqual("C1", order.client_order_id) self.assertEqual("1", order.exchange_order_id) self.assertEqual("BTC-USDT", order.trading_pair) self.assertEqual(OrderType.LIMIT, order.order_type) self.assertEqual(TradeType.SELL, order.trade_type) self.assertEqual(Decimal("35000"), order.price) self.assertEqual(Decimal("1.1"), order.amount) self.assertEqual(Decimal("0"), order.executed_amount_base) self.assertEqual(Decimal("0"), order.executed_amount_quote) self.assertEqual(order.quote_asset, order.fee_asset) self.assertEqual(Decimal("0"), order.fee_paid)
def test_cancel(self, mock_cancel): mock_cancel.return_value = None order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0) self.exchange._in_flight_orders.update({order.client_order_id: order}) # Note: BUY simply returns immediately with the client order id. return_val: str = self.exchange.cancel(self.trading_pair, order.client_order_id) # Order ID is simply a timestamp. The assertion below checks if it is created within 1 sec self.assertTrue(order.client_order_id, return_val)
def test_execute_cancel_cancels(self, mock_cancel): order: MexcInFlightOrder = MexcInFlightOrder( client_order_id="0", exchange_order_id="123", trading_pair=self.trading_pair, order_type=OrderType.LIMIT, trade_type=TradeType.BUY, price=Decimal(10.0), amount=Decimal(1.0), creation_timestamp=1640001112.0, initial_state="Working", ) self.exchange._in_flight_orders.update({order.client_order_id: order}) url = CONSTANTS.MEXC_BASE_URL + CONSTANTS.MEXC_ORDER_CANCEL regex_url = re.compile(f"^{url}".replace(".", r"\.").replace("?", r"\?")) mock_cancel.delete(regex_url, exception=asyncio.CancelledError) with self.assertRaises(asyncio.CancelledError): self.async_run_with_timeout( self.exchange.execute_cancel(self.trading_pair, order.client_order_id))
def restore_tracking_states(self, saved_states: Dict[str, Any]): self._in_flight_orders.update({ key: MexcInFlightOrder.from_json(value) for key, value in saved_states.items() })
def test_is_failure(self): order = MexcInFlightOrder.from_json(self._example_json()) for status in ["NEW", "PARTIALLY_FILLED"]: order.last_state = status self.assertFalse(order.is_failure)
def test_is_cancelled(self): order = MexcInFlightOrder.from_json(self._example_json()) for status in ["Working", "FullyExecuted", "Rejected"]: order.last_state = status self.assertFalse(order.is_cancelled)
def test_mark_as_filled(self): order = MexcInFlightOrder.from_json(self._example_json()) order.mark_as_filled() self.assertEqual("FILLED", order.last_state)
def test_to_json(self): order = MexcInFlightOrder.from_json(self._example_json()) self.assertEqual(self._example_json(), order.to_json())