Fix stale pending orders after CTP rejection or cancel.
When the exchange rejects or cancels an order, close local pending monitors once the order leaves CTP active list instead of waiting for the full timeout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
"""Deploy pending order reconcile fix and verify stale monitors cleared."""
|
||||
import paramiko
|
||||
import sys
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
|
||||
FILES = [
|
||||
"order_pending.py",
|
||||
"install_trading.py",
|
||||
]
|
||||
|
||||
VERIFY = textwrap.dedent(
|
||||
'''
|
||||
import sqlite3, urllib.request, urllib.parse, http.cookiejar, json
|
||||
|
||||
conn = sqlite3.connect("/opt/qihuo/data.db")
|
||||
conn.row_factory = sqlite3.Row
|
||||
pending = conn.execute(
|
||||
"SELECT id, symbol, direction, vt_order_id, status FROM trade_order_monitors WHERE status='pending'"
|
||||
).fetchall()
|
||||
print("pending_monitors", len(pending))
|
||||
for r in pending:
|
||||
print(dict(r))
|
||||
|
||||
jar = http.cookiejar.CookieJar()
|
||||
op = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
|
||||
user = pwd = ""
|
||||
for line in open("/opt/qihuo/.env"):
|
||||
line = line.strip()
|
||||
if line.startswith("ADMIN_USERNAME="):
|
||||
user = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||||
if line.startswith("ADMIN_PASSWORD="):
|
||||
pwd = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||||
op.open(urllib.request.Request(
|
||||
"http://127.0.0.1:6600/login",
|
||||
urllib.parse.urlencode({"username": user, "password": pwd}).encode(),
|
||||
))
|
||||
raw = op.open("http://127.0.0.1:6600/api/trading/live").read().decode()
|
||||
data = json.loads(raw)
|
||||
orders = data.get("active_orders") or []
|
||||
cj = [o for o in orders if "CJ" in (o.get("symbol_code") or "").upper()]
|
||||
print("active_orders", len(orders), "cj_orders", len(cj))
|
||||
ok = True
|
||||
if cj:
|
||||
ok = False
|
||||
print("FAIL still showing CJ pending in active_orders", cj)
|
||||
if ok:
|
||||
print("VERIFY PASS")
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
c = paramiko.SSHClient()
|
||||
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
c.connect("192.168.8.21", username="root", password="woaini88", timeout=15)
|
||||
sftp = c.open_sftp()
|
||||
for rel in FILES:
|
||||
local = root / rel
|
||||
remote = f"/opt/qihuo/{rel.replace(chr(92), '/')}"
|
||||
sftp.put(str(local), remote)
|
||||
print("uploaded", rel)
|
||||
sftp.close()
|
||||
|
||||
for cmd in (
|
||||
"cd /opt/qihuo && pm2 restart qihuo",
|
||||
"sleep 4",
|
||||
):
|
||||
print(">>>", cmd)
|
||||
_, stdout, stderr = c.exec_command(cmd)
|
||||
out = stdout.read().decode("utf-8", errors="replace")
|
||||
err = stderr.read().decode("utf-8", errors="replace")
|
||||
if out.strip():
|
||||
print(out.strip())
|
||||
if err.strip():
|
||||
print(err.strip())
|
||||
|
||||
sftp = c.open_sftp()
|
||||
with sftp.open("/tmp/verify_pending_fix.py", "w") as f:
|
||||
f.write(VERIFY)
|
||||
sftp.close()
|
||||
|
||||
_, stdout, stderr = c.exec_command("/opt/qihuo/venv/bin/python /tmp/verify_pending_fix.py")
|
||||
print(stdout.read().decode("utf-8", errors="replace"))
|
||||
err = stderr.read().decode("utf-8", errors="replace")
|
||||
if err.strip():
|
||||
print(err.strip())
|
||||
c.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,55 @@
|
||||
import paramiko
|
||||
import sys
|
||||
|
||||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||||
|
||||
VERIFY = r"""
|
||||
import sqlite3, urllib.request, urllib.parse, http.cookiejar, json, os
|
||||
|
||||
db = "/opt/qihuo/futures.db"
|
||||
print("db", db)
|
||||
|
||||
conn = sqlite3.connect(db)
|
||||
conn.row_factory = sqlite3.Row
|
||||
pending = conn.execute(
|
||||
"SELECT id, symbol, direction, vt_order_id, status FROM trade_order_monitors WHERE status='pending'"
|
||||
).fetchall()
|
||||
print("pending_monitors", len(pending))
|
||||
for r in pending:
|
||||
print(dict(r))
|
||||
|
||||
jar = http.cookiejar.CookieJar()
|
||||
op = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
|
||||
user = pwd = ""
|
||||
for line in open("/opt/qihuo/.env"):
|
||||
line = line.strip()
|
||||
if line.startswith("ADMIN_USERNAME="):
|
||||
user = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||||
if line.startswith("ADMIN_PASSWORD="):
|
||||
pwd = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||||
op.open(urllib.request.Request(
|
||||
"http://127.0.0.1:6600/login",
|
||||
urllib.parse.urlencode({"username": user, "password": pwd}).encode(),
|
||||
))
|
||||
raw = op.open("http://127.0.0.1:6600/api/trading/live").read().decode()
|
||||
data = json.loads(raw)
|
||||
orders = data.get("active_orders") or []
|
||||
cj = [o for o in orders if "CJ" in (o.get("symbol_code") or "").upper()]
|
||||
print("active_orders", len(orders), "cj_orders", len(cj))
|
||||
if cj:
|
||||
print("cj detail", cj)
|
||||
else:
|
||||
print("VERIFY PASS")
|
||||
"""
|
||||
|
||||
c = paramiko.SSHClient()
|
||||
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
c.connect("192.168.8.21", username="root", password="woaini88", timeout=15)
|
||||
sftp = c.open_sftp()
|
||||
with sftp.open("/tmp/verify_pending_fix.py", "w") as f:
|
||||
f.write(VERIFY)
|
||||
sftp.close()
|
||||
_, stdout, stderr = c.exec_command("/opt/qihuo/venv/bin/python /tmp/verify_pending_fix.py")
|
||||
print(stdout.read().decode("utf-8", errors="replace"))
|
||||
print(stderr.read().decode("utf-8", errors="replace"))
|
||||
c.close()
|
||||
Reference in New Issue
Block a user