mirror of
https://github.com/OpenByteInc/QuantDinger.git
synced 2026-09-28 15:22:56 +08:00
106 lines
3.1 KiB
Python
106 lines
3.1 KiB
Python
import inspect
|
|
from contextlib import contextmanager
|
|
|
|
from flask import Flask, g
|
|
|
|
from app.routes import quick_trade
|
|
from app.services.live_trading import fee_quote
|
|
from app.services.pending_orders import live_order_phases
|
|
|
|
|
|
class _Cursor:
|
|
def __init__(self, row=None):
|
|
self.row = row
|
|
self.query = ""
|
|
self.params = ()
|
|
|
|
def execute(self, query, params):
|
|
self.query = query
|
|
self.params = params
|
|
|
|
def fetchone(self):
|
|
return self.row
|
|
|
|
def close(self):
|
|
return None
|
|
|
|
|
|
class _Db:
|
|
def __init__(self, cursor):
|
|
self.cursor_value = cursor
|
|
self.committed = False
|
|
|
|
def cursor(self):
|
|
return self.cursor_value
|
|
|
|
def commit(self):
|
|
self.committed = True
|
|
|
|
|
|
def test_cancel_limit_order_uses_owned_record_and_reconciles_fill(monkeypatch):
|
|
select_cursor = _Cursor({
|
|
"id": 41,
|
|
"user_id": 99,
|
|
"credential_id": 305,
|
|
"exchange_id": "okx",
|
|
"symbol": "BTC/USDT",
|
|
"order_type": "limit",
|
|
"market_type": "swap",
|
|
"status": "submitted",
|
|
"exchange_order_id": "order-41",
|
|
"filled_amount": 0,
|
|
"avg_fill_price": 0,
|
|
"commission": 0,
|
|
"commission_ccy": "",
|
|
"commission_quote": None,
|
|
"raw_result": {"_quick_trade": {"requested_base_qty": 0.01, "client_order_id": "client-41"}},
|
|
})
|
|
update_cursor = _Cursor()
|
|
databases = [_Db(select_cursor), _Db(update_cursor)]
|
|
|
|
@contextmanager
|
|
def fake_connection():
|
|
yield databases.pop(0)
|
|
|
|
client = object()
|
|
captured = {}
|
|
|
|
def fake_cancel(**kwargs):
|
|
captured.update(kwargs)
|
|
return {"status": "cancelled"}
|
|
|
|
monkeypatch.setattr(quick_trade, "get_db_connection", fake_connection)
|
|
monkeypatch.setattr(quick_trade, "build_exchange_config", lambda *args, **kwargs: {"market_type": "swap"})
|
|
monkeypatch.setattr(quick_trade, "create_exchange_client", lambda *args, **kwargs: client)
|
|
monkeypatch.setattr(live_order_phases, "cancel_live_limit_order", fake_cancel)
|
|
monkeypatch.setattr(
|
|
quick_trade,
|
|
"enrich_fill",
|
|
lambda *args, **kwargs: {
|
|
"filled": 0.002,
|
|
"avg_price": 75000,
|
|
"fee": 0.03,
|
|
"fee_ccy": "USDT",
|
|
"status": "cancelled",
|
|
},
|
|
)
|
|
monkeypatch.setattr(fee_quote, "fee_to_quote", lambda *args, **kwargs: 0.03)
|
|
|
|
app = Flask(__name__)
|
|
handler = inspect.unwrap(quick_trade.cancel_order)
|
|
with app.test_request_context("/api/quick-trade/cancel-order", method="POST"):
|
|
g.user_id = 99
|
|
response = handler({"trade_id": 41})
|
|
|
|
payload = response.get_json()
|
|
assert payload["code"] == 1
|
|
assert payload["data"]["status"] == "cancelled"
|
|
assert payload["data"]["filled_amount"] == 0.002
|
|
assert captured["client"] is client
|
|
assert captured["order_id"] == "order-41"
|
|
assert captured["client_order_id"] == "client-41"
|
|
assert select_cursor.params == (41, 99)
|
|
assert "status = %s" in update_cursor.query
|
|
assert update_cursor.params[0] == "cancelled"
|
|
assert update_cursor.params[-2:] == (41, 99)
|