fix(live): 成交时间1970守卫——08-20探针首日实锤9笔traded_at=1970-01-01 00:00:01(QMT原始时间经引擎pd.to_datetime失败形态落epoch),前端『今日成交』按日期过滤全空+账本trade_date失真(当日仓被当历史仓,T+1视图frozen=0);修=_effective_trade_time守卫:年份<2000一律回退当前时刻(归因轮询≤60s,日期误差仅跨日60s窗口);+2测试(1970回退当日记账且frozen生效/有效时间原样保留);附带已治疗VPS存量9行(从引擎日志按标的+数量回填13:03/13:05真实时刻,#18今日成交即时可见);portfolio 29+398绿 [vps]

This commit is contained in:
2026-08-20 13:32:54 +08:00
parent 2191160dda
commit b436adef1b
2 changed files with 54 additions and 2 deletions
@@ -129,6 +129,44 @@ def _fake_engine():
class TestAttributionAndSnapshot:
def test_sync_time_guard_rejects_epoch_1970(self, tmp_path):
"""2026-08-20 事故回归:引擎成交 time 落 1970 → traded_at/账本 trade_date
必须回退当前时刻(否则前端今日成交全空、T+1 视图把当日仓当历史仓)。"""
from datetime import date as _date
from sanguo_live.persistence import init_db, list_trades
db = str(tmp_path / "live.db")
init_db(db)
led = LiveInstanceLedger(initial_cash=1_000_000)
own = SimpleNamespace(order_id="o1", is_buy=True)
t_bad = SimpleNamespace(
order_id="o1", security="000001.XSHE", amount=100, price=10.0,
time=datetime(1970, 1, 1, 0, 0, 1), commission=0.0, tax=0.0)
engine = SimpleNamespace(
get_orders=lambda: {"o1": own},
get_trades=lambda: {"t1": t_bad},
context=SimpleNamespace(portfolio=SimpleNamespace(positions={})),
)
_sync_instance_trades(engine, led, db, 44, "channel_test")
rows = list_trades(db, 44)
assert len(rows) == 1
assert rows[0]["traded_at"].startswith(_date.today().isoformat())
# 账本按今天记账 → 当日买入冻结(T+1),不再被当历史仓
view = led.positions_view(_date.today().isoformat())
assert view["000001.XSHE"]["closeable_amount"] == 0
def test_sync_time_guard_keeps_valid_time(self, tmp_path):
from sanguo_live.persistence import init_db, list_trades
db = str(tmp_path / "live.db")
init_db(db)
led = LiveInstanceLedger(initial_cash=1_000_000)
engine = _fake_engine()
_sync_instance_trades(engine, led, db, 44, "channel_test")
rows = list_trades(db, 44)
assert rows[0]["traded_at"] == "2026-08-19 09:35:00" # 有效时间原样保留
def test_sync_attributes_only_own_orders(self, tmp_path):
from sanguo_live.persistence import init_db, list_trades