#!/usr/bin/env python3
"""沙盒重跑扫描(0911): 不动实盘。SBX 环境变量指定沙盒数据根。"""
import os, sys, hashlib, json
import pandas as pd, numpy as np
sys.path.insert(0, '/Users/xpresso/zt_app/code')
SBX = os.environ['SBX']
import grid_or as g
g.BASE = SBX
import scan_daily_tb as S
S.BASE = SBX
sys.argv = ['scan_daily_tb.py', os.environ.get('TARGET', '20260911')]

live_baseline = '/Users/xpresso/zt_app/backtest_zt_full/strength_baseline.csv'
before = pd.read_csv(f'{SBX}/strength_baseline.csv', dtype={'buy_date': str})
import io, contextlib
buf = io.StringIO()
with contextlib.redirect_stdout(buf):
    S.main()
out = buf.getvalue()
S.BASE = SBX
after = pd.read_csv(f'{SBX}/strength_baseline.csv', dtype={'buy_date': str})
live = pd.read_csv(live_baseline, dtype={'buy_date': str})
print('扫描stdout行数:', len(out.split('\n')), '| 末5行:')
print('\n'.join(out.strip().split('\n')[-5:]))
print('\n沙盒 baseline: 前%d 后%d 行' % (len(before), len(after)))
print('实盘 baseline: %d 行' % len(live))

# 键集合
kb = set(zip(after['code'], after['buy_date'].astype(str)))
kl = set(zip(live['code'], live['buy_date'].astype(str)))
print('键集合: 沙盒%d 实盘%d 仅沙盒%d 仅实盘%d' % (len(kb), len(kl), len(kb-kl), len(kl-kb)))
print('  仅在沙盒:', sorted(kb-kl)[:10])
print('  仅在实盘:', sorted(kl-kb)[:10])

# 逐行逐值比对(共有键)
mg = live.merge(after, on=['code', 'buy_date'], suffixes=('_L', '_S'))
cols = [c for c in live.columns if c in after.columns and c not in ('code', 'buy_date')]
diff = {}
for c in cols:
    a = pd.to_numeric(mg[c+'_L'], errors='coerce')
    b = pd.to_numeric(mg[c+'_S'], errors='coerce')
    d = (a-b).abs()
    if d.notna().any() and d.max() > 0:
        i = d.idxmax()
        diff[c] = (float(d.max()), str(mg.loc[i, 'code']), str(mg.loc[i, 'buy_date']))
print('\n共有键 %d 行; 有差异的列 %d 个:' % (len(mg), len(diff)))
for c, v in sorted(diff.items(), key=lambda x: -x[1][0])[:12]:
    print('  %-22s max %-12.3e @ %s|%s' % (c, v[0], v[1], v[2]))

# 0911 当日行明细
d11_L = live[live['buy_date'] == '20260911'][['code', 'strength', 'raw_score']].sort_values('code')
d11_S = after[after['buy_date'] == '20260911'][['code', 'strength', 'raw_score']].sort_values('code')
print('\nbuy_date=20260911: 实盘%d 行, 重跑%d 行' % (len(d11_L), len(d11_S)))
mm = d11_L.merge(d11_S, on='code', suffixes=('_L', '_S'))
mm['d_strength'] = (mm['strength_L']-mm['strength_S']).abs()
mm['d_raw'] = (mm['raw_score_L']-mm['raw_score_S']).abs()
print('  强度最大差 %.3e ; raw_score 最大差 %.3e' % (mm['d_strength'].max(), mm['d_raw'].max()))
print(mm.to_string(index=False))

h = hashlib.sha256(open(f'{SBX}/strength_baseline.csv', 'rb').read()).hexdigest()
open('/tmp/sbx_baseline_hash1.txt', 'w').write(h)
print('\n沙盒 baseline sha256(第1次):', h)
print('实盘 baseline sha256:', hashlib.sha256(open(live_baseline, 'rb').read()).hexdigest())
