alphaengine 1.0.3__tar.gz → 1.1.1__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-1.0.3 → alphaengine-1.1.1}/.github/workflows/publish.yml +1 -1
- alphaengine-1.1.1/CHANGELOG.md +81 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/PKG-INFO +158 -26
- {alphaengine-1.0.3 → alphaengine-1.1.1}/README.md +157 -25
- alphaengine-1.1.1/docs/free-vs-firm.md +88 -0
- alphaengine-1.1.1/docs/plugins.md +60 -0
- alphaengine-1.1.1/docs/project-format.md +81 -0
- alphaengine-1.1.1/docs/result-format.md +89 -0
- alphaengine-1.1.1/examples/process_stress_monitor.yaml +15 -0
- alphaengine-1.1.1/examples/screen_validate_size.yaml +12 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/pyproject.toml +7 -4
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/__init__.py +20 -3
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/_version.py +14 -2
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/sim.py +7 -4
- alphaengine-1.1.1/src/alphaengine/auth.py +294 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/cli.py +1476 -51
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/client/executor.py +1 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/commands.py +301 -28
- alphaengine-1.1.1/src/alphaengine/complete.py +123 -0
- alphaengine-1.1.1/src/alphaengine/contracts/__init__.py +11 -0
- alphaengine-1.1.1/src/alphaengine/contracts/hash_golden.json +113 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/__init__.py +1 -1
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/pairs.py +1 -1
- alphaengine-1.1.1/src/alphaengine/datasets.py +383 -0
- alphaengine-1.1.1/src/alphaengine/envelope.py +133 -0
- alphaengine-1.1.1/src/alphaengine/ideas.py +281 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/io.py +48 -5
- alphaengine-1.1.1/src/alphaengine/ledger.py +705 -0
- alphaengine-1.1.1/src/alphaengine/memo.py +383 -0
- alphaengine-1.1.1/src/alphaengine/pipeline.py +348 -0
- alphaengine-1.1.1/src/alphaengine/plugins.py +264 -0
- alphaengine-1.1.1/src/alphaengine/project.py +306 -0
- alphaengine-1.1.1/src/alphaengine/repl.py +149 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/study/__init__.py +4 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/study/report.py +12 -52
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/study/schema.py +75 -10
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/sweep/runner.py +95 -17
- alphaengine-1.1.1/src/alphaengine/sync.py +386 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/tui/app.py +8 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/tui/dispatch.py +210 -7
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/tui/stage.py +2 -1
- alphaengine-1.1.1/src/alphaengine/watch.py +272 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_coverage_paths.py +1 -7
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_goldens.py +16 -0
- alphaengine-1.1.1/tests/test_project.py +1095 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_sim.py +3 -3
- alphaengine-1.1.1/tests/test_smoke.py +180 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_sweep.py +8 -34
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_tui.py +2 -2
- alphaengine-1.0.3/CHANGELOG.md +0 -49
- alphaengine-1.0.3/src/alphaengine/auth.py +0 -203
- alphaengine-1.0.3/src/alphaengine/complete.py +0 -71
- alphaengine-1.0.3/src/alphaengine/repl.py +0 -80
- alphaengine-1.0.3/tests/test_smoke.py +0 -96
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.github/ISSUE_TEMPLATE/data_shape.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.github/ISSUE_TEMPLATE/method_request.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.github/dependabot.yml +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.github/workflows/ci.yml +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.github/workflows/codeql.yml +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/.gitignore +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/AGENTS.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/CODE_OF_CONDUCT.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/CONTRIBUTING.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/LICENSE +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/SECURITY.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/assets/banner.png +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/assets/data_boundary.png +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/assets/session.png +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/figure_contract.md +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/workflows/evaluate_process.json +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/workflows/research_week.json +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/docs/workflows/stress_study.json +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/scripts/gen_docs.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/__main__.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/__init__.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/answer.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/bakeoff.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/brief.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/chart.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/agent/driver.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/book.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/charts.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/client/__init__.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/client/agent.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/client/session.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/connectors/__init__.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/context.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/active.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/allocate.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/backtest.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/bakeoff.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/covariance.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/cross_section.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/factors.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/market.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/options.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/panel.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/performance.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/portfolio.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/process.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/profile.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/rates.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/regime.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/relations.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/risk.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/screen.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/series_shapes.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/signals.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/stress.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/technical.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/trace.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/validation.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/core/walkforward.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/demo.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/demo_book.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/demo_returns.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/demo_signal.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/demo_universe.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/events.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/loaders.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/model.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/py.typed +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/sweep/__init__.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/tui/__init__.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/tui/mark.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/src/alphaengine/tui/typeface.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_agent.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_answer.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_bakeoff.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_book.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_cli.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_client.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_commands.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_context.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_events.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_executor_ops.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_io.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_loaders.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_math_audit.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_model.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_portfolio.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_process.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_quant_maths.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_relations.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_screen.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_signals.py +0 -0
- {alphaengine-1.0.3 → alphaengine-1.1.1}/tests/test_trace.py +0 -0
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
python-version: "3.12"
|
|
36
36
|
- name: Verify git tag matches __version__
|
|
37
37
|
run: |
|
|
38
|
-
python -c "import os,
|
|
38
|
+
python -c "import os, tomllib, sys; v = tomllib.load(open('pyproject.toml', 'rb'))['project']['version']; ref = os.environ.get('GITHUB_REF_NAME') or os.environ.get('GITHUB_REF', '').removeprefix('refs/tags/'); exp = f'v{v}'; sys.exit(f'Tag {ref!r} != {exp!r}' if ref != exp else 0)"
|
|
39
39
|
- run: python -m pip install --upgrade build
|
|
40
40
|
- run: python -m build
|
|
41
41
|
- uses: actions/upload-artifact@v4
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `alphaengine` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to Semantic Versioning (with computed golden values
|
|
7
|
+
treated as part of the public contract).
|
|
8
|
+
|
|
9
|
+
## [1.1.1] - 2026-10-24
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **Single firm-key choke point (`alphaengine.auth.require_firm_key`):** Used by every gated command (`run`, `show`, `monitor`/`watch`, `validate`, `screen`, `diagnose`, `signal`, `stress`, `overlap`, `size`, `workflows`, `runs`, `gaps`, `tonight`, and the CLI OS: `init`, `log`, `diff`, `rerun`, `data`, `idea`, `seal`, `report`, `remote`, `push`, `pull`, `plugin`, `shell`). Free and keyless forever: `import alphaengine`, `alphaengine demo`, `alphaengine process`, and `ae verify`.
|
|
13
|
+
- **OS keychain support & key redaction:** `auth.py` stores keys in the OS keychain (`keyring`) when available with `~/.config/alphaengine/credentials.json` (`0600`) as fallback, and `redact_secrets()` strips `ae_live_*` tokens from CLI output, error messages, tracebacks, and `--json` envelopes.
|
|
14
|
+
- **Canonical SHA-256 contract & golden fixture (`alphaengine/contracts/hash_golden.json`):** Unified `content_sha256`, study seals, `.alphaengine/objects/` CAS blobs, dataset hashes, and parameter hashes on `canonical_sha256()` (Schema 1.2 sorted-key JSON, `.8f` float formatting, 64-hex SHA-256). Added `verify_study_mode()` so studies sealed under the pre-1.2 legacy format still verify and are labeled `"legacy"`.
|
|
15
|
+
- **Free vs. Firm documentation (`docs/free-vs-firm.md`):** Documents the offline open-source library boundary, firm `ae_live_` Connect keys, and what uses the network.
|
|
16
|
+
- **Socket-blocked offline smoke test:** Replaced the import-only check in `tests/test_smoke.py` with a socket-blocked test (`socket.socket` and `socket.create_connection` patched to raise) that imports `alphaengine` and executes `deflated_sharpe` (DSR), `pbo_cscv` (PBO via CSCV), `combinatorial_oos_stability`, `performance_report`, `compute_var_cvar`, `sweep`, `load_csv`, `from_quantconnect`, and `from_vectorbt`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- **Cumulative project-wide trials & DSR everywhere:** Project-wide cumulative trial counts (`project_trials` across `.alphaengine/ledger/trials.jsonl`) now feed every DSR — run output, headline `deflated_sharpe` and `n_trials`, `ae push` payloads, and `ae seal` studies — with no per-run or per-family reset.
|
|
20
|
+
- **Identical re-run deduplication:** Re-running an identical configuration (`command`, `params_hash`, and `dataset_hashes` matching a prior run in `.alphaengine/ledger/runs.jsonl`) records `duplicate_of` and adds `0` new trials (`9 -> 9`), whereas distinct configurations always increment cumulative `N` (`9 -> 18`).
|
|
21
|
+
- **Removed bare `except Exception: pass` in `sweep/runner.py`:** `_maybe_record_project_sweep` now raises a descriptive `RuntimeError` when a discovered `.alphaengine/` project ledger cannot be written.
|
|
22
|
+
- **Metadata-driven `__version__` and naming cleanup:** `__version__` is loaded via `importlib.metadata.version("alphaengine")` with no hardcoded version strings; standardized `combinatorial_oos_stability` (with `cpcv_score` emitting `DeprecationWarning`) and `PBO via CSCV` across docs and top-level exports.
|
|
23
|
+
|
|
24
|
+
### Removed
|
|
25
|
+
- **Retail CLI path (`--retail` and `/api/retail/ledger/import`):** Removed `--retail` from `report` and CLI dispatch. Retail ledger import is performed via web upload in the quantOS portal.
|
|
26
|
+
|
|
27
|
+
## [1.1.0] - 2026-10-24
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- **Project workspace (`ae init` and `ae` alias):** Initializes `.alphaengine/` (`project.toml`, `ledger/`, `data/`, `studies/`, `ideas/`, `universes/`, and SHA-256 content-addressed `objects/`). Commands walk up from the current directory to locate the project; documented in `docs/project-format.md`.
|
|
31
|
+
- **Project-wide ledger (`ae log`, `ae show`, `ae diff`, `ae rerun`):** Every run and `sweep()` inside a project writes an append-only run record and accumulates trial counts across runs on the same `idea_id` or `family`.
|
|
32
|
+
- **Dataset registry (`ae data add`, `ae data list`, `ae data show`, `ae data lineage`):** Registers CSV and Parquet datasets locally with full 64-hex SHA-256 hashes, row counts, date ranges, column schemas, and checks for duplicate timestamps, gaps, look-ahead rows (`--asof-col`), and survivorship hints.
|
|
33
|
+
- **Standard result envelope (`v1.0`), pipes, and declarative YAML pipelines:** Added `--json` and `--stdin` support across commands (`ae screen --json | ae validate --stdin | ae size --stdin`), `ae run <pipeline.yaml>`, two example pipelines in `examples/`, and `docs/result-format.md`.
|
|
34
|
+
- **Hypotheses as objects (`ae idea new`, `ae idea list`, `ae idea status`, `ae idea show`):** First-class hypothesis tracking with `--kill-if` rule evaluation, `--idea <id>` run linking, and pre-run prior-work checks.
|
|
35
|
+
- **Extended seal, verify, and committee memos:** `ae seal <run|idea>`, `ae verify <study.json> [--data <file>]`, and `ae report memo <idea|run> --format md|pdf` where every figure cites its `[run_id]`.
|
|
36
|
+
- **Research shell (`ae shell`):** Interactive shell with tab completion over verbs, run IDs, dataset names, and idea IDs, a project status line with cumulative trial count, inline ledger/idea commands, and automatic ledger recording of agent proposals.
|
|
37
|
+
- **Entry-point plugin system (`alphaengine.plugins`, `ae plugin list`):** Supports `loader`, `method`, and `template` plugins, with `quantconnect`, `vectorbt`, `csv`, `deflated_sharpe`, `combinatorial_oos_stability`, and `committee_memo` registered as built-ins (`docs/plugins.md`).
|
|
38
|
+
- **Local file watcher & live drift monitor:** `ae watch <pipeline.yaml>` re-runs pipelines when watched datasets change on disk; `ae monitor <run> --live <file>` compares live returns against the backtest's bootstrapped 95% intervals.
|
|
39
|
+
- **Opt-in workspace sync (`ae remote`, `ae push [--dry-run]`, `ae pull`):** Syncs sealed studies, allowlisted ledger runs, and ideas to `POST /api/workspace/sync` (with 404 fallback to `POST /api/me/runs/ingest`), enforcing the 512-element series cap and never uploading dataset rows.
|
|
40
|
+
|
|
41
|
+
## [1.0.3] - 2026-10-24
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
- **Sealed studies (Schema 1.2):** Canonical-JSON SHA-256 content hash (`content_sha256` with sorted keys and fixed 8-decimal float formatting), full 64-hex `data_hash`, and optional per-trial ledger export (`SweepResult.ledger()`, `include_ledger=True`).
|
|
45
|
+
- **CLI study verbs:** `alphaengine seal <study.json>` (writes `content_sha256` and verifies on re-run) and `alphaengine report <study.json> [--retail]` (reports to `/api/me/runs/ingest` by default or `/api/retail/ledger/import` with `--retail`).
|
|
46
|
+
- **Complete study ingest payload:** `study/report.py` `_payload()` now includes `selection` (PBO), `psr_vs_zero`, `sr0_expected_max`, `min_track_record_length`, `grid_keys`, `n_failed_trials`, `content_sha256`, and optional `assignment_id` and `thesis_id`.
|
|
47
|
+
- **Interop loaders (`alphaengine.io`):** `from_quantconnect(path)` and `from_vectorbt(portfolio_or_csv)` construct a `Study` with returns, performance metrics, data hash, and trial-count provenance (`"asserted"` when provided/present, `"not_recorded"` with verdict refusal when absent).
|
|
48
|
+
- **Credentials purge:** `alphaengine logout --purge` removes `~/.config/alphaengine/credentials.json`, cleans up its config directory, and clears managed keys from the current process.
|
|
49
|
+
- **API URL override:** `ALPHAENGINE_API_URL` environment variable and unified `DEFAULT_API_URL` constant across CLI and study reporting.
|
|
50
|
+
- **Security & governance:** Weekly Dependabot configuration (pip + GitHub Actions), Python CodeQL workflow, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, and GitHub issue templates.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
- **Opt-in series sharing on `/traces`:** `_report_trace` sends scalar figures only by default. Uploading full series to `/api/harness/runs/{id}/traces` requires `--share-series` or `ALPHAENGINE_SHARE_SERIES=1`; any payload sent without opt-in is guarded at most 512 elements.
|
|
54
|
+
- **Deliberate math & golden updates:**
|
|
55
|
+
- `deflated_sharpe(..., n_trials=1)` no longer silently deflates as `N=2`. At `n_trials=1`, `sr0_expected_max` is `0.0` (was `0.037` on the `rets(9, 200)` golden) and `deflated_sharpe` equals `psr_vs_zero` (`0.8434`, was `0.6875` on the golden), with an explicit note that no multiple-testing deflation applies.
|
|
56
|
+
- `SweepResult.verdict()` passes the cross-trial Sharpe dispersion across valid grid trials into `deflated_sharpe` per Bailey & López de Prado (2014), falling back to single-series sampling error only when fewer than 2 valid trials exist.
|
|
57
|
+
- Renamed `cpcv_score` to `combinatorial_oos_stability` (keeping `cpcv_score` as a deprecated alias) to accurately describe single-stream purged/embargoed sub-sample stability.
|
|
58
|
+
- `pbo_cscv` validates `n_splits` (even integer $\ge 2$) and raises a clear `ValueError`.
|
|
59
|
+
- **Neutral framing:** Added *"Research tool, not investment advice"* disclaimer to README, `--help`, and the boot screen; renamed user-facing bakeoff `survivor` / `survivor_weights` to `top_ranked_config` / `model_weights` while preserving backward-compatible dictionary keys.
|
|
60
|
+
- **Release guard:** `.github/workflows/publish.yml` verifies that the git tag matches `v{__version__}` before building.
|
|
61
|
+
|
|
62
|
+
## [1.0.2] - 2026-10-20
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
- **Four-pass adversarial GAN bakeoff:** `run_bakeoff` and `core.bakeoff.referee` run four passes (eight candidate proposals across `equal`, `hrp`, `risk_parity`, `inverse_vol`, `var_sorted`, `low_vol`, `momentum`, and `reversion` against eight regime, tail, rate, and crash-cluster attacks) under a hard 12-call, 60-second ceiling.
|
|
66
|
+
- **Multi-pass bakeoff scorecard in PDF reports:** Cumulative wealth across passes, in-sample vs. post-attack Sharpe comparison, and candidate scorecard table.
|
|
67
|
+
|
|
68
|
+
## [1.0.1] - 2026-10-19
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- **Harness simulation tools:** Added `monte_carlo` and `scenarios` to the local session tool stack.
|
|
72
|
+
- **Multi-page PDF & text reports:** Accepted session traces render multi-panel portfolio, scenario stress, Monte Carlo fan, and bakeoff reports to the user's `Downloads` folder.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
- **Ledoit-Wolf sample-count divisor:** Fixed sample covariance scaling in `ledoit_wolf_cov` so `hrp_weights` and `risk_parity_weights` differentiate weights across wide panels.
|
|
76
|
+
|
|
77
|
+
## [1.0.0] - 2026-10-18
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
- **Interactive terminal simulator (`alphaengine`):** Full-screen Textual session where plain-English questions execute as a deterministic stack of local tool calls (`profile`, `align`, `regime`, `price`, `reprice`, `correlation`, `covariance`, `cointegration`, `portfolio`, `overlap`, `performance`, `var`, `process`, `workflow`, `bakeoff`) with citation guarding.
|
|
81
|
+
- **Pinned cash rate & statistical refinements:** Default risk-free rate pinned to the H.15 3-month Treasury constant maturity (`4.21%` as of `2026-10-06`, `DGS3MO`; pass `0` for excess of zero), automatic Newey-West HAC lag selection in factor regressions, and Benjamini-Hochberg FDR survivors in cointegration screening.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: alphaengine
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Validated research tooling for investment strategies: deflation, overfitting detection, and honest trial counts.
|
|
5
5
|
Project-URL: Homepage, https://qosai.app
|
|
6
6
|
Project-URL: Documentation, https://github.com/quantOSC/alphaengine#readme
|
|
@@ -170,16 +170,15 @@ Each is useful without the one above it. `login` lights the next one.
|
|
|
170
170
|
|
|
171
171
|
| Rung | What you need | What you get |
|
|
172
172
|
|---|---|---|
|
|
173
|
-
| **The maths** | nothing | `alphaengine demo`, `alphaengine process`, and the full Python API (`import alphaengine`, `sweep`, `core`), offline, forever. No account. |
|
|
174
|
-
| **
|
|
173
|
+
| **The maths** | nothing | `alphaengine demo`, `alphaengine process`, `ae verify`, and the full Python API (`import alphaengine`, `sweep`, `core`), offline, forever. No account. |
|
|
174
|
+
| **Firm workflows & CLI OS** | a firm `ae_live_` key from **Connect** in your firm's quantOS portal (`login` or `QUANTOS_API_KEY`; see [docs/free-vs-firm.md](docs/free-vs-firm.md)) | The eight workflow commands (`diagnose`, `screen`, `signal`, `validate`, `stress`, `overlap`, `size`, `monitor`), `workflows`, `runs`, `gaps`, `tonight`, `run <workflow>`, and the Research OS (`init`, `log`, `show`, `diff`, `rerun`, `watch`, `data`, `idea`, `seal`, `report`, `remote`, `push`, `pull`, `plugin`, `shell`). |
|
|
175
175
|
| **Ask anything** | your OWN model key (`login anthropic`) | Plain English in. Runs under your account, not ours. |
|
|
176
176
|
|
|
177
|
-
The
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
work completely offline without an account or key.
|
|
177
|
+
The workflow commands and Research OS require a firm `ae_live_` key issued through
|
|
178
|
+
**Connect** in your firm's quantOS portal (see [docs/free-vs-firm.md](docs/free-vs-firm.md)).
|
|
179
|
+
There is no retail CLI key. `alphaengine demo`, `alphaengine process`, `ae verify`,
|
|
180
|
+
and the Python library (`import alphaengine`) work completely offline without an
|
|
181
|
+
account or key.
|
|
183
182
|
|
|
184
183
|
**How credentials are handled.** QuantOS never receives your LLM provider key:
|
|
185
184
|
it goes directly from this process to your chosen provider. By default, keys can
|
|
@@ -197,7 +196,7 @@ at `login`). To delete the stored file at any time, run
|
|
|
197
196
|
flowchart LR
|
|
198
197
|
A["demo / import<br/>offline maths"] --> B["login<br/>QuantOS key"]
|
|
199
198
|
B --> C["login anthropic<br/>your model"]
|
|
200
|
-
A -.->|"no account"| D["DSR · PBO · ICIR · HRP"]
|
|
199
|
+
A -.->|"no account"| D["DSR · PBO (CSCV) · ICIR · HRP"]
|
|
201
200
|
B -.->|"ae_live_"| E["screen · validate · runs"]
|
|
202
201
|
C -.->|"BYOK"| F["plain English in"]
|
|
203
202
|
```
|
|
@@ -249,10 +248,89 @@ distinction is the whole of the data boundary below.
|
|
|
249
248
|
|
|
250
249
|
---
|
|
251
250
|
|
|
251
|
+
## Quickstart: Offline First, Then Connect for Firms
|
|
252
|
+
|
|
253
|
+
### 1. Free and offline (no account, no API key)
|
|
254
|
+
|
|
255
|
+
The Python library (`import alphaengine`), every validation and portfolio math primitive, `alphaengine demo`, `alphaengine process`, and `ae verify` run 100% offline with no key (see [Free vs. Firm](docs/free-vs-firm.md)):
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
pip install alphaengine
|
|
259
|
+
|
|
260
|
+
# Run the built-in 9-trial parameter sweep and inspect the surface & DSR verdict
|
|
261
|
+
alphaengine demo
|
|
262
|
+
|
|
263
|
+
# Fit OU, GBM, jump-diffusion, and GARCH(1,1) processes and run DGP stress offline
|
|
264
|
+
alphaengine process
|
|
265
|
+
|
|
266
|
+
# Verify any sealed Study artifact (Schema 1.2 or legacy) without an account
|
|
267
|
+
ae verify study.json
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 2. Connect for firms (`ae_live_` key from the quantOS portal)
|
|
271
|
+
|
|
272
|
+
CLI workflows and the local-first Research OS (`ae init`, project ledgers, dataset registry, hypothesis tracking, sealing, memos, and workspace sync) require a firm `ae_live_` key issued through **Connect** in your firm's [quantOS portal](https://qosai.app). There is no retail CLI key or `--retail` flag.
|
|
273
|
+
|
|
274
|
+
Both `alphaengine` and the short alias `ae` run the same entry point (see [Free vs. Firm](docs/free-vs-firm.md), [project format](docs/project-format.md), [result envelope](docs/result-format.md), and [plugins](docs/plugins.md)):
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Sign in with your firm's Connect key (stored in OS keychain or 0600 fallback)
|
|
278
|
+
ae login
|
|
279
|
+
|
|
280
|
+
# 1. Initialize a local .alphaengine/ workspace
|
|
281
|
+
ae init --name equity-momentum
|
|
282
|
+
|
|
283
|
+
# 2. Register a local CSV (or Parquet) dataset and run hygiene checks
|
|
284
|
+
ae data add prices.csv --name equities --asof-col date
|
|
285
|
+
ae data show equities
|
|
286
|
+
|
|
287
|
+
# 3. Record a falsifiable hypothesis with an explicit kill rule
|
|
288
|
+
ae idea new "Cross-sectional 20d momentum holds net of costs" --kill-if "DSR < 0.9" --family mom_20d
|
|
289
|
+
|
|
290
|
+
# 4. Run a validation, declarative YAML pipeline, or Unix JSON pipe
|
|
291
|
+
ae validate --project alphaengine.demo --idea idea_1
|
|
292
|
+
ae run examples/screen_validate_size.yaml
|
|
293
|
+
ae screen --data equities --json | ae validate --stdin --json | ae size --stdin
|
|
294
|
+
|
|
295
|
+
# 5. Inspect the append-only project ledger, cumulative trials, and diffs
|
|
296
|
+
ae log --family mom_20d
|
|
297
|
+
ae show HEAD
|
|
298
|
+
ae rerun HEAD
|
|
299
|
+
|
|
300
|
+
# 6. Seal into a Schema 1.2 Study, verify against data (keyless), and export a committee memo
|
|
301
|
+
ae seal HEAD
|
|
302
|
+
ae verify .alphaengine/studies/HEAD.json
|
|
303
|
+
ae report memo HEAD --format md
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## What's new in 1.1.1
|
|
309
|
+
|
|
310
|
+
- **Single firm-key choke point (`require_firm_key()`):** Every gated CLI workflow (`run`, `validate`, `screen`, `diagnose`, `signal`, `stress`, `overlap`, `size`, `monitor`) and Research OS command (`init`, `log`, `show`, `diff`, `rerun`, `watch`, `data`, `idea`, `seal`, `report`, `remote`, `push`, `pull`, `plugin`, `shell`) validates a firm `ae_live_` key upfront via `alphaengine.auth.require_firm_key()`. The library, `alphaengine demo`, `alphaengine process`, and `ae verify` remain free and keyless.
|
|
311
|
+
- **OS keychain storage & secret redaction:** `auth.py` stores credentials in the OS keychain (`keyring`) when available with `~/.config/alphaengine/credentials.json` (`0600`) as fallback, and automatically redacts `ae_live_*` tokens from CLI output, errors, tracebacks, and `--json` envelopes.
|
|
312
|
+
- **Retail CLI path removed:** Removed `--retail` and `/api/retail/ledger/import` from the CLI; retail ledger import happens via web upload in the quantOS portal.
|
|
313
|
+
- **Unified canonical SHA-256 contract & golden fixture:** `canonical_sha256()` (Schema 1.2 sorted-key JSON with fixed `.8f` float formatting and full 64-hex SHA-256) powers `content_sha256`, study seals, CAS objects, dataset hashes, and parameter hashes. Legacy seals still verify and are labeled `"legacy"`. Shipped `alphaengine/contracts/hash_golden.json` in the wheel for cross-repo verification.
|
|
314
|
+
- **Project-wide cumulative trials & DSR everywhere (with re-run deduplication):** The project-wide cumulative trial ledger feeds every DSR — run output, headline `deflated_sharpe` and `n_trials`, push payloads, and sealed studies — with no per-run or per-family reset. Re-running an identical configuration (`command` + `params_hash` + `dataset_hashes`) records `duplicate_of` and adds `0` new trials (`9 -> 9`), while distinct configurations increment cumulative `N` (`9 -> 18`).
|
|
315
|
+
- **Metadata versioning & socket-blocked offline test:** `__version__` is read from `importlib.metadata.version("alphaengine")` with no hardcoded version strings, `combinatorial_oos_stability` and `PBO via CSCV` naming is standardized throughout, and `tests/test_smoke.py` enforces zero socket calls across DSR, PBO via CSCV, `combinatorial_oos_stability`, metrics, `sweep`, and loaders.
|
|
316
|
+
- **Free vs. Firm guide:** Added [`docs/free-vs-firm.md`](docs/free-vs-firm.md).
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## What's new in 1.1.0
|
|
321
|
+
|
|
322
|
+
- **Local-first project workspace (`ae init`):** Creates `.alphaengine/` (`project.toml`, `ledger/`, `data/`, `studies/`, `ideas/`, `universes/`, and SHA-256 content-addressed `objects/`). Commands walk up from the current directory to find the project; outside a project, every command behaves as a standalone call.
|
|
323
|
+
- **Project-wide ledger & cumulative trial counting (`ae log`, `ae show`, `ae diff`, `ae rerun`):** Runs and sweeps inside a project automatically record parameter hashes, dataset hashes, and figures, accumulating trial counts across runs on the same `idea_id` or `family`.
|
|
324
|
+
- **Dataset registry (`ae data add|list|show|lineage`):** Tracks local CSV and Parquet datasets by full SHA-256, row count, date range, column schema, and hygiene diagnostics (duplicate timestamps, missing/calendar gaps, `--asof-col` look-ahead hints, and survivorship hints).
|
|
325
|
+
- **Versioned `v1.0` JSON result envelope, `--stdin` pipes, & YAML pipelines:** Every command supports `--json` and `--stdin` (`ae screen --json | ae validate --stdin | ae size --stdin`), plus declarative multi-step recipes (`ae run pipeline.yaml`).
|
|
326
|
+
- **Hypotheses as objects (`ae idea new|list|status|show`):** Link runs with `--idea <id>`, evaluate `--kill-if` rules against cumulative figures, and receive automatic prior-work warnings before running overlapping parameter sets.
|
|
327
|
+
- **Seal, verify, & cited committee memos:** `ae seal <run|idea>`, `ae verify <study.json> [--data <file>]`, and `ae report memo <idea|run> --format md|pdf` (where every figure cites `[run_id]`).
|
|
328
|
+
- **Research shell (`ae shell`), plugins (`ae plugin list`), watcher (`ae watch`), live drift monitor (`ae monitor <run> --live <file>`), & opt-in sync (`ae remote`, `ae push [--dry-run]`, `ae pull`).**
|
|
329
|
+
|
|
252
330
|
## What's new in 1.0.3
|
|
253
331
|
|
|
254
332
|
- **Opt-in series sharing & 512-element wire guard:** By default, workflow step traces (`/api/harness/runs/{id}/traces`) report scalar figures only; full series are shared only when you pass `--share-series` or set `ALPHAENGINE_SHARE_SERIES=1`.
|
|
255
|
-
- **Sealed studies (schema 1.2) & CLI reporting:** Studies now carry a canonical-JSON SHA-256 seal (`content_sha256`), a full 64-hex `data_hash`, and an optional per-trial ledger (`include_ledger=True`). Use `alphaengine seal <study.json>` to seal or verify a study file, and `alphaengine report <study.json
|
|
333
|
+
- **Sealed studies (schema 1.2) & CLI reporting:** Studies now carry a canonical-JSON SHA-256 seal (`content_sha256`), a full 64-hex `data_hash`, and an optional per-trial ledger (`include_ledger=True`). Use `alphaengine seal <study.json>` to seal or verify a study file, and `alphaengine report <study.json>` to ingest into quantOS.
|
|
256
334
|
- **Math fixes:** `SweepResult.verdict()` passes cross-trial Sharpe dispersion into `deflated_sharpe` per Bailey & López de Prado (2014); `deflated_sharpe(n_trials=1)` returns `psr_vs_zero` with `sr0_expected_max = 0.0` instead of deflating as `N=2`; `combinatorial_oos_stability` replaces `cpcv_score` (kept as a deprecated alias); and `pbo_cscv` validates that `n_splits` is an even integer $\ge 2$.
|
|
257
335
|
- **Interop loaders (`alphaengine.io`):** `from_quantconnect(path)` and `from_vectorbt(portfolio_or_csv)` build a `Study` with returns and preserve trial-count provenance (`"asserted"` vs. `"not_recorded"`).
|
|
258
336
|
|
|
@@ -273,7 +351,7 @@ A portal that rejects the trace does not fail the run.
|
|
|
273
351
|
## What's new in 0.8.0
|
|
274
352
|
|
|
275
353
|
Named processes, Grinold, and a frozen chart contract. Existing goldens
|
|
276
|
-
(deflated Sharpe, PBO, performance, screen) are byte-identical. New figures
|
|
354
|
+
(deflated Sharpe, PBO via CSCV, performance, screen) are byte-identical. New figures
|
|
277
355
|
are a public contract from this release. The study schema is **1.1**: optional
|
|
278
356
|
`process` and `charts` fields; 1.0 studies still load.
|
|
279
357
|
|
|
@@ -302,7 +380,7 @@ a = grinold_alpha(panel, ic=0.05, vols=vols) # alpha stays here; missing vols a
|
|
|
302
380
|
## What's new in 0.7.0
|
|
303
381
|
|
|
304
382
|
The daily modelling morning, and the overnight book, without a third
|
|
305
|
-
dependency. Existing goldens (deflated Sharpe, PBO, performance, screen) are
|
|
383
|
+
dependency. Existing goldens (deflated Sharpe, PBO via CSCV, performance, screen) are
|
|
306
384
|
byte-identical. New figures are a public contract from this release.
|
|
307
385
|
|
|
308
386
|
| You have | You get | Module |
|
|
@@ -339,9 +417,13 @@ w = hrp_weights(cov, names=names) # no matrix inverse; weights sum to one
|
|
|
339
417
|
|
|
340
418
|
| Command | Does | Where |
|
|
341
419
|
|---|---|---|
|
|
420
|
+
| `init [--name NAME]` | initialize a local .alphaengine/ research project in this directory | shell + session |
|
|
342
421
|
| `demo` | run the built-in example offline, with no account and no data | shell + session |
|
|
343
422
|
| `process [ou \| gbm \| jump \| garch]` | fit a named process to a series and stress it, offline | shell + session |
|
|
344
423
|
| `runs [--limit N]` | your own week: what ran, what it decided, what it filed | shell + session |
|
|
424
|
+
| `log [--idea ID] [--family FAMILY] [--since DATE] [--verdict VERDICT]` | list local project ledger runs, trial counts, and verdicts | shell + session |
|
|
425
|
+
| `show <run>` | inspect one recorded project run, its hashes, trials, and figures | shell + session |
|
|
426
|
+
| `diff <run-a> <run-b>` | compare data, parameter, trial, and figure changes between two runs | shell + session |
|
|
345
427
|
| `gaps` | what your record says is UNANSWERED, and what closes each one | shell + session |
|
|
346
428
|
| `tonight [--budget N]` | what would run unattended tonight, without running any of it | shell + session |
|
|
347
429
|
| `workflows` | what the server offers, what each needs, and which reproduce | shell + session |
|
|
@@ -365,8 +447,11 @@ w = hrp_weights(cov, names=names) # no matrix inverse; weights sum to one
|
|
|
365
447
|
| `size` | what sizing does the risk model imply? | shell + session |
|
|
366
448
|
| `monitor` | still inside the lines? | shell + session |
|
|
367
449
|
| `run <workflow>` | run one workflow exactly as written | shell + session |
|
|
368
|
-
| `
|
|
369
|
-
| `
|
|
450
|
+
| `rerun <run>` | reproduce a recorded project run from its inputs and check figures | shell + session |
|
|
451
|
+
| `watch <pipeline.yaml> [--interval SECONDS]` | re-run a declarative pipeline whenever a registered dataset file changes | shell + session |
|
|
452
|
+
| `seal <study.json \| run \| idea>` | write canonical content_sha256 into a study (or seal a project run/idea) | shell + session |
|
|
453
|
+
| `verify <study.json> [--data FILE]` | verify a study.json content_sha256 seal and optionally re-check figures | shell + session |
|
|
454
|
+
| `report <study.json> \| memo <idea \| run> [--format md \| pdf]` | send a study to quantOS (/api/me/runs/ingest), or export a cited committee memo | shell + session |
|
|
370
455
|
| `<anything else>` | ask in plain English; your model picks a workflow and drives it | session |
|
|
371
456
|
| `status` | the current run, and what is loaded | session |
|
|
372
457
|
|
|
@@ -376,19 +461,25 @@ w = hrp_weights(cov, names=names) # no matrix inverse; weights sum to one
|
|
|
376
461
|
|---|---|---|
|
|
377
462
|
| `book [<name> \| status]` | show or load sleeves on the multi-strategy book | session |
|
|
378
463
|
| `load <file \| module \| universe>` | a CSV, a project module, or a portal universe | session |
|
|
464
|
+
| `idea new "<thesis>" --kill-if "<rule>" [--family FAMILY] \| list \| status <id> <state> \| show <id>` | create, list, update, and evaluate local research hypotheses | shell + session |
|
|
379
465
|
| `thesis [<name> \| clear]` | choose a portal thesis for the next run | session |
|
|
380
466
|
| `correlation` | the correlation of every loaded name with every other name | session |
|
|
381
467
|
| `covariance` | the sample covariance of every loaded name with every other name | session |
|
|
382
468
|
| `cointegration` | which loaded names are cointegrated | session |
|
|
383
469
|
| `portfolio` | weights for the names already loaded | session |
|
|
384
470
|
| `universe <name>` | same as load: a universe registered in the portal | session |
|
|
385
|
-
| `data <file>` |
|
|
471
|
+
| `data add <file> [--name NAME] [--asof-col COL] \| list \| show <name> \| lineage <run>` | register, inspect, and trace local CSV/Parquet datasets | shell + session |
|
|
386
472
|
| `project <module>` | same as load: a module with data and backtest_fn | session |
|
|
387
473
|
|
|
388
474
|
### Session
|
|
389
475
|
|
|
390
476
|
| Command | Does | Where |
|
|
391
477
|
|---|---|---|
|
|
478
|
+
| `remote add <name> [url] \| list` | configure or list remote sync endpoints in .alphaengine/project.toml | shell + session |
|
|
479
|
+
| `push [remote] [--dry-run] [--share-series]` | sync sealed studies, ledger runs, and ideas to quantOS (opt-in network) | shell + session |
|
|
480
|
+
| `pull [remote]` | pull team runs and ideas from quantOS into the local ledger (read-only) | shell + session |
|
|
481
|
+
| `plugin list` | list installed loader, method, and report template plugins | shell + session |
|
|
482
|
+
| `shell` | open the interactive research shell with project completion and status | shell |
|
|
392
483
|
| `logout [--purge]` | remove stored credentials from this machine | shell + session |
|
|
393
484
|
| `version` | print the version | shell |
|
|
394
485
|
| `help` | the short list: demo, login, load, then a question | session |
|
|
@@ -421,7 +512,20 @@ w = hrp_weights(cov, names=names) # no matrix inverse; weights sum to one
|
|
|
421
512
|
| `--limit N` | how many rows to show (default 25) |
|
|
422
513
|
| `--budget N` | how many runs a night is worth (default 3) |
|
|
423
514
|
| `--purge` | remove ~/.config/alphaengine/credentials.json and clean up its config directory |
|
|
424
|
-
| `--
|
|
515
|
+
| `--name NAME` | name for the initialized project or registered dataset |
|
|
516
|
+
| `--idea ID` | attach the run or filter the log to a local hypothesis id |
|
|
517
|
+
| `--family FAMILY` | strategy or experiment family for cumulative trial counting |
|
|
518
|
+
| `--since DATE` | filter project log to runs on or after YYYY-MM-DD |
|
|
519
|
+
| `--verdict VERDICT` | filter project log by verdict (e.g. robust, marginal, likely_noise) |
|
|
520
|
+
| `--asof-col COL` | as-of column name or cutoff date for look-ahead checks in data add |
|
|
521
|
+
| `--json` | emit a versioned v1.0 JSON result envelope to stdout |
|
|
522
|
+
| `--stdin` | read an upstream JSON result envelope from standard input |
|
|
523
|
+
| `--kill-if RULE` | kill rule for a hypothesis, e.g. 'DSR < 0.9' |
|
|
524
|
+
| `--format FMT` | output format for report memo: md or pdf (default md) |
|
|
525
|
+
| `--dry-run` | print the exact sync payload without making a network call |
|
|
526
|
+
| `--live FILE` | live return series CSV to compare against a recorded backtest run |
|
|
527
|
+
| `--interval SECONDS` | polling interval in seconds for watch (default 1.0) |
|
|
528
|
+
| `--cycles N` | number of polling cycles for watch before exiting (0 means continuous) |
|
|
425
529
|
|
|
426
530
|
### Examples
|
|
427
531
|
|
|
@@ -434,11 +538,17 @@ alphaengine stress
|
|
|
434
538
|
alphaengine overlap
|
|
435
539
|
alphaengine size
|
|
436
540
|
alphaengine monitor
|
|
541
|
+
alphaengine init
|
|
542
|
+
alphaengine init --name momentum
|
|
437
543
|
alphaengine demo
|
|
438
544
|
alphaengine process
|
|
439
545
|
alphaengine process ou
|
|
440
546
|
alphaengine runs
|
|
441
547
|
alphaengine runs --limit 50
|
|
548
|
+
alphaengine log
|
|
549
|
+
alphaengine log --family momentum --verdict likely_noise
|
|
550
|
+
alphaengine show HEAD
|
|
551
|
+
alphaengine diff run_a run_b
|
|
442
552
|
alphaengine gaps
|
|
443
553
|
alphaengine tonight
|
|
444
554
|
alphaengine tonight --budget 5
|
|
@@ -448,12 +558,33 @@ alphaengine commands
|
|
|
448
558
|
alphaengine run screen_universe --universe sp500
|
|
449
559
|
alphaengine run size_position --data returns.csv
|
|
450
560
|
alphaengine run validate_study --project research.momentum
|
|
561
|
+
alphaengine run examples/screen_validate_size.yaml
|
|
562
|
+
alphaengine rerun HEAD
|
|
563
|
+
alphaengine watch examples/screen_validate_size.yaml
|
|
451
564
|
alphaengine seal study.json
|
|
565
|
+
alphaengine seal HEAD
|
|
566
|
+
alphaengine verify study.json
|
|
567
|
+
alphaengine verify study.json --data prices.csv
|
|
452
568
|
alphaengine report study.json
|
|
453
|
-
alphaengine report
|
|
569
|
+
alphaengine report memo HEAD --format md
|
|
454
570
|
alphaengine models
|
|
455
571
|
alphaengine trace
|
|
572
|
+
alphaengine idea new "Cross-sectional momentum holds" --kill-if "DSR < 0.9" --family momentum
|
|
573
|
+
alphaengine idea list
|
|
574
|
+
alphaengine idea status idea_1 testing
|
|
575
|
+
alphaengine idea show idea_1
|
|
456
576
|
alphaengine run screen_universe --thesis momentum
|
|
577
|
+
alphaengine data add prices.csv --name equities
|
|
578
|
+
alphaengine data list
|
|
579
|
+
alphaengine data show equities
|
|
580
|
+
alphaengine data lineage HEAD
|
|
581
|
+
alphaengine remote add quantos
|
|
582
|
+
alphaengine remote add quantos https://qosai.app
|
|
583
|
+
alphaengine push --dry-run
|
|
584
|
+
alphaengine push
|
|
585
|
+
alphaengine pull
|
|
586
|
+
alphaengine plugin list
|
|
587
|
+
alphaengine shell
|
|
457
588
|
alphaengine logout
|
|
458
589
|
alphaengine logout --purge
|
|
459
590
|
alphaengine version
|
|
@@ -489,7 +620,7 @@ above exists to copy:
|
|
|
489
620
|
per-period returns themselves. `sweep` does `np.asarray(list(raw))`, so a dict
|
|
490
621
|
of results iterates its *keys* and fails on the first string.
|
|
491
622
|
|
|
492
|
-
**Return the same length for every combination.** PBO splits the trial matrix
|
|
623
|
+
**Return the same length for every combination.** PBO via CSCV splits the trial matrix
|
|
493
624
|
into time blocks and compares configurations within each block, which only means
|
|
494
625
|
anything if they line up in time. Ragged output is refused rather than truncated,
|
|
495
626
|
because silently trimming produces a confident number over series that do not
|
|
@@ -541,7 +672,7 @@ diffable, and versioned so it still parses in two years.
|
|
|
541
672
|
|
|
542
673
|
| Module | Contents |
|
|
543
674
|
|---|---|
|
|
544
|
-
| `alphaengine.core` | deflated Sharpe, PSR, PBO via CSCV,
|
|
675
|
+
| `alphaengine.core` | deflated Sharpe, PSR, PBO via CSCV, `combinatorial_oos_stability`, minimum track record length, performance and risk |
|
|
545
676
|
| `alphaengine.core.panel` | cross-sectional rank, z-score, winsorize, neutralize |
|
|
546
677
|
| `alphaengine.core.signals` | IC, ICIR, quantile returns, decay |
|
|
547
678
|
| `alphaengine.core.cross_section` | Fama-MacBeth, quantile book with turnover |
|
|
@@ -580,14 +711,15 @@ Study.from_sweep(r, label="momentum, 9 configs").report()
|
|
|
580
711
|
What crosses is an explicit allowlist: the trial count and how it was obtained,
|
|
581
712
|
a content hash of the data, the verdict, the shape of the neighbourhood, the
|
|
582
713
|
performance figures. Computation runs locally; when you are signed in to
|
|
583
|
-
quantOS, summary figures are reported to your account, and full series
|
|
584
|
-
|
|
585
|
-
|
|
714
|
+
quantOS, summary figures are reported to your account, and full return series
|
|
715
|
+
upload only with `--share-series` (or `ALPHAENGINE_SHARE_SERIES=1`). Without
|
|
716
|
+
`--share-series`, a guard keyed on length (at most 512 elements) refuses to send
|
|
586
717
|
anything series-shaped whatever it is called.
|
|
587
718
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
719
|
+
### What uses the network
|
|
720
|
+
|
|
721
|
+
- **Zero network calls (completely offline):** `import alphaengine`, `sweep()`, `Study.save()`, `Study.load()`, every math primitive in `alphaengine.core` (`deflated_sharpe`, `pbo_cscv`, `combinatorial_oos_stability`, performance, risk, covariance, allocation, process calibration/stress, Grinold), local loaders (`load_csv`, `from_quantconnect`, `from_vectorbt`), `alphaengine demo`, `alphaengine process`, and `ae verify`.
|
|
722
|
+
- **Uses the network (requires a firm `ae_live_` key from Connect):** `login` / `whoami`, CLI workflows (`validate`, `screen`, `diagnose`, `decompose`, `pairs`, `walkforward`, `compare`, `size`, `run`, `workflows`, `runs`, `gaps`, `tonight`), `Study.report()` / `ae report`, and workspace sync (`ae seal` key check, `ae push`, `ae pull`). Full return series upload **only** when `--share-series` is passed.
|
|
591
723
|
|
|
592
724
|
## Where this sits in QuantOS
|
|
593
725
|
|