Self-hosted algorithmic trading research system — data ingestion, backtesting, report persistence, and strategy visualization for Indian equity markets.
Built as a freelance contract for a trading firm. Production-grade, fully self-hosted, zero cloud dependency.
A complete end-to-end quantitative research platform covering the full pipeline:
| Module | What it does |
|---|---|
| Data Ingestion | Live OHLCV data from Groww API — NSE Equity, F&O, Index Spot, Index F&O. Incremental download, idempotent guarantees, OHLC validation, 5-sigma outlier detection. 12 datasets, 2,567+ persisted bars. |
| Backtesting Engine | Event-driven bar feed, BaseStrategy abstraction, order simulation (market/limit/stop/bracket), slippage + commission models. Full metrics: Sharpe, Sortino, CAGR, Max Drawdown, VaR, Win Rate, Alpha/Beta vs NIFTY 50. |
| Report Store | Immutable versioned reports — every run gets a UUID, metadata in PostgreSQL, artifacts (equity_curve.parquet, trades.parquet, report_full.json) on disk. Full audit trail, run_group linking for continuous backtesting. |
| Strategy Visualizer | React + TypeScript + TradingView Lightweight Charts. Normalized equity comparison, side-by-side Sharpe/Return/Drawdown table, PDF/CSV export. |
Python · FastAPI · PostgreSQL · Apache Parquet / PyArrow · React 18 · TypeScript · TradingView Lightweight Charts · Recharts · Tailwind CSS · SQLite (dev)
algotrade/ingestion/for Groww instrument and candle ingestionalgotrade/core/for the event-driven backtesting enginealgotrade/api/for the middleware and report store APIalgotrade/orchestration/for continuous run scheduling and orchestrationfrontend/for the strategy visualizer
The primary v1 path is:
- Groww historical ingestion
- Python backtesting
- versioned report storage
- web-based visualization and export
Yahoo is kept only as an optional demo fallback when Groww access is unavailable.
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
algotrade init-db
algotrade serveRecommended for real Groww ingestion: use PostgreSQL instead of SQLite.
Create a local connection string once:
createdb algotrade
printf '%s' 'postgresql+psycopg:///algotrade' > .secrets/database_urlThen algotrade init-db will use PostgreSQL automatically.
In a second terminal:
cd frontend
npm install
npm run devSet your token:
export ALGOTRADE_GROWW_API_TOKEN='your_token_here'Or place it in:
.secrets/groww_api_token
algotrade ingest-instrumentsFor low-disk validation runs, ingest only the symbols you need:
algotrade ingest-instruments \
--groww-symbol NSE-RELIANCE \
--groww-symbol NSE-BANKNIFTY \
--groww-symbol NSE-RELIANCE-30Mar26-FUT \
--groww-symbol NSE-BANKNIFTY-30Mar26-FUTExamples:
algotrade ingest-candles NSE-RELIANCE 1D 2025-01-01 2025-03-01 --segment EQ
algotrade ingest-candles NSE-NIFTY 1D 2025-01-01 2025-03-01 --segment IDX
algotrade ingest-candles NSE-BANKNIFTY-28Apr26-38000-CE 1D 2026-01-01 2026-03-01 --segment IDX_FNOSupported PRD-style segments:
EQEQ_FNOIDXIDX_FNO
algotrade backtest strategies/momentum.py RELIANCE 1D 2025-01-01 2025-03-01 --segment EQThe report is written under:
data/reports/<StrategyName>/<run_id>/
Open:
http://127.0.0.1:5173
Then:
- Enter the workspace
- Go to
Runs - Use the
Run backtestform - Pick a strategy, instrument, timeframe, and date range
- Export report JSON, equity CSV, or trades CSV from the selected run
If Groww is not available yet, use demo mode explicitly.
algotrade demo-bootstrap
algotrade backtest strategies/momentum.py RELIANCE 1D 2025-09-01 2026-03-13 --segment EQFor ad hoc demo ingestion:
algotrade ingest-instruments --provider demo
algotrade ingest-candles RELIANCE 1D 2025-09-01 2026-03-13 --segment EQ --provider demoalgotrade register-continuous strategies/momentum.py RELIANCE 1D 2025-01-01 --segment EQ
algotrade scheduler --onceGET /healthGET /dashboard/summaryGET /backtests/strategiesPOST /backtests/executeGET /runsGET /runs/{run_id}/equity-curveGET /runs/{run_id}/tradesGET /runs/{run_id}/report-fullGET /runs/{run_id}/equity-curve.csvGET /runs/{run_id}/trades.csvGET /strategiesGET /data/instrumentsGET /data/candlesGET /scheduler/registrationsPOST /scheduler/registrationsPOST /scheduler/run-now





