"""R624:同机合成三股票计时,计时无速度保证,优化结果必须一致。""" import json from statistics import median from time import perf_counter_ns def indicator(series,optimized): prefix=[0] if optimized: for value in series:prefix.append(prefix[-1]+value) out=[] for t in range(len(series)): if t<19:out.append(None);continue fast=(prefix[t+1]-prefix[t-2])/3 if optimized else sum(series[t-2:t+1])/3 slow=(prefix[t+1]-prefix[t-19])/20 if optimized else sum(series[t-19:t+1])/20 out.append((fast,slow)) return out def pipeline(n,optimized): source=json.dumps({name:[100+((i*7+offset)%17) for i in range(n)] for offset,name in enumerate(['A','B','C'])}) times={};start=perf_counter_ns();prices=json.loads(source);times['load']=perf_counter_ns()-start start=perf_counter_ns();ind={k:indicator(v,optimized) for k,v in prices.items()};times['indicators']=perf_counter_ns()-start start=perf_counter_ns();signals={k:[int(v[0]>v[1]) if v else 0 for v in rows] for k,rows in ind.items()};times['signals']=perf_counter_ns()-start start=perf_counter_ns();targets={k:list(rows) for k,rows in signals.items()};times['portfolio_targets']=perf_counter_ns()-start start=perf_counter_ns();fills={};equity={} for key,p in prices.items(): cash,shares=1000,0;rows=[];values=[1000] for t in range(1,n): target=targets[key][t-1];qty=target-shares if qty:rows.append((t,qty,p[t])) cash-=qty*p[t];shares=target;values.append(cash+shares*p[t]) fills[key]=rows;equity[key]=values times['account_and_fills']=perf_counter_ns()-start start=perf_counter_ns();metrics={'ending':sum(v[-1] for v in equity.values()),'fills':sum(map(len,fills.values())),'stocks':len(prices),'observations':n};times['metrics']=perf_counter_ns()-start return {'indicators':ind,'signals':signals,'fills':fills,'equity':equity,'metrics':metrics},times for n in [2000,8000]: records={False:[],True:[]};reference=None for optimized in [False,True]: for _ in range(3): result,times=pipeline(n,optimized) assert result['metrics']['stocks']==3 and result['metrics']['observations']==n expected={2000:{'ending':4732,'fills':2794,'stocks':3,'observations':2000}, 8000:{'ending':10047,'fills':11266,'stocks':3,'observations':8000}} assert result['metrics']==expected[n] if reference is None:reference=result assert result==reference assert all(t>=0 for t in times.values()) records[optimized].append(times) for optimized in [False,True]: med={k:round(median(row[k] for row in records[optimized])/1e6,4) for k in records[optimized][0]} print('n='+str(n)+' optimized='+str(optimized)+' median_ms='+str(med)) print('n='+str(n)+' optimized='+str(optimized)+' raw_ns='+str(records[optimized])) print('n='+str(n)+' equivalent=True metrics='+str(reference['metrics'])) print('cache_policy=in_memory_JSON_reparsed_each_run no_external_cache no_speed_assertion')