|
| 1 | +# RiskSim |
1 | 2 |
|
2 | | -# RiskSim: Risk-Return and Asset Correlation Simulator |
| 3 | +**Interactive risk management simulator for traders and portfolio managers.** |
3 | 4 |
|
4 | | -**RiskSim** is a Python-based tool designed for portfolio and risk simulation. It offers an intuitive interface to model risk-return dynamics and assess portfolio performance under various asset correlation scenarios, providing deep insights into risk management strategies and investment outcomes. |
| 5 | +RiskSim helps you understand how trading parameters and asset correlations affect portfolio outcomes. It uses Monte Carlo simulation and correlated Brownian motion to model thousands of scenarios, giving you a realistic picture of expected returns, drawdowns, and diversification benefits. |
5 | 6 |
|
6 | | -## Link to the app |
| 7 | +[](https://github.com/chrisduvillard/RiskSim/actions/workflows/ci.yml) |
| 8 | +[](https://risk-return-analysis.streamlit.app/) |
7 | 9 |
|
8 | | -[Click here to access the app](https://risk-return-analysis.streamlit.app/) |
| 10 | +--- |
9 | 11 |
|
10 | 12 | ## Features |
11 | 13 |
|
12 | | -- **Risk-Return Analysis**: Simulate various risk-return scenarios using adjustable parameters like win rate, trades per year, risk per trade, and return per unit of risk (RPUR). Uses Monte Carlo simulation to estimate expected returns and drawdowns. |
13 | | -- **Asset Correlation Simulator**: Generate and visualize portfolio performance based on customizable asset correlation matrices, with options for single or random correlation ranges. Computes Sharpe, Sortino, Calmar ratios, max drawdown, and more. |
| 14 | +### Risk-Return Analysis |
14 | 15 |
|
15 | | -## Screenshots |
| 16 | +Explore how win rate, trade frequency, position sizing, and reward-to-risk ratio interact to produce your expected P&L. |
16 | 17 |
|
17 | | - |
18 | | -*Risk-Return Analysis Page* |
| 18 | +- **Monte Carlo engine** — runs up to 100,000 simulations per parameter set |
| 19 | +- **RPUR sweep** — bar chart of average return across 16 Return Per Unit Risk levels (0.5x to 8x) |
| 20 | +- **Win-rate sweep** — bar chart of average return across win rates (28% to 70%) |
| 21 | +- **Drawdown estimation** — expected and worst-case consecutive-loss drawdown |
| 22 | +- **Live metrics** — trades/year, win rate, risk/trade, RPUR, expected drawdown, max drawdown |
19 | 23 |
|
20 | | - |
21 | | -*Risk-Return Analysis Page* |
| 24 | +| Parameter | Range | Default | |
| 25 | +|---|---|---| |
| 26 | +| Trades per year | 5 – 100 | 30 | |
| 27 | +| Win rate | 28% – 70% | 40% | |
| 28 | +| Risk per trade | 0.25% – 5% | 1% | |
| 29 | +| Return per unit risk | 0.5x – 8x | 3x | |
| 30 | +| Simulations | 10,000 – 100,000 | 10,000 | |
22 | 31 |
|
23 | | - |
24 | | -*Asset Correlation Simulation Page* |
| 32 | +### Asset Correlation Simulator |
25 | 33 |
|
26 | | - |
27 | | -*Asset Correlation Simulation Page* |
| 34 | +Generate synthetic multi-asset portfolios and see how correlation structure drives risk and return. |
28 | 35 |
|
29 | | -## Project Structure |
| 36 | +- **Flexible correlation** — set a single uniform correlation or a random range (min/max) |
| 37 | +- **Configurable assets** — 1 to 50 assets, 1 to 10 years of simulated prices |
| 38 | +- **Randomization** — optionally vary mean returns and volatilities across assets |
| 39 | +- **Performance metrics** — Sharpe, Sortino, Calmar ratios, annualized return/volatility, max drawdown |
| 40 | +- **Correlation sweep** — compares portfolio performance across correlation levels from -1.0 to +1.0 |
| 41 | +- **Heatmap** — visualize the realized correlation matrix |
30 | 42 |
|
31 | | -``` |
32 | | -RiskSim/ |
33 | | -├── Welcome.py # Streamlit entrypoint (landing page) |
34 | | -├── pages/ |
35 | | -│ ├── 1_🎯_risk_return_analysis.py # Risk-return Monte Carlo simulation |
36 | | -│ └── 2_📈_asset_correlation.py # Asset correlation portfolio simulator |
37 | | -├── config/ |
38 | | -│ └── slider_configs.py # Centralized slider defaults and bounds |
39 | | -├── utils/ |
40 | | -│ ├── risk_simulation.py # TradingSimulator class + drawdown simulation |
41 | | -│ └── style.py # Footer and metric box HTML helpers |
42 | | -├── tests/ |
43 | | -│ ├── test_risk_simulation.py # Tests for simulation logic |
44 | | -│ └── test_style.py # Tests for style helpers |
45 | | -├── docs/ |
46 | | -│ ├── audit_report.md # Codebase audit report |
47 | | -│ └── images/ # Screenshots and header image |
48 | | -├── .github/workflows/ci.yml # GitHub Actions CI (ruff + pytest) |
49 | | -├── pyproject.toml # Ruff and pytest configuration |
50 | | -├── requirements.txt # Python dependencies |
51 | | -├── CHANGELOG.md # Change log |
52 | | -├── LICENSE.txt # MIT License |
53 | | -└── README.md |
54 | | -``` |
| 43 | +--- |
| 44 | + |
| 45 | +## Screenshots |
55 | 46 |
|
56 | | -## Setup |
| 47 | +<table> |
| 48 | + <tr> |
| 49 | + <td><img src="docs/images/image.png" alt="RPUR Analysis" width="100%"></td> |
| 50 | + <td><img src="docs/images/image_2.png" alt="Win Rate Analysis" width="100%"></td> |
| 51 | + </tr> |
| 52 | + <tr> |
| 53 | + <td><em>RPUR sweep — average return by reward-to-risk ratio</em></td> |
| 54 | + <td><em>Win-rate sweep — average return by win rate</em></td> |
| 55 | + </tr> |
| 56 | + <tr> |
| 57 | + <td><img src="docs/images/image_3.png" alt="Asset Price Simulation" width="100%"></td> |
| 58 | + <td><img src="docs/images/image_4.png" alt="Correlation Heatmap" width="100%"></td> |
| 59 | + </tr> |
| 60 | + <tr> |
| 61 | + <td><em>Synthetic asset price paths with portfolio overlay</em></td> |
| 62 | + <td><em>Portfolio performance across different correlation regimes</em></td> |
| 63 | + </tr> |
| 64 | +</table> |
| 65 | + |
| 66 | +--- |
| 67 | + |
| 68 | +## Getting Started |
57 | 69 |
|
58 | 70 | ### Prerequisites |
59 | 71 |
|
60 | | -- Python 3.10 or higher |
61 | | -- pip |
| 72 | +- Python 3.10+ |
62 | 73 |
|
63 | | -### Installation |
| 74 | +### Install |
64 | 75 |
|
65 | 76 | ```bash |
66 | | -# Clone the repository |
67 | 77 | git clone https://github.com/chrisduvillard/RiskSim.git |
68 | 78 | cd RiskSim |
69 | | - |
70 | | -# Create and activate a virtual environment |
71 | 79 | python -m venv .venv |
72 | | -# On Windows: |
| 80 | + |
| 81 | +# Activate the virtual environment |
| 82 | +# Windows: |
73 | 83 | .venv\Scripts\activate |
74 | | -# On macOS/Linux: |
| 84 | +# macOS / Linux: |
75 | 85 | source .venv/bin/activate |
76 | 86 |
|
77 | | -# Install dependencies |
78 | 87 | pip install -r requirements.txt |
79 | 88 | ``` |
80 | 89 |
|
81 | | -### Run the App |
| 90 | +### Run |
82 | 91 |
|
83 | 92 | ```bash |
84 | 93 | streamlit run Welcome.py |
85 | 94 | ``` |
86 | 95 |
|
87 | | -This launches the app in your browser. Use the sidebar to navigate between pages. |
| 96 | +The app opens in your browser. Use the sidebar to navigate between pages, adjust parameters, and click **Run Simulation**. |
88 | 97 |
|
89 | | -### Run Tests |
| 98 | +--- |
| 99 | + |
| 100 | +## Development |
| 101 | + |
| 102 | +### Run tests |
90 | 103 |
|
91 | 104 | ```bash |
92 | 105 | pip install pytest |
93 | 106 | pytest -v |
94 | 107 | ``` |
95 | 108 |
|
96 | | -### Run Linter |
| 109 | +### Lint |
97 | 110 |
|
98 | 111 | ```bash |
99 | 112 | pip install ruff |
100 | 113 | ruff check . |
101 | 114 | ``` |
102 | 115 |
|
103 | | -## Methodology |
| 116 | +### CI |
104 | 117 |
|
105 | | -### Risk-Return Analysis |
| 118 | +GitHub Actions runs both `ruff check .` and `pytest` on every push and PR against `main` (Python 3.10 and 3.12). |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +## How It Works |
| 123 | + |
| 124 | +### Risk-Return Analysis — Monte Carlo Trading Simulation |
| 125 | + |
| 126 | +The simulator models a year of trading as a sequence of independent bets: |
| 127 | + |
| 128 | +1. Each trade risks a fixed percentage of **current** AUM (compounding, not flat sizing). |
| 129 | +2. Wins return `risk_amount * RPUR`; losses lose `risk_amount`. |
| 130 | +3. Trade outcomes are shuffled randomly each simulation to capture path dependency. |
| 131 | +4. The process repeats thousands of times to build a distribution of final portfolio values. |
| 132 | +5. Drawdown is estimated by counting the longest streak of consecutive losses across simulations. |
| 133 | + |
| 134 | +This reveals the non-obvious interaction between win rate and reward-to-risk: a 35% win rate with a 4:1 payoff can outperform a 55% win rate with a 1.5:1 payoff. |
| 135 | + |
| 136 | +### Asset Correlation — Correlated Geometric Brownian Motion |
| 137 | + |
| 138 | +The portfolio simulator generates realistic multi-asset price paths: |
| 139 | + |
| 140 | +1. **Correlation matrix** — either uniform (all pairs share the same correlation) or random within a user-specified range. Non-positive-definite matrices are projected to the nearest valid matrix. |
| 141 | +2. **Covariance matrix** — constructed from per-asset volatilities and the correlation matrix (`S @ C @ S`). |
| 142 | +3. **Log-returns** — sampled from a multivariate normal distribution with drift adjustment (`mu - 0.5 * sigma^2`) to ensure prices follow geometric Brownian motion. |
| 143 | +4. **Metrics** — computed from the resulting price paths: annualized return, volatility, max drawdown, and risk-adjusted ratios (Sharpe, Sortino, Calmar). |
| 144 | +5. **Correlation sweep** — the entire simulation is repeated across correlation levels from -1.0 to +1.0 to illustrate the diversification benefit. |
| 145 | + |
| 146 | +--- |
| 147 | + |
| 148 | +## Project Structure |
| 149 | + |
| 150 | +``` |
| 151 | +RiskSim/ |
| 152 | +├── Welcome.py # Streamlit entrypoint |
| 153 | +├── pages/ |
| 154 | +│ ├── 1_🎯_risk_return_analysis.py # Risk-return Monte Carlo page |
| 155 | +│ └── 2_📈_asset_correlation.py # Correlation portfolio page |
| 156 | +├── config/ |
| 157 | +│ └── slider_configs.py # Centralized slider defaults |
| 158 | +├── utils/ |
| 159 | +│ ├── risk_simulation.py # TradingSimulator + drawdown estimation |
| 160 | +│ └── style.py # Footer and metric box helpers |
| 161 | +├── tests/ |
| 162 | +│ ├── test_risk_simulation.py # Simulation logic tests |
| 163 | +│ └── test_style.py # Style helper tests |
| 164 | +├── .github/workflows/ci.yml # CI pipeline |
| 165 | +├── pyproject.toml # Ruff + pytest config |
| 166 | +├── requirements.txt # Dependencies |
| 167 | +├── CHANGELOG.md |
| 168 | +├── LICENSE.txt # MIT |
| 169 | +└── README.md |
| 170 | +``` |
| 171 | + |
| 172 | +--- |
106 | 173 |
|
107 | | -The Risk-Return Analysis page uses **Monte Carlo simulation** to model trading outcomes. Given a set of parameters (number of trades per year, win rate, risk per trade, and return per unit of risk), the simulator: |
| 174 | +## Tech Stack |
108 | 175 |
|
109 | | -1. Generates random trade sequences where each trade is a win or loss based on the specified win rate |
110 | | -2. Applies compounding: each trade's P&L is a percentage of the *current* AUM (not the initial capital) |
111 | | -3. Repeats this process thousands of times to build a distribution of outcomes |
112 | | -4. Reports average returns across different RPUR levels and win rates |
113 | | -5. Estimates the expected maximum consecutive-loss drawdown |
| 176 | +| Layer | Tool | |
| 177 | +|---|---| |
| 178 | +| App framework | [Streamlit](https://streamlit.io/) | |
| 179 | +| Visualization | [Plotly](https://plotly.com/python/) | |
| 180 | +| Numerical engine | [NumPy](https://numpy.org/) + [Pandas](https://pandas.pydata.org/) | |
| 181 | +| Styling | [htbuilder](https://github.com/tvst/htbuilder) | |
| 182 | +| Linting | [Ruff](https://docs.astral.sh/ruff/) | |
| 183 | +| Testing | [pytest](https://docs.pytest.org/) | |
| 184 | +| CI | [GitHub Actions](https://github.com/features/actions) | |
114 | 185 |
|
115 | | -### Asset Correlation Simulation |
| 186 | +--- |
116 | 187 |
|
117 | | -The Asset Correlation page generates synthetic multi-asset portfolios using **correlated geometric Brownian motion**: |
| 188 | +## Contributing |
118 | 189 |
|
119 | | -1. Builds a correlation matrix (uniform or random within a range), ensuring positive definiteness |
120 | | -2. Constructs a covariance matrix from per-asset volatilities and the correlation matrix |
121 | | -3. Samples multivariate normal log-returns and converts to price paths |
122 | | -4. Computes per-asset and portfolio performance metrics (Sharpe, Sortino, Calmar, max drawdown) |
123 | | -5. Sweeps across correlation levels to show how diversification affects portfolio risk |
| 190 | +Contributions are welcome. Fork the repo, create a branch, and open a pull request. Please make sure `ruff check .` and `pytest` pass before submitting. |
124 | 191 |
|
125 | 192 | ## License |
126 | 193 |
|
127 | | -This project is licensed under the MIT License. See the [LICENSE.txt](LICENSE.txt) file for details. |
| 194 | +MIT — see [LICENSE.txt](LICENSE.txt). |
128 | 195 |
|
129 | 196 | ## Author |
130 | 197 |
|
131 | | -Made by [Christophe Duvillard](https://www.linkedin.com/in/christopheduvillard/) |
| 198 | +Built by [Christophe Duvillard](https://www.linkedin.com/in/christopheduvillard/) |
0 commit comments