Skip to content

Commit 72e4da6

Browse files
Release v0.2.4
1 parent afffaa2 commit 72e4da6

19 files changed

Lines changed: 1111 additions & 6 deletions

.github/workflows/ci.yml

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,75 @@ jobs:
3535
run: |
3636
ruff check .
3737
38+
- name: Format check (ruff)
39+
run: |
40+
ruff format --check src tests scripts
41+
3842
- name: Run tests
3943
run: |
4044
pytest -q
4145
46+
docs-build:
47+
name: Docs build / Python 3.12
48+
runs-on: ubuntu-latest
49+
needs: test-base
50+
51+
steps:
52+
- name: Checkout
53+
uses: actions/checkout@v4
54+
55+
- name: Set up Python
56+
uses: actions/setup-python@v5
57+
with:
58+
python-version: "3.12"
59+
cache: pip
60+
61+
- name: Upgrade packaging tooling
62+
run: |
63+
python -m pip install --upgrade pip
64+
65+
- name: Install package + docs deps
66+
run: |
67+
python -m pip install -e ".[docs]"
68+
69+
- name: Build docs with warnings as errors
70+
run: |
71+
python -m sphinx -W -b html docs docs/_build/html
72+
73+
notebook-smoke:
74+
name: Notebook smoke / Python 3.12
75+
runs-on: ubuntu-latest
76+
needs: test-base
77+
78+
steps:
79+
- name: Checkout
80+
uses: actions/checkout@v4
81+
82+
- name: Set up Python
83+
uses: actions/setup-python@v5
84+
with:
85+
python-version: "3.12"
86+
cache: pip
87+
88+
- name: Upgrade packaging tooling
89+
run: |
90+
python -m pip install --upgrade pip
91+
92+
- name: Install package + notebook smoke deps
93+
run: |
94+
python -m pip install -e ".[dev,notebooks]"
95+
96+
- name: Execute smoke notebook
97+
run: |
98+
pytest --nbmake notebooks/Binary.ipynb
99+
42100
package-validation:
43101
name: Package validation / Python 3.12
44102
runs-on: ubuntu-latest
45-
needs: test-base
103+
needs:
104+
- test-base
105+
- docs-build
106+
- notebook-smoke
46107

47108
steps:
48109
- name: Checkout

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ ENV/
3838
# Jupyter
3939
# -----------------------
4040
.ipynb_checkpoints/
41+
notebooks/notebooks/
4142

4243
# -----------------------
4344
# Lint / format caches

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Notebook client:
6464

6565
- `notebooks/Binary.ipynb`
6666
- `notebooks/examples/02_Real_Example.ipynb`
67+
- `notebooks/examples/04_Larger_Real_Data_Example.ipynb`
6768

6869
---
6970

@@ -98,6 +99,7 @@ Notebook client:
9899

99100
- `notebooks/QAOA.ipynb`
100101
- `notebooks/examples/03_Real_Example.ipynb`
102+
- `notebooks/examples/04_Larger_Real_Data_Example.ipynb`
101103

102104
---
103105

@@ -123,6 +125,7 @@ Notebook clients:
123125

124126
- `notebooks/Fractional.ipynb`
125127
- `notebooks/examples/01_Real_example.ipynb`
128+
- `notebooks/examples/04_Larger_Real_Data_Example.ipynb`
126129

127130
---
128131

@@ -211,14 +214,16 @@ src/
211214
212215
scripts/
213216
├── generate_comparison_results.py # Synthetic baselines and repeatability CSVs
214-
└── generate_ansatz_comparison.py # Compact ansatz comparison CSV
217+
├── generate_ansatz_comparison.py # Compact ansatz comparison CSV
218+
└── generate_larger_real_data_example.py # 12-stock real-data example artifacts
215219
216220
results/
217221
├── synthetic_comparison.csv
218222
├── real_data_comparison.csv
219223
├── generated_comparison_summary.csv
220224
├── generated_repeatability_trials.csv
221225
├── real_data_method_comparison.csv
226+
├── larger_real_data_comparison.csv
222227
└── ansatz_comparison.csv
223228
224229
notebooks/
@@ -231,7 +236,8 @@ notebooks/
231236
├── examples/
232237
│ ├── 01_Real_example.ipynb
233238
│ ├── 02_Real_Example.ipynb
234-
│ └── 03_Real_Example.ipynb
239+
│ ├── 03_Real_Example.ipynb
240+
│ └── 04_Larger_Real_Data_Example.ipynb
235241
└── images/
236242
237243
tests/

RESULTS.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Machine-readable copies of the comparison tables are committed under `results/`:
99
- `results/generated_comparison_summary.csv`
1010
- `results/generated_repeatability_trials.csv`
1111
- `results/real_data_method_comparison.csv`
12+
- `results/larger_real_data_comparison.csv`
1213
- `results/ansatz_comparison.csv`
1314

1415
For repeatable synthetic benchmark summaries, regenerate a compact comparison CSV with:
@@ -180,6 +181,32 @@ Binary rows use equal-weight selected portfolios for reported return and risk, w
180181
![Real data method comparison fractional objective](notebooks/images/Real_Data_Method_Comparison_Fractional_Objective.png)
181182
![Real data method comparison feasibility](notebooks/images/Real_Data_Method_Comparison_Feasibility.png)
182183

184+
### Larger Real-Data Universe
185+
186+
`scripts/generate_larger_real_data_example.py` writes `results/larger_real_data_comparison.csv`, regenerates `notebooks/examples/04_Larger_Real_Data_Example.ipynb`, and saves figures for a 12-stock 2024 market-data window. The binary and QAOA methods use one qubit per asset, so this example is deliberately a scalability/stress example rather than a claim of production scale or quantum advantage.
187+
188+
Regenerate it with:
189+
190+
```bash
191+
python scripts/generate_larger_real_data_example.py
192+
```
193+
194+
| Method | Objective family | K | Selection or weights | Return | Risk | Best objective | Feasible rate |
195+
| --- | --- | ---: | --- | ---: | ---: | ---: | ---: |
196+
| Classical exhaustive search | binary QUBO | 5 | AAPL, NVDA, JPM, JNJ, PG | 0.341060 | 0.128919 | -0.043287 | 1.000000 |
197+
| Binary VQE best feasible | binary QUBO | 5 | NVDA, XOM, JNJ, PG, HD | 0.257295 | 0.120824 | 0.173363 | 0.777344 |
198+
| QAOA X best feasible | binary QUBO | 5 | AAPL, META, JPM, PG, UNH | 0.248903 | 0.117525 | 0.136708 | 0.343750 |
199+
| QAOA XY best feasible | binary QUBO | 5 | MSFT, NVDA, GOOGL, JPM, UNH | 0.346208 | 0.172098 | 1.230733 | 1.000000 |
200+
| Classical exact Markowitz | fractional simplex | | simplex weights | 0.580921 | 0.226857 | -0.375066 | 1.000000 |
201+
| Fractional VQE | fractional simplex | | simplex weights | 0.549605 | 0.217478 | -0.360419 | 1.000000 |
202+
203+
![Larger real-data risk return](notebooks/examples/images/Larger_Real_Data_Risk_Return.png)
204+
![Larger real-data binary objective](notebooks/examples/images/Larger_Real_Data_Binary_Objective.png)
205+
![Larger real-data fractional objective](notebooks/examples/images/Larger_Real_Data_Fractional_Objective.png)
206+
![Larger real-data feasibility](notebooks/examples/images/Larger_Real_Data_Feasibility.png)
207+
![Larger real-data asset returns](notebooks/examples/images/Larger_Real_Data_Asset_Returns.png)
208+
![Larger real-data fractional allocation pies](notebooks/examples/images/Larger_Real_Data_Fractional_Weights.png)
209+
183210
### Real Fractional Frontier
184211

185212
| Method | λ | Return | Risk |
@@ -245,5 +272,6 @@ Then open the notebook clients:
245272
- `notebooks/examples/01_Real_example.ipynb`
246273
- `notebooks/examples/02_Real_Example.ipynb`
247274
- `notebooks/examples/03_Real_Example.ipynb`
275+
- `notebooks/examples/04_Larger_Real_Data_Example.ipynb`
248276

249277
The notebooks should save updated plots under `notebooks/images/` and `notebooks/examples/images/`.

0 commit comments

Comments
 (0)