alphaengine 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,47 @@
1
+ """AlphaEngine, validated research tooling for investment strategies.
2
+
3
+ Answers one question honestly: **is this result an edge, or did you try enough
4
+ things that something was bound to look good?**
5
+
6
+ from alphaengine import sweep
7
+
8
+ r = sweep(backtest_fn, grid, data=prices) # runs every combination
9
+ r.surface() # stable plateau, or a knife edge
10
+ r.verdict() # deflated for the trials you ran
11
+ r.save("study.json") # the artifact, on your disk
12
+
13
+ WHY A SWEEP AND NOT A CALCULATOR
14
+ The correction that makes a Sharpe ratio honest needs to know how many
15
+ variants you tested. Ask a person for that number and you get the number
16
+ that flatters them, not from dishonesty, but because nobody counts the
17
+ thing they threw away. Run the grid and the count is `len(grid)`, so the
18
+ question never has to be asked.
19
+
20
+ WHAT THIS LIBRARY IS NOT
21
+ Not a backtester. `sweep()` takes YOUR function. We orchestrate and measure;
22
+ you simulate. The engine you already trust stays the engine you trust.
23
+
24
+ OFFLINE BY CONSTRUCTION
25
+ Importing this module makes no network call and needs no account. numpy and
26
+ scipy, nothing else. Everything above runs on a laptop with the wifi off,
27
+ and your data never leaves the machine.
28
+ """
29
+
30
+ from ._version import __version__
31
+ from .study import SCHEMA_VERSION, Study, load, save
32
+ from .sweep import SweepResult, sweep
33
+
34
+ # `sweep` is bound here to the FUNCTION, deliberately shadowing the subpackage
35
+ # of the same name. The documented entry point is `from alphaengine import
36
+ # sweep`, and a user who writes that and gets a module back has hit a bug on
37
+ # their first line. `from alphaengine.sweep import ...` still resolves through
38
+ # sys.modules for anyone who wants the module explicitly.
39
+ __all__ = [
40
+ "__version__",
41
+ "sweep",
42
+ "SweepResult",
43
+ "Study",
44
+ "save",
45
+ "load",
46
+ "SCHEMA_VERSION",
47
+ ]
@@ -0,0 +1,15 @@
1
+ """Single source of the version.
2
+
3
+ Read by hatchling at build time (see [tool.hatch.version] in pyproject.toml), so
4
+ this file and the published artifact can never disagree.
5
+
6
+ SEMVER, WITH ONE LOCAL RULE: a MAJOR bump is required whenever a computed value
7
+ changes. Once this is on PyPI the numbers are a public contract, somebody's
8
+ saved study has to reproduce in two years, so a different result from the same
9
+ inputs is a breaking change even when the signature is untouched.
10
+
11
+ While the leading digit is 0, the MINOR position carries that rule: 0.1 -> 0.2
12
+ is what a changed figure costs. The API may still move underneath it.
13
+ """
14
+
15
+ __version__ = "0.1.0"
@@ -0,0 +1,63 @@
1
+ """Deterministic quantitative primitives.
2
+
3
+ Pure functions over arrays. No I/O, no network, no global state, no clock, the
4
+ same inputs return the same outputs on every machine, which is the property
5
+ everything else here is built on. numpy and scipy only.
6
+
7
+ These are published methods, not proprietary formulae:
8
+
9
+ probabilistic / deflated Sharpe Bailey & Lopez de Prado (2014)
10
+ PBO via CSCV Bailey, Borwein, Lopez de Prado & Zhu (2017)
11
+ CPCV purged, embargoed cross-validation
12
+ minimum track record length how long a record must be before skill is
13
+ distinguishable from luck
14
+
15
+ That they are published is the point. A referee whose reasoning you cannot
16
+ inspect is not a referee.
17
+
18
+ THE RETURN VALUES ARE A PUBLIC CONTRACT. A study written today has to reproduce
19
+ in two years, so a changed number is a breaking change requiring a major version
20
+ bump even when the signature is untouched. See tests/test_goldens.py.
21
+
22
+ Exports are listed explicitly rather than star-imported: on a published package
23
+ the difference between the API and an implementation detail should be a
24
+ decision, not an accident of which names happen to be module-level.
25
+
26
+ `factors` and `pairs` are NOT imported here. They need statsmodels, which is an
27
+ optional extra, and importing them eagerly would make the core install fail for
28
+ everyone who does not need them:
29
+
30
+ from alphaengine.core.factors import decompose_factors # pip install 'alphaengine[factors]'
31
+ from alphaengine.core.pairs import find_cointegrated_pairs
32
+ """
33
+
34
+ from .backtest import run_backtest, score_backtest
35
+ from .performance import performance_report
36
+ from .risk import compute_var_cvar
37
+ from .technical import technical_features
38
+ from .validation import (
39
+ cpcv_score,
40
+ deflated_sharpe,
41
+ expected_max_sharpe,
42
+ min_track_record_length,
43
+ pbo_cscv,
44
+ probabilistic_sharpe_ratio,
45
+ )
46
+
47
+ __all__ = [
48
+ # validation, the honesty layer
49
+ "deflated_sharpe",
50
+ "probabilistic_sharpe_ratio",
51
+ "expected_max_sharpe",
52
+ "min_track_record_length",
53
+ "pbo_cscv",
54
+ "cpcv_score",
55
+ # performance and risk
56
+ "performance_report",
57
+ "compute_var_cvar",
58
+ # simulation and scoring
59
+ "run_backtest",
60
+ "score_backtest",
61
+ # features
62
+ "technical_features",
63
+ ]