# Nifty & BankNifty monthly futures 1m, all contracts expired since 2024-10 (Upstox expired-instruments API) + live Oct/Nov 2026 (v2 historical) import sys,os,json,pandas as pd,time;sys.path.insert(0,'scripts');from up import get,q out='data/fut'; os.makedirs(out,exist_ok=True); log=open('data/fetch_fut.log','a') def L(*a): print(*a,file=log,flush=True); print(*a,flush=True) def cand(path): c,j=get(path) if c!=200: L('ERR',c,path.split('/')[3][:40],str(j)[:200]); return None d=j['data']['candles']; df=pd.DataFrame(d,columns=['ts','open','high','low','close','volume','oi']); df['ts']=pd.to_datetime(df.ts.str[:19]); return df.sort_values('ts') for und,name in [('NSE_INDEX|Nifty 50','NIFTY'),('NSE_INDEX|Nifty Bank','BANKNIFTY')]: c,j=get('/v2/expired-instruments/expiries',{'instrument_key':und}); exps=j['data'] cons=[] for e in exps: c,j=get('/v2/expired-instruments/future/contract',{'instrument_key':und,'expiry_date':e}) if c==200 and j.get('data'): cons+= [x for x in j['data'] if x['instrument_type']=='FUT'] json.dump(cons,open(f'data/{name}_fut_contracts.json','w')) L(name,'contracts',len(cons),[x['expiry'] for x in cons]) for x in cons: f=f"{out}/{name}_{x['expiry']}.parquet" if os.path.exists(f): continue e=pd.Timestamp(x['expiry']); parts=[] for a,b in [(e-pd.Timedelta(days=100),e-pd.Timedelta(days=50)),(e-pd.Timedelta(days=49),e)]: df=cand(f"/v2/expired-instruments/historical-candle/{q(x['instrument_key'],safe='')}/1minute/{b:%Y-%m-%d}/{a:%Y-%m-%d}") if df is not None: parts.append(df) if parts: df=pd.concat(parts).drop_duplicates('ts'); df['expiry']=x['expiry']; df.to_parquet(f); L(name,x['expiry'],len(df),df.ts.min(),df.ts.max()) # live contracts keys=json.load(open('../data/keys.json')) for name,k,e in [('NIFTY',keys['NIFTYFUT'],'2026-10-27'),('NIFTY',keys['NIFTYFUT_NOV'],'2026-11-24'),('BANKNIFTY',keys['BANKNIFTYFUT'],'2026-10-27')]: parts=[] for a,b in [('2026-08-01','2026-09-10'),('2026-09-11','2026-10-23')]: df=cand(f"/v2/historical-candle/{q(k,safe='')}/1minute/{b}/{a}") if df is not None: parts.append(df) df=pd.concat(parts).drop_duplicates('ts'); df['expiry']=e; df.to_parquet(f'{out}/{name}_{e}.parquet'); L(name,e,len(df),df.ts.min(),df.ts.max()) L('DONE')