Skip to content

Commit 22000d0

Browse files
Merge pull request #2 from rohitashwachaks/init
Init
2 parents 0106092 + 2c5b3ed commit 22000d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1887
-1404
lines changed

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,12 @@ cython_debug/
173173
# PyPI configuration file
174174
.pypirc
175175
.idea/
176-
.qodo/
176+
.qodo/
177+
/data_cache
178+
/figures
179+
/logs
180+
product_roadmap.md
181+
/run
182+
/logs
183+
/.run
184+
/.vscode

README.md

Lines changed: 147 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
1-
# 🚀 Trader++: The Next-Gen Quant Trading Engine
2-
1+
<p align="center">
2+
<img src="./assets/trader_pp_logo.png" alt="Trader++ Logo" width="100%" style="object-fit:cover;height:300px;object-position:center;border-radius:12px;box-shadow:0 4px 24px rgba(0,0,0,0.10);" />
3+
</p>
4+
5+
> 💡 Why Trader++?
6+
>
7+
> I built Trader++ because I wanted a tool that didn’t lie to me.
8+
>
9+
> I needed something that could:
10+
> - Let me write strategies quickly
11+
> - Simulate realistically
12+
> - Go from backtest → paper → live with zero rewrites
13+
> - Show me how my portfolio’s actually doing, holistically!
14+
>
15+
> Existing tools? Clunky. Proprietary. Not programmable enough.
16+
>
17+
> So I built it — for myself first. Now, it’s for every quant who thinks like a developer.
18+
>
319
> **Unleash the power of modular, realistic, and extensible portfolio simulation.**
420
521
---
@@ -22,6 +38,76 @@ Trader++ isn’t just another backtesting tool. It’s a full-fledged quant trad
2238

2339
---
2440

41+
## 🏆 MVP Roadmap
42+
43+
### 1. Unified Execution Engine
44+
- Common interface: `BacktestExecutor`, `PaperExecutor`, `LiveExecutor`
45+
- Live broker integration (Alpaca, IBKR, TD Ameritrade)
46+
- Real-time slippage, partial fills, latency simulation
47+
48+
### 2. Advanced Strategy Framework
49+
- YAML/DSL config loader for no-code strategies
50+
- Multi-frequency, multi-asset support
51+
- ML model integration (Torch/Sklearn) + MLFlow/W&B logging
52+
53+
### 3. Modular Risk & Portfolio Control
54+
- Position sizing (Kelly, risk parity, volatility targeting)
55+
- Real-time rule engine (e.g., freeze strategy on drawdown)
56+
- Hierarchical/nested portfolios with capital/risk constraints
57+
58+
### 4. Performance & Attribution Analytics
59+
- Alpha, beta, Sharpe, Sortino, Calmar
60+
- Attribution by asset, sector, strategy
61+
- Trade replay and audit trail
62+
63+
### 5. Interactive Visualization
64+
- Streamlit/Dash hybrid dashboard
65+
- Trade timeline, rolling metrics, slippage/turnover/holding histograms
66+
67+
### 6. Scalable Simulation Engine
68+
- Multiprocessed/multithreaded backtesting core
69+
- GPU acceleration for ML strategies
70+
- Clean, event-driven simulation loop
71+
72+
### 7. Data Layer
73+
- SQL/Parquet backend support
74+
- Live feed adapters
75+
- Flexible bar aggregators (time, volume, event)
76+
77+
### 8. AI & Data-Driven Research
78+
- Sentiment and alt-data adapters (Reddit, news, Google Trends)
79+
- Cointegration, Kalman filter, auto-correlation modules
80+
81+
### 9. Tests, Docs, Demos
82+
- Unit tests for each module
83+
- Example strategies (momentum, mean-reversion, breakout)
84+
- Jupyter/Streamlit demo notebooks
85+
86+
---
87+
88+
## 🚦 MVP Status (June 2025)
89+
90+
| Feature | Status | Notes |
91+
|-----------------------------------|-------------|----------------------------------------------------------------------------------------------------------------|
92+
| Unified Execution Engine | ✅ Complete | Backtest, Paper, Live modes implemented with shared API. Paper & Live mode requires broker API implementation. |
93+
| Modular Strategy Framework | ✅ Complete | StrategyBase and example strategies present. Plug-and-play. |
94+
| Portfolio/Risk Management | ✅ Complete | Portfolio class, guardrails, position sizing hooks implemented. |
95+
| Analytics & Attribution | ✅ Partial | Core metrics (Sharpe, alpha, etc.) present. Some advanced analytics in progress. |
96+
| Interactive Dashboard | ⚠️ Partial | Streamlit app exists, some features stubbed or in progress. |
97+
| Scalable Simulation Engine | ⚠️ Partial | Event-driven core present; multiprocessing support basic or planned. |
98+
| Data Layer | ✅ Complete | Data ingestion, caching, and basic adapters present. |
99+
| ML/DSL Integration | 🚧 Planned | ML model integration and YAML/DSL loader planned. |
100+
101+
---
102+
103+
## Next Steps (Post-MVP)
104+
- Expand broker integrations for live trading
105+
- Enhance dashboard with more analytics and controls
106+
- Add ML/DSL strategy support
107+
- Improve test coverage and documentation
108+
109+
---
110+
25111
## 🧠 Objective
26112

27113
Empower quants and developers to:
@@ -62,6 +148,38 @@ flowchart TD
62148

63149
---
64150

151+
## 🏗️ Project Structure & Architecture
152+
153+
- `contracts/` — Core contracts and abstract base classes (Portfolio, StrategyBase, Executor)
154+
- `core/` — Core logic, execution engines, simulation loop
155+
- `strategies/` — Example and user strategies (momentum, buy & hold, etc.)
156+
- `data_ingestion/`, `data_cache/` — Data loaders, adapters, and caching for reproducible research
157+
- `analytics/`, `ml_engine/` — Analytics, reporting, and ML integrations
158+
- `dashboard/` — Streamlit/Dash dashboard for visualization
159+
- `run_backtest.py` — CLI entry point to run backtests
160+
- `main.py`, `run/` — Additional CLI tools and runners
161+
162+
---
163+
164+
## 🚦 Development Roadmap (Next Steps)
165+
166+
1. **Finalize Core Contracts**
167+
- Audit and refine `Portfolio`, `StrategyBase`, and `PortfolioExecutor` for strict modularity and safety (no future leaks).
168+
2. **Strategy API**
169+
- Enforce and document the `generate_signals` interface. Add more example strategies.
170+
3. **Backtesting Engine**
171+
- Expand test coverage and logging in `run_backtest.py` and `core/executors/backtest.py`.
172+
4. **Data Layer**
173+
- Ensure robust, reproducible data ingestion and caching. Document data contracts.
174+
5. **CLI & Developer Experience**
175+
- Improve CLI usability and add clear usage examples.
176+
6. **Dashboard & Analytics**
177+
- Expand analytics and dashboard integration for portfolio and strategy reporting.
178+
7. **Documentation**
179+
- Add docstrings, inline docs, and contribution guidelines for new modules and strategies.
180+
181+
---
182+
65183
## 🔧 Core Components
66184

67185
| Module | Purpose |
@@ -76,84 +194,47 @@ flowchart TD
76194

77195
## 💡 Main Features
78196

79-
- 📈 **Backtesting Engine** — Realistic execution, guardrails, cash balance checks
197+
- 📈 **Backtesting Engine** — Realistic execution, guardrails, cash shares checks
80198
- 🧠 **Pluggable Strategy Interface** — Stateful/stateless signal generation
81199
- 💼 **Portfolio Tracking** — Accurate PnL with trade logs, equity curves
82-
- 🛡️ **Guardrail System** — Risk management hooks (stop-loss, asset unregister)
200+
- 🛡️ **GuardrailBase System** — Risk management hooks (stop-loss, asset unregister)
83201
- 📊 **Performance Reporting** — Sharpe, max drawdown, win rate, CAGR, more
84202
- 🔬 **Benchmark Comparison** — Alpha, beta, vs SPY or other tickers
85203
- 🧪 **Test Strategies** — Debug pipeline (e.g., “buy once on day 1”)
86204

87205
---
88206

89-
## 🚀 Quick Start
90-
91-
```sh
92-
# Install dependencies
93-
pip install -r requirements.txt
94-
95-
# Run a backtest
96-
python run_backtest.py --strategy momentum --tickers AAPL,MSFT --start 2023-01-01 --end 2023-12-31 --plot
97-
98-
# Or use the Streamlit UI
99-
streamlit run streamlit_app.py
100-
```
101-
102-
---
103-
104-
## 🧩 Project Structure
105-
106-
```text
107-
📦traderplusplus
108-
├── contracts
109-
│ ├── asset.py # Asset & CashAsset classes
110-
│ └── portfolio.py # Portfolio definition
111-
├── core
112-
│ ├── backtester.py # Runs simulation
113-
│ ├── executor.py # Executes trades
114-
│ ├── market_data.py # Loads, stores & queries market data
115-
│ ├── data_loader.py # Yahoo/Polygon loaders + caching
116-
│ ├── guardrails # Risk guardrail classes
117-
│ └── visualizer.py # Matplotlib + Plotly charts
118-
├── strategies
119-
│ ├── base.py # StrategyBase + factory
120-
│ └── stock
121-
│ ├── momentum.py # Example strategy
122-
├── analytics
123-
│ └── performance.py # Sharpe, Alpha etc.
124-
├── run_backtest.py # CLI tool
125-
└── streamlit_app.py # UI
126-
```
127-
207+
## 🚀 Quickstart
208+
209+
1. **Install Requirements**
210+
```bash
211+
pip install -r requirements.txt
212+
```
213+
2. **Run a Backtest**
214+
```bash
215+
python main.py --start=2022-05-29 --end=2025-05-29 --cash 50000 --plot --export --tickers=META --refresh --strategy=momentum --benchmark=META --guardrail=trailing_stop_loss
216+
```
217+
3. **Add a New Strategy**
218+
- Implement a new class in `strategies/` inheriting from `StrategyBase` and implementing `generate_signals()`.
219+
- Register your strategy by importing it in `strategies/__init__.py`.
220+
221+
4 **Add a New Guardrail**
222+
- Implement a new class in `guardrails/` inheriting from `GuardrailBase` and implementing `evaluate()`.
223+
- Register your guardrail by importing it in `guardrails/__init__.py`.
128224
---
129225

130-
## 🌱 Vision for Future Work
131-
132-
### 🎯 Execution & Simulation
133-
- Live trading interface (Alpaca, IBKR)
134-
- Slippage and commission modeling
135-
- Real-time execution with event-based feed
136-
137-
### 🧠 Strategy Framework
138-
- Portfolio optimization (Risk Parity, Markowitz)
139-
- Signal pipelines (multi-indicator, ML-based)
140-
- RL and LLM-based adaptive strategies
226+
## 🤝 Contributing
141227

142-
### 📊 Analytics & Visualization
143-
- Interactive dashboard (Streamlit/Plotly)
144-
- Trade replay, diagnostics
145-
- Alpha decomposition, factor attribution
146-
147-
### 🧱 Engine Internals
148-
- Custom logging, debugging, test harness
149-
- Multiprocess strategy evaluation
150-
- Config-driven simulation pipelines
228+
[//]: # (- See the Development Roadmap above for high-priority areas.)
229+
- Add new strategies, data adapters, or analytics modules as composable units.
230+
- Follow modular design and document your code.
231+
- PRs and issues welcome!
151232

152233
---
153234

154-
## 🙌 Contributing
235+
## 🌱 Vision for Future Work
155236

156-
Pull requests and suggestions are welcome! For major changes, please open an issue first to discuss what you’d like to change.
237+
See the MVP Roadmap above for our ambitious next steps!
157238

158239
---
159240

@@ -169,4 +250,4 @@ Open an issue or reach out via GitHub for questions and collaboration!
169250

170251
---
171252

172-
Enjoy building and experimenting with Trader++! 🚀
253+
Enjoy building and experimenting with Trader++! 🚀

analytics/performance_evaluator.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"""
2+
PerformanceEvaluator: Evaluate portfolio performance against a benchmark.
3+
Clean, stateless, and extensible. Accepts equity curves as pandas Series/DataFrames.
4+
"""
5+
from typing import Optional, Dict
6+
import pandas as pd
7+
import numpy as np
8+
9+
10+
class PerformanceEvaluator:
11+
"""
12+
Evaluates portfolio performance relative to a benchmark.
13+
Usage:
14+
evaluator = PerformanceEvaluator(equity_curve, benchmark_curve)
15+
metrics = evaluator.compute_metrics()
16+
"""
17+
def __init__(self,
18+
portfolio_curve: pd.Series,
19+
benchmark_curve: pd.Series,
20+
risk_free_rate: float = 0.0):
21+
"""
22+
Args:
23+
portfolio_curve (pd.Series): Portfolio net worth indexed by date.
24+
benchmark_curve (pd.Series): Benchmark value/indexed by date.
25+
risk_free_rate (float): Annualized risk-free rate (as decimal).
26+
"""
27+
self.portfolio_curve = portfolio_curve#.sort_index()
28+
self.benchmark_curve = benchmark_curve#.sort_index()
29+
self.risk_free_rate = risk_free_rate
30+
# self._align_curves()
31+
32+
# def _align_curves(self):
33+
# # Align curves to common dates
34+
# common_idx = self.portfolio_curve.index.intersection(self.benchmark_curve.index)
35+
# self.portfolio_curve = self.portfolio_curve.loc[common_idx]
36+
# self.benchmark_curve = self.benchmark_curve.loc[common_idx]
37+
38+
def compute_metrics(self) -> Dict[str, float]:
39+
"""
40+
Compute absolute and relative performance metrics.
41+
Returns:
42+
Dict[str, float]: Metrics including return, volatility, Sharpe, alpha, beta, etc.
43+
"""
44+
port_ret = self.portfolio_curve.pct_change().dropna()
45+
bench_ret = self.benchmark_curve.pct_change().dropna()
46+
# Align returns
47+
port_ret, bench_ret = port_ret.align(bench_ret, join='inner')
48+
49+
# Defensive checks
50+
if len(port_ret) < 2 or len(bench_ret) < 2:
51+
print(f"[WARN] Not enough overlapping data for regression. Portfolio returns: {len(port_ret)}, Benchmark returns: {len(bench_ret)}")
52+
return {
53+
'portfolio_return': np.nan,
54+
'benchmark_return': np.nan,
55+
'active_return': np.nan,
56+
'win': np.nan,
57+
'cagr': np.nan,
58+
'volatility': np.nan,
59+
'sharpe': np.nan,
60+
'alpha': np.nan,
61+
'beta': np.nan,
62+
'max_drawdown': np.nan
63+
}
64+
excess_ret = port_ret - self.risk_free_rate/252
65+
excess_bench = bench_ret - self.risk_free_rate/252
66+
67+
metrics = {}
68+
metrics['portfolio_return'] = (self.portfolio_curve.iloc[-1] / self.portfolio_curve.iloc[0]) - 1
69+
metrics['benchmark_return'] = (self.benchmark_curve.iloc[-1] / self.benchmark_curve.iloc[0]) - 1
70+
metrics['active_return'] = metrics['portfolio_return'] - metrics['benchmark_return']
71+
metrics['win'] = (port_ret > 0).mean()
72+
metrics['cagr'] = port_ret.mean() * 252
73+
metrics['volatility'] = port_ret.std() * np.sqrt(252)
74+
metrics['sharpe'] = excess_ret.mean() / (port_ret.std() + 1e-9) * np.sqrt(252)
75+
76+
# Alpha/Beta via linear regression
77+
try:
78+
X = np.vstack([np.ones(len(excess_bench)), excess_bench.values]).T
79+
alpha, beta = np.linalg.lstsq(X, excess_ret.values, rcond=None)[0]
80+
metrics['alpha'] = alpha * 252 # annualized
81+
metrics['beta'] = beta
82+
except Exception as e:
83+
print(f"[WARN] Could not compute alpha/beta: {e}")
84+
metrics['alpha'] = np.nan
85+
metrics['beta'] = np.nan
86+
87+
# Max drawdown
88+
roll_max = self.portfolio_curve.cummax()
89+
drawdown = (self.portfolio_curve - roll_max) / roll_max
90+
metrics['max_drawdown'] = drawdown.min()
91+
92+
return metrics
93+
94+
def summary(self, as_str: bool = True) -> str | dict[str, float]:
95+
metrics = self.compute_metrics()
96+
if as_str:
97+
return '\n'.join(f"{k}: {v:.4f}" for k, v in metrics.items())
98+
return metrics

assets/favicon.png

950 KB
Loading

assets/trader_pp_logo.png

1.01 MB
Loading

0 commit comments

Comments
 (0)