Step-by-Step Guide: Implementing Quant Strategies with Upstox API
This guide walks through developing, deploying, and testing the top-performing strategies (Kalman-Filter Pairs, Buy-on-Gap, Sectoral ETF Mean Reversion) on the Indian stock market using the Upstox API in Python.
1. Prerequisites
-
Upstox developer account with API key & secret
-
Python 3.8+ environment
-
Libraries:
upstox-api,pandas,numpy,statsmodels,scikit-learn,vectorbt -
Real-time and historical data access permissions
-
Virtual environment or Docker for isolation
2. Environment Setup
bash# Create a virtual environment python3 -m venv quant_env source quant_env/bin/activate # Install required packages pip install upstox-api pandas numpy statsmodels scikit-learn vectorbt
3. Authentication & Session Management
pythonfrom upstox_api.api import Upstox, Session, AccessToken API_KEY = 'YOUR_API_KEY' API_SECRET = 'YOUR_API_SECRET' REDIRECT_URI = 'https://yourapp.com/callback' # 1. Generate login URL u = Upstox(API_KEY, None) login_url = u.get_login_url(redirect_uri=REDIRECT_URI, response_type='code') print("Open this URL in browser:", login_url) # 2. After login, Upstox redirects with ?code=YOUR_CODE # Exchange code for access token code = 'RECEIVED_CODE' session = Session(API_KEY, API_SECRET) session.set_redirect_uri(REDIRECT_URI) session.set_code(code) access_token = session.retrieve_access_token() u = Upstox(API_KEY, access_token)
4. Data Retrieval
4.1 Historical Data (Daily, Intraday)
pythonimport pandas as pd # Fetch OHLCV for a symbol symbol = 'RELIANCE' from_date, to_date = '2023-01-01', '2025-10-14' interval = 'ONE_MINUTE' # options: ONE_MINUTE, FIVE_MINUTE, DAY bars = u.get_ohlc(u.get_instrument_by_symbol('NSE_EQ', symbol), interval, from_date, to_date) df = pd.DataFrame([{ 'datetime': bar.timestamp, 'open': bar.open, 'high': bar.high, 'low': bar.low, 'close': bar.close, 'volume': bar.volume } for bar in bars]) df.set_index('datetime', inplace=True)
4.2 Real-Time Quotes
python# Subscribe to live feed def on_quote_update(quote): print(quote) u.subscribe(u.get_instrument_by_symbol('NSE_EQ', 'TCS'), LiveFeedType.LTP) u.set_live_feed_listener(on_quote_update)
5. Strategy Modules
5.1 Kalman-Filter Pairs Trading
pythonfrom statsmodels.regression.kalman_filter import KalmanFilter import numpy as np def kalman_spread(series_x, series_y): # Estimate time-varying hedge ratio kf = KalmanFilter(k_endog=1, k_states=2) # Simplified implementation; see statsmodels docs # Fit on spread = y - beta*x # ... return spread, beta_series # Backtest loop def backtest_kalman(df_x, df_y): spread, beta = kalman_spread(df_x['close'], df_y['close']) zscore = (spread - spread.mean()) / spread.std() signals = np.where(zscore > 1, -1, np.where(zscore < -1, 1, 0)) # Implement position logic, P&L calculation, transaction costs return pnl_series
5.2 Buy-on-Gap Model
pythondef backtest_buy_on_gap(df): df['prev_close'] = df['close'].shift(1) df['gap_pct'] = (df['open'] - df['prev_close']) / df['prev_close'] entries = df['gap_pct'] < -0.01 # gap down >1% df['position'] = entries.astype(int) df['returns'] = df['close'].pct_change() df['strategy_ret'] = df['position'].shift(1) * df['returns'] return df['strategy_ret'].cumsum()
5.3 Sectoral ETF Mean Reversion
pythondef backtest_etf_mean_reversion(df_etf): df_etf['ma'] = df_etf['close'].rolling(window=20).mean() df_etf['std'] = df_etf['close'].rolling(window=20).std() df_etf['upper'] = df_etf['ma'] + 2*df_etf['std'] df_etf['lower'] = df_etf['ma'] - 2*df_etf['std'] df_etf['position'] = np.where(df_etf['close'] > df_etf['upper'], -1, np.where(df_etf['close'] < df_etf['lower'], 1, 0)) df_etf['ret'] = df_etf['close'].pct_change() df_etf['strat_ret'] = df_etf['position'].shift(1) * df_etf['ret'] return df_etf['strat_ret'].cumsum()
6. Backtesting & Performance Evaluation
pythonimport vectorbt as vbt # Example: Evaluate Buy-on-Gap strategy on Reliance pnl = backtest_buy_on_gap(df) stats = vbt.Portfolio.from_returns(pnl).stats() print(stats[['Total Return', 'Sharpe Ratio', 'Max Drawdown']])
7. Deployment & Live Trading
-
Paper Trading
-
Run strategy modules on real-time quotes without sending orders.
-
Log signals and simulated P&L to verify live performance.
-
-
Order Placement
pythondef place_order(symbol, quantity, buy=True): instrument = u.get_instrument_by_symbol('NSE_EQ', symbol) order_type = TransactionType.Buy if buy else TransactionType.Sell u.place_order(instrument, quantity, order_type, ProductType.Intraday, OrderType.Market, None, None, None, None) -
Risk Controls
-
Pre-trade: verify position limits, exposure
-
Post-trade: monitor P&L, cancel stale orders
-
Kill switch: terminate strategy if drawdown >10%
-
-
Scheduling
-
Use
cronor an orchestrator (Airflow) to run backtests and live modules. -
Daily start at 9:10 AM IST for data sync.
-
Daily end at 3:40 PM IST for shutdown and reporting.
-
8. Monitoring & Reporting
-
Dashboard: Streamlit or Grafana displaying P&L, positions, alpha metrics.
-
Alerts: Email/SMS notifications for threshold breaches (drawdown, unfilled orders).
-
Logs: Maintain structured logs for audit trail (order, fills, exceptions).
9. Next Steps
-
Parameter Optimization: Grid search on look-back windows, z-score thresholds.
-
Robustness Testing: Walk-forward analysis and Monte Carlo simulations.
-
Strategy Expansion: Add momentum and volatility arbitrage modules.
-
Compliance Review: Final audit of algorithm documentation for SEBI registration.
This end-to-end guide provides the code templates, architectural patterns, and operational procedures to develop, test, and deploy your quant strategies on the Indian market using the Upstox API.
Comments
Post a Comment