"""以此前收盘、显式限价元数据与含滑点开盘判断;不读未来收盘。""" from decimal import Decimal as D,ROUND_HALF_UP import json metadata={'valid_from':'2026-07-06','valid_to':'2026-12-31','limit':'0.10','tick':'0.01', 'status':'ordinary_main_fixture'} def audit(side,opening,previous,slippage='0',rules=metadata,day='2026-10-26'): if side not in ('buy','sell'): raise ValueError('side') if not rules or not rules['valid_from']<=day<=rules['valid_to']: return {'status':'unknown_rules'} if previous is None: return {'status':'unknown_previous_close'} opening,previous,slippage=D(str(opening)),D(str(previous)),D(str(slippage)) rate,tick=D(rules['limit']),D(rules['tick']) if any(not x.is_finite() for x in [opening,previous,slippage,rate,tick]) or min(opening,previous,tick)<=0 or not 0<=slippage<1 or not 0=upper if side=='buy' else candidate<=lower return {'status':'blocked' if blocked else 'permitted_by_guard','upper':str(upper), 'lower':str(lower),'candidate':str(candidate),'scope':'conservative guard, not queue-fill proof'} at_limit=audit('buy',11,10) open_ok=audit('buy',10.5,10) slip=audit('buy',10.99,10,'0.002') down=audit('sell',9,10) sell_slip=audit('sell',9.01,10,'0.002') assert at_limit['status']=='blocked' and open_ok['status']=='permitted_by_guard' assert slip['status']=='blocked' and slip['candidate']=='11.01198' assert down['status']==sell_slip['status']=='blocked' assert audit('buy',10, None)['status']=='unknown_previous_close' assert audit('buy',10,10,rules=None)['status']=='unknown_rules' assert audit('buy',10,10,day='2026-01-01')['status']=='unknown_rules' star=dict(metadata,limit='0.20',status='STAR_fixture') assert audit('buy',11.5,10,rules=star)['status']=='permitted_by_guard' assert audit('buy',11.5,10)['status']=='blocked' for args in [('BUY',10,10),('buy',float('nan'),10),('sell',10,float('inf'))]: try: audit(*args) except ValueError: pass else: raise AssertionError('非法方向或非有限价必须拒绝') # 两条案例的当天收盘与开盘相反;收盘根本不是audit参数。 cases=[{'open':11,'later_close':10.5},{'open':10.5,'later_close':11}] assert [audit('buy',c['open'],10)['status'] for c in cases]==['blocked','permitted_by_guard'] cash,quantity,fees=D(2000),0,0 assert open_ok['status']=='permitted_by_guard' cash-=100*D(open_ok['candidate'])+1;quantity=100;fees+=1 assert cash==949 exit_result=audit('sell',10.8,10) assert exit_result['status']=='permitted_by_guard' cash+=quantity*D(exit_result['candidate'])-1;quantity=0;fees+=1 assert cash==2028 and quantity==0 and fees==2 print(json.dumps({'opening_at_upper_later_unlocked':at_limit,'opening_clear_later_at_upper':open_ok, 'buy_slippage_crosses_band':slip,'lower_sell_block':down,'sell_slippage_crosses':sell_slip, 'synthetic_roundtrip_cash':str(cash),'fees':fees,'quantity':quantity, 'scope':'explicit 2026 board metadata and conservative opening guard; no full historical bands or queues'}))