User-Friendly Quant Strategies for Small Retail Traders (₹5–10 Lakh)
Below are three of the easiest yet best-performing strategies distilled from Ernest P. Chan and Rishi Narang’s work, tailored for solo quant traders with limited capital. Each strategy includes rationale, step-by-step implementation, and an Upstox API script for safe backtest, paper-trade, and live deployment.
1. Intraday Buy-on-Gap Mean Reversion
Source: Chan’s Buy-on-Gap model
Why It’s Easy: Simple entry on large overnight gaps; only one signal per day per stock.
Target Capital: ₹5–10 Lakh across 2–4 stocks
Expected Metrics: APR ~8–12%, Sharpe ~1.5
Strategy Details
-
Universe: 3–5 high-liquidity NSE stocks (Reliance, TCS, HDFC Bank, Infosys)
-
Entry: If today’s open < previous close × 0.99 (gap down ≥1%)
-
Exit: Market close on same day
-
Position Sizing: Equal capital per stock; max 25% per ticker
Implementation Steps
-
Environment Setup
bashpython3 -m venv quant_env source quant_env/bin/activate pip install upstox-api pandas numpy vectorbt -
Upstox Authentication
pythonfrom upstox_api.api import Upstox, Session API_KEY, API_SECRET, REDIRECT_URI = 'YOUR_KEY','YOUR_SECRET','https://app/callback' session = Session(API_KEY, API_SECRET); session.set_redirect_uri(REDIRECT_URI) print(Upstox(API_KEY,None).get_login_url(redirect_uri=REDIRECT_URI,response_type='code')) # After login, exchange code: session.set_code('RECEIVED_CODE'); token = session.retrieve_access_token() u = Upstox(API_KEY, token) -
Data Retrieval & Backtest
pythonimport pandas as pd, numpy as np, vectorbt as vbt def get_ohlc(symbol,start,end): bars = u.get_ohlc(u.get_instrument_by_symbol('NSE_EQ',symbol),'ONE_MINUTE',start,end) df=pd.DataFrame([{ 'dt':b.timestamp,'open':b.open,'close':b.close } for b in bars]).set_index('dt') return df.resample('1D').agg({'open':'first','close':'last'}) def backtest_gap(df): df['prev_close']=df.close.shift(1) df['gap_pct']=(df.open-df.prev_close)/df.prev_close df['pos']=(df.gap_pct< -0.01).astype(int) df['ret']=df.close.pct_change() return (df.pos.shift(1)*df.ret).fillna(0) symbols=['RELIANCE','TCS'] rets=[backtest_gap(get_ohlc(s,'2023-01-01','2025-10-14')) for s in symbols] port=vbt.Portfolio.from_returns(sum(rets)) print(port.stats()) -
Paper Trading
pythonfrom datetime import date today = date.today().isoformat() for sym in symbols: df = get_ohlc(sym,today,today) if (df.open.iloc[0]/df.close.shift(1).iloc[0])<0.99: print(f"Signal BUY {sym}") -
Live Order Placement
pythonfrom upstox_api.api import TransactionType,OrderType,ProductType def place_buy(sym,qty): inst=u.get_instrument_by_symbol('NSE_EQ',sym) u.place_order(inst,qty,TransactionType.Buy,ProductType.Intraday,OrderType.Market) # On signal day: capital=500000; per_stock=capital/len(symbols) for s in symbols: price=get_ohlc(s,today,today).open.iloc[0] qty=int(per_stock/price) if qty: place_buy(s,qty) -
Risk Controls & Shutdown
-
Kill switch if drawdown >5%
-
Flat positions at 15:20 IST via market‐sell
-
2. Simple Moving-Average Crossover (Trend-Following)
Source: Narang’s concept in Inside the Black Box
Why It’s Easy: Only two moving averages; daily signals; works on liquid ETFs/stocks.
Target Capital: ₹5–10 Lakh
Expected Metrics: APR ~10–15%, Sharpe ~1.2
Strategy Details
-
Universe: Nifty 50 ETF (e.g., NIFTYBEES) or liquid blue-chips
-
Fast MA: 20-day; Slow MA: 50-day
-
Entry: Fast MA crosses above Slow MA (Go Long)
-
Exit: Fast MA crosses below Slow MA (Go Flat)
Implementation Steps
-
Data & Signal Generation
pythondef backtest_macross(df): df['MA20']=df.close.rolling(20).mean() df['MA50']=df.close.rolling(50).mean() df['pos']=(df.MA20>df.MA50).astype(int) df['ret']=df.close.pct_change() return (df.pos.shift(1)*df.ret).fillna(0) df=get_ohlc('NIFTYBEES','2020-01-01','2025-10-14') stats=vbt.Portfolio.from_returns(backtest_macross(df)).stats() print(stats[['Sharpe Ratio','Total Return']]) -
Paper Trade Logic
pythontoday_df=get_ohlc('NIFTYBEES',today,today) if today_df.MA20.iloc[-1]>today_df.MA50.iloc[-1]: print("Go Long ETF") else: print("Go Flat") -
Live Execution
pythondef rebalance_etf(sym,capital): df=get_ohlc(sym,today,today) pos= int((capital/df.close.iloc[-1])) if df.MA20.iloc[-1]>df.MA50.iloc[-1] else 0 # Send order to match pos # Retrieve current qty via u.get_positions() -
Risk Controls
-
Maximum leverage 1.5×
-
Stop-trail at 1% daily drawdown
-
3. Sectoral ETF Mean Reversion (Pairs)
Source: Chan’s ETF pairs with Bollinger Bands
Why It’s Easy: One ETF pair, simple z-score; low trade frequency.
Target Capital: ₹5–10 Lakh
Expected Metrics: APR ~12–18%, Sharpe ~1.4
Strategy Details
-
Pair: BankBees (banking ETF) vs AutoBees (auto ETF)
-
Spread = Price(AutoBees) – β × Price(BankBees) (β via simple regression)
-
Entry: Spread > mean + 2 σ (short) or < mean – 2 σ (long)
-
Exit: Spread returns to mean
Implementation Steps
-
Spread Calculation & Backtest
pythonfrom sklearn.linear_model import LinearRegression df1=get_ohlc('BANKBEES','2023-01-01','2025-10-14') df2=get_ohlc('AUTOBEES','2023-01-01','2025-10-14') lr=LinearRegression().fit(df1.close.values.reshape(-1,1),df2.close) beta=lr.coef_[0] spread=df2.close - beta*df1.close mu,σ=spread.mean(),spread.std() z=(spread-mu)/σ pos = np.where(z>2,-1,np.where(z< -2,1,0)) ret=pd.Series(df2.close.pct_change().fillna(0))*pos[:-1] stats=vbt.Portfolio.from_returns(ret).stats() print(stats[['Sharpe Ratio','Total Return']]) -
Paper Trading
python# Same spread logic on today’s bar; generate pos -
Execution
pythondef trade_pair(sym_long,sym_short,qty): u.place_order(u.get_instrument_by_symbol('NSE_EQ',sym_long),qty,TransactionType.Buy,ProductType.Delivery,OrderType.Market) u.place_order(u.get_instrument_by_symbol('NSE_EQ',sym_short),qty,TransactionType.Sell,ProductType.Delivery,OrderType.Market) -
Risk Controls
-
Max capital per pair: ₹2 Lakh
-
Weekly rebalancing; close positions if no mean reversion in 5 trading days
-
Deployment Plan & Safety Measures
-
Local Testing & Backtesting
-
Run all backtests on historical data; verify Sharpe >1.2.
-
Use vectorbt for performance reports.
-
-
Paper Trading Phase (1–2 months)
-
Auto-generate signals; log P&L without real orders.
-
Validate live data feeds and latency.
-
-
Live Deployment (Start Small)
-
Allocate ₹1–2 Lakh initially per strategy.
-
Scale capital gradually only upon consistent performance (≥2 months).
-
-
Monitoring & Kill Switches
-
Daily P&L dashboard (Streamlit/Grafana).
-
Automatic full-stop if drawdown >5% in a week.
-
-
Regulatory Compliance
-
Register algorithm with SEBI-registered broker (Upstox).
-
Maintain audit logs for 3 years.
-
Adhere to position limits (5% free float) and margin requirements.
-
By focusing on Buy-on-Gap, MA Crossover, and ETF Pair Mean Reversion, retail traders with ₹5–10 Lakh can implement robust, low-complexity quant strategies using Upstox API—with clear steps for data, backtesting, paper-trading, and live deployment under SEBI guidelines.
References
Ernie P. Chan, Algorithmic Trading (2013)
Rishi K. Narang, Inside the Black Box (2009)
Comments
Post a Comment