Forráskód Böngészése

Throttle Bitstamp reconciliation calls

Lukas Goldschmidt 1 hónapja
szülő
commit
a31467cd57
1 módosított fájl, 21 hozzáadás és 2 törlés
  1. 21 2
      src/exec_mcp/services_orders.py

+ 21 - 2
src/exec_mcp/services_orders.py

@@ -1,6 +1,8 @@
 from __future__ import annotations
 
 import json
+import os
+import time
 from datetime import datetime, timezone, timedelta
 from decimal import Decimal, ROUND_DOWN
 from uuid import uuid4
@@ -15,6 +17,13 @@ from .storage import get_connection
 OPEN_ORDER_STATUSES = {"open", "new", "partially_filled"}
 
 
+def _bitstamp_call_delay_seconds() -> float:
+    try:
+        return max(int(os.getenv("BITSTAMP_CALL_DELAY_MS", "250")) / 1000.0, 0.0)
+    except Exception:
+        return 0.25
+
+
 def _utc_now() -> str:
     return datetime.now(timezone.utc).isoformat()
 
@@ -168,14 +177,19 @@ def get_open_orders(*, account_id: str, client_id: str | None = None) -> dict:
                 (account_id, client_id),
             ).fetchall()
 
+    order_status_v2 = getattr(getattr(client, "trading", None), "order_status_v2", None)
+    if order_status_v2 is None:
+        return {"ok": True, "client_id": client_id, "orders": [dict(row) for row in rows]}
+
     orders = []
+    delay = _bitstamp_call_delay_seconds()
     for row in rows:
         order = dict(row)
         bitstamp_order_id = order.get("bitstamp_order_id")
         if not bitstamp_order_id:
             continue
         try:
-            result = client.trading.order_status_v2(order_id=str(bitstamp_order_id), omit_transactions=True)
+            result = order_status_v2(order_id=str(bitstamp_order_id), omit_transactions=True)
             status = _normalize_status(result.get("status", "unknown"))
             if status not in OPEN_ORDER_STATUSES:
                 _set_local_order_status(bitstamp_order_id=str(bitstamp_order_id), status=status)
@@ -183,13 +197,15 @@ def get_open_orders(*, account_id: str, client_id: str | None = None) -> dict:
             order["status"] = status
             order["raw_json"] = json.dumps(result)
             orders.append(order)
-        except BitstampError as exc:
+        except Exception as exc:
             msg = str(exc)
             if "not found" in msg.lower():
                 _set_local_order_status(bitstamp_order_id=str(bitstamp_order_id), status="missing")
                 continue
             # Best effort: keep the local record when the exchange cannot be queried.
             orders.append(order)
+        if delay > 0:
+            time.sleep(delay)
 
     return {"ok": True, "client_id": client_id, "orders": orders}
 
@@ -198,6 +214,7 @@ def cancel_all_orders(*, account_id: str, client_id: str | None = None) -> dict:
     client_id = _normalize_client_id(client_id)
     orders = get_open_orders(account_id=account_id, client_id=client_id)["orders"]
     results = []
+    delay = _bitstamp_call_delay_seconds()
     for order in orders:
         bitstamp_order_id = order.get("bitstamp_order_id")
         if not bitstamp_order_id:
@@ -212,6 +229,8 @@ def cancel_all_orders(*, account_id: str, client_id: str | None = None) -> dict:
                 results.append({"ok": False, "order_id": bitstamp_order_id, "error": detail, "status": "missing"})
                 continue
             raise
+        if delay > 0:
+            time.sleep(delay)
     return {"ok": True, "client_id": client_id, "cancelled": results, "count": len(results)}