{"id":20778893,"url":"https://github.com/chrisduvillard/risksim","last_synced_at":"2026-04-21T17:06:11.008Z","repository":{"id":243077195,"uuid":"811402889","full_name":"chrisduvillard/RiskSim","owner":"chrisduvillard","description":"A tool for portfolio risk simulation that models asset correlations, offering insights into risk-return dynamics and investment outcomes.","archived":false,"fork":false,"pushed_at":"2024-09-18T13:49:56.000Z","size":977,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-18T08:36:46.865Z","etag":null,"topics":["correlation","python","risk-management","streamlit"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisduvillard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-06T14:28:04.000Z","updated_at":"2024-09-18T13:50:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"c55e25a5-d25e-425c-b035-2557379d1a0c","html_url":"https://github.com/chrisduvillard/RiskSim","commit_stats":null,"previous_names":["chrisduvillard/risksim"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduvillard%2FRiskSim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduvillard%2FRiskSim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduvillard%2FRiskSim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduvillard%2FRiskSim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisduvillard","download_url":"https://codeload.github.com/chrisduvillard/RiskSim/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243119538,"owners_count":20239321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["correlation","python","risk-management","streamlit"],"created_at":"2024-11-17T13:24:46.876Z","updated_at":"2026-04-21T17:06:11.002Z","avatar_url":"https://github.com/chrisduvillard.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RiskSim\n\n**Interactive risk management simulator for traders and portfolio managers.**\n\nRiskSim 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.\n\n[![CI](https://github.com/chrisduvillard/RiskSim/actions/workflows/ci.yml/badge.svg)](https://github.com/chrisduvillard/RiskSim/actions/workflows/ci.yml)\n[![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://risk-return-analysis.streamlit.app/)\n\n---\n\n## Features\n\n### Risk-Return Analysis\n\nExplore how win rate, trade frequency, position sizing, and reward-to-risk ratio interact to produce your expected P\u0026L.\n\n- **Monte Carlo engine** \u0026mdash; runs up to 100,000 simulations per parameter set\n- **RPUR sweep** \u0026mdash; bar chart of average return across 16 Return Per Unit Risk levels (0.5x to 8x)\n- **Win-rate sweep** \u0026mdash; bar chart of average return across win rates (28% to 70%)\n- **Drawdown estimation** \u0026mdash; expected and worst-case consecutive-loss drawdown\n- **Live metrics** \u0026mdash; trades/year, win rate, risk/trade, RPUR, expected drawdown, max drawdown\n\n| Parameter | Range | Default |\n|---|---|---|\n| Trades per year | 5 \u0026ndash; 100 | 30 |\n| Win rate | 28% \u0026ndash; 70% | 40% |\n| Risk per trade | 0.25% \u0026ndash; 5% | 1% |\n| Return per unit risk | 0.5x \u0026ndash; 8x | 3x |\n| Simulations | 10,000 \u0026ndash; 100,000 | 10,000 |\n\n### Asset Correlation Simulator\n\nGenerate synthetic multi-asset portfolios and see how correlation structure drives risk and return.\n\n- **Flexible correlation** \u0026mdash; set a single uniform correlation or a random range (min/max)\n- **Configurable assets** \u0026mdash; 1 to 50 assets, 1 to 10 years of simulated prices\n- **Randomization** \u0026mdash; optionally vary mean returns and volatilities across assets\n- **Performance metrics** \u0026mdash; Sharpe, Sortino, Calmar ratios, annualized return/volatility, max drawdown\n- **Correlation sweep** \u0026mdash; compares portfolio performance across correlation levels from -1.0 to +1.0\n- **Heatmap** \u0026mdash; visualize the realized correlation matrix\n\n---\n\n## Screenshots\n\nThe app fully supports both light and dark themes.\n\n### Welcome Page\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/welcome_light.png\" alt=\"Welcome page (light)\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/welcome_dark.png\" alt=\"Welcome page (dark)\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eLight mode\u003c/em\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eDark mode\u003c/em\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Risk-Return Analysis\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/risk_return_rpur_light.png\" alt=\"RPUR Analysis (light)\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/risk_return_rpur_dark.png\" alt=\"RPUR Analysis (dark)\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eRPUR sweep \u0026mdash; light mode\u003c/em\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eRPUR sweep \u0026mdash; dark mode\u003c/em\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/risk_return_winrate_light.png\" alt=\"Win Rate Analysis (light)\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/risk_return_winrate_dark.png\" alt=\"Win Rate Analysis (dark)\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eWin-rate sweep \u0026mdash; light mode\u003c/em\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eWin-rate sweep \u0026mdash; dark mode\u003c/em\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Asset Correlation Simulator\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/correlation_prices_light.png\" alt=\"Asset Prices (light)\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/correlation_prices_dark.png\" alt=\"Asset Prices (dark)\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eSynthetic asset price paths \u0026mdash; light mode\u003c/em\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eSynthetic asset price paths \u0026mdash; dark mode\u003c/em\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/correlation_heatmap_light.png\" alt=\"Correlation Heatmap (light)\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/correlation_heatmap_dark.png\" alt=\"Correlation Heatmap (dark)\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eCorrelation matrix heatmap \u0026mdash; light mode\u003c/em\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eCorrelation matrix heatmap \u0026mdash; dark mode\u003c/em\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/correlation_sweep_light.png\" alt=\"Correlation Sweep (light)\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"docs/images/correlation_sweep_dark.png\" alt=\"Correlation Sweep (dark)\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eCorrelation sweep \u0026mdash; light mode\u003c/em\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003cem\u003eCorrelation sweep \u0026mdash; dark mode\u003c/em\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## Getting Started\n\n### Prerequisites\n\n- Python 3.10+\n\n### Install\n\n```bash\ngit clone https://github.com/chrisduvillard/RiskSim.git\ncd RiskSim\npython -m venv .venv\n\n# Activate the virtual environment\n# Windows:\n.venv\\Scripts\\activate\n# macOS / Linux:\nsource .venv/bin/activate\n\npip install -r requirements.txt\n```\n\n### Run\n\n```bash\nstreamlit run Welcome.py\n```\n\nThe app opens in your browser. Use the sidebar to navigate between pages, adjust parameters, and click **Run Simulation**.\n\n---\n\n## Development\n\n### Run tests\n\n```bash\npip install pytest\npytest -v\n```\n\n### Lint\n\n```bash\npip install ruff\nruff check .\n```\n\n### CI\n\nGitHub Actions runs both `ruff check .` and `pytest` on every push and PR against `main` (Python 3.10 and 3.12).\n\n---\n\n## How It Works\n\n### Risk-Return Analysis \u0026mdash; Monte Carlo Trading Simulation\n\nThe simulator models a year of trading as a sequence of independent bets:\n\n1. Each trade risks a fixed percentage of **current** AUM (compounding, not flat sizing).\n2. Wins return `risk_amount * RPUR`; losses lose `risk_amount`.\n3. Trade outcomes are shuffled randomly each simulation to capture path dependency.\n4. The process repeats thousands of times to build a distribution of final portfolio values.\n5. Drawdown is estimated by counting the longest streak of consecutive losses across simulations.\n\nThis 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.\n\n### Asset Correlation \u0026mdash; Correlated Geometric Brownian Motion\n\nThe portfolio simulator generates realistic multi-asset price paths:\n\n1. **Correlation matrix** \u0026mdash; 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.\n2. **Covariance matrix** \u0026mdash; constructed from per-asset volatilities and the correlation matrix (`S @ C @ S`).\n3. **Log-returns** \u0026mdash; sampled from a multivariate normal distribution with drift adjustment (`mu - 0.5 * sigma^2`) to ensure prices follow geometric Brownian motion.\n4. **Metrics** \u0026mdash; computed from the resulting price paths: annualized return, volatility, max drawdown, and risk-adjusted ratios (Sharpe, Sortino, Calmar).\n5. **Correlation sweep** \u0026mdash; the entire simulation is repeated across correlation levels from -1.0 to +1.0 to illustrate the diversification benefit.\n\n---\n\n## Project Structure\n\n```\nRiskSim/\n├── Welcome.py                          # Streamlit entrypoint\n├── pages/\n│   ├── 1_🎯_risk_return_analysis.py    # Risk-return Monte Carlo page\n│   └── 2_📈_asset_correlation.py       # Correlation portfolio page\n├── config/\n│   └── slider_configs.py               # Centralized slider defaults\n├── utils/\n│   ├── risk_simulation.py              # TradingSimulator + drawdown estimation\n│   └── style.py                        # Footer and metric box helpers\n├── tests/\n│   ├── test_risk_simulation.py         # Simulation logic tests\n│   └── test_style.py                   # Style helper tests\n├── .github/workflows/ci.yml            # CI pipeline\n├── pyproject.toml                      # Ruff + pytest config\n├── requirements.txt                    # Dependencies\n├── CHANGELOG.md\n├── LICENSE.txt                         # MIT\n└── README.md\n```\n\n---\n\n## Tech Stack\n\n| Layer | Tool |\n|---|---|\n| App framework | [Streamlit](https://streamlit.io/) |\n| Visualization | [Plotly](https://plotly.com/python/) |\n| Numerical engine | [NumPy](https://numpy.org/) + [Pandas](https://pandas.pydata.org/) |\n| Styling | [htbuilder](https://github.com/tvst/htbuilder) |\n| Linting | [Ruff](https://docs.astral.sh/ruff/) |\n| Testing | [pytest](https://docs.pytest.org/) |\n| CI | [GitHub Actions](https://github.com/features/actions) |\n\n---\n\n## Contributing\n\nContributions are welcome. Fork the repo, create a branch, and open a pull request. Please make sure `ruff check .` and `pytest` pass before submitting.\n\n## License\n\nMIT \u0026mdash; see [LICENSE.txt](LICENSE.txt).\n\n## Author\n\nBuilt by [Christophe Duvillard](https://www.linkedin.com/in/christopheduvillard/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisduvillard%2Frisksim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisduvillard%2Frisksim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisduvillard%2Frisksim/lists"}