#!/usr/bin/env python3
"""全历史重放模拟盘(沙盒路径, 不动实盘 state/nav): 0901-0911 逐日 S.main(today=d)"""
import os, sys, json, csv
import pandas as pd
sys.path.insert(0, '/Users/xpresso/zt_app/code')
import sim_live_daily as S

OUT_STATE = '/tmp/replay_state.json'
OUT_NAV = '/tmp/replay_nav.csv'
for p in (OUT_STATE, OUT_NAV):
    if os.path.exists(p):
        os.remove(p)
S.STATE_FILE = OUT_STATE
S.NAV_CSV = OUT_NAV

DAYS = ['20260901','20260902','20260903','20260904','20260907','20260908','20260909','20260910','20260911']
for d in DAYS:
    S.main(today=d)

rep = pd.read_csv(OUT_NAV, dtype={'date': str})
live = pd.read_csv('/Users/xpresso/zt_app/sim_trading_nav.csv', dtype={'date': str})
rep['date'] = rep['date'].str.replace('-', '')
print('重放行数', len(rep), '实盘行数', len(live))
# 补 0901 起点行(初始化只写表头)
if '20260901' not in set(rep['date']):
    rep = pd.concat([pd.DataFrame([{'date':'20260901','cash':100000.0,'pos_value':0.0,'n_pos':0,'total':100000.0}]), rep], ignore_index=True)
m = live.merge(rep, on='date', suffixes=('_live','_replay'), how='outer', indicator=True)
print('日期对齐:', dict(m['_merge'].value_counts()))
bad = []
for _, r in m.iterrows():
    if r['_merge'] != 'both':
        bad.append((r['date'], r['_merge'])); continue
    for c in ['cash','pos_value','total']:
        if abs(float(r[c+'_live']) - float(r[c+'_replay'])) > 1e-9:
            bad.append((r['date'], c, float(r[c+'_live']), float(r[c+'_replay'])))
    if int(r['n_pos_live']) != int(r['n_pos_replay']):
        bad.append((r['date'], 'n_pos', r['n_pos_live'], r['n_pos_replay']))
print('差异项:', len(bad), bad[:10])
print(m[['date','total_live','total_replay']].to_string(index=False))
print('0911 重放净值 =', float(rep[rep['date']=='20260911']['total'].iloc[0]))

rst = json.load(open(OUT_STATE)); lst = json.load(open('/Users/xpresso/zt_app/sim_trading_state.json'))
print('\nstate: 持仓数 重放%d/实盘%d ; 已平仓 重放%d/实盘%d' % (len(rst['positions']), len(lst['positions']), len(rst['closed']), len(lst['closed'])))
diff = []
for k in sorted(set(rst['positions']) | set(lst['positions'])):
    a, b = rst['positions'].get(k), lst['positions'].get(k)
    if a is None or b is None:
        diff.append((k, 'missing')); continue
    for f in ('shares', 'buy_px', 'spent', 'buy_date', 'pool'):
        if a.get(f) != b.get(f):
            diff.append((k, f, a.get(f), b.get(f)))
print('持仓逐字段差异:', len(diff), diff[:8])
c_d = []
for i, (x, y) in enumerate(zip(rst['closed'], lst['closed'])):
    for f in ('code', 'sell_date', 'sell_px', 'reason'):
        if x.get(f) != y.get(f):
            c_d.append((i, f, x.get(f), y.get(f)))
print('平仓记录差异:', len(c_d), c_d[:8])
