alphaspec 0.1.0__tar.gz → 0.2.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.
Files changed (92) hide show
  1. {alphaspec-0.1.0 → alphaspec-0.2.0}/.github/workflows/pages.yml +1 -1
  2. {alphaspec-0.1.0 → alphaspec-0.2.0}/CHANGELOG.md +19 -0
  3. {alphaspec-0.1.0 → alphaspec-0.2.0}/PKG-INFO +13 -9
  4. {alphaspec-0.1.0 → alphaspec-0.2.0}/README.md +11 -7
  5. {alphaspec-0.1.0 → alphaspec-0.2.0}/README.zh-CN.md +11 -7
  6. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/README.md +3 -2
  7. alphaspec-0.2.0/conformance/cases/as013-exits-replace-exit-rule.json +58 -0
  8. alphaspec-0.2.0/conformance/cases/as016-arm-without-trailing.json +69 -0
  9. alphaspec-0.2.0/conformance/cases/as017-entry-above-symbol-cap.json +68 -0
  10. alphaspec-0.2.0/conformance/cases/as017-not-for-atr-risk.json +67 -0
  11. alphaspec-0.2.0/conformance/cases/as018-scale-in-no-room.json +73 -0
  12. alphaspec-0.2.0/conformance/cases/schema-exit-zero.json +68 -0
  13. alphaspec-0.2.0/conformance/cases/schema-fill-timing-unknown.json +68 -0
  14. alphaspec-0.2.0/conformance/cases/schema-scale-in-averaging-down.json +73 -0
  15. alphaspec-0.2.0/conformance/cases/schema-sizing-unsupported-mode.json +69 -0
  16. alphaspec-0.2.0/conformance/cases/schema-sizing-without-target.json +68 -0
  17. alphaspec-0.2.0/conformance/cases/schema-trade-settings-in-0.1.json +68 -0
  18. alphaspec-0.2.0/conformance/cases/valid-sizing-atr-pyramid.json +76 -0
  19. alphaspec-0.2.0/conformance/cases/valid-trade-settings.json +80 -0
  20. alphaspec-0.2.0/docs/ROADMAP.md +72 -0
  21. {alphaspec-0.1.0 → alphaspec-0.2.0}/docs/RULES.md +23 -1
  22. {alphaspec-0.1.0 → alphaspec-0.2.0}/docs/RUNTIME_API.md +17 -2
  23. {alphaspec-0.1.0 → alphaspec-0.2.0}/docs/SPEC.md +52 -4
  24. alphaspec-0.2.0/examples/artifacts/06-trend-with-trade-settings.json +28 -0
  25. {alphaspec-0.1.0 → alphaspec-0.2.0}/pyproject.toml +1 -1
  26. alphaspec-0.2.0/schema/0.2/artifact.schema.json +847 -0
  27. alphaspec-0.2.0/schema/0.2/common.schema.json +96 -0
  28. alphaspec-0.2.0/schema/0.2/evidence.schema.json +152 -0
  29. alphaspec-0.2.0/schema/0.2/gate-result.schema.json +55 -0
  30. alphaspec-0.2.0/schema/0.2/score.schema.json +79 -0
  31. {alphaspec-0.1.0 → alphaspec-0.2.0}/skills/alphaspec/SKILL.md +20 -1
  32. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/__init__.py +1 -1
  33. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/_resources.py +4 -1
  34. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/lints.py +35 -2
  35. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/validate.py +8 -7
  36. {alphaspec-0.1.0 → alphaspec-0.2.0}/tests/test_conformance.py +1 -1
  37. {alphaspec-0.1.0 → alphaspec-0.2.0}/.github/workflows/ci.yml +0 -0
  38. {alphaspec-0.1.0 → alphaspec-0.2.0}/.github/workflows/release.yml +0 -0
  39. {alphaspec-0.1.0 → alphaspec-0.2.0}/.gitignore +0 -0
  40. {alphaspec-0.1.0 → alphaspec-0.2.0}/LICENSE +0 -0
  41. {alphaspec-0.1.0 → alphaspec-0.2.0}/catalog/i18n/en.json +0 -0
  42. {alphaspec-0.1.0 → alphaspec-0.2.0}/catalog/indicators.json +0 -0
  43. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as001-unresolved-indicator.json +0 -0
  44. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as002-unresolved-param.json +0 -0
  45. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as003-htf-live-lookahead.json +0 -0
  46. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as004-indicator-cycle.json +0 -0
  47. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as005-unknown-type.json +0 -0
  48. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as006-unknown-param.json +0 -0
  49. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as007-cn-indicator-on-us-market.json +0 -0
  50. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as008-primary-only-timeframe-ignored.json +0 -0
  51. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as009-finer-than-primary.json +0 -0
  52. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as010-tick-timeframe.json +0 -0
  53. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as011-missing-suffix.json +0 -0
  54. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as012-ai-without-search-trials.json +0 -0
  55. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as013-no-exit.json +0 -0
  56. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as014-intraday-on-daily.json +0 -0
  57. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as015-unused-indicator.json +0 -0
  58. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as101-duplicate-symbol.json +0 -0
  59. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as102-all-null.json +0 -0
  60. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as103-asof-future.json +0 -0
  61. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as104-zero-as-missing.json +0 -0
  62. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/as105-weights-over-one.json +0 -0
  63. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-bare-number-operand.json +0 -0
  64. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-no-code-fields.json +0 -0
  65. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-noncanonical-timeframe.json +0 -0
  66. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-not-uses-rule.json +0 -0
  67. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-score-without-direction.json +0 -0
  68. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-scores-and-weights.json +0 -0
  69. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/schema-universe-mode-conflict.json +0 -0
  70. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/score-valid.json +0 -0
  71. {alphaspec-0.1.0 → alphaspec-0.2.0}/conformance/cases/valid-minimal.json +0 -0
  72. {alphaspec-0.1.0 → alphaspec-0.2.0}/docs/MARKETS.md +0 -0
  73. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/artifacts/01-ema-cross-us-equity.json +0 -0
  74. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/artifacts/02-rsi-reversion-params.json +0 -0
  75. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/artifacts/03-mtf-trend-pullback.json +0 -0
  76. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/artifacts/04-breakout-retest-sequence.json +0 -0
  77. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/artifacts/05-cn-limit-up-pullback.json +0 -0
  78. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/scores/01-model-scores-cn-stock.json +0 -0
  79. {alphaspec-0.1.0 → alphaspec-0.2.0}/examples/scores/02-target-weights-us-equity.json +0 -0
  80. {alphaspec-0.1.0 → alphaspec-0.2.0}/schema/0.1/artifact.schema.json +0 -0
  81. {alphaspec-0.1.0 → alphaspec-0.2.0}/schema/0.1/common.schema.json +0 -0
  82. {alphaspec-0.1.0 → alphaspec-0.2.0}/schema/0.1/evidence.schema.json +0 -0
  83. {alphaspec-0.1.0 → alphaspec-0.2.0}/schema/0.1/gate-result.schema.json +0 -0
  84. {alphaspec-0.1.0 → alphaspec-0.2.0}/schema/0.1/score.schema.json +0 -0
  85. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/cli.py +0 -0
  86. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/client.py +0 -0
  87. {alphaspec-0.1.0 → alphaspec-0.2.0}/src/alphaspec/mcp_server.py +0 -0
  88. {alphaspec-0.1.0 → alphaspec-0.2.0}/tests/test_cli_reference.py +0 -0
  89. {alphaspec-0.1.0 → alphaspec-0.2.0}/tests/test_client.py +0 -0
  90. {alphaspec-0.1.0 → alphaspec-0.2.0}/tests/test_examples.py +0 -0
  91. {alphaspec-0.1.0 → alphaspec-0.2.0}/tests/test_mcp_server.py +0 -0
  92. {alphaspec-0.1.0 → alphaspec-0.2.0}/tools/export_indicator_catalog.py +0 -0
@@ -1,5 +1,5 @@
1
1
  name: pages
2
- # Serves the schemas at their $id URLs: https://openalpha-dev.github.io/alphaspec/schema/0.1/<kind>.schema.json
2
+ # Serves the schemas at their $id URLs: https://openalpha-dev.github.io/alphaspec/schema/<version>/<kind>.schema.json
3
3
  # One-time setup: repository Settings → Pages → Source: GitHub Actions.
4
4
  on:
5
5
  push:
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 — 2026-10-11
4
+
5
+ - Contract 0.2 (`schema/0.2/`): trade settings in three optional artifact blocks.
6
+ - `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.
8
+ - `sizing`: `FIXED_PCT` or `ATR_RISK` per entry, `maxHoldings`, pyramiding `scaleIn`.
9
+ - `execution`: fill timing (`NEXT_OPEN` / `BAR_CLOSE`).
10
+ Semantics in SPEC §4a.
11
+ - Versions are additive: the validator accepts 0.1 and 0.2 and checks each document against the schemas of the
12
+ version it declares. `CONTRACT_VERSION` is now `"0.2"`; `SUPPORTED_VERSIONS` lists both.
13
+ - New lint rules AS016 (trailing-stop activation without a trailing stop), AS017 (entry size above the per-symbol
14
+ cap) and AS018 (pyramiding cap leaves no room for an add-on). AS013 no longer fires when an `exits` block closes
15
+ positions.
16
+ - Example `06-trend-with-trade-settings`.
17
+ - RUNTIME_API documents the reference runtime's default sizing when a document has no `sizing` block.
18
+ - Reference runtime: portfolio backtests (used by `evaluate`) now honour holding caps, ATR risk sizing and
19
+ pyramiding, and size fixed-fraction entries on equity rather than remaining cash. Before this release those
20
+ settings were silently ignored there, which is why they were not in 0.1.
21
+
3
22
  ## 0.1.0 — 2026-10-09
4
23
 
5
24
  - Contract 0.1 drafts: `artifact`, `score`, `gate-result`, `evidence`, shared `common` definitions.
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: alphaspec
3
- Version: 0.1.0
3
+ Version: 0.2.0
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
7
7
  Project-URL: Changelog, https://github.com/openalpha-dev/alphaspec/blob/main/CHANGELOG.md
8
- Project-URL: Schemas, https://openalpha-dev.github.io/alphaspec/schema/0.1/
8
+ Project-URL: Schemas, https://openalpha-dev.github.io/alphaspec/schema/0.2/
9
9
  Author: OpenAlpha contributors
10
10
  License-Expression: Apache-2.0
11
11
  License-File: LICENSE
@@ -80,15 +80,15 @@ Two ways in, written by you or your agent:
80
80
 
81
81
  | Level | Document | For | You send |
82
82
  |---|---|---|---|
83
- | **L1 · Score** | [`score`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/score.schema.json) | ML teams, factor researchers | `(asOf, market, symbol, score)` or target weights |
84
- | **L2 · Artifact** | [`artifact`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/artifact.schema.json) | rule-based strategies, AI agents | a rule tree with parameters, universe and risk overrides |
83
+ | **L1 · Score** | [`score`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/score.schema.json) | ML teams, factor researchers | `(asOf, market, symbol, score)` or target weights |
84
+ | **L2 · Artifact** | [`artifact`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/artifact.schema.json) | rule-based strategies, AI agents | a rule tree with parameters, universe and risk overrides |
85
85
 
86
86
  Two ways back, written by the runtime and never by the submitter:
87
87
 
88
88
  | Document | What it answers |
89
89
  |---|---|
90
- | [`gate-result`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/gate-result.schema.json) | Did it pass, judged on figures the runtime **recomputed itself**, check by check |
91
- | [`evidence`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/evidence.schema.json) | What happened in a real market: rejections, slippage, fills, deviation from target, every number with its caliber |
90
+ | [`gate-result`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/gate-result.schema.json) | Did it pass, judged on figures the runtime **recomputed itself**, check by check |
91
+ | [`evidence`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/evidence.schema.json) | What happened in a real market: rejections, slippage, fills, deviation from target, every number with its caliber |
92
92
 
93
93
  The way back is the point. Research tools see prices, news and filings; none of that says whether
94
94
  an order was rejected, how much slippage it paid, or how far the portfolio drifted from its target.
@@ -110,7 +110,7 @@ A short artifact:
110
110
 
111
111
  ```json
112
112
  {
113
- "contractVersion": "0.1",
113
+ "contractVersion": "0.2",
114
114
  "kind": "artifact",
115
115
  "title": "RSI rebound above the 60-day average",
116
116
  "market": "cn_stock",
@@ -127,6 +127,8 @@ A short artifact:
127
127
  "right": { "type": "GT", "left": { "ind": "close" }, "right": { "ind": "ma60" } } },
128
128
  "exit": { "type": "GTE", "left": { "ind": "rsi" }, "right": { "const": 70 } }
129
129
  },
130
+ "exits": { "stopLossPct": 8, "noNewHighDays": 20 },
131
+ "sizing": { "positionMode": "FIXED_PCT", "targetPctPerOrder": 20 },
130
132
  "universe": { "mode": "SYMBOLS", "symbols": ["600519.SH", "000333.SZ"] },
131
133
  "producer": { "kind": "AI_AGENT", "name": "my-agent@0.1", "searchTrials": 3 }
132
134
  }
@@ -314,8 +316,10 @@ docs/ semantics, lint rules, markets, runtime API
314
316
  ## Versioning
315
317
 
316
318
  Every document carries `contractVersion`, so a runtime can refuse what it does not understand.
317
- Breaking changes bump the contract version. Schemas are published at their `$id` URLs, e.g.
318
- `https://openalpha-dev.github.io/alphaspec/schema/0.1/artifact.schema.json`.
319
+ Versions are additive and each keeps its own schema directory: a document is validated
320
+ against the version it declares. 0.2 adds trade settings (`exits`, `sizing`, `execution`);
321
+ see [docs/ROADMAP.md](https://github.com/openalpha-dev/alphaspec/blob/main/docs/ROADMAP.md). Schemas are published at their `$id` URLs, e.g.
322
+ `https://openalpha-dev.github.io/alphaspec/schema/0.2/artifact.schema.json`.
319
323
 
320
324
  ## License
321
325
 
@@ -53,15 +53,15 @@ Two ways in, written by you or your agent:
53
53
 
54
54
  | Level | Document | For | You send |
55
55
  |---|---|---|---|
56
- | **L1 · Score** | [`score`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/score.schema.json) | ML teams, factor researchers | `(asOf, market, symbol, score)` or target weights |
57
- | **L2 · Artifact** | [`artifact`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/artifact.schema.json) | rule-based strategies, AI agents | a rule tree with parameters, universe and risk overrides |
56
+ | **L1 · Score** | [`score`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/score.schema.json) | ML teams, factor researchers | `(asOf, market, symbol, score)` or target weights |
57
+ | **L2 · Artifact** | [`artifact`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/artifact.schema.json) | rule-based strategies, AI agents | a rule tree with parameters, universe and risk overrides |
58
58
 
59
59
  Two ways back, written by the runtime and never by the submitter:
60
60
 
61
61
  | Document | What it answers |
62
62
  |---|---|
63
- | [`gate-result`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/gate-result.schema.json) | Did it pass, judged on figures the runtime **recomputed itself**, check by check |
64
- | [`evidence`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/evidence.schema.json) | What happened in a real market: rejections, slippage, fills, deviation from target, every number with its caliber |
63
+ | [`gate-result`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/gate-result.schema.json) | Did it pass, judged on figures the runtime **recomputed itself**, check by check |
64
+ | [`evidence`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/evidence.schema.json) | What happened in a real market: rejections, slippage, fills, deviation from target, every number with its caliber |
65
65
 
66
66
  The way back is the point. Research tools see prices, news and filings; none of that says whether
67
67
  an order was rejected, how much slippage it paid, or how far the portfolio drifted from its target.
@@ -83,7 +83,7 @@ A short artifact:
83
83
 
84
84
  ```json
85
85
  {
86
- "contractVersion": "0.1",
86
+ "contractVersion": "0.2",
87
87
  "kind": "artifact",
88
88
  "title": "RSI rebound above the 60-day average",
89
89
  "market": "cn_stock",
@@ -100,6 +100,8 @@ A short artifact:
100
100
  "right": { "type": "GT", "left": { "ind": "close" }, "right": { "ind": "ma60" } } },
101
101
  "exit": { "type": "GTE", "left": { "ind": "rsi" }, "right": { "const": 70 } }
102
102
  },
103
+ "exits": { "stopLossPct": 8, "noNewHighDays": 20 },
104
+ "sizing": { "positionMode": "FIXED_PCT", "targetPctPerOrder": 20 },
103
105
  "universe": { "mode": "SYMBOLS", "symbols": ["600519.SH", "000333.SZ"] },
104
106
  "producer": { "kind": "AI_AGENT", "name": "my-agent@0.1", "searchTrials": 3 }
105
107
  }
@@ -287,8 +289,10 @@ docs/ semantics, lint rules, markets, runtime API
287
289
  ## Versioning
288
290
 
289
291
  Every document carries `contractVersion`, so a runtime can refuse what it does not understand.
290
- Breaking changes bump the contract version. Schemas are published at their `$id` URLs, e.g.
291
- `https://openalpha-dev.github.io/alphaspec/schema/0.1/artifact.schema.json`.
292
+ Versions are additive and each keeps its own schema directory: a document is validated
293
+ against the version it declares. 0.2 adds trade settings (`exits`, `sizing`, `execution`);
294
+ see [docs/ROADMAP.md](https://github.com/openalpha-dev/alphaspec/blob/main/docs/ROADMAP.md). Schemas are published at their `$id` URLs, e.g.
295
+ `https://openalpha-dev.github.io/alphaspec/schema/0.2/artifact.schema.json`.
292
296
 
293
297
  ## License
294
298
 
@@ -48,15 +48,15 @@ AlphaSpec 守的是那道边界:**跨进执行层的东西,必须是一份
48
48
 
49
49
  | 档位 | 文档 | 适合谁 | 提交什么 |
50
50
  |---|---|---|---|
51
- | **L1 · Score** | [`score`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/score.schema.json) | 机构 ML 团队、因子研究员 | `(asOf, market, symbol, score)`,或者直接给目标权重 |
52
- | **L2 · Artifact** | [`artifact`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/artifact.schema.json) | 规则策略、AI agent | 一棵完整的规则树,加上参数、标的范围和风控设置 |
51
+ | **L1 · Score** | [`score`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/score.schema.json) | 机构 ML 团队、因子研究员 | `(asOf, market, symbol, score)`,或者直接给目标权重 |
52
+ | **L2 · Artifact** | [`artifact`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/artifact.schema.json) | 规则策略、AI agent | 一棵完整的规则树,加上参数、标的范围和风控设置 |
53
53
 
54
54
  两种回执,只由执行系统生成,提交方不能自己填:
55
55
 
56
56
  | 文档 | 回答什么问题 |
57
57
  |---|---|
58
- | [`gate-result`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/gate-result.schema.json) | 门禁过没过。绩效由执行系统**自己重算**,逐项列出判据 |
59
- | [`evidence`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.1/evidence.schema.json) | 在真实市场里发生了什么:拒单、滑点、成交、与目标持仓的偏差,每个数字都注明口径 |
58
+ | [`gate-result`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/gate-result.schema.json) | 门禁过没过。绩效由执行系统**自己重算**,逐项列出判据 |
59
+ | [`evidence`](https://github.com/openalpha-dev/alphaspec/blob/main/schema/0.2/evidence.schema.json) | 在真实市场里发生了什么:拒单、滑点、成交、与目标持仓的偏差,每个数字都注明口径 |
60
60
 
61
61
  回执才是重点。研究端看得到行情、新闻和研报,却看不到一笔委托有没有被拒、付了多少滑点、
62
62
  组合离目标持仓偏了多远——这些只有执行系统知道,而且只有当它用研究端读得懂的格式说出来,才算数。
@@ -77,7 +77,7 @@ flowchart LR
77
77
 
78
78
  ```json
79
79
  {
80
- "contractVersion": "0.1",
80
+ "contractVersion": "0.2",
81
81
  "kind": "artifact",
82
82
  "title": "RSI 超卖反弹 + 站上 60 日线",
83
83
  "market": "cn_stock",
@@ -94,6 +94,8 @@ flowchart LR
94
94
  "right": { "type": "GT", "left": { "ind": "close" }, "right": { "ind": "ma60" } } },
95
95
  "exit": { "type": "GTE", "left": { "ind": "rsi" }, "right": { "const": 70 } }
96
96
  },
97
+ "exits": { "stopLossPct": 8, "noNewHighDays": 20 },
98
+ "sizing": { "positionMode": "FIXED_PCT", "targetPctPerOrder": 20 },
97
99
  "universe": { "mode": "SYMBOLS", "symbols": ["600519.SH", "000333.SZ"] },
98
100
  "producer": { "kind": "AI_AGENT", "name": "my-agent@0.1", "searchTrials": 3 }
99
101
  }
@@ -260,9 +262,11 @@ docs/ 字段语义、检查规则、市场、运行时接口
260
262
 
261
263
  ## 版本
262
264
 
263
- 每份文档都带 `contractVersion`,执行系统可以拒绝它不认识的版本;不兼容的改动会提升契约版本号。
265
+ 每份文档都带 `contractVersion`,执行系统可以拒绝它不认识的版本。版本只做加法、各有一份 schema 目录,
266
+ 文档按自己声明的版本校验。0.2 加入交易设置(`exits` 止盈止损、`sizing` 仓位、`execution` 成交时点),
267
+ 路线图见 [docs/ROADMAP.md](https://github.com/openalpha-dev/alphaspec/blob/main/docs/ROADMAP.md)。
264
268
  Schema 发布在各自的 `$id` 地址,例如
265
- `https://openalpha-dev.github.io/alphaspec/schema/0.1/artifact.schema.json`。
269
+ `https://openalpha-dev.github.io/alphaspec/schema/0.2/artifact.schema.json`。
266
270
 
267
271
  ## 许可证
268
272
 
@@ -3,8 +3,9 @@
3
3
  Each file is `{ "description", "document", "expect": { "valid", "errors", "warnings" } }`.
4
4
  `errors` and `warnings` are the exact sets of rule codes (`SCHEMA` for any schema failure).
5
5
 
6
- A runtime that claims AlphaSpec 0.1 support must, for every case, accept or reject the
7
- document as `expect.valid` says and report the same error codes. Matching warnings is
6
+ Each case's document declares its `contractVersion`. A runtime that claims support for a
7
+ contract version must, for every case of that version, accept or reject the document as
8
+ `expect.valid` says and report the same error codes. Matching warnings is
8
9
  recommended.
9
10
 
10
11
  Add a case for every new rule; the test suite fails if a rule has none.
@@ -0,0 +1,58 @@
1
+ {
2
+ "description": "No dsl.exit, but an exits block closes positions: AS013 does not fire.",
3
+ "document": {
4
+ "contractVersion": "0.2",
5
+ "kind": "artifact",
6
+ "title": "EMA 20/60 crossover",
7
+ "note": "The smallest useful artifact: two indicators, one entry, one exit, a fixed symbol list.",
8
+ "market": "us_equity",
9
+ "timeframe": "1d",
10
+ "dsl": {
11
+ "version": 1,
12
+ "indicators": {
13
+ "fast": {
14
+ "type": "EMA",
15
+ "period": 20
16
+ },
17
+ "slow": {
18
+ "type": "EMA",
19
+ "period": 60
20
+ }
21
+ },
22
+ "entry": {
23
+ "type": "CROSS_UP",
24
+ "left": {
25
+ "ind": "fast"
26
+ },
27
+ "right": {
28
+ "ind": "slow"
29
+ }
30
+ }
31
+ },
32
+ "universe": {
33
+ "mode": "SYMBOLS",
34
+ "symbols": [
35
+ "AAPL",
36
+ "MSFT",
37
+ "NVDA"
38
+ ]
39
+ },
40
+ "riskProfile": {
41
+ "maxSymbolExposurePct": 20,
42
+ "maxTotalExposurePct": 60
43
+ },
44
+ "producer": {
45
+ "kind": "HUMAN",
46
+ "name": "example"
47
+ },
48
+ "exits": {
49
+ "stopLossPct": 5,
50
+ "trailingStopPct": 8
51
+ }
52
+ },
53
+ "expect": {
54
+ "valid": true,
55
+ "errors": [],
56
+ "warnings": []
57
+ }
58
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "description": "trailingArmProfitPct without trailingStopPct does nothing.",
3
+ "document": {
4
+ "contractVersion": "0.2",
5
+ "kind": "artifact",
6
+ "title": "EMA 20/60 crossover",
7
+ "note": "The smallest useful artifact: two indicators, one entry, one exit, a fixed symbol list.",
8
+ "market": "us_equity",
9
+ "timeframe": "1d",
10
+ "dsl": {
11
+ "version": 1,
12
+ "indicators": {
13
+ "fast": {
14
+ "type": "EMA",
15
+ "period": 20
16
+ },
17
+ "slow": {
18
+ "type": "EMA",
19
+ "period": 60
20
+ }
21
+ },
22
+ "entry": {
23
+ "type": "CROSS_UP",
24
+ "left": {
25
+ "ind": "fast"
26
+ },
27
+ "right": {
28
+ "ind": "slow"
29
+ }
30
+ },
31
+ "exit": {
32
+ "type": "CROSS_DOWN",
33
+ "left": {
34
+ "ind": "fast"
35
+ },
36
+ "right": {
37
+ "ind": "slow"
38
+ }
39
+ }
40
+ },
41
+ "universe": {
42
+ "mode": "SYMBOLS",
43
+ "symbols": [
44
+ "AAPL",
45
+ "MSFT",
46
+ "NVDA"
47
+ ]
48
+ },
49
+ "riskProfile": {
50
+ "maxSymbolExposurePct": 20,
51
+ "maxTotalExposurePct": 60
52
+ },
53
+ "producer": {
54
+ "kind": "HUMAN",
55
+ "name": "example"
56
+ },
57
+ "exits": {
58
+ "stopLossPct": 8,
59
+ "trailingArmProfitPct": 5
60
+ }
61
+ },
62
+ "expect": {
63
+ "valid": true,
64
+ "errors": [],
65
+ "warnings": [
66
+ "AS016"
67
+ ]
68
+ }
69
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "description": "20% per entry against a 20% cap is fine; 30% is cut to 20% on every entry.",
3
+ "document": {
4
+ "contractVersion": "0.2",
5
+ "kind": "artifact",
6
+ "title": "EMA 20/60 crossover",
7
+ "note": "The smallest useful artifact: two indicators, one entry, one exit, a fixed symbol list.",
8
+ "market": "us_equity",
9
+ "timeframe": "1d",
10
+ "dsl": {
11
+ "version": 1,
12
+ "indicators": {
13
+ "fast": {
14
+ "type": "EMA",
15
+ "period": 20
16
+ },
17
+ "slow": {
18
+ "type": "EMA",
19
+ "period": 60
20
+ }
21
+ },
22
+ "entry": {
23
+ "type": "CROSS_UP",
24
+ "left": {
25
+ "ind": "fast"
26
+ },
27
+ "right": {
28
+ "ind": "slow"
29
+ }
30
+ },
31
+ "exit": {
32
+ "type": "CROSS_DOWN",
33
+ "left": {
34
+ "ind": "fast"
35
+ },
36
+ "right": {
37
+ "ind": "slow"
38
+ }
39
+ }
40
+ },
41
+ "universe": {
42
+ "mode": "SYMBOLS",
43
+ "symbols": [
44
+ "AAPL",
45
+ "MSFT",
46
+ "NVDA"
47
+ ]
48
+ },
49
+ "riskProfile": {
50
+ "maxSymbolExposurePct": 20,
51
+ "maxTotalExposurePct": 60
52
+ },
53
+ "producer": {
54
+ "kind": "HUMAN",
55
+ "name": "example"
56
+ },
57
+ "sizing": {
58
+ "targetPctPerOrder": 30
59
+ }
60
+ },
61
+ "expect": {
62
+ "valid": true,
63
+ "errors": [],
64
+ "warnings": [
65
+ "AS017"
66
+ ]
67
+ }
68
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "description": "Under ATR_RISK, targetPctPerOrder is a risk budget, not a position size, so it is not compared with the per-symbol cap.",
3
+ "document": {
4
+ "contractVersion": "0.2",
5
+ "kind": "artifact",
6
+ "title": "EMA 20/60 crossover",
7
+ "note": "The smallest useful artifact: two indicators, one entry, one exit, a fixed symbol list.",
8
+ "market": "us_equity",
9
+ "timeframe": "1d",
10
+ "dsl": {
11
+ "version": 1,
12
+ "indicators": {
13
+ "fast": {
14
+ "type": "EMA",
15
+ "period": 20
16
+ },
17
+ "slow": {
18
+ "type": "EMA",
19
+ "period": 60
20
+ }
21
+ },
22
+ "entry": {
23
+ "type": "CROSS_UP",
24
+ "left": {
25
+ "ind": "fast"
26
+ },
27
+ "right": {
28
+ "ind": "slow"
29
+ }
30
+ },
31
+ "exit": {
32
+ "type": "CROSS_DOWN",
33
+ "left": {
34
+ "ind": "fast"
35
+ },
36
+ "right": {
37
+ "ind": "slow"
38
+ }
39
+ }
40
+ },
41
+ "universe": {
42
+ "mode": "SYMBOLS",
43
+ "symbols": [
44
+ "AAPL",
45
+ "MSFT",
46
+ "NVDA"
47
+ ]
48
+ },
49
+ "riskProfile": {
50
+ "maxSymbolExposurePct": 20,
51
+ "maxTotalExposurePct": 60
52
+ },
53
+ "producer": {
54
+ "kind": "HUMAN",
55
+ "name": "example"
56
+ },
57
+ "sizing": {
58
+ "positionMode": "ATR_RISK",
59
+ "targetPctPerOrder": 30
60
+ }
61
+ },
62
+ "expect": {
63
+ "valid": true,
64
+ "errors": [],
65
+ "warnings": []
66
+ }
67
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "description": "10% entries with a 15% pyramiding cap: the first add-on would take the symbol to 20%, so no add-on ever happens.",
3
+ "document": {
4
+ "contractVersion": "0.2",
5
+ "kind": "artifact",
6
+ "title": "EMA 20/60 crossover",
7
+ "note": "The smallest useful artifact: two indicators, one entry, one exit, a fixed symbol list.",
8
+ "market": "us_equity",
9
+ "timeframe": "1d",
10
+ "dsl": {
11
+ "version": 1,
12
+ "indicators": {
13
+ "fast": {
14
+ "type": "EMA",
15
+ "period": 20
16
+ },
17
+ "slow": {
18
+ "type": "EMA",
19
+ "period": 60
20
+ }
21
+ },
22
+ "entry": {
23
+ "type": "CROSS_UP",
24
+ "left": {
25
+ "ind": "fast"
26
+ },
27
+ "right": {
28
+ "ind": "slow"
29
+ }
30
+ },
31
+ "exit": {
32
+ "type": "CROSS_DOWN",
33
+ "left": {
34
+ "ind": "fast"
35
+ },
36
+ "right": {
37
+ "ind": "slow"
38
+ }
39
+ }
40
+ },
41
+ "universe": {
42
+ "mode": "SYMBOLS",
43
+ "symbols": [
44
+ "AAPL",
45
+ "MSFT",
46
+ "NVDA"
47
+ ]
48
+ },
49
+ "riskProfile": {
50
+ "maxSymbolExposurePct": 20,
51
+ "maxTotalExposurePct": 60
52
+ },
53
+ "producer": {
54
+ "kind": "HUMAN",
55
+ "name": "example"
56
+ },
57
+ "sizing": {
58
+ "targetPctPerOrder": 10,
59
+ "scaleIn": {
60
+ "maxAddOns": 3,
61
+ "spacingAtr": 1,
62
+ "maxTotalPct": 15
63
+ }
64
+ }
65
+ },
66
+ "expect": {
67
+ "valid": true,
68
+ "errors": [],
69
+ "warnings": [
70
+ "AS018"
71
+ ]
72
+ }
73
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "description": "0 is not 'off': omit the field to leave an exit off. A 0 stop loss would read as 'stop immediately' to one runtime and 'disabled' to another.",
3
+ "document": {
4
+ "contractVersion": "0.2",
5
+ "kind": "artifact",
6
+ "title": "EMA 20/60 crossover",
7
+ "note": "The smallest useful artifact: two indicators, one entry, one exit, a fixed symbol list.",
8
+ "market": "us_equity",
9
+ "timeframe": "1d",
10
+ "dsl": {
11
+ "version": 1,
12
+ "indicators": {
13
+ "fast": {
14
+ "type": "EMA",
15
+ "period": 20
16
+ },
17
+ "slow": {
18
+ "type": "EMA",
19
+ "period": 60
20
+ }
21
+ },
22
+ "entry": {
23
+ "type": "CROSS_UP",
24
+ "left": {
25
+ "ind": "fast"
26
+ },
27
+ "right": {
28
+ "ind": "slow"
29
+ }
30
+ },
31
+ "exit": {
32
+ "type": "CROSS_DOWN",
33
+ "left": {
34
+ "ind": "fast"
35
+ },
36
+ "right": {
37
+ "ind": "slow"
38
+ }
39
+ }
40
+ },
41
+ "universe": {
42
+ "mode": "SYMBOLS",
43
+ "symbols": [
44
+ "AAPL",
45
+ "MSFT",
46
+ "NVDA"
47
+ ]
48
+ },
49
+ "riskProfile": {
50
+ "maxSymbolExposurePct": 20,
51
+ "maxTotalExposurePct": 60
52
+ },
53
+ "producer": {
54
+ "kind": "HUMAN",
55
+ "name": "example"
56
+ },
57
+ "exits": {
58
+ "stopLossPct": 0
59
+ }
60
+ },
61
+ "expect": {
62
+ "valid": false,
63
+ "errors": [
64
+ "SCHEMA"
65
+ ],
66
+ "warnings": []
67
+ }
68
+ }