alphaengine 0.6.1__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {alphaengine-0.6.1 → alphaengine-0.8.0}/AGENTS.md +24 -7
- {alphaengine-0.6.1 → alphaengine-0.8.0}/PKG-INFO +178 -19
- {alphaengine-0.6.1 → alphaengine-0.8.0}/README.md +178 -19
- alphaengine-0.8.0/docs/assets/banner.png +0 -0
- alphaengine-0.8.0/docs/assets/data_boundary.png +0 -0
- alphaengine-0.8.0/docs/assets/session.png +0 -0
- alphaengine-0.8.0/docs/figure_contract.md +46 -0
- alphaengine-0.8.0/docs/workflows/evaluate_process.json +18 -0
- alphaengine-0.8.0/docs/workflows/research_week.json +29 -0
- alphaengine-0.8.0/docs/workflows/stress_study.json +14 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/_version.py +8 -1
- alphaengine-0.8.0/src/alphaengine/charts.py +56 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/cli.py +414 -94
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/client/executor.py +368 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/commands.py +64 -11
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/__init__.py +40 -1
- alphaengine-0.8.0/src/alphaengine/core/active.py +95 -0
- alphaengine-0.8.0/src/alphaengine/core/allocate.py +245 -0
- alphaengine-0.8.0/src/alphaengine/core/covariance.py +181 -0
- alphaengine-0.8.0/src/alphaengine/core/cross_section.py +176 -0
- alphaengine-0.8.0/src/alphaengine/core/panel.py +289 -0
- alphaengine-0.8.0/src/alphaengine/core/process.py +450 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/signals.py +85 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/demo.py +2 -1
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/repl.py +6 -1
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/study/report.py +4 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/study/schema.py +7 -1
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_cli.py +78 -6
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_commands.py +7 -5
- alphaengine-0.8.0/tests/test_process.py +201 -0
- alphaengine-0.8.0/tests/test_quant_maths.py +286 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_sweep.py +27 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/.github/workflows/ci.yml +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/.github/workflows/publish.yml +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/.gitignore +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/LICENSE +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/SECURITY.md +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/pyproject.toml +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/scripts/gen_docs.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/__init__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/__main__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/agent/__init__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/agent/answer.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/agent/driver.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/auth.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/book.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/client/__init__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/client/agent.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/client/session.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/complete.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/connectors/__init__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/backtest.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/factors.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/pairs.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/performance.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/profile.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/risk.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/screen.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/series_shapes.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/stress.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/technical.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/validation.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/core/walkforward.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/demo_book.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/demo_returns.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/demo_signal.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/demo_universe.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/events.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/loaders.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/model.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/py.typed +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/study/__init__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/sweep/__init__.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/src/alphaengine/sweep/runner.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_agent.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_answer.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_book.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_client.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_events.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_executor_ops.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_goldens.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_loaders.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_model.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_screen.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_signals.py +0 -0
- {alphaengine-0.6.1 → alphaengine-0.8.0}/tests/test_smoke.py +0 -0
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
## Cursor Cloud specific instructions
|
|
4
4
|
|
|
5
5
|
AlphaEngine is a pure-Python CLI + library (`alphaengine`) for validated quant
|
|
6
|
-
research. There is no GUI
|
|
6
|
+
research. There is no windowed GUI: the product is a terminal session (an
|
|
7
|
+
animated parameter-surface canvas at boot and while Working) plus
|
|
7
8
|
`import alphaengine`.
|
|
8
9
|
|
|
9
10
|
### Environment
|
|
@@ -29,12 +30,20 @@ research. There is no GUI; all interaction is via the terminal or
|
|
|
29
30
|
- **Three rungs.** `demo` and the importable library are fully offline. Workflow
|
|
30
31
|
CLI verbs (`diagnose`, `screen`, …, `run <workflow>`) need a portal
|
|
31
32
|
`ae_live_` key (`QUANTOS_API_KEY`). Plain-English mode also needs a **model**
|
|
32
|
-
key.
|
|
33
|
+
key. In a session: `login` (QuantOS) or `login anthropic`. `key` is the same
|
|
34
|
+
verb. Any OpenAI-compatible key works: Anthropic, OpenAI (`OPENAI_BASE_URL` for
|
|
33
35
|
gateways), Gemini, Groq, OpenRouter, Azure, or
|
|
34
36
|
`ALPHAENGINE_API_KEY`+`ALPHAENGINE_BASE_URL`. `alphaengine models` lists what
|
|
35
37
|
this machine can actually use. Keys may persist in
|
|
36
38
|
`~/.config/alphaengine/credentials.json` (mode 0600) if the user says yes at
|
|
37
|
-
`
|
|
39
|
+
`login`; env always wins. LLM keys are never sent to QuantOS.
|
|
40
|
+
- **One data verb.** `load prices.csv` / `load research.momentum` / `load sp500`
|
|
41
|
+
unifies `--data` / `--project` / `--universe`. The old verbs still work.
|
|
42
|
+
- **Motion is a real TTY.** Boot and `Working` paint a tall parameter-surface
|
|
43
|
+
canvas. Tests that monkeypatch `_tty` get colour without frame sleeps
|
|
44
|
+
(`_live_tty` gates motion). Do not add `time.sleep` on the `_tty()` path.
|
|
45
|
+
This image often has `NO_COLOR=1`; unset it to see the canvas
|
|
46
|
+
(`env -u NO_COLOR COLORTERM=truecolor TERM=xterm-256color`).
|
|
38
47
|
- **A stop / `marginal` verdict exits 0.** Only a step that could not execute
|
|
39
48
|
exits non-zero. Unauthenticated workflow calls exit 2.
|
|
40
49
|
- **Data never leaves.** Executor and study-report guards refuse lists longer
|
|
@@ -45,10 +54,18 @@ research. There is no GUI; all interaction is via the terminal or
|
|
|
45
54
|
keys. `alphaengine trace` reads the local dump.
|
|
46
55
|
- **Goldens are a public contract.** Do not "fix" a golden to land a speedup;
|
|
47
56
|
that is a version bump (`_version.py`).
|
|
48
|
-
- **
|
|
49
|
-
`
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
- **Compute ops on the executor** include the 0.6 workflow set (`backtest`,
|
|
58
|
+
`score_backtest`, `cpcv`, `factors`, `pairs`, `cointegrated_pairs`,
|
|
59
|
+
`walk_forward`, `book_overlap`), the 0.7 CS / book set
|
|
60
|
+
(`panel_transform`, `signal_icir`, `fama_macbeth`, `quantile_book`,
|
|
61
|
+
`ewma_cov`, `denoise_cov`, `hrp`, `risk_parity`, `vol_target`), and the
|
|
62
|
+
0.8 process / Grinold set (`ou_calibrate`, `ou_simulate`, `gbm_calibrate`,
|
|
63
|
+
`jump_calibrate`, `garch`, `dgp_stress`, `grinold_alpha`, `breadth_ir`,
|
|
64
|
+
`detone_cov`). Panels, covariance matrices, GARCH variance paths, OU paths
|
|
65
|
+
and alpha vectors stay in the workspace; figures go over the wire. The
|
|
66
|
+
portal must offer an op in a workflow graph or it sits unused; the CLI
|
|
67
|
+
`process` command runs the DGP stress offline without a portal. Short names
|
|
68
|
+
in a panel are skipped and counted, they do not shrink the rest of the book.
|
|
52
69
|
- `sweep(..., jobs=N)` defaults to 1. Greater than 1 is opt-in and must keep
|
|
53
70
|
trial index identity, including failures.
|
|
54
71
|
- The `connectors` extra is lazy: parquet via `pyarrow`, HTTP via `httpx` to a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: alphaengine
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Validated research tooling for investment strategies: deflation, overfitting detection, and honest trial counts.
|
|
5
5
|
Project-URL: Homepage, https://github.com/quantOSC/alphaengine
|
|
6
6
|
Project-URL: Documentation, https://github.com/quantOSC/alphaengine#readme
|
|
@@ -40,17 +40,47 @@ Provides-Extra: factors
|
|
|
40
40
|
Requires-Dist: statsmodels>=0.14; extra == 'factors'
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
<p align="center">
|
|
44
|
+
<img src="docs/assets/banner.png" alt="AlphaEngine: the research loop, on your machine" width="100%">
|
|
45
|
+
</p>
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
<h1 align="center">AlphaEngine</h1>
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<strong>The research loop, on your machine.</strong><br>
|
|
51
|
+
Ask what is worth looking at, whether it holds up, how much to hold,<br>
|
|
52
|
+
and whether anything has crossed a line. Your data never leaves.
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<a href="https://pypi.org/project/alphaengine/"><img src="https://img.shields.io/pypi/v/alphaengine.svg?style=flat-square&color=1B7A7A" alt="PyPI"></a>
|
|
57
|
+
<a href="https://pypi.org/project/alphaengine/"><img src="https://img.shields.io/pypi/pyversions/alphaengine.svg?style=flat-square" alt="Python 3.10+"></a>
|
|
58
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-0B1220?style=flat-square" alt="Apache 2.0"></a>
|
|
59
|
+
<a href="https://github.com/quantOSC/alphaengine/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/quantOSC/alphaengine/ci.yml?branch=main&style=flat-square&label=CI" alt="CI"></a>
|
|
60
|
+
<img src="https://img.shields.io/badge/deps-numpy%20%2B%20scipy-C4893A?style=flat-square" alt="Two dependencies: numpy and scipy">
|
|
61
|
+
</p>
|
|
48
62
|
|
|
49
63
|
```bash
|
|
50
64
|
pip install alphaengine
|
|
51
65
|
alphaengine demo # the whole offline half, no account, no data of your own
|
|
66
|
+
alphaengine process # fit a DGP to the demo walk and stress it
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="docs/assets/session.png" alt="The session canvas: tracked ALPHAENGINE over a teal plateau and amber ridge, then your data never leaves." width="92%">
|
|
71
|
+
</p>
|
|
72
|
+
|
|
73
|
+
The session is the product. Sign in, load something, then ask:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
alphaengine
|
|
77
|
+
❯ login
|
|
78
|
+
❯ load prices.csv
|
|
79
|
+
❯ screen
|
|
52
80
|
```
|
|
53
81
|
|
|
82
|
+
---
|
|
83
|
+
|
|
54
84
|
## What it answers
|
|
55
85
|
|
|
56
86
|
Eight questions, in the order a research week actually asks them. The command
|
|
@@ -84,7 +114,7 @@ Or say it in plain English and let your own model pick:
|
|
|
84
114
|
|
|
85
115
|
```bash
|
|
86
116
|
alphaengine
|
|
87
|
-
|
|
117
|
+
❯ which of my names are overbought on RSI?
|
|
88
118
|
```
|
|
89
119
|
|
|
90
120
|
That second path is EXPLORATORY: the model chooses a workflow and then chooses
|
|
@@ -92,27 +122,48 @@ each step from what the server permits. Two runs of the same question may
|
|
|
92
122
|
differ, and the run says so. `run <workflow>` is SCRIPTED and reproducible.
|
|
93
123
|
Both are legitimate; presenting one as the other is not.
|
|
94
124
|
|
|
125
|
+
---
|
|
126
|
+
|
|
95
127
|
## The three rungs
|
|
96
128
|
|
|
97
|
-
Each is useful without the one above it.
|
|
129
|
+
Each is useful without the one above it. `login` lights the next one.
|
|
98
130
|
|
|
99
131
|
| Rung | What you need | What you get |
|
|
100
132
|
|---|---|---|
|
|
101
133
|
| **The maths** | nothing | Every statistic, offline, forever. No account. |
|
|
102
|
-
| **Workflows** | a QuantOS `ae_live_` key | The loop end to end, with the record. |
|
|
103
|
-
| **Ask anything** | your OWN model key | Plain English in. Runs under your account, not ours. |
|
|
134
|
+
| **Workflows** | a QuantOS `ae_live_` key (`login`) | The loop end to end, with the record. |
|
|
135
|
+
| **Ask anything** | your OWN model key (`login anthropic`) | Plain English in. Runs under your account, not ours. |
|
|
104
136
|
|
|
105
137
|
Nothing here stores a model key: it is read from your environment at call time
|
|
106
138
|
and handed to the provider's own client. There is no field to put one in.
|
|
107
139
|
|
|
140
|
+
```mermaid
|
|
141
|
+
flowchart LR
|
|
142
|
+
A["demo / import<br/>offline maths"] --> B["login<br/>QuantOS key"]
|
|
143
|
+
B --> C["login anthropic<br/>your model"]
|
|
144
|
+
A -.->|"no account"| D["DSR · PBO · ICIR · HRP"]
|
|
145
|
+
B -.->|"ae_live_"| E["screen · validate · runs"]
|
|
146
|
+
C -.->|"BYOK"| F["plain English in"]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
108
151
|
## Getting your data in
|
|
109
152
|
|
|
110
|
-
|
|
153
|
+
One verb, three shapes. Nothing is ever fetched on your behalf.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
load prices.csv # a local CSV
|
|
157
|
+
load sp500 # registered in the portal, with the closes you stored
|
|
158
|
+
load research.momentum # a module of yours (the only door that can carry a simulator)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
From a shell the same doors are flags, for scripts:
|
|
111
162
|
|
|
112
163
|
```bash
|
|
113
|
-
alphaengine
|
|
114
|
-
alphaengine
|
|
115
|
-
alphaengine
|
|
164
|
+
alphaengine screen --data prices.csv
|
|
165
|
+
alphaengine screen --universe sp500
|
|
166
|
+
alphaengine validate --project research.momentum
|
|
116
167
|
```
|
|
117
168
|
|
|
118
169
|
`--data` reads three shapes, decided by the header and nothing else:
|
|
@@ -136,6 +187,68 @@ for the scores it measures — while the rest run on prices alone.
|
|
|
136
187
|
upload decrypted back to your own account, not us fetching market data, and the
|
|
137
188
|
distinction is the whole of the data boundary below.
|
|
138
189
|
|
|
190
|
+
<p align="center">
|
|
191
|
+
<img src="docs/assets/data_boundary.png" alt="Your machine holds prices and notebooks; only figures cross to the QuantOS record" width="92%">
|
|
192
|
+
</p>
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## What's new in 0.8.0
|
|
197
|
+
|
|
198
|
+
Named processes, Grinold, and a frozen chart contract. Existing goldens
|
|
199
|
+
(deflated Sharpe, PBO, performance, screen) are byte-identical. New figures
|
|
200
|
+
are a public contract from this release. The study schema is **1.1**: optional
|
|
201
|
+
`process` and `charts` fields; 1.0 studies still load.
|
|
202
|
+
|
|
203
|
+
| You have | You get | Module |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| A spread or a close | OU / GBM / jump / GARCH(1,1) calibration, then Monte Carlo stress under that law | `core.process` |
|
|
206
|
+
| An IC and a cross-section | Grinold alpha, breadth, transfer coefficient | `core.active` |
|
|
207
|
+
| A return panel | Detoned covariance and a PCA variance-explained table | `core.covariance` |
|
|
208
|
+
| Figures that already travel | `{kind, key, title}` hints a portal maps to a chart | `charts`, [figure contract](docs/figure_contract.md) |
|
|
209
|
+
|
|
210
|
+
The terminal boot is the README banner: tracked `ALPHAENGINE`, the subtitle,
|
|
211
|
+
a teal-left / amber-right mesh (plateau, valley, knife-edge ridge), and
|
|
212
|
+
`your data never leaves.` `alphaengine process` fits a DGP offline, no account.
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from alphaengine.core import ou_calibrate, garch_calibrate, dgp_stress, grinold_alpha
|
|
216
|
+
|
|
217
|
+
ou = ou_calibrate(spread) # kappa, theta, half_life; or not mean-reverting
|
|
218
|
+
g = garch_calibrate(returns) # omega, alpha, beta, persistence in (0, 1)
|
|
219
|
+
s = dgp_stress(close, dgp="ou") # n_trials = n_paths, source monte_carlo
|
|
220
|
+
a = grinold_alpha(panel, ic=0.05) # alpha vector stays here; scalars travel
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## What's new in 0.7.0
|
|
226
|
+
|
|
227
|
+
The daily modelling morning, and the overnight book, without a third
|
|
228
|
+
dependency. Existing goldens (deflated Sharpe, PBO, performance, screen) are
|
|
229
|
+
byte-identical. New figures are a public contract from this release.
|
|
230
|
+
|
|
231
|
+
| You have | You get | Module |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| A raw factor panel | Cross-sectional rank, z-score, winsorize, neutralize | `core.panel` |
|
|
234
|
+
| A signal and prices | ICIR, Newey-West t-stat, Fama-MacBeth λ, quantile book with one-way turnover | `core.signals`, `core.cross_section` |
|
|
235
|
+
| A return panel | EWMA / Ledoit-Wolf / Marchenko-Pastur covariance, HRP, risk parity, vol target | `core.covariance`, `core.allocate` |
|
|
236
|
+
|
|
237
|
+
The session is slimmer too: `login` lights a rung, `load` is the one data verb,
|
|
238
|
+
and boot paints the parameter surface this tool actually judges rather than a
|
|
239
|
+
command encyclopedia.
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from alphaengine.core import cs_zscore, signal_icir, hrp_weights, fama_macbeth
|
|
243
|
+
|
|
244
|
+
z = cs_zscore(factor_panel) # skipped names are counted, not dropped
|
|
245
|
+
ic = signal_icir(signal, prices) # Spearman ICIR; Pearson is opt-in
|
|
246
|
+
fm = fama_macbeth(signal, prices) # λ_mean, t-stat, Newey-West
|
|
247
|
+
w = hrp_weights(cov, names=names) # no matrix inverse; weights sum to one
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
139
252
|
## Command reference
|
|
140
253
|
|
|
141
254
|
`alphaengine commands` prints this directory in the terminal, and
|
|
@@ -150,11 +263,13 @@ distinction is the whole of the data boundary below.
|
|
|
150
263
|
| Command | Does | Where |
|
|
151
264
|
|---|---|---|
|
|
152
265
|
| `demo` | run the built-in example offline, with no account and no data | shell + session |
|
|
266
|
+
| `process [ou \| gbm \| jump \| garch]` | fit a named process to a series and stress it, offline | shell + session |
|
|
153
267
|
| `runs [--limit N]` | your own week: what ran, what it decided, what it filed | shell + session |
|
|
154
268
|
| `gaps` | what your record says is UNANSWERED, and what closes each one | shell + session |
|
|
155
269
|
| `tonight [--budget N]` | what would run unattended tonight, without running any of it | shell + session |
|
|
156
270
|
| `workflows` | what the server offers, what each needs, and which reproduce | shell + session |
|
|
157
|
-
| `
|
|
271
|
+
| `login [quantos \| anthropic \| openai \| gemini \| groq \| azure \| openrouter \| gateway]` | sign in, or login anthropic for a model key | shell + session |
|
|
272
|
+
| `key [quantos \| anthropic \| openai \| gemini \| groq \| azure \| openrouter \| gateway]` | same as login: enter a credential, or see which rungs are lit | session |
|
|
158
273
|
| `commands [verb]` | this directory, or one command in full | shell + session |
|
|
159
274
|
| `models` | which model providers this machine can actually use | shell + session |
|
|
160
275
|
| `model [<provider[:name]>]` | pin the model for this session, or show the pin | session |
|
|
@@ -181,9 +296,10 @@ distinction is the whole of the data boundary below.
|
|
|
181
296
|
| Command | Does | Where |
|
|
182
297
|
|---|---|---|
|
|
183
298
|
| `book [<name> \| status]` | show or load sleeves on the multi-strategy book | session |
|
|
184
|
-
| `
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
299
|
+
| `load <file \| module \| universe>` | a CSV, a project module, or a portal universe | session |
|
|
300
|
+
| `universe <name>` | same as load: a universe registered in the portal | session |
|
|
301
|
+
| `data <file>` | same as load: a local CSV or parquet | session |
|
|
302
|
+
| `project <module>` | same as load: a module with data and backtest_fn | session |
|
|
187
303
|
|
|
188
304
|
### Session
|
|
189
305
|
|
|
@@ -191,7 +307,7 @@ distinction is the whole of the data boundary below.
|
|
|
191
307
|
|---|---|---|
|
|
192
308
|
| `logout` | remove stored credentials from this machine | shell + session |
|
|
193
309
|
| `version` | print the version | shell |
|
|
194
|
-
| `help` | the short list | session |
|
|
310
|
+
| `help` | the short list: demo, login, load, then a question | session |
|
|
195
311
|
| `quit` | leave the session | session |
|
|
196
312
|
|
|
197
313
|
### Data flags
|
|
@@ -231,12 +347,15 @@ alphaengine overlap
|
|
|
231
347
|
alphaengine size
|
|
232
348
|
alphaengine monitor
|
|
233
349
|
alphaengine demo
|
|
350
|
+
alphaengine process
|
|
351
|
+
alphaengine process ou
|
|
234
352
|
alphaengine runs
|
|
235
353
|
alphaengine runs --limit 50
|
|
236
354
|
alphaengine gaps
|
|
237
355
|
alphaengine tonight
|
|
238
356
|
alphaengine tonight --budget 5
|
|
239
357
|
alphaengine workflows
|
|
358
|
+
alphaengine login
|
|
240
359
|
alphaengine commands
|
|
241
360
|
alphaengine run screen_universe --universe sp500
|
|
242
361
|
alphaengine run size_position --data returns.csv
|
|
@@ -329,7 +448,15 @@ diffable, and versioned so it still parses in two years.
|
|
|
329
448
|
|
|
330
449
|
| Module | Contents |
|
|
331
450
|
|---|---|
|
|
332
|
-
| `alphaengine.core` | deflated Sharpe, PSR, PBO via CSCV, CPCV, minimum track record length, performance and risk
|
|
451
|
+
| `alphaengine.core` | deflated Sharpe, PSR, PBO via CSCV, CPCV, minimum track record length, performance and risk |
|
|
452
|
+
| `alphaengine.core.panel` | cross-sectional rank, z-score, winsorize, neutralize |
|
|
453
|
+
| `alphaengine.core.signals` | IC, ICIR, quantile returns, decay |
|
|
454
|
+
| `alphaengine.core.cross_section` | Fama-MacBeth, quantile book with turnover |
|
|
455
|
+
| `alphaengine.core.covariance` | EWMA, Ledoit-Wolf, Marchenko-Pastur denoise, detone, variance explained |
|
|
456
|
+
| `alphaengine.core.allocate` | HRP, risk parity, vol target (EWMA or GARCH) |
|
|
457
|
+
| `alphaengine.core.process` | OU, GBM, jumps, GARCH(1,1), DGP stress |
|
|
458
|
+
| `alphaengine.core.active` | Grinold alpha, breadth, transfer coefficient |
|
|
459
|
+
| `alphaengine.charts` | frozen `{kind, key, title}` hints; see [figure contract](docs/figure_contract.md) |
|
|
333
460
|
| `alphaengine.sweep` | the grid runner and the sensitivity surface |
|
|
334
461
|
| `alphaengine.study` | the study artifact and its schema |
|
|
335
462
|
| `alphaengine.client` | the workflow client and the step executor |
|
|
@@ -401,12 +528,44 @@ Probability of Backtest Overfitting." *Journal of Computational Finance* 20(4),
|
|
|
401
528
|
López de Prado, M. (2018). *Advances in Financial Machine Learning.* Wiley,
|
|
402
529
|
chapters 7 and 12.
|
|
403
530
|
|
|
531
|
+
**Hierarchical Risk Parity**
|
|
532
|
+
López de Prado, M. (2016). "Building Diversified Portfolios that Outperform
|
|
533
|
+
Out of Sample." *Journal of Portfolio Management* 42(4), 59 to 69.
|
|
534
|
+
|
|
535
|
+
**Covariance shrinkage and spectral denoising**
|
|
536
|
+
Ledoit, O., and Wolf, M. (2004). "A Well-Conditioned Estimator for
|
|
537
|
+
Large-Dimensional Covariance Matrices." *Journal of Multivariate Analysis*
|
|
538
|
+
88(2), 365 to 411.
|
|
539
|
+
Laloux, L., Cizeau, P., Bouchaud, J.-P., and Potters, M. (1999). "Noise
|
|
540
|
+
Dressing of Financial Correlation Matrices." *Physical Review Letters* 83(7),
|
|
541
|
+
1467 to 1470.
|
|
542
|
+
|
|
404
543
|
**Multiple testing in asset pricing**
|
|
405
544
|
Harvey, C. R., Liu, Y., and Zhu, H. (2016). "... and the Cross-Section of
|
|
406
545
|
Expected Returns." *Review of Financial Studies* 29(1), 5 to 68.
|
|
407
546
|
Harvey, C. R., and Liu, Y. (2015). "Backtesting." *Journal of Portfolio
|
|
408
547
|
Management* 42(1), 13 to 28.
|
|
409
548
|
|
|
549
|
+
**Fama-MacBeth**
|
|
550
|
+
Fama, E. F., and MacBeth, J. D. (1973). "Risk, Return, and Equilibrium:
|
|
551
|
+
Empirical Tests." *Journal of Political Economy* 81(3), 607 to 636.
|
|
552
|
+
|
|
553
|
+
**Ornstein-Uhlenbeck / Vasicek**
|
|
554
|
+
Vasicek, O. (1977). "An Equilibrium Characterization of the Term Structure."
|
|
555
|
+
*Journal of Financial Economics* 5(2), 177 to 188.
|
|
556
|
+
|
|
557
|
+
**GARCH(1,1)**
|
|
558
|
+
Bollerslev, T. (1986). "Generalized Autoregressive Conditional
|
|
559
|
+
Heteroskedasticity." *Journal of Econometrics* 31(3), 307 to 327.
|
|
560
|
+
|
|
561
|
+
**Jump-diffusion**
|
|
562
|
+
Merton, R. C. (1976). "Option Pricing When Underlying Stock Returns Are
|
|
563
|
+
Discontinuous." *Journal of Financial Economics* 3(1-2), 125 to 144.
|
|
564
|
+
|
|
565
|
+
**The fundamental law of active management**
|
|
566
|
+
Grinold, R. C., and Kahn, R. N. (2000). *Active Portfolio Management.* 2nd ed.
|
|
567
|
+
McGraw-Hill.
|
|
568
|
+
|
|
410
569
|
**Downside deviation**
|
|
411
570
|
Sortino, F. A., and Price, L. N. (1994). "Performance Measurement in a Downside
|
|
412
571
|
Risk Framework." *Journal of Investing* 3(3), 59 to 64.
|
|
@@ -1,14 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/banner.png" alt="AlphaEngine: the research loop, on your machine" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">AlphaEngine</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>The research loop, on your machine.</strong><br>
|
|
9
|
+
Ask what is worth looking at, whether it holds up, how much to hold,<br>
|
|
10
|
+
and whether anything has crossed a line. Your data never leaves.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://pypi.org/project/alphaengine/"><img src="https://img.shields.io/pypi/v/alphaengine.svg?style=flat-square&color=1B7A7A" alt="PyPI"></a>
|
|
15
|
+
<a href="https://pypi.org/project/alphaengine/"><img src="https://img.shields.io/pypi/pyversions/alphaengine.svg?style=flat-square" alt="Python 3.10+"></a>
|
|
16
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-0B1220?style=flat-square" alt="Apache 2.0"></a>
|
|
17
|
+
<a href="https://github.com/quantOSC/alphaengine/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/quantOSC/alphaengine/ci.yml?branch=main&style=flat-square&label=CI" alt="CI"></a>
|
|
18
|
+
<img src="https://img.shields.io/badge/deps-numpy%20%2B%20scipy-C4893A?style=flat-square" alt="Two dependencies: numpy and scipy">
|
|
19
|
+
</p>
|
|
6
20
|
|
|
7
21
|
```bash
|
|
8
22
|
pip install alphaengine
|
|
9
23
|
alphaengine demo # the whole offline half, no account, no data of your own
|
|
24
|
+
alphaengine process # fit a DGP to the demo walk and stress it
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="docs/assets/session.png" alt="The session canvas: tracked ALPHAENGINE over a teal plateau and amber ridge, then your data never leaves." width="92%">
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
The session is the product. Sign in, load something, then ask:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
alphaengine
|
|
35
|
+
❯ login
|
|
36
|
+
❯ load prices.csv
|
|
37
|
+
❯ screen
|
|
10
38
|
```
|
|
11
39
|
|
|
40
|
+
---
|
|
41
|
+
|
|
12
42
|
## What it answers
|
|
13
43
|
|
|
14
44
|
Eight questions, in the order a research week actually asks them. The command
|
|
@@ -42,7 +72,7 @@ Or say it in plain English and let your own model pick:
|
|
|
42
72
|
|
|
43
73
|
```bash
|
|
44
74
|
alphaengine
|
|
45
|
-
|
|
75
|
+
❯ which of my names are overbought on RSI?
|
|
46
76
|
```
|
|
47
77
|
|
|
48
78
|
That second path is EXPLORATORY: the model chooses a workflow and then chooses
|
|
@@ -50,27 +80,48 @@ each step from what the server permits. Two runs of the same question may
|
|
|
50
80
|
differ, and the run says so. `run <workflow>` is SCRIPTED and reproducible.
|
|
51
81
|
Both are legitimate; presenting one as the other is not.
|
|
52
82
|
|
|
83
|
+
---
|
|
84
|
+
|
|
53
85
|
## The three rungs
|
|
54
86
|
|
|
55
|
-
Each is useful without the one above it.
|
|
87
|
+
Each is useful without the one above it. `login` lights the next one.
|
|
56
88
|
|
|
57
89
|
| Rung | What you need | What you get |
|
|
58
90
|
|---|---|---|
|
|
59
91
|
| **The maths** | nothing | Every statistic, offline, forever. No account. |
|
|
60
|
-
| **Workflows** | a QuantOS `ae_live_` key | The loop end to end, with the record. |
|
|
61
|
-
| **Ask anything** | your OWN model key | Plain English in. Runs under your account, not ours. |
|
|
92
|
+
| **Workflows** | a QuantOS `ae_live_` key (`login`) | The loop end to end, with the record. |
|
|
93
|
+
| **Ask anything** | your OWN model key (`login anthropic`) | Plain English in. Runs under your account, not ours. |
|
|
62
94
|
|
|
63
95
|
Nothing here stores a model key: it is read from your environment at call time
|
|
64
96
|
and handed to the provider's own client. There is no field to put one in.
|
|
65
97
|
|
|
98
|
+
```mermaid
|
|
99
|
+
flowchart LR
|
|
100
|
+
A["demo / import<br/>offline maths"] --> B["login<br/>QuantOS key"]
|
|
101
|
+
B --> C["login anthropic<br/>your model"]
|
|
102
|
+
A -.->|"no account"| D["DSR · PBO · ICIR · HRP"]
|
|
103
|
+
B -.->|"ae_live_"| E["screen · validate · runs"]
|
|
104
|
+
C -.->|"BYOK"| F["plain English in"]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
66
109
|
## Getting your data in
|
|
67
110
|
|
|
68
|
-
|
|
111
|
+
One verb, three shapes. Nothing is ever fetched on your behalf.
|
|
69
112
|
|
|
70
113
|
```bash
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
114
|
+
load prices.csv # a local CSV
|
|
115
|
+
load sp500 # registered in the portal, with the closes you stored
|
|
116
|
+
load research.momentum # a module of yours (the only door that can carry a simulator)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
From a shell the same doors are flags, for scripts:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
alphaengine screen --data prices.csv
|
|
123
|
+
alphaengine screen --universe sp500
|
|
124
|
+
alphaengine validate --project research.momentum
|
|
74
125
|
```
|
|
75
126
|
|
|
76
127
|
`--data` reads three shapes, decided by the header and nothing else:
|
|
@@ -94,6 +145,68 @@ for the scores it measures — while the rest run on prices alone.
|
|
|
94
145
|
upload decrypted back to your own account, not us fetching market data, and the
|
|
95
146
|
distinction is the whole of the data boundary below.
|
|
96
147
|
|
|
148
|
+
<p align="center">
|
|
149
|
+
<img src="docs/assets/data_boundary.png" alt="Your machine holds prices and notebooks; only figures cross to the QuantOS record" width="92%">
|
|
150
|
+
</p>
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## What's new in 0.8.0
|
|
155
|
+
|
|
156
|
+
Named processes, Grinold, and a frozen chart contract. Existing goldens
|
|
157
|
+
(deflated Sharpe, PBO, performance, screen) are byte-identical. New figures
|
|
158
|
+
are a public contract from this release. The study schema is **1.1**: optional
|
|
159
|
+
`process` and `charts` fields; 1.0 studies still load.
|
|
160
|
+
|
|
161
|
+
| You have | You get | Module |
|
|
162
|
+
|---|---|---|
|
|
163
|
+
| A spread or a close | OU / GBM / jump / GARCH(1,1) calibration, then Monte Carlo stress under that law | `core.process` |
|
|
164
|
+
| An IC and a cross-section | Grinold alpha, breadth, transfer coefficient | `core.active` |
|
|
165
|
+
| A return panel | Detoned covariance and a PCA variance-explained table | `core.covariance` |
|
|
166
|
+
| Figures that already travel | `{kind, key, title}` hints a portal maps to a chart | `charts`, [figure contract](docs/figure_contract.md) |
|
|
167
|
+
|
|
168
|
+
The terminal boot is the README banner: tracked `ALPHAENGINE`, the subtitle,
|
|
169
|
+
a teal-left / amber-right mesh (plateau, valley, knife-edge ridge), and
|
|
170
|
+
`your data never leaves.` `alphaengine process` fits a DGP offline, no account.
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from alphaengine.core import ou_calibrate, garch_calibrate, dgp_stress, grinold_alpha
|
|
174
|
+
|
|
175
|
+
ou = ou_calibrate(spread) # kappa, theta, half_life; or not mean-reverting
|
|
176
|
+
g = garch_calibrate(returns) # omega, alpha, beta, persistence in (0, 1)
|
|
177
|
+
s = dgp_stress(close, dgp="ou") # n_trials = n_paths, source monte_carlo
|
|
178
|
+
a = grinold_alpha(panel, ic=0.05) # alpha vector stays here; scalars travel
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## What's new in 0.7.0
|
|
184
|
+
|
|
185
|
+
The daily modelling morning, and the overnight book, without a third
|
|
186
|
+
dependency. Existing goldens (deflated Sharpe, PBO, performance, screen) are
|
|
187
|
+
byte-identical. New figures are a public contract from this release.
|
|
188
|
+
|
|
189
|
+
| You have | You get | Module |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| A raw factor panel | Cross-sectional rank, z-score, winsorize, neutralize | `core.panel` |
|
|
192
|
+
| A signal and prices | ICIR, Newey-West t-stat, Fama-MacBeth λ, quantile book with one-way turnover | `core.signals`, `core.cross_section` |
|
|
193
|
+
| A return panel | EWMA / Ledoit-Wolf / Marchenko-Pastur covariance, HRP, risk parity, vol target | `core.covariance`, `core.allocate` |
|
|
194
|
+
|
|
195
|
+
The session is slimmer too: `login` lights a rung, `load` is the one data verb,
|
|
196
|
+
and boot paints the parameter surface this tool actually judges rather than a
|
|
197
|
+
command encyclopedia.
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from alphaengine.core import cs_zscore, signal_icir, hrp_weights, fama_macbeth
|
|
201
|
+
|
|
202
|
+
z = cs_zscore(factor_panel) # skipped names are counted, not dropped
|
|
203
|
+
ic = signal_icir(signal, prices) # Spearman ICIR; Pearson is opt-in
|
|
204
|
+
fm = fama_macbeth(signal, prices) # λ_mean, t-stat, Newey-West
|
|
205
|
+
w = hrp_weights(cov, names=names) # no matrix inverse; weights sum to one
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
97
210
|
## Command reference
|
|
98
211
|
|
|
99
212
|
`alphaengine commands` prints this directory in the terminal, and
|
|
@@ -108,11 +221,13 @@ distinction is the whole of the data boundary below.
|
|
|
108
221
|
| Command | Does | Where |
|
|
109
222
|
|---|---|---|
|
|
110
223
|
| `demo` | run the built-in example offline, with no account and no data | shell + session |
|
|
224
|
+
| `process [ou \| gbm \| jump \| garch]` | fit a named process to a series and stress it, offline | shell + session |
|
|
111
225
|
| `runs [--limit N]` | your own week: what ran, what it decided, what it filed | shell + session |
|
|
112
226
|
| `gaps` | what your record says is UNANSWERED, and what closes each one | shell + session |
|
|
113
227
|
| `tonight [--budget N]` | what would run unattended tonight, without running any of it | shell + session |
|
|
114
228
|
| `workflows` | what the server offers, what each needs, and which reproduce | shell + session |
|
|
115
|
-
| `
|
|
229
|
+
| `login [quantos \| anthropic \| openai \| gemini \| groq \| azure \| openrouter \| gateway]` | sign in, or login anthropic for a model key | shell + session |
|
|
230
|
+
| `key [quantos \| anthropic \| openai \| gemini \| groq \| azure \| openrouter \| gateway]` | same as login: enter a credential, or see which rungs are lit | session |
|
|
116
231
|
| `commands [verb]` | this directory, or one command in full | shell + session |
|
|
117
232
|
| `models` | which model providers this machine can actually use | shell + session |
|
|
118
233
|
| `model [<provider[:name]>]` | pin the model for this session, or show the pin | session |
|
|
@@ -139,9 +254,10 @@ distinction is the whole of the data boundary below.
|
|
|
139
254
|
| Command | Does | Where |
|
|
140
255
|
|---|---|---|
|
|
141
256
|
| `book [<name> \| status]` | show or load sleeves on the multi-strategy book | session |
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
257
|
+
| `load <file \| module \| universe>` | a CSV, a project module, or a portal universe | session |
|
|
258
|
+
| `universe <name>` | same as load: a universe registered in the portal | session |
|
|
259
|
+
| `data <file>` | same as load: a local CSV or parquet | session |
|
|
260
|
+
| `project <module>` | same as load: a module with data and backtest_fn | session |
|
|
145
261
|
|
|
146
262
|
### Session
|
|
147
263
|
|
|
@@ -149,7 +265,7 @@ distinction is the whole of the data boundary below.
|
|
|
149
265
|
|---|---|---|
|
|
150
266
|
| `logout` | remove stored credentials from this machine | shell + session |
|
|
151
267
|
| `version` | print the version | shell |
|
|
152
|
-
| `help` | the short list | session |
|
|
268
|
+
| `help` | the short list: demo, login, load, then a question | session |
|
|
153
269
|
| `quit` | leave the session | session |
|
|
154
270
|
|
|
155
271
|
### Data flags
|
|
@@ -189,12 +305,15 @@ alphaengine overlap
|
|
|
189
305
|
alphaengine size
|
|
190
306
|
alphaengine monitor
|
|
191
307
|
alphaengine demo
|
|
308
|
+
alphaengine process
|
|
309
|
+
alphaengine process ou
|
|
192
310
|
alphaengine runs
|
|
193
311
|
alphaengine runs --limit 50
|
|
194
312
|
alphaengine gaps
|
|
195
313
|
alphaengine tonight
|
|
196
314
|
alphaengine tonight --budget 5
|
|
197
315
|
alphaengine workflows
|
|
316
|
+
alphaengine login
|
|
198
317
|
alphaengine commands
|
|
199
318
|
alphaengine run screen_universe --universe sp500
|
|
200
319
|
alphaengine run size_position --data returns.csv
|
|
@@ -287,7 +406,15 @@ diffable, and versioned so it still parses in two years.
|
|
|
287
406
|
|
|
288
407
|
| Module | Contents |
|
|
289
408
|
|---|---|
|
|
290
|
-
| `alphaengine.core` | deflated Sharpe, PSR, PBO via CSCV, CPCV, minimum track record length, performance and risk
|
|
409
|
+
| `alphaengine.core` | deflated Sharpe, PSR, PBO via CSCV, CPCV, minimum track record length, performance and risk |
|
|
410
|
+
| `alphaengine.core.panel` | cross-sectional rank, z-score, winsorize, neutralize |
|
|
411
|
+
| `alphaengine.core.signals` | IC, ICIR, quantile returns, decay |
|
|
412
|
+
| `alphaengine.core.cross_section` | Fama-MacBeth, quantile book with turnover |
|
|
413
|
+
| `alphaengine.core.covariance` | EWMA, Ledoit-Wolf, Marchenko-Pastur denoise, detone, variance explained |
|
|
414
|
+
| `alphaengine.core.allocate` | HRP, risk parity, vol target (EWMA or GARCH) |
|
|
415
|
+
| `alphaengine.core.process` | OU, GBM, jumps, GARCH(1,1), DGP stress |
|
|
416
|
+
| `alphaengine.core.active` | Grinold alpha, breadth, transfer coefficient |
|
|
417
|
+
| `alphaengine.charts` | frozen `{kind, key, title}` hints; see [figure contract](docs/figure_contract.md) |
|
|
291
418
|
| `alphaengine.sweep` | the grid runner and the sensitivity surface |
|
|
292
419
|
| `alphaengine.study` | the study artifact and its schema |
|
|
293
420
|
| `alphaengine.client` | the workflow client and the step executor |
|
|
@@ -359,12 +486,44 @@ Probability of Backtest Overfitting." *Journal of Computational Finance* 20(4),
|
|
|
359
486
|
López de Prado, M. (2018). *Advances in Financial Machine Learning.* Wiley,
|
|
360
487
|
chapters 7 and 12.
|
|
361
488
|
|
|
489
|
+
**Hierarchical Risk Parity**
|
|
490
|
+
López de Prado, M. (2016). "Building Diversified Portfolios that Outperform
|
|
491
|
+
Out of Sample." *Journal of Portfolio Management* 42(4), 59 to 69.
|
|
492
|
+
|
|
493
|
+
**Covariance shrinkage and spectral denoising**
|
|
494
|
+
Ledoit, O., and Wolf, M. (2004). "A Well-Conditioned Estimator for
|
|
495
|
+
Large-Dimensional Covariance Matrices." *Journal of Multivariate Analysis*
|
|
496
|
+
88(2), 365 to 411.
|
|
497
|
+
Laloux, L., Cizeau, P., Bouchaud, J.-P., and Potters, M. (1999). "Noise
|
|
498
|
+
Dressing of Financial Correlation Matrices." *Physical Review Letters* 83(7),
|
|
499
|
+
1467 to 1470.
|
|
500
|
+
|
|
362
501
|
**Multiple testing in asset pricing**
|
|
363
502
|
Harvey, C. R., Liu, Y., and Zhu, H. (2016). "... and the Cross-Section of
|
|
364
503
|
Expected Returns." *Review of Financial Studies* 29(1), 5 to 68.
|
|
365
504
|
Harvey, C. R., and Liu, Y. (2015). "Backtesting." *Journal of Portfolio
|
|
366
505
|
Management* 42(1), 13 to 28.
|
|
367
506
|
|
|
507
|
+
**Fama-MacBeth**
|
|
508
|
+
Fama, E. F., and MacBeth, J. D. (1973). "Risk, Return, and Equilibrium:
|
|
509
|
+
Empirical Tests." *Journal of Political Economy* 81(3), 607 to 636.
|
|
510
|
+
|
|
511
|
+
**Ornstein-Uhlenbeck / Vasicek**
|
|
512
|
+
Vasicek, O. (1977). "An Equilibrium Characterization of the Term Structure."
|
|
513
|
+
*Journal of Financial Economics* 5(2), 177 to 188.
|
|
514
|
+
|
|
515
|
+
**GARCH(1,1)**
|
|
516
|
+
Bollerslev, T. (1986). "Generalized Autoregressive Conditional
|
|
517
|
+
Heteroskedasticity." *Journal of Econometrics* 31(3), 307 to 327.
|
|
518
|
+
|
|
519
|
+
**Jump-diffusion**
|
|
520
|
+
Merton, R. C. (1976). "Option Pricing When Underlying Stock Returns Are
|
|
521
|
+
Discontinuous." *Journal of Financial Economics* 3(1-2), 125 to 144.
|
|
522
|
+
|
|
523
|
+
**The fundamental law of active management**
|
|
524
|
+
Grinold, R. C., and Kahn, R. N. (2000). *Active Portfolio Management.* 2nd ed.
|
|
525
|
+
McGraw-Hill.
|
|
526
|
+
|
|
368
527
|
**Downside deviation**
|
|
369
528
|
Sortino, F. A., and Price, L. N. (1994). "Performance Measurement in a Downside
|
|
370
529
|
Risk Framework." *Journal of Investing* 3(3), 59 to 64.
|
|
Binary file
|
|
Binary file
|