# builds section_whoflow.html (section 9) from whoflow/results CSVs import pandas as pd P=pd.read_csv('results/participant_changes.csv') def tbl(df): return df.to_html(index=False,border=0,float_format=lambda x:f'{x:,.0f}') p=P[['date','Client Type','FutIdx bought(vol)','FutIdx sold(vol)','FutIdx L','FutIdx S','FutIdx net OI chg','Call L','Call S','Put L','Put S','Calls net (L-S) chg','Puts net (L-S) chg']].copy() p.columns=['date','who','idx fut bought','idx fut sold','fut long OI chg','fut short OI chg','net fut chg','call long chg','call short chg','put long chg','put short chg','net calls','net puts'] F=pd.read_csv('results/fut_phases_2026-10-23.csv'); O=pd.read_csv('results/options_bands_2026-10-23.csv') f=F[['phase','nifty_spot','NIfut_pts','NI_vol_ctr','NI_dOI_ctr_allexp','NI_dOI_ctr_oct','bn_spot','BA_vol_ctr','BA_dOI_ctr_allexp']].copy() f.columns=['phase (IST)','Nifty spot pts','Nifty Oct fut pts','Nifty fut vol (ctr, all exp)','Nifty fut OI chg (all exp)','Nifty fut OI chg (Oct)','BN spot pts','BN fut vol','BN fut OI chg'] o=O.pivot_table(index='phase',columns='type',values=['dOI_all','vol_all']).round(0); o.columns=[f'{t} {"OI chg" if a=="dOI_all" else "volume"} (contracts)' for a,t in o.columns]; o=o.reset_index().rename(columns={'phase':'phase (IST)'}) F13=pd.read_csv('results/fut_phases_2026-10-13.csv')[['phase','nifty_spot','NIfut_pts','NI_vol_ctr','NI_dOI_ctr_allexp','bn_spot','BA_dOI_ctr_allexp']] F13.columns=['phase (IST)','Nifty spot pts','Nifty Oct fut pts','Nifty fut vol (ctr)','Nifty fut OI chg (all exp)','BN spot pts','BN fut OI chg'] C=pd.read_csv('results/components_2026-10-23_1336.csv').head(10)[['sym','pts_contrib','pct','vol_x20d','first_up015']] C.columns=['stock','Nifty pts 13:36→13:47','% move','cash vol vs 20d','first +0.15% minute'] h=f"""

9. Who bought and who sold: 23-Oct 13:38 burst and 13-Oct rally (added 25-Oct-2026 08:45 IST)

Short answer. NSE does not publish who traded in a given minute, only end-of-day positions by category (FII, DII, Pro = brokers' own trading, Client = retail and other clients). So the per-minute identities below are inference. The end-of-day positions are direct evidence.
23-Oct 13:38 (+137 futures pts in 5 min): the burst started with aggressive buying in Nifty futures. Nifty futures volume was 8.8x normal, against 3.1x in Bank Nifty futures. The futures premium widened from ~64 to ~85 points, and all heavyweights turned up in the same minute (13:38), which looks like a basket being bought, not stock-specific news. Call writers were the forced buyers: call OI at the 21,950–22,900 strikes fell by ~448k contracts between 13:37 and 13:47 while call premiums rose 38% (22,200) to 84% (22,800). Put writers were the sellers from 13:41: put OI rose by ~93k contracts, with fresh puts written at 22,500–22,600. Futures OI rose (fresh longs, not short covering), but the intraday OI feed is unreliable that day. End of day: Pro added the most index-futures longs (+8,833) and also +7,583 shorts. FIIs added both sides (+2,283 long / +2,166 short, net flat): net buyers of Nifty futures (+1,626 contracts, ₹224 cr) and net sellers of Bank Nifty futures (−2,257, −₹377 cr). Clients sold: they added +2,921 futures shorts and wrote puts (+246,800 short against +102,621 long). FIIs and Pros bought puts. The burst was fully reversed: the day closed −88 with short buildup in Nifty and Bank Nifty futures.
13-Oct (+359): buyers were FIIs and Pros, sellers were clients. FIIs bought 18,726 and sold 12,361 index futures, a net +6,365 made up of 3,217 shorts covered and 3,148 new longs. Pros were net +6,337 (3,052 shorts covered). Clients were net −13,072: they sold 11,981 longs and added 1,091 shorts. Most of the rise came at 09:15–10:00 (+245 spot, IT results; HCL Tech cash volume 10x) while Nifty futures OI fell by ~4,400 contracts, which is short covering. The afternoon leg (14:15–15:00, +98; FM remarks from 14:25) came with futures OI rising (+2,540), which is fresh longs, and call OI in the expiring weekly falling ~966k contracts (call writers covering on expiry day). In cash, FIIs were still net sellers (−₹1,305 cr) and DIIs net buyers (+₹2,439 cr).

Direct: NSE participant-wise index derivatives (contracts; change vs previous session)

{tbl(p)}

Source: NSE fao_participant_oi / fao_participant_vol archives. 'bought/sold' = that day's long/short-side volume. Index futures and options cover all indices (Nifty, Bank Nifty, etc.). 13-Oct was a weekly Nifty expiry, so its option OI changes are mostly expiry settlement.

23-Oct intraday: Nifty and Bank Nifty futures by phase (Upstox 1m)

{tbl(f)}

23-Oct intraday: Nifty 27-Oct options, strikes 21,950–22,900 (OI change and volume in contracts)

{tbl(o)}

23-Oct burst: heavyweights (cash, 13:36→13:47)

{tbl(C)}

All 50 stocks together: +136.8 pts. Banks (HDFCB, ICICI, Axis, Kotak, SBI) +36.7, Reliance +13.2, IT +11.8. Bank Nifty and Nifty turned in the same minute (BN spot +0.19%, Nifty +0.20% at 13:38), so there was no Bank Nifty lead this time. Bulk deals 23-Oct: no Nifty-50 stock appears. Block deals 23-Oct: none.

13-Oct intraday: Nifty futures by phase

{tbl(F13)}

Caveats. (1) Who traded in a given minute is not published; the per-minute identities above are inferred from end-of-day category positions plus OI, premium and options patterns. (2) On 23-Oct (rollover week) Upstox 1m Nifty Oct-futures OI ended at 13.39M against NSE's official 11.32M. Calendar-spread trades are missing from the 1m feed (1m volume = 72% of the day's total), and one bar (13:57) shows a −2,939-contract OI jump on 185 contracts of volume, which is impossible. So the 23-Oct futures 'fresh longs' reading is low confidence. Option 1m OI matched NSE end-of-day within 1–2%. 13-Oct futures 1m volume matched NSE exactly. (3) Spot 15:15–15:29 is not used. (4) 13-Oct bulk/block deals: not available free (NSE historical API returned 503; the archive keeps only the latest day). Data: whoflow/results/, scripts: whoflow/scripts/.

""" open('../whoflow/section_whoflow.html','w').write(h); print(len(h))