import pandas as pd, glob, numpy as np
fs = sorted(glob.glob('backtest_zt_full/daily_*/*.csv'))
NS = len(fs)
# 1) 全库: pre_close 与 前一日 raw_close 不自洽(且因子未变)的行占比 —— 即 pct_chg 无法用 raw 复现
bad_days = {}; tot_rows = 0; bad_rows = 0; facmismatch = 0
by_year = {}
for f in fs:
    d = pd.read_csv(f, dtype={'trade_date': str}).sort_values('trade_date').reset_index(drop=True)
    if len(d) < 3: continue
    tot_rows += len(d)
    prev = d['raw_close'].shift(1).values
    fp = d['adj_factor'].shift(1).values
    # pct_chg 是否与 raw 自洽: pct_chg ?= (raw_close/pre_close-1)*100
    pc = d['pct_chg'].values
    calc = (d['raw_close'].values / d['pre_close'].values - 1) * 100
    m = ~np.isnan(pc) * 1
    okmask = np.abs(calc - pc) < 0.05
    good = np.logical_and(np.isfinite(prev), okmask)
    badi = np.where(np.logical_and(np.isfinite(prev), np.logical_not(okmask)))[0]
    facchanged = np.logical_and(np.isfinite(fp), fp != d['adj_factor'].values)
    for i in badi:
        bad_rows += 1
        if facchanged[i]: facmismatch += 1
        y = d['trade_date'].values[i][:4]
        by_year[y] = by_year.get(y, 0) + 1
        bad_days[d['trade_date'].values[i]] = bad_days.get(d['trade_date'].values[i], 0) + 1
print('总行', tot_rows, '| pct_chg 与 raw_close/pre_close 不自洽的行', bad_rows, f'({bad_rows/tot_rows*100:.2f}%)', '| 其中当日因子有变化', facmismatch)
print('按年:', dict(sorted(by_year.items())))
top = sorted(bad_days.items(), key=lambda x: -x[1])[:15]
print('最集中的交易日:', top)