"""策略内部shift与引擎次开盘shift逐行区分,五bar完整往返。""" from decimal import Decimal as D import json def delay(values,steps): if type(steps) is not int or steps not in (0,1): raise ValueError('supported_shift') return ([0]*steps+list(values))[:len(values)] def run(closes,opens,internal_shift): if len(closes)!=len(opens): raise ValueError('alignment') raw=[int(D(str(p))>D('9.5')) for p in closes] strategy=delay(raw,internal_shift);targets=delay(strategy,1) cash,quantity,fees,rows=D(1000),0,0,[] for i,target in enumerate(targets): price=D(str(opens[i]));orders=[] if not price.is_finite() or price<=0: raise ValueError('invalid_open') if target and quantity==0: if 40*price+1>cash: raise ValueError('cash') cash-=40*price+1;quantity=40;fees+=1;orders.append(['buy',40,str(price),1]) elif not target and quantity: cash+=quantity*price-1;orders.append(['sell',quantity,str(price),1]);quantity=0;fees+=1 rows.append({'i':i,'raw':raw[i],'strategy_output':strategy[i],'target':target, 'source_close_index':i-1-internal_shift if i>=1+internal_shift else None, 'orders':orders,'cash':str(cash),'quantity':quantity,'fees':fees, 'equity':str(cash+quantity*price)}) return rows closes=[10,12,8,9,8];opens=[10,11,15,9,8] single,double=run(closes,opens,0),run(closes,opens,1) assert [r['target'] for r in single]==[0,1,1,0,0] assert [r['target'] for r in double]==[0,0,1,1,0] assert single[0]['orders']==[] and single[1]['orders']==[['buy',40,'11',1]] assert single[3]['orders']==[['sell',40,'9',1]] and single[1]['cash']=='559' assert single[-1]['cash']=='918' and single[-1]['quantity']==0 and single[-1]['fees']==2 assert double[2]['orders']==[['buy',40,'15',1]] and double[2]['cash']=='399' assert double[4]['orders']==[['sell',40,'8',1]] assert double[-1]['cash']=='718' and double[-1]['quantity']==0 and double[-1]['fees']==2 changed=run([10,12,1000,9,8],opens,0) for i in range(3): assert [changed[i][k] for k in ['orders','cash','quantity']]==[single[i][k] for k in ['orders','cash','quantity']] assert changed[3]['orders']==[] and single[3]['orders'] assert run(closes[:3],opens[:3],0)==single[:3] print(json.dumps({'single_engine_delay':single,'strategy_plus_engine_delay':double, 'changed_current_close_does_not_change_same_open':True, 'scope':'authored alignment reproduction, not a live product runner test'}))