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.
Files changed (92) hide show
  1. {alphaspec-0.2.0 → alphaspec-0.2.1}/CHANGELOG.md +13 -1
  2. {alphaspec-0.2.0 → alphaspec-0.2.1}/PKG-INFO +1 -1
  3. {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/SPEC.md +6 -3
  4. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/artifact.schema.json +2 -2
  5. {alphaspec-0.2.0 → alphaspec-0.2.1}/skills/alphaspec/SKILL.md +1 -1
  6. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/__init__.py +1 -1
  7. {alphaspec-0.2.0 → alphaspec-0.2.1}/.github/workflows/ci.yml +0 -0
  8. {alphaspec-0.2.0 → alphaspec-0.2.1}/.github/workflows/pages.yml +0 -0
  9. {alphaspec-0.2.0 → alphaspec-0.2.1}/.github/workflows/release.yml +0 -0
  10. {alphaspec-0.2.0 → alphaspec-0.2.1}/.gitignore +0 -0
  11. {alphaspec-0.2.0 → alphaspec-0.2.1}/LICENSE +0 -0
  12. {alphaspec-0.2.0 → alphaspec-0.2.1}/README.md +0 -0
  13. {alphaspec-0.2.0 → alphaspec-0.2.1}/README.zh-CN.md +0 -0
  14. {alphaspec-0.2.0 → alphaspec-0.2.1}/catalog/i18n/en.json +0 -0
  15. {alphaspec-0.2.0 → alphaspec-0.2.1}/catalog/indicators.json +0 -0
  16. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/README.md +0 -0
  17. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as001-unresolved-indicator.json +0 -0
  18. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as002-unresolved-param.json +0 -0
  19. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as003-htf-live-lookahead.json +0 -0
  20. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as004-indicator-cycle.json +0 -0
  21. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as005-unknown-type.json +0 -0
  22. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as006-unknown-param.json +0 -0
  23. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as007-cn-indicator-on-us-market.json +0 -0
  24. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as008-primary-only-timeframe-ignored.json +0 -0
  25. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as009-finer-than-primary.json +0 -0
  26. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as010-tick-timeframe.json +0 -0
  27. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as011-missing-suffix.json +0 -0
  28. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as012-ai-without-search-trials.json +0 -0
  29. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as013-exits-replace-exit-rule.json +0 -0
  30. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as013-no-exit.json +0 -0
  31. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as014-intraday-on-daily.json +0 -0
  32. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as015-unused-indicator.json +0 -0
  33. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as016-arm-without-trailing.json +0 -0
  34. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as017-entry-above-symbol-cap.json +0 -0
  35. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as017-not-for-atr-risk.json +0 -0
  36. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as018-scale-in-no-room.json +0 -0
  37. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as101-duplicate-symbol.json +0 -0
  38. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as102-all-null.json +0 -0
  39. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as103-asof-future.json +0 -0
  40. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as104-zero-as-missing.json +0 -0
  41. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/as105-weights-over-one.json +0 -0
  42. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-bare-number-operand.json +0 -0
  43. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-exit-zero.json +0 -0
  44. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-fill-timing-unknown.json +0 -0
  45. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-no-code-fields.json +0 -0
  46. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-noncanonical-timeframe.json +0 -0
  47. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-not-uses-rule.json +0 -0
  48. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-scale-in-averaging-down.json +0 -0
  49. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-score-without-direction.json +0 -0
  50. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-scores-and-weights.json +0 -0
  51. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-sizing-unsupported-mode.json +0 -0
  52. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-sizing-without-target.json +0 -0
  53. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-trade-settings-in-0.1.json +0 -0
  54. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/schema-universe-mode-conflict.json +0 -0
  55. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/score-valid.json +0 -0
  56. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/valid-minimal.json +0 -0
  57. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/valid-sizing-atr-pyramid.json +0 -0
  58. {alphaspec-0.2.0 → alphaspec-0.2.1}/conformance/cases/valid-trade-settings.json +0 -0
  59. {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/MARKETS.md +0 -0
  60. {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/ROADMAP.md +0 -0
  61. {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/RULES.md +0 -0
  62. {alphaspec-0.2.0 → alphaspec-0.2.1}/docs/RUNTIME_API.md +0 -0
  63. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/01-ema-cross-us-equity.json +0 -0
  64. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/02-rsi-reversion-params.json +0 -0
  65. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/03-mtf-trend-pullback.json +0 -0
  66. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/04-breakout-retest-sequence.json +0 -0
  67. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/05-cn-limit-up-pullback.json +0 -0
  68. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/artifacts/06-trend-with-trade-settings.json +0 -0
  69. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/scores/01-model-scores-cn-stock.json +0 -0
  70. {alphaspec-0.2.0 → alphaspec-0.2.1}/examples/scores/02-target-weights-us-equity.json +0 -0
  71. {alphaspec-0.2.0 → alphaspec-0.2.1}/pyproject.toml +0 -0
  72. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/artifact.schema.json +0 -0
  73. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/common.schema.json +0 -0
  74. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/evidence.schema.json +0 -0
  75. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/gate-result.schema.json +0 -0
  76. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.1/score.schema.json +0 -0
  77. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/common.schema.json +0 -0
  78. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/evidence.schema.json +0 -0
  79. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/gate-result.schema.json +0 -0
  80. {alphaspec-0.2.0 → alphaspec-0.2.1}/schema/0.2/score.schema.json +0 -0
  81. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/_resources.py +0 -0
  82. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/cli.py +0 -0
  83. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/client.py +0 -0
  84. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/lints.py +0 -0
  85. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/mcp_server.py +0 -0
  86. {alphaspec-0.2.0 → alphaspec-0.2.1}/src/alphaspec/validate.py +0 -0
  87. {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_cli_reference.py +0 -0
  88. {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_client.py +0 -0
  89. {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_conformance.py +0 -0
  90. {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_examples.py +0 -0
  91. {alphaspec-0.2.0 → alphaspec-0.2.1}/tests/test_mcp_server.py +0 -0
  92. {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
- (calendar days on every timeframe), no-new-high exit.
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.0
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 all of the above) none fires within n **calendar** days of entry; `dsl.exit` still does |
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 calendar days on every timeframe: 3 on a 5m strategy is three days.
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": "Calendar days after entry during which none of the exits above fire (dsl.exit still does). Calendar days on every timeframe: 3 on a 5m strategy is three days, not three bars."
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 of the bar that triggers it.",
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` (calendar days during which stops do not fire). Percentages are 0–100.
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).
@@ -5,4 +5,4 @@ from .validate import Issue, Report, validate
5
5
 
6
6
  __all__ = ["CONTRACT_VERSION", "AlphaSpecError", "Client", "EvaluationFailed", "Issue", "Rejected", "Report",
7
7
  "load_catalog", "load_schema", "validate"]
8
- __version__ = "0.2.0"
8
+ __version__ = "0.2.1"
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