alphaspec 0.2.0__tar.gz → 0.2.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.
- {alphaspec-0.2.0 → alphaspec-0.2.1}/CHANGELOG.md +13 -1
- {alphaspec-0.2.0 → alphaspec-0.2.1}/PKG-INFO +1 -1
- {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/SPEC.md +6 -3
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/artifact.schema.json +2 -2
- {alphaspec-0.2.0 → alphaspec-0.2.1}/skills/alphaspec/SKILL.md +1 -1
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/__init__.py +1 -1
- {alphaspec-0.2.0 → alphaspec-0.2.1}/.github/workflows/ci.yml +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/.github/workflows/pages.yml +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/.github/workflows/release.yml +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/.gitignore +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/LICENSE +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/README.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/README.zh-CN.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/catalog/i18n/en.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/catalog/indicators.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/README.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as001-unresolved-indicator.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as002-unresolved-param.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as003-htf-live-lookahead.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as004-indicator-cycle.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as005-unknown-type.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as006-unknown-param.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as007-cn-indicator-on-us-market.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as008-primary-only-timeframe-ignored.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as009-finer-than-primary.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as010-tick-timeframe.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as011-missing-suffix.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as012-ai-without-search-trials.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as013-exits-replace-exit-rule.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as013-no-exit.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as014-intraday-on-daily.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as015-unused-indicator.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as016-arm-without-trailing.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as017-entry-above-symbol-cap.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as017-not-for-atr-risk.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as018-scale-in-no-room.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as101-duplicate-symbol.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as102-all-null.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as103-asof-future.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as104-zero-as-missing.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as105-weights-over-one.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-bare-number-operand.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-exit-zero.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-fill-timing-unknown.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-no-code-fields.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-noncanonical-timeframe.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-not-uses-rule.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-scale-in-averaging-down.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-score-without-direction.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-scores-and-weights.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-sizing-unsupported-mode.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-sizing-without-target.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-trade-settings-in-0.1.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-universe-mode-conflict.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/score-valid.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/valid-minimal.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/valid-sizing-atr-pyramid.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/valid-trade-settings.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/MARKETS.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/ROADMAP.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/RULES.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/RUNTIME_API.md +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/01-ema-cross-us-equity.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/02-rsi-reversion-params.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/03-mtf-trend-pullback.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/04-breakout-retest-sequence.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/05-cn-limit-up-pullback.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/06-trend-with-trade-settings.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/scores/01-model-scores-cn-stock.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/scores/02-target-weights-us-equity.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/pyproject.toml +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/artifact.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/common.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/evidence.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/gate-result.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/score.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/common.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/evidence.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/gate-result.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/score.schema.json +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/_resources.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/cli.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/client.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/lints.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/mcp_server.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/validate.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_cli_reference.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_client.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_conformance.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_examples.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_mcp_server.py +0 -0
- {alphaspec-0.2.0 → alphaspec-0.2.1}/tools/export_indicator_catalog.py +0 -0
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1 — 2026-10-11
|
|
4
|
+
|
|
5
|
+
Semantics clarified to match what a runtime can apply the same way in backtests and live trading:
|
|
6
|
+
|
|
7
|
+
- `exits.minHoldDays` counts **trading days** (entry day = 0; weekends and holidays excluded) and holds back
|
|
8
|
+
`dsl.exit` as well as the other exits. 0.2.0 said calendar days and left `dsl.exit` free.
|
|
9
|
+
- `sizing.scaleIn` add-ons are filled per `execution.fillTiming` (next open under `NEXT_OPEN`), and never on a bar
|
|
10
|
+
that also closes the position. 0.2.0 said "at the close of the triggering bar".
|
|
11
|
+
- Reference runtime: backtests and live trading now apply both rules identically; live pyramiding honours
|
|
12
|
+
`maxTotalPct`; live minimum holding is counted from the start of the current position, not the first time the
|
|
13
|
+
symbol was ever held.
|
|
14
|
+
|
|
3
15
|
## 0.2.0 — 2026-10-11
|
|
4
16
|
|
|
5
17
|
- Contract 0.2 (`schema/0.2/`): trade settings in three optional artifact blocks.
|
|
6
18
|
- `exits`: stop loss, take profit, trailing stop with activation, ATR stop / take profit, minimum holding days
|
|
7
|
-
(
|
|
19
|
+
(see 0.2.1), no-new-high exit.
|
|
8
20
|
- `sizing`: `FIXED_PCT` or `ATR_RISK` per entry, `maxHoldings`, pyramiding `scaleIn`.
|
|
9
21
|
- `execution`: fill timing (`NEXT_OPEN` / `BAR_CLOSE`).
|
|
10
22
|
Semantics in SPEC §4a.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: alphaspec
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: The auditable contract between alpha and execution: JSON schemas, a validator and lint rules for declarative trading strategies.
|
|
5
5
|
Project-URL: Homepage, https://github.com/openalpha-dev/alphaspec
|
|
6
6
|
Project-URL: Documentation, https://github.com/openalpha-dev/alphaspec#readme
|
|
@@ -99,11 +99,14 @@ Whichever fires first closes the whole position.
|
|
|
99
99
|
| `atrStopMultiplier` | close ≤ entry − k × ATR(14) |
|
|
100
100
|
| `atrTakeProfitMultiplier` | close ≥ entry + k × ATR(14) |
|
|
101
101
|
| `noNewHighDays` | n trading days pass without a new highest close since entry |
|
|
102
|
-
| `minHoldDays` | (modifies
|
|
102
|
+
| `minHoldDays` | (modifies everything, `dsl.exit` included) nothing closes the position until n **trading days** after entry |
|
|
103
103
|
|
|
104
104
|
- Omit a field to leave that exit off. `0` is rejected for the on/off fields: one runtime's
|
|
105
105
|
"disabled" is another's "stop immediately".
|
|
106
|
-
- `minHoldDays` counts
|
|
106
|
+
- `minHoldDays` counts trading days in the market's calendar: the entry day is day 0, weekends and
|
|
107
|
+
holidays do not count, and the meaning is the same on every timeframe (3 on a 5m strategy is three
|
|
108
|
+
trading days). It holds back rule exits too: its purpose is to keep a fresh position from being
|
|
109
|
+
shaken out by short-term noise. Leave it out if the strategy should be free to exit at once.
|
|
107
110
|
|
|
108
111
|
**`sizing`** — how large each position is and how many are held.
|
|
109
112
|
|
|
@@ -112,7 +115,7 @@ Whichever fires first closes the whole position.
|
|
|
112
115
|
| `positionMode` | `FIXED_PCT` (default): each entry buys `targetPctPerOrder`% of current equity. `ATR_RISK`: each entry is sized so one ATR(14) against it costs `targetPctPerOrder`% of equity; no entry while ATR cannot be computed |
|
|
113
116
|
| `targetPctPerOrder` | the percentage above (required when `sizing` is present) |
|
|
114
117
|
| `maxHoldings` | at most n symbols held at once; buys already queued count as held, so signals on the same bar cannot overshoot; further entries are skipped |
|
|
115
|
-
| `scaleIn` | pyramiding: `{maxAddOns, spacingAtr, maxTotalPct}` — add to a winner each time the close is `spacingAtr` × ATR(14) above the last buy, at most `maxAddOns` times; an add-on that would take the symbol above `maxTotalPct`% of equity is skipped |
|
|
118
|
+
| `scaleIn` | pyramiding: `{maxAddOns, spacingAtr, maxTotalPct}` — add to a winner each time the close is `spacingAtr` × ATR(14) above the last buy, at most `maxAddOns` times; an add-on that would take the symbol above `maxTotalPct`% of equity is skipped; filled per `execution.fillTiming`, never on a bar that closes the position |
|
|
116
119
|
|
|
117
120
|
Equity is cash plus the market value of all positions. Every buy rounds down to the market's
|
|
118
121
|
lot and is capped by `riskProfile.maxSymbolExposurePct` and by cash. Without a `sizing`
|
|
@@ -756,7 +756,7 @@
|
|
|
756
756
|
"type": "integer",
|
|
757
757
|
"minimum": 1,
|
|
758
758
|
"maximum": 365,
|
|
759
|
-
"description": "
|
|
759
|
+
"description": "Trading days after entry during which nothing closes the position: neither the exits above nor dsl.exit. The entry day is day 0; weekends and market holidays do not count, on every timeframe (3 on a 5m strategy is three trading days). Use it to keep a fresh position from being shaken out by short-term noise; omit it if that is not wanted."
|
|
760
760
|
},
|
|
761
761
|
"noNewHighDays": {
|
|
762
762
|
"type": "integer",
|
|
@@ -821,7 +821,7 @@
|
|
|
821
821
|
"maxAddOns",
|
|
822
822
|
"spacingAtr"
|
|
823
823
|
],
|
|
824
|
-
"description": "Pyramiding: add to a winning position each time the close rises spacingAtr × ATR(14) above the last buy price. Each add-on is sized like an entry (positionMode / targetPctPerOrder). Filled at the close
|
|
824
|
+
"description": "Pyramiding: add to a winning position each time the close rises spacingAtr × ATR(14) above the last buy price. Each add-on is sized like an entry (positionMode / targetPctPerOrder). Filled like any other order under execution.fillTiming: at the triggering bar's close (BAR_CLOSE) or at the next bar's open (NEXT_OPEN). No add-on is made on a bar that also closes the position.",
|
|
825
825
|
"properties": {
|
|
826
826
|
"maxAddOns": {
|
|
827
827
|
"type": "integer",
|
|
@@ -72,7 +72,7 @@ Stops, sizing and fill timing go in three optional top-level blocks — not in t
|
|
|
72
72
|
"execution": { "fillTiming": "NEXT_OPEN" }
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
- Other exits: `takeProfitPct`, `atrStopMultiplier`, `atrTakeProfitMultiplier` (ATR 14), `minHoldDays` (
|
|
75
|
+
- Other exits: `takeProfitPct`, `atrStopMultiplier`, `atrTakeProfitMultiplier` (ATR 14), `minHoldDays` (trading days after entry during which nothing closes the position, rule exits included). Percentages are 0–100.
|
|
76
76
|
- Leave a field out to turn that exit off; never write `0` (rejected).
|
|
77
77
|
- **Always write `sizing`.** Without it the reference runtime sizes entries by its account limits (up to 60% of equity per symbol), which rarely matches what the user has in mind.
|
|
78
78
|
- Keep `sizing.targetPctPerOrder` ≤ `riskProfile.maxSymbolExposurePct` (AS017).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as008-primary-only-timeframe-ignored.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|