62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""B-pack client-side fix 2026-09-11: shim get_trading_dates output normalization.
|
|
|
|
The server-side fix (market_bigqmt.py patch) normalizes the RPC answer, but
|
|
fresh client processes (xt_eod wrapper, future engines) load THIS shim first.
|
|
Defense in depth: normalize here too, so the contract holds even if the server
|
|
side regresses (e.g. server file restored from a backup).
|
|
Idempotent: re-running on a patched file exits 0.
|
|
|
|
Run ON THE VPS: C:\\Python310\\python.exe -X utf8 patch_shim_xtdata_20260911.py
|
|
"""
|
|
import io
|
|
import shutil
|
|
import sys
|
|
|
|
P = r"C:\sanguo_bigqmt\xtquant_bridge\xtquant\xtdata.py"
|
|
BAK = P + ".bak_20260911"
|
|
|
|
OLD = '''def get_trading_dates(market, start_time="", end_time="", count=-1):
|
|
return _compat.xtdata.get_trading_dates(market, start_time, end_time, count)'''
|
|
|
|
NEW = '''def _norm_calendar_ms(result):
|
|
"""Contract fix 2026-09-11: 'YYYYMMDD' strings -> Beijing-midnight epoch ms.
|
|
|
|
The bridge server's native xtdata path returns string dates whenever a
|
|
local quote source has been reachable (2026-09-11 incident: all 12 engine
|
|
schedulers starved on ts/1000 TypeErrors). Consumers divide by 1000 with
|
|
local-timezone fromtimestamp, and this host runs Asia/Shanghai, so
|
|
datetime().timestamp() is the exact inverse. All-numeric lists pass
|
|
through untouched."""
|
|
if not isinstance(result, list) or not result:
|
|
return result
|
|
if all(isinstance(x, (int, float)) and not isinstance(x, bool) for x in result):
|
|
return result
|
|
out = []
|
|
for x in result:
|
|
if isinstance(x, str) and len(x) == 8 and x.isdigit():
|
|
import datetime as _dt
|
|
out.append(int(_dt.datetime(int(x[:4]), int(x[4:6]), int(x[6:8])).timestamp() * 1000))
|
|
else:
|
|
out.append(x)
|
|
return out
|
|
|
|
|
|
def get_trading_dates(market, start_time="", end_time="", count=-1):
|
|
return _norm_calendar_ms(_compat.xtdata.get_trading_dates(market, start_time, end_time, count))'''
|
|
|
|
src = io.open(P, encoding="utf-8").read()
|
|
|
|
if "_norm_calendar_ms(_compat.xtdata.get_trading_dates" in src:
|
|
print("ALREADY_PATCHED")
|
|
sys.exit(0)
|
|
|
|
if src.count(OLD) != 1:
|
|
print("ANCHOR_NOT_UNIQUE: %d" % src.count(OLD))
|
|
sys.exit(1)
|
|
|
|
shutil.copyfile(P, BAK)
|
|
src = src.replace(OLD, NEW)
|
|
io.open(P, "w", encoding="utf-8", newline="\n").write(src)
|
|
print("PATCHED ok, backup=%s" % BAK)
|