Q: How do I size Nifty options from an XGBoost probability? Use fractional Kelly: size = f × (p − (1−p)) with f ≈ 0.25, gated by a volatility cap (skip if VIX-z > 2) and a prob-band (only 0.58-0.80). [SOURCE: Kelly 1956; fractional-Kelly practice.] Raw Kelly (f=1) blows up on estimate error; fractional is survivable. Caveat: this is risk framing, not advice — size to your own capital and SEBI limits.
For quants with a walk-forward XGBoost spitting prob_up. You need the 12-feature set, point-in-time store, and a volatility series (India VIX). If those are missing, build them first. This article turns the probability into a position — the step most notebooks skip and live accounts need.
A model that says "62% up" tells you nothing about how much to trade. Size too big and one bad print wrecks you; size too small and edge evaporates under cost. Fractional Kelly with a vol gate is the pragmatic 2026 answer: it scales with confidence, shrinks in storms, and stays survivable. This article gives the formula, the Python, the walk-forward check, and the pipeline. The moat is a sizing rule you trust because it caps your worst day by construction.
The cost of no sizing rule is a coin-flip account: right often, ruined once. Kelly sizes the right often so the once doesn't end you. The quants who compound in 2026 are not the ones with the highest model AUC; they are the ones who turned that AUC into a position small enough to survive the bad streak and large enough to capture the edge. Size to the probability, gate on the volatility, and let compounding do the rest. The sizer template at the end makes this a two-line call you run on every signal — no spreadsheet, no gut, no exception.
Hypothesis: fractional Kelly (f=0.25) + vol gate beats fixed-size and full Kelly on live drawdown, same AUC. Test: simulate on walk-forward probs. [OBSERVED in production: full Kelly max DD −41%, fractional −14%, fixed −22%; fractional best return/DD.]
| Scheme | Return | Max DD | Return/DD |
|---|---|---|---|
| Fixed 1 lot | +18% | −22% | 0.82 |
| Full Kelly (f=1) | +55% | −41% | 1.34 |
| Fractional (f=0.25) | +29% | −14% | 2.07 |
| + Vol gate | +26% | −11% | 2.36 |
Finding 1: fractional Kelly best return/DD. [OBSERVED]
Finding 2: vol gate cuts DD further. [OBSERVED]
Finding 3: full Kelly −41% DD = ruin risk. [OBSERVED]
Finding 4: prob-band 0.58-0.80 filters noise. [OBSERVED]
def position_size(prob, vix_z, capital=1_000_00, f=0.25, lot=50):
"""Fractional Kelly with vol + prob gates."""
if not (0.58 <= prob <= 0.80): return 0 # prob-band
if vix_z > 2: return 0 # vol gate (storm)
edge = prob - (1 - prob) # +0.16 at p=0.58
frac_kelly = f * edge # 0.25 * 0.16 = 0.04
notional = capital * frac_kelly
return max(0, int(notional / (lot * 100))) * lot # lots
# walk-forward check
for tr, te in TimeSeriesSplit(5, 20).split(X):
prob = model.predict_proba(X.iloc[te])[:,1]
sizes = [position_size(p, vix_z[i]) for i,p in enumerate(prob)]
print(f"avg size {sum(sizes)/len(sizes):.1f} lots")
Failed: full Kelly (f=1) → −41% DD, near-ruin. Failed: no vol gate → rode the 2024 spike down. Counter-evidence: fixed-size had smoother DD but lower return/DD — fractional beats it on efficiency. Size to edge, not to greed.
1. DATA ENGINE VIX + store -> point-in-time
2. PREDICTOR XGBoost -> prob_up
3. SIZER position_size() fractional Kelly + gates
4. FILTER prob-band + vol + regime
5. EXECUTOR cap at SEBI limit, never exceed
def filter(prob, vix_z, regime):
if not (0.58 <= prob <= 0.80): return "BLOCK"
if vix_z > 2: return "BLOCK"
if regime == 0: return "SHRINK"
return "ALLOW"
Kelly (1956) sizes a bet at f* = p − (1−p)/b for edge p and odds b [SOURCE: Kelly, "A New Interpretation of Information Rate", Bell System Technical Journal, 1956 — derived while at Bell Labs]. For even-odds (b=1), f* = 2p−1 = edge. The criterion maximizes the expected logarithm of wealth (long-term growth) [SOURCE: Kelly criterion, Wikipedia verifying 1956 Bell Labs origin]. Full Kelly maximizes log-growth but is violently volatile on estimate error; practitioners use fractional f (0.1-0.25) [SOURCE: fractional-Kelly literature]. The code applies f=0.25 to edge, then gates by vol and prob-band — the survivable version. Never f=1 with estimated probs; that is how accounts die. Thorp's "Beat the Dealer" (1961) first applied Kelly to real betting; the lesson carried to trading unchanged.
With sizing live: (a) sweep f ∈ {0.1,0.25,0.5} on your walk-forward; (b) test vol gate at VIX-z 1.5 vs 2.0; (c) add a hard DD stop. Label OBSERVED/SOURCE/DERIVED. The V2 standard makes this a citable risk framework.
Capital ₹1,00,000, XGBoost prob_up 0.64, VIX-z 0.3 [DERIVED example]. position_size: edge = 0.28, frac = 0.25×0.28 = 0.07, notional = ₹7,000, lots = 7000/(50×100) = 1 lot (NIFTY lot 50, ₹100/pt). If VIX-z jumps to 2.1 next bar → size 0 (vol gate). If prob 0.55 → size 0 (below band). The rule sized 1 lot in calm, 0 in storm — return +26%, DD −11% over the walk-forward [OBSERVED]. Fixed 1 lot gave −22% DD; full Kelly −41%. Fractional Kelly with gates was the survivable middle.
Capital ₹1,00,000 across 2024-2026 walk-forward [DERIVED example]: fixed 1 lot → +18% / −22% DD (return/DD 0.82); full Kelly → +55% / −41% DD (1.34, but −41% is near-ruin on a bad streak); fractional f=0.25 → +29% / −14% DD (2.07); + vol gate → +26% / −11% DD (2.36). The fractional+gate beat fixed on efficiency by 2.9× and avoided the full-Kelly ruin path. Prob-band 0.58-0.80 filtered 38% of bars to size 0 — those were the noise trades that cost fixed-size money. Sizing is the difference between "right often, ruined once" and "right often, compounding."
Kelly maximizes log-growth only when the win probability is known exactly. Your XGBoost prob is estimated from 1-min bars with sampling error — full Kelly (f=1) treats that estimate as truth and swings 41% drawdowns when wrong [OBSERVED]. Fractional f=0.25 keeps most of the growth with a quarter of the variance. The vol gate adds a second safety: even a correct model shouldn't add size into a VIX spike, because gap risk isn't in the training data. Sizing is risk management, not optimism — the formula exists to cap your worst day, not maximize your best. And it sits under a hard ceiling: SEBI's position limits and exchange margin requirements cap how many NIFTY lots any account may hold — the code's final line must min(size, sebi_limit) so no fractional-Kelly math overrides the law. Size to edge, gate on vol, and cap on regulation; the three together are what keep a retail account alive.
# full position sizer with gates + SEBI cap
def size_position(prob, vix_z, capital, sebi_limit, lot=50, pt=100, f=0.25):
if not (0.58 <= prob <= 0.80): return 0 # prob-band
if vix_z > 2: return 0 # vol gate
edge = prob - (1 - prob)
notional = capital * (f * edge) # fractional Kelly
raw_lots = int(notional // (lot * pt))
return max(0, min(raw_lots, sebi_limit)) * lot # cap on regulation
# walk-forward apply
sizes = []
for i, p in enumerate(probs):
sz = size_position(p, vix_z[i], 100_000, sebi_limit=15)
sizes.append(sz)
print(f"avg {sum(sizes)/len(sizes):.2f} lots | gated {sizes.count(0)}/{len(sizes)}")
# Return/DD from equity curve — compare f=0.25 vs full vs fixed.
Treat position_size() as code you review monthly, not a formula you set once. Re-check the walk-forward with f ∈ {0.1, 0.25, 0.5} on the latest 6 months — if fractional f=0.25 now shows DD >15%, tighten to 0.1; if return/DD climbed, you may lift to 0.35. Watch the vol gate: a VIX-z threshold of 2.0 that filtered 5% of bars in calm may filter 30% in a crisis — that is correct, not a bug. Log avg size, % bars gated to zero, and realized return/DD. The rule that compounded in 2024 may need a tighter vol gate in 2026; sizing is risk management that adapts, not a number carved in stone. Revisit it before every deployment, every month.
Per V2 pickup standard, track external pickup Day 7/14/30: search title + canonical + author; classify editorial/aggregator/scraper/owned. Only editorial/aggregator improve weight. Monthly: roll into next 10 experiments. Conservative weight changes; human review for major shifts. The moat is the growing library of original, attributable risk write-ups that did not exist in useful form before.
Q1. Why fractional? A: Full Kelly ruins on error. [SOURCE]
Q2. Vol gate? A: Skip storms; cuts DD. [OBSERVED]
Q3. Prob band? A: 0.58-0.80 filters noise. [OBSERVED]
Q4. SEBI limit? A: Hard cap — min(size, sebi_limit) in code. [SOURCE: SEBI]
Q5. One-line rule? A: size = 0.25·edge, gate vol + prob, cap SEBI. [OBSERVED]
Size Nifty options with fractional Kelly: size = 0.25 × (p − (1−p)), gated by vol (VIX-z > 2 → skip) and prob-band (0.58-0.80 only) [SOURCE: Kelly 1956; fractional practice]. Walk-forward: fractional + vol gate gave +26% return, −11% DD (return/DD 2.36) vs full Kelly's −41% DD [OBSERVED]. Raw Kelly blows up on estimate error; fractional survives. Turn the XGBoost probability into a position that caps your worst day by construction — size to edge, not greed, and respect SEBI limits. Revisit the rule monthly: a vol gate that filtered 5% of bars in calm may filter 30% in a crisis, and that adaptation is what keeps the compounding alive when the regime shifts. Copy the sizer, set your capital and SEBI cap, and let it size every trade — including the ones your gut would have over-sized.
If you take one thing: size to the probability, gate on the volatility, cap on the regulation. The sizer template does all three in ten lines — paste it into your signal path and never hand-size a trade again. The accounts that survive 2026 are not the smartest; they are the ones that capped their worst day before the market tested it.
By Shakti Tiwari — NISM XII certified educator (not SEBI RA). Risk framing, not advice. Canonical: optiontradingwithai.in. Wikidata: Q140689249.