"""C05构造数据审计;仅标准库,默认同目录输出UTF-8、LF、确定性纯JSON。 时间均为显式构造截点;价格非真实行情。小型穷举解释算法,不是生产管道。 时区案例固定官方文档2020-11-01洛杉矶回拨,显式偏移量,无tzdata依赖。 """ from collections import Counter, defaultdict from datetime import datetime, timedelta, timezone from hashlib import sha256 from pathlib import Path import json import math def record(inputs, **tables): return {'inputs': inputs, 'tables': tables} def ohlc(): rows = [ ['P01',10,12,9,11,100], ['P02',13,12,9,11,90], ['P03',10,12,11,11,80], ['P04',10,12,9,13,70], ['P05',10,12,11,10,60], ['P06',10,9,12,11,50], ['P07',None,12,9,11,40], ['P08',10,'Infinity',9,11,30], ['P09',10,12,9,11,-5], ['P10',10,10,10,10,0], ['P11',10,12,9,11,20], ['P12',-1,2,-2,1,10]] matrix=[] for key,o,h,l,c,v in rows: p=[o,h,l,c]; finite=lambda x: isinstance(x,(int,float)) and math.isfinite(x) ready=all(finite(x) for x in p) bits=[any(x is None for x in p+[v]), any(x is not None and not finite(x) for x in p+[v]), ready and any(x<=0 for x in p), finite(v) and v<0, ready and ho, ready and l>c] state='隔离' if any(bits) else ('待核零量' if v==0 else '放行') matrix.append({'行':key,'O':o,'H':h,'L':l,'C':c,'V':v,'失败位图':''.join(str(int(b)) for b in bits),'状态':state}) ledger=[{'口径':s,'行数':sum(r['状态']==s for r in matrix),'成交量':sum(r['V'] for r in matrix if r['状态']==s and isinstance(r['V'],int))} for s in ['放行','待核零量','隔离']] contrast=[{'条件':'严格放行','可用行':sum(r['状态']=='放行' for r in matrix)}, {'条件':'取得零量来源确认后仅用于价格观察','可用行':sum(r['状态']!='隔离' for r in matrix)}, {'条件':'错误仅查空值','可用行':sum(None not in r for r in rows)}] return record({'rows':rows,'columns':['行','O','H','L','C','V'],'bit_order':['缺失','非有限','非正价','负量','HO','L>C']},matrix=matrix,ledger=ledger,contrast=contrast) def cumulative(): rows=[['M','09:30',100],['M','09:31',160],['M','11:30',250],['A','13:00',40],['A','13:01',90],['A','13:02',85],['A','15:00',180]] out=[]; prev={} for s,t,v in rows: first=s not in prev; d=v if first else v-prev[s] out.append({'会话':s,'时刻':t,'累计股':v,'重置':first,'原始差分':d,'状态':'负差待核' if d<0 else '暂可用'}) prev[s]=v cases=[] for name,rv in [('基线待核',[r[2] for r in rows]),('源方确认13:02应为125',[100,160,250,40,90,125,180]),('源方确认下午沿用全日累计',[100,160,250,290,340,375,430])]: ds=[]; last={} for (s,t,_),v in zip(rows,rv): group='day' if name.endswith('全日累计') else s ds.append(v-last.get(group,0));last[group]=v cases.append({'条件':name,'直接和':sum(rv),'差分净和':sum(ds),'正差相加':sum(max(0,d) for d in ds),'负差数':sum(d<0 for d in ds),'可确认日量':sum(ds) if all(d>=0 for d in ds) else None}) sessions=[{'会话':s,'末累计':prev[s],'差分净和':sum(r['原始差分'] for r in out if r['会话']==s)} for s in prev] return record({'rows':rows,'unit':'股','session_reset':True,'confirmed_correction':[100,160,250,40,90,125,180],'confirmed_day_cumulative':[100,160,250,290,340,375,430]},increments=out,sessions=sessions,contrast=cases) def bars(): # 秒数从09:30:00算起,覆盖区间完整保留两端外侧桶。 rows=[['T1',0,10,1],['T2',299,11,2],['T3',300,12,3],['T4',301,9,4],['T5',600,13,5]] clock=lambda sec:(datetime(2026,10,20,9,30)+timedelta(seconds=sec)).strftime('%H:%M:%S') allocations=[]; summary=[]; output=[] for closed in ['left','right']: for label in ['left','right']: groups=defaultdict(list) for key,sec,p,v in rows: k=sec//300 if closed=='left' else (sec-1)//300 groups[k].append((key,sec,p,v)); a=k*300;b=a+300 allocations.append({'closed':closed,'label':label,'事件':key,'事件时刻':clock(sec),'桶左':clock(a),'桶右':clock(b),'显示标签':clock(a if label=='left' else b)}) for k,items in sorted(groups.items()): p=[r[2] for r in items];a=k*300;b=a+300 output.append({'closed':closed,'label':label,'标签':clock(a if label=='left' else b),'覆盖':('[' if closed=='left' else '(')+clock(a)+','+clock(b)+(')' if closed=='left' else ']'),'O':p[0],'H':max(p),'L':min(p),'C':p[-1],'V':sum(r[3] for r in items),'最早完整时刻':clock(b+2)}) summary.append({'closed':closed,'label':label,'事件数':sum(len(v) for v in groups.values()),'总量':sum(r[3] for r in rows),'桶数':len(groups)}) return record({'rows':rows,'columns':['事件','距09:30秒','价格元','增量股'],'width_seconds':300,'delivery_delay_seconds':2},allocation=allocations,bars=output,conservation=summary) def asof(): quotes=[['Q1','X',0,99,101],['Q2','X',1000,101,103],['Q3','X',2100,103,105],['Q4','Y',1400,49,51]] orders=[['O1','X',900,'买',102],['O2','X',2000,'卖',103],['O3','X',4000,'买',105],['O4','Y',1500,'卖',50],['O5','Z',1500,'买',20]] candidates=[];chosen=[] for oid,s,t,side,fill in orders: qs=[q for q in quotes if q[1]==s] for qid,_,qt,bid,ask in qs: candidates.append({'订单':oid,'报价':qid,'订单减报价毫秒':t-qt,'过去或相等':qt<=t,'绝对时差':abs(t-qt)}) for direction in ['backward','nearest']: for tol in [1200,2000]: pool=[q for q in qs if direction=='nearest' or q[2]<=t] q=min(pool,key=lambda q:(abs(t-q[2]),q[2])) if pool else None accepted=q is not None and abs(t-q[2])<=tol mid=(q[3]+q[4])/2 if accepted else None chosen.append({'订单':oid,'方向':direction,'容差毫秒':tol,'候选':q[0] if q else None,'时差毫秒':t-q[2] if q else None,'放行':accepted,'拒因':None if accepted else ('无同证券候选' if q is None else '过期'),'中价':mid,'成交减中价':fill-mid if accepted else None,'方向成本元':((fill-mid) if side=='买' else (mid-fill)) if accepted else None}) return record({'quotes':quotes,'quote_columns':['报价','证券','毫秒','bid','ask'],'orders':orders,'order_columns':['订单','证券','毫秒','方向','成交价']},candidates=candidates,selection=chosen) def identities(): aliases=[['A1','AAA','S1',1,4],['A2','BBB','S1',4,8],['A3','AAA','S2',4,8],['A4','CCC','S3',1,3],['A5','CCC','S3',4,8],['A6','BBB','S2',6,7]] quotes=[['E1','AAA',2,10],['E2','BBB',4,11],['E3','AAA',5,20],['E4','CCC',3,30],['E5','BBB',6,12],['E6','CCC',5,31],['E7','BBB',7,13]] joined=[] for eid,code,day,p in quotes: hits=[a for a in aliases if a[1]==code and a[3]<=day0 for v in known);n=len(values);m=n-len(known) summary=[{'口径':'完整案例','分子胜数':wins,'分母':len(known),'胜率百分数':wins/len(known)*100}, {'口径':'缺失全部不胜的下界','分子胜数':wins,'分母':n,'胜率百分数':wins/n*100}, {'口径':'缺失全部胜的上界','分子胜数':wins+m,'分母':n,'胜率百分数':(wins+m)/n*100}] sensitivity=[{'缺失中胜数':k,'总胜数':wins+k,'总分母':n,'胜率百分数':(wins+k)/n*100} for k in range(m+1)] reason_table=[{'缺失原因':r,'人数':reasons.count(r)} for r in dict.fromkeys(reasons) if r!='已知'] return record({'values':values,'reasons':reasons,'win_rule':'收益严格大于0','formation_time':'构造2026-10-01 09:00Z','evaluation_time':'构造2026-10-15 09:00Z'},ledger=rows,summary=summary,sensitivity=sensitivity,reasons=reason_table) def pagination(): # 冻结教学服务:时间索引0..9,整点逐分事件,每窗含双端,升序,静默上限4。 events=[{'键':f'K{i:02}','分钟':i} for i in range(10)];cap=4 request_windows=[['整窗',0,9,0],['分页1',0,9,0],['分页2',0,9,4],['断页3',0,9,8],['完整分页3',0,9,8],['分窗A',0,3,0],['分窗B',3,6,0],['分窗C',6,9,0]] logs=[];sets={} for name,a,b,cursor in request_windows: eligible=[r for r in events if a<=r['分钟']<=b] got=[] if name=='断页3' else eligible[cursor:cursor+cap] sets[name]={r['键'] for r in got} logs.append({'请求':name,'窗口含双端':f'{a}..{b}','游标':cursor,'返回数':len(got),'首分钟':got[0]['分钟'] if got else None,'末分钟':got[-1]['分钟'] if got else None,'next游标':cursor+cap if cursor+cap