Download scripts/audit_execution_costs.py from Ypeng12/quant-ai: direct link, hf CLI and curl.
- Browser
- Download file 3.9 kB
-
https://huggingface.co/spaces/Ypeng12/quant-ai/resolve/main/scripts/audit_execution_costs.py
- Command line
-
hf download hf://spaces/Ypeng12/quant-ai/scripts/audit_execution_costs.py
-
curl -L -o audit_execution_costs.py https://huggingface.co/spaces/Ypeng12/quant-ai/resolve/main/scripts/audit_execution_costs.py
3.9 kB
| #!/usr/bin/env python3 | |
| """Read-only Paper fill/fee evidence and historical quote matching. Private output.""" | |
| import argparse,json,sys | |
| from pathlib import Path | |
| import pandas as pd | |
| import requests | |
| from dotenv import dotenv_values | |
| ROOT=Path(__file__).resolve().parents[1];sys.path.insert(0,str(ROOT/'backend')) | |
| from app.broker.credentials import resolve_trading_credentials | |
| from app.research.execution_cost_audit import audit_fills_against_quotes | |
| def run(args): | |
| credentials=resolve_trading_credentials(dotenv_values(args.env_file)) | |
| if credentials is None or not credentials.is_paper:raise ValueError('Paper-only audit') | |
| output=Path(args.output);output.mkdir(parents=True,exist_ok=False) | |
| session=requests.Session();session.headers.update({'APCA-API-KEY-ID':credentials.key,'APCA-API-SECRET-KEY':credentials.secret}) | |
| def get(url,params): | |
| r=session.get(url,params=params,timeout=25) | |
| if r.status_code!=200:raise ValueError(f'Endpoint HTTP {r.status_code}') | |
| return r.json() | |
| start=pd.Timestamp(args.date,tz='America/New_York');until=min(start+pd.Timedelta(days=1),pd.Timestamp.now(tz='UTC')) | |
| activities=[];token=None;seen=set() | |
| while True: | |
| params=dict(after=start.isoformat(),until=until.isoformat(),direction='asc',page_size=100) | |
| if token:params['page_token']=token | |
| page=get(credentials.endpoint+'/v2/account/activities',params) | |
| activities.extend(page) | |
| if len(page)<100:break | |
| token=page[-1]['id'] | |
| if token in seen:raise ValueError('Repeated activity page') | |
| seen.add(token) | |
| (output/'activities.json').write_text(json.dumps(activities,indent=2)+'\n') | |
| fills=[];quotes=[];errors=[] | |
| for a in activities: | |
| if a.get('activity_type')!='FILL':continue | |
| fill=dict(fill_id=a['id'],symbol=a['symbol'],side=a['side'],qty=float(a['qty']),price=float(a['price']),timestamp=a['transaction_time']) | |
| fills.append(fill);t=pd.Timestamp(fill['timestamp']) | |
| if t>pd.Timestamp.now(tz='UTC')-pd.Timedelta(minutes=15): | |
| errors.append(dict(fill_id=a['id'],reason='Historical SIP query must be 15 minutes old'));continue | |
| try: | |
| raw=get('https://data.alpaca.markets/v2/stocks/'+a['symbol']+'/quotes',dict(start=(t-pd.Timedelta(seconds=1)).isoformat(),end=t.isoformat(),feed='sip',sort='desc',limit=10000)) | |
| for q in raw.get('quotes') or []: | |
| quotes.append(dict(symbol=a['symbol'],timestamp=q['t'],bid=q['bp'],ask=q['ap'],feed='sip')) | |
| except Exception as exc:errors.append(dict(fill_id=a['id'],reason=str(exc))) | |
| diagnostic=audit_fills_against_quotes(fills,quotes) | |
| fee_entries=[a for a in activities if a.get('activity_type') in {'FEE','CFEE'}] | |
| report=dict(date=args.date,account_type='paper',read_only=True,broker_mutations=0, | |
| coverage_start=start.isoformat(),coverage_end=until.isoformat(),activity_count=len(activities), | |
| observed_activity_types=sorted({a.get('activity_type','unknown') for a in activities}), | |
| observed_fee_entries=len(fee_entries),observed_fee_cash_amount=sum(float(a.get('net_amount') or 0) for a in fee_entries), | |
| all_actual_fees_verified=False,fee_interpretation='No observed FEE rows does not establish absence of later charges or fees posted under other activity types.', | |
| quote_errors=errors,execution_diagnostic=diagnostic) | |
| (output/'report.json').write_text(json.dumps(report,indent=2,allow_nan=False)+'\n') | |
| print(json.dumps({k:v for k,v in report.items() if k not in {'execution_diagnostic','quote_errors'}},indent=2)) | |
| print(json.dumps({k:v for k,v in diagnostic.items() if k!='rows'},indent=2)) | |
| if __name__=='__main__': | |
| p=argparse.ArgumentParser(description=__doc__);p.add_argument('--env-file',required=True);p.add_argument('--date',required=True);p.add_argument('--output',required=True) | |
| run(p.parse_args()) | |