https://github.com/memran/portfolio-optimizer
Web-based portfolio optimization tool built with **Streamlit**.
https://github.com/memran/portfolio-optimizer
Last synced: 8 days ago
JSON representation
Web-based portfolio optimization tool built with **Streamlit**.
- Host: GitHub
- URL: https://github.com/memran/portfolio-optimizer
- Owner: memran
- License: mit
- Created: 2026-06-06T14:29:24.000Z (28 days ago)
- Default Branch: main
- Last Pushed: 2026-06-19T18:27:25.000Z (15 days ago)
- Last Synced: 2026-06-19T19:23:49.014Z (15 days ago)
- Language: Python
- Size: 374 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ๐ Portfolio Optimizer โ Streamlit Web App
[](https://www.python.org/)
[](https://streamlit.io/)
[](LICENSE)
[](https://github.com/memran/portfolio-optimizer/commits/main)
[](https://portfolio-optimizer-nzrsddmhxnfxgznhckcaav.streamlit.app/)
> A web-based portfolio optimization tool that computes the optimal asset allocation by maximizing the Sharpe ratio, plots the efficient frontier, and visualizes asset covariance โ all from a CSV upload.
---
## Table of Contents
- [Features](#-features)
- [Project Structure](#-project-structure)
- [Which Script Do I Run?](#-which-script-do-i-run)
- [Quick Start](#-quick-start)
- [CSV File Format](#-csv-file-format)
- [Usage Walkthrough](#-usage-walkthrough)
- [Methodology](#-methodology)
- [Outputs](#-outputs)
- [Assumptions & Limitations](#-assumptions--limitations)
- [Deployment](#-deployment)
- [Troubleshooting](#-troubleshooting)
- [Roadmap](#-roadmap)
- [Contributing](#-contributing)
- [License](#-license)
- [Acknowledgements](#-acknowledgements)
---
## โจ Features
- ๐ค **CSV upload** โ works with either raw prices or pre-computed returns.
- ๐งฎ **Automatic return calculation** (simple monthly returns) from price data.
- ๐ฏ **Two optimization modes:**
- Maximum Sharpe ratio (long-only / no short selling)
- Maximum Sharpe ratio (short selling allowed)
- ๐ **Performance metrics** โ annualized return, volatility, Sharpe ratio.
- ๐ **Efficient frontier** plot.
- ๐ฅ **Covariance matrix heatmap.**
- ๐ท๏ธ **Optional benchmark column** (e.g., `DSEX`) that can be excluded from the asset set.
- ๐ฅ **Downloadable weight CSVs** for both optimization modes.
---
## ๐ Project Structure
```
portfolio-optimizer/
โโโ app_price.py # Streamlit app โ input CSV contains raw prices
โโโ main.py # Streamlit app โ input CSV contains pre-computed monthly returns
โโโ data/
โ โโโ sample_prices.csv # Sample price file (try the app instantly)
โโโ requirements.txt
โโโ pyproject.toml
โโโ uv.lock
โโโ LICENSE
โโโ README.md
```
---
## ๐ค Which Script Do I Run?
| If your CSV containsโฆ | Run |
| ------------------------------------------- | -------------------------------- |
| **Raw prices** (e.g., monthly closing) | `streamlit run app_price.py` |
| **Pre-computed monthly returns** | `streamlit run main.py` |
If unsure, use **`app_price.py`** โ it derives returns automatically from prices.
---
## ๐ Quick Start
### Option A โ Using `uv` (recommended, matches `uv.lock`)
```bash
git clone https://github.com/memran/portfolio-optimizer.git
cd portfolio-optimizer
uv sync
uv run streamlit run app_price.py
```
### Option B โ Using `pip` + `venv`
```bash
git clone https://github.com/memran/portfolio-optimizer.git
cd portfolio-optimizer
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
streamlit run app_price.py
```
The app will open in your browser at .
---
## ๐ CSV File Format
### Prices mode (`app_price.py`)
- First column: **date** in **`dd/mm/yyyy`** format (e.g., `01/01/2014`).
- Remaining columns: **asset closing prices** (numeric).
- Optional **benchmark** column (e.g., `DSEX`) โ you'll be prompted to exclude it in the UI.
**Example** (`data/sample_prices.csv`):
```csv
Date,Eastern Bank Ltd,Islami Bank Limited,BRAC Bank,DSEX
01/01/2014,100.0,95.5,102.3,5000
01/02/2014,103.5,94.2,98.7,5100
01/03/2014,105.1,96.8,101.4,5180
...
```
> โ ๏ธ The date parser is hard-coded to `%d/%m/%Y`. Other formats will produce `NaT` and drop those rows.
### Returns mode (`main.py`)
- Columns: `Year`, `Month`, one column per asset, optional `DSEX` (benchmark โ auto-dropped).
- Values: **monthly returns as decimals** (e.g., `0.0123` = 1.23%).
**Example:**
```csv
Year,Month,Eastern Bank Ltd,Islami Bank Limited,BRAC Bank,DSEX
2014,1,0.0123,-0.0045,0.0210,0.0150
2014,2,0.0089,0.0067,-0.0034,0.0098
...
```
---
## ๐งญ Usage Walkthrough
1. **Upload** your CSV via the file uploader.
2. (Prices mode) **Select a benchmark** to exclude, or choose `None`.
3. Review the **Asset Summary** โ annualized mean returns and covariance matrix.
4. Inspect the **Optimal Portfolio (No Short Selling)** card โ expected return, volatility, Sharpe ratio, and weights.
5. View the **Efficient Frontier** plot โ the red star marks the max-Sharpe portfolio.
6. Expand **Optimal Portfolio (Short Selling Allowed)** for the unconstrained variant.
7. Examine the **Covariance Heatmap** for asset interdependence.
8. **Download** weight CSVs for either mode.
---
## ๐ Methodology
Built on **Markowitz meanโvariance optimization** (Modern Portfolio Theory).
**Sharpe ratio**
```
S = (Rโ โ R_f) / ฯโ
```
where `Rโ` is portfolio return, `R_f` is the risk-free rate (assumed `0`), and `ฯโ` is portfolio volatility.
**Annualization** (monthly โ annual)
```
ฮผ_annual = ฮผ_monthly ร 12
ฮฃ_annual = ฮฃ_monthly ร 12
```
**Optimization**
- Solver: SciPy `minimize` with **SLSQP**.
- Constraint: `ฮฃ wแตข = 1` (fully invested).
- Bounds:
- Long-only: `0 โค wแตข โค 1`
- Short selling allowed: `โ1 โค wแตข โค 1`
- Objective: minimize `โSharpe`.
The efficient frontier is computed by sweeping target returns and minimizing portfolio variance for each.
---
## ๐ฆ Outputs
- Mean annual returns table.
- Annualized covariance matrix.
- Optimal portfolio weights (no short selling).
- Efficient frontier chart with max-Sharpe marker.
- Short-selling-allowed analysis (expandable section).
- Covariance heatmap.
- Download buttons for weight CSV files.
---
## โ ๏ธ Assumptions & Limitations
- **Risk-free rate = 0** (not user-configurable yet).
- **Simple returns** (`pct_change`) by default; log-return mode exists in code but is not exposed in the UI.
- **No transaction costs, taxes, or slippage.**
- **No position limits** other than the bounds above.
- **Annualization factor = 12** โ assumes monthly data. Daily/weekly inputs will be mis-annualized.
- **Date format must be `dd/mm/yyyy`** in prices mode.
- **Historical performance โ future returns.** This tool is for education / research, not investment advice.
---
## โ๏ธ Live App & Deployment
**Try it now:** [portfolio-optimizer.streamlit.app](https://portfolio-optimizer-nzrsddmhxnfxgznhckcaav.streamlit.app/)
Deploy to **Streamlit Community Cloud** in three steps:
1. Push the repo to GitHub (already done if you cloned this).
2. Go to and click **New app**.
3. Select your repo, branch `main`, and set **Main file path** to `app_price.py` (or `main.py`).
The first deploy takes ~1โ2 minutes; subsequent pushes redeploy automatically.
---
## ๐ Troubleshooting
| Symptom | Likely Cause | Fix |
| --- | --- | --- |
| `ValueError: time data ... doesn't match format` | Dates are not `dd/mm/yyyy` | Re-format the date column or adjust `format=` in `app_price.py:22` |
| Empty results / all-NaN returns | Non-numeric cells (e.g., `"1,000"`) coerced to NaN | Clean the CSV โ remove thousand separators and stray text |
| Optimization fails or weights look random | Too few rows, or singular covariance matrix | Provide more history; ensure at least ~24 monthly observations |
| Benchmark column appears in the optimization | `DSEX` (or your benchmark) wasn't excluded | Select it in the **"benchmark column"** dropdown |
| `streamlit: command not found` | Virtualenv not activated, or install failed | Re-activate venv and re-run `pip install -r requirements.txt` |
---
## ๐บ๏ธ Roadmap
- [ ] Configurable **risk-free rate** in the UI.
- [ ] Configurable **annualization factor** (daily / weekly / monthly).
- [ ] **Auto-detect** date formats in `app_price.py`.
- [ ] Merge `main.py` and `app_price.py` into a single app with a mode toggle.
- [ ] Additional optimization objectives: **min-variance**, **risk parity**, **BlackโLitterman**.
- [ ] Export full report (PDF / HTML).
---
## ๐ค Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
1. Fork the repo and create your branch: `git checkout -b feature/my-feature`
2. Commit your changes: `git commit -m "feat: add my feature"`
3. Push to the branch: `git push origin feature/my-feature`
4. Open a Pull Request.
---
## ๐ License
Released under the [MIT License](LICENSE).
---
## ๐ Acknowledgements
- Markowitz, H. (1952). *Portfolio Selection*. **The Journal of Finance**, 7(1), 77โ91.
- [SciPy SLSQP documentation](https://docs.scipy.org/doc/scipy/reference/optimize.minimize-slsqp.html)
- [Streamlit documentation](https://docs.streamlit.io/)