"""C06构造教学核算。仅标准库;不提供真实策略显著性保证。 默认向脚本相邻JSON写入确定性UTF8/LF结果,无网络及仓库依赖。 所有输入在各函数中;浮点中间值不预先舍入,展示由读者另行舍入。 """ from pathlib import Path import itertools import json import math import random import statistics as st def quantile(xs, q): ys = sorted(xs) h = (len(ys) - 1) * q i = int(h) return ys[i] if i == len(ys) - 1 else ys[i] + (h-i)*(ys[i+1]-ys[i]) def c056(): intervals = [[1, 6], [4, 14], [8, 21], [10, 11], [12, 15], [14, 24], [16, 17], [18, 19], [19, 22], [20, 25], [22, 30], [24, 26]] tests = intervals[9:] rows = [] for i, (a, b) in enumerate(intervals, 1): hits = [int(max(a, c) <= min(b, d)) for c, d in tests] truth = i < 10 and any(hits) fixed = i < 10 and a >= 20-5 rows.append(dict(id=i, start=a, end=b, intersections=hits, role='test' if i >= 10 else 'train_candidate', purge=bool(truth), fixed_gap5=bool(fixed))) return dict(input=dict(intervals=intervals, test_ids=[10,11,12], closed=True, gap=5), interval_matrix=rows, kept=[r['id'] for r in rows[:9] if not r['purge']], purged=[r['id'] for r in rows[:9] if r['purge']], missed=[r['id'] for r in rows[:9] if r['purge'] and not r['fixed_gap5']], false_removal=[r['id'] for r in rows[:9] if not r['purge'] and r['fixed_gap5']]) def date_indices(rows, dates): """日期到行索引转换;同一天的所有股票一起进入相同集合。""" return [i for i, r in enumerate(rows) if r['day'] in dates] def c057(): rows=[] for d in range(1,16): for s in 'ABC': if s == 'B' and d % 3 == 0 or s == 'C' and d % 2 == 0: continue rows.append(dict(index=len(rows),day=d,stock=s)) test=date_indices(rows,[13,14,15]); start=min(test) row_train=list(range(start-5)); row_gap=list(range(start-5,start)) date_train=date_indices(rows,list(range(1,8))) date_gap=date_indices(rows,list(range(8,13))) summary=[] for name,tr,gap in [('row_gap5',row_train,row_gap),('date_gap5',date_train,date_gap)]: trdays=sorted({rows[i]['day'] for i in tr}) summary.append(dict(method=name,train=tr,gap=gap,test=test,train_rows=len(tr), train_dates=len(trdays),last_train_day=max(trdays), whole_dates_between=13-max(trdays)-1)) days=[] for d in range(1,16): ids=date_indices(rows,[d]) def roles(train,gap): return ['train' if i in train else 'gap' if i in gap else 'test' for i in ids] days.append(dict(day=d,stocks=[rows[i]['stock'] for i in ids],indices=ids, row_roles=roles(row_train,row_gap),date_roles=roles(date_train,date_gap))) return dict(input=dict(days=15,stocks=['A','B','C'],test_dates=[13,14,15],gap=5), rows=rows,date_map=days,split_summary=summary) def fit_chain(raw, fit_indices, observed_clip=False): observed=[raw[i] for i in fit_indices if raw[i] is not None] median=st.median(observed) filled=[median if x is None else x for x in raw] fitfilled=[filled[i] for i in fit_indices] base=observed if observed_clip else fitfilled low,high=quantile(base,.2),quantile(base,.8) clipped=[min(high,max(low,x)) for x in filled] train=[clipped[i] for i in fit_indices] mean=st.mean(train); scale=st.pstdev(train) return dict(fit_rows=[i+1 for i in fit_indices],median=median,q20=low,q80=high, mean=mean,scale_population=scale, rows=[dict(row=i+1,raw=x,filled=filled[i],clipped=clipped[i], z=(clipped[i]-mean)/scale if scale else None) for i,x in enumerate(raw)]) def c058(): raw=[1,None,3,9,100,None,200,300] return dict(input=dict(raw=raw,train_rows=[1,2,3,4,5],test_rows=[6,7,8], quantiles=[.2,.8],quantile_rule='linear (n-1)q'), train_only=fit_chain(raw,list(range(5))), wrong_all=fit_chain(raw,list(range(8))), order_change=fit_chain(raw,list(range(5)),True)) def c059(): y=[1,2,1,2,3,4,3,4,8,7,8,7,2,1,2,1,6,5,6,5,0,1,0,1] ks=[2,4]; folds=[]; preds=[] for end in [12,16,20]: losses=[] for vstart in [end-5,end-3]: train_end=vstart-1 # 一日gap:0基索引的训练终点不含该项 for k in ks: fit=list(range(train_end-k,train_end)) p=st.mean([y[i] for i in fit]) valid=list(range(vstart,vstart+2)) loss=st.mean([(y[i]-p)**2 for i in valid]) losses.append(dict(k=k,fit_days=[i+1 for i in fit],gap_day=vstart, validation_days=[i+1 for i in valid],prediction=p,mse=loss)) av={k:st.mean([r['mse'] for r in losses if r['k']==k]) for k in ks} selected=min(ks,key=lambda k:(av[k],k)) train_end=end-1 p=st.mean(y[train_end-selected:train_end]) outer=[] for i in range(end,end+4): row=dict(day=i+1,label=y[i],outer_train_end=end-1,k=selected, model_id=f'O{end}-K{selected}',prediction=p,squared_error=(y[i]-p)**2) outer.append(row);preds.append(row) wrong=[] for k in ks: wp=st.mean(y[train_end-k:train_end]) wrong.append(dict(k=k,prediction=wp,mse=st.mean([(y[i]-wp)**2 for i in range(end,end+4)]))) w=min(wrong,key=lambda r:(r['mse'],r['k'])) folds.append(dict(outer_test_days=list(range(end+1,end+5)),outer_gap_day=end, inner=losses,inner_mean=[dict(k=k,mse=av[k]) for k in ks], selected_k=selected,refit_days=list(range(train_end-selected+1,train_end+1)), outer_mse=st.mean([r['squared_error'] for r in outer]), wrong_outer_selection=wrong,wrong_selected_k=w['k'],wrong_reported_mse=w['mse'])) return dict(input=dict(labels=y,candidates_last_k=ks,outer_train_prefix=[12,16,20],gap_days=1), folds=folds,predictions=preds,nested_mean_mse=st.mean([r['outer_mse'] for r in folds]), wrong_mean_mse=st.mean([r['wrong_reported_mse'] for r in folds])) def c060(): x=[.08,.07,.06,.05,.04,.03,.02,.01,-.01,-.02,-.03,-.04, -.04,-.03,-.02,-.01,.01,.02,.03,.04,.05,.06,.07,.08] n=len(x); mean=st.mean(x); u=[v-mean for v in x] gamma=[sum(u[t]*u[t-j] for t in range(j,n))/n for j in range(7)] lags=[dict(lag=j,pairs=n-j,gamma=gamma[j],weight_L3=1-j/4 if j<=3 else 0) for j in range(7)] sensitivity=[] for L in [0,1,3,6]: omega=gamma[0]+2*sum((1-j/(L+1))*gamma[j] for j in range(1,L+1)) se=math.sqrt(omega/n) corrected=se*math.sqrt(n/(n-1)) sensitivity.append(dict(L=L,long_run_variance=omega,se_uncorrected=se, se_df_corrected=corrected,t_uncorrected=mean/se, t_df_corrected=mean/corrected)) iid=st.stdev(x)/math.sqrt(n) return dict(input=dict(ic=x,bandwidths=[0,1,3,6],autocov_denominator=n,regression_k=1), observations=[dict(day=i+1,ic=v,demeaned=u[i]) for i,v in enumerate(x)], mean=mean,lags=lags,sensitivity=sensitivity,iid_se=iid,iid_t=mean/iid, correction_factor=n/(n-1),inference_status='教学统计量;不输出小样本显著性结论') def circular_samples(x,length,reps,seed): if not x or not 1<=length<=len(x): raise ValueError('块长必须在1与序列长度之间') rng=random.Random(seed);out=[];n=len(x) for r in range(reps): starts=[rng.randrange(n) for _ in range(math.ceil(n/length))] blocks=[[(s+j)%n for j in range(length)] for s in starts] ids=[i for block in blocks for i in block][:n] out.append(dict(replicate=r+1,starts=starts,blocks=blocks,indices=ids, wrap=[s+length>n for s in starts],mean=st.mean([x[i] for i in ids]))) return out def c061(): x=[3,4,5,4,-3,-4,-5,-4,2,3,4,3] sims={str(L):circular_samples(x,L,16,6061) for L in [1,3,6]} summaries=[] for L,rows in sims.items(): means=[r['mean'] for r in rows] summaries.append(dict(block_length=int(L),replicates=len(rows),mean_of_means=st.mean(means), p025=quantile(means,.025),p975=quantile(means,.975), min=min(means),max=max(means))) return dict(input=dict(returns_percent=x,seed=6061,replicates=16,block_lengths=[1,3,6], quantile_rule='linear (B-1)q',index_base=0), original_mean=st.mean(x),samples=sims,summary=summaries) def c062(): p=[.032,.001,.20,.014,.049,.004,.80,.021,.008,.07] m=len(p);order=sorted(range(m),key=lambda i:(p[i],i));alpha=.05 holm=[];run=0 for j,i in enumerate(order): run=max(run,(m-j)*p[i]);holm.append(min(1,run)) bh=[0]*m;run=1 for j in range(m-1,-1,-1): run=min(run,m*p[order[j]]/(j+1));bh[j]=min(1,run) sorted_rows=[dict(rank=j+1,factor=f'F{i+1}',p=p[i],holm_threshold=alpha/(m-j), bh_threshold=(j+1)*alpha/m,holm_adjusted=holm[j],bh_adjusted=bh[j], holm_reject=holm[j]<=alpha,bh_reject=bh[j]<=alpha) for j,i in enumerate(order)] by=sum(1/i for i in range(1,m+1)) return dict(input=dict(pvalues=p,alpha=alpha,family=[f'F{i+1}' for i in range(m)]), sorted=sorted_rows,original_order=sorted(sorted_rows,key=lambda r:int(r['factor'][1:])), raw_reject=[f'F{i+1}' for i in range(m) if p[i]<=alpha], holm_reject=[r['factor'] for r in sorted_rows if r['holm_reject']], bh_reject=[r['factor'] for r in sorted_rows if r['bh_reject']], by_harmonic=by,by_adjusted=[dict(factor=r['factor'],p=min(1,r['bh_adjusted']*by)) for r in sorted_rows]) def moments(x): mean=st.mean(x);m2=st.mean([(v-mean)**2 for v in x]) return dict(n=len(x),mean=mean,sd_sample=st.stdev(x),sr=mean/st.stdev(x), skew=st.mean([(v-mean)**3 for v in x])/m2**1.5, kurtosis_raw=st.mean([(v-mean)**4 for v in x])/m2**2) def c063(): base=[-3,-1,0,1,2,1,-2,3,0,2,1,-1,2,0,1,3,-2,2,0,1,2,-1,4,-2] rows=[] # 台账100次:同族近似变体,共用24个构造日;不伪称独立100次。 series=[] for i in range(100): shift=(i-49.5)*.01 x=[v+shift for v in base] series.append(x);q=moments(x) rows.append(dict(trial=i+1,shift=shift,sr_daily=q['sr'],sr_annual_display=q['sr']*math.sqrt(252))) winner=max(range(100),key=lambda i:rows[i]['sr_daily']);stats=moments(series[winner]) all_var=st.variance([r['sr_daily'] for r in rows]); short=rows[-10:] short_var=st.variance([r['sr_daily'] for r in short]) correlations=[] for a,b in itertools.combinations(series,2): ma,mb=st.mean(a),st.mean(b) cov=sum((x-ma)*(y-mb) for x,y in zip(a,b)) correlations.append(cov/math.sqrt(sum((x-ma)**2 for x in a)*sum((y-mb)**2 for y in b))) rho=st.mean(correlations) if abs(rho-1)<1e-12: rho=1.0 # 数值舍入;这些序列由同一个基序列加常数构成。 estimated_n=rho+(1-rho)*len(series) denom=1-stats['skew']*stats['sr']+(stats['kurtosis_raw']-1)*stats['sr']**2/4 norm=st.NormalDist();gamma=.5772156649015329 scenarios=[] # N是敏感性假设;同位移构造的相关系数恰为1,不能从它估出有效独立试验数。 for label,N,var in [('相关退化边界',1,all_var),('完整台账_N5',5,all_var), ('完整台账_N20',20,all_var),('完整台账_N100',100,all_var), ('漏记90次_N10',10,short_var)]: z1=None if N==1 else norm.inv_cdf(1-1/N) z2=None if N==1 else norm.inv_cdf(1-1/(N*math.e)) maxz=0 if N==1 else (1-gamma)*z1+gamma*z2 threshold=math.sqrt(var)*maxz z=(stats['sr']-threshold)*math.sqrt(stats['n']-1)/math.sqrt(denom) scenarios.append(dict(scenario=label,N_effective_assumed=N,trial_sr_variance=var, quantile1=z1,quantile2=z2,maxz=maxz,sr0_daily=threshold, denominator=denom,z=z,dsr=norm.cdf(z))) return dict(input=dict(base_daily_excess_percent=base,trial_count=100,shift_formula='(trial-1-49.5)*0.01', annual_days_display_only=252,selected_trial=winner+1), ledger=rows,selected_returns=series[winner],selected_moments=stats, sr_variance_all=all_var,sr_variance_last10=short_var,scenarios=scenarios, trial_correlation=rho,correlation_pairs=len(correlations), independent_trials_interpolation=estimated_n, status='完全相关构造;N>1仅压力情景,不能称有效N估计或真实DSR证据') def rank_average(values,i): return 1+sum(v