create-tradejs 3.1.22 → 3.1.23-beta.239
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.
- package/README.md +19 -3
- package/dist/index.js +36 -5
- package/dist/skill-bundle/.codex/skills/ai-train-local-research/SKILL.md +596 -0
- package/dist/skill-bundle/.codex/skills/ai-train-local-research/references/gate-ablation.md +324 -0
- package/dist/skill-bundle/.codex/skills/ai-train-local-research/references/reporting.md +227 -0
- package/dist/skill-bundle/.codex/skills/ai-train-local-research/scripts/ai-gate-ablation.mjs +5082 -0
- package/dist/skill-bundle/.codex/skills/ai-train-local-research/scripts/ai-gate-ablation.test.mjs +1170 -0
- package/dist/skill-bundle/.codex/skills/backtest-config-redis/SKILL.md +17 -0
- package/dist/skill-bundle/.codex/skills/backtest-config-redis/scripts/get_backtest_config.sh +21 -0
- package/dist/skill-bundle/.codex/skills/runtime-parity-mismatch-analysis/SKILL.md +146 -0
- package/dist/skill-bundle/.codex/skills/save-strategy-config-from-backtest/SKILL.md +58 -0
- package/dist/skill-bundle/.codex/skills/save-strategy-config-from-backtest/agents/openai.yaml +4 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/SKILL.md +334 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/references/research-notes.md +247 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/backtest-run-metrics.mjs +647 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/backtest-run-metrics.test.mjs +321 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/fast-ai-export-metrics.mjs +744 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/fast-ai-export-metrics.test.mjs +553 -0
- package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/research-notes-check.mjs +125 -0
- package/dist/skill-bundle/.codex/skills/strategy-improvement-research/SKILL.md +18 -1
- package/dist/skill-bundle/.codex/skills/strategy-release/SKILL.md +22 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/agents/openai.yaml +4 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/diagnose-live.md +126 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/direction-policy.md +141 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/directional-parameter-split.md +93 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/evidence-limitations.md +76 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/evidence-retention.md +157 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/historical-hypothesis-audit.md +163 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/professional-research-loop.md +198 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/release-workflow.md +755 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/research-objective.md +255 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/references/verdict-contract.md +200 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/scripts/direction-policy-checkpoint.mjs +137 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/scripts/direction-policy-checkpoint.test.mjs +85 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/scripts/directional-parameter-checkpoint.mjs +149 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/scripts/directional-parameter-checkpoint.test.mjs +120 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/scripts/release-progress-checkpoint.mjs +621 -0
- package/dist/skill-bundle/.codex/skills/strategy-release/scripts/release-progress-checkpoint.test.mjs +349 -0
- package/dist/skill-bundle/.codex/tradejs-skill-bundle.json +44 -3
- package/package.json +1 -1
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-train-local-research
|
|
3
|
+
description: Execute deterministic AI-gate research for a frozen TradeJS core/export with ai-train, ai-pocket-search, and the reusable gate-ablation tool. Use strategy-improvement-research instead to choose or retune core candidates and orchestrate the full improvement lineage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AI Train Local Research
|
|
7
|
+
|
|
8
|
+
Run these commands with `PROJECT_CWD` pointing to `TradeJS-Project`, which owns
|
|
9
|
+
`data/`, `notes/`, `.env`, and `tradejs.config.ts`. Set
|
|
10
|
+
`TRADEJS_SOURCE_REPOSITORY_ROOT` to the exact framework or standalone strategy
|
|
11
|
+
Git checkout whose build and lineage are under study. When that source is a
|
|
12
|
+
standalone strategy, also set `TRADEJS_FRAMEWORK_REPOSITORY_ROOT` to the exact
|
|
13
|
+
framework checkout that provides the built `@tradejs/node` and `@tradejs/cli`
|
|
14
|
+
research runtime. Never infer either source root from `PROJECT_CWD`.
|
|
15
|
+
|
|
16
|
+
This is a gate-stage specialist. It does not select core hypothesis families,
|
|
17
|
+
run multi-round core tuning, or replace the raw-core verdict. Use
|
|
18
|
+
`$strategy-improvement-research` for the complete lineage; invoke this skill
|
|
19
|
+
only after the core/export identity is frozen.
|
|
20
|
+
|
|
21
|
+
Use this skill when the user asks to:
|
|
22
|
+
|
|
23
|
+
- run `ai-train` for a strategy
|
|
24
|
+
- run `ai-pocket-search` over AI export files
|
|
25
|
+
- research or tune a local deterministic AI gate
|
|
26
|
+
- analyze `latest N` or `skip K`
|
|
27
|
+
- do the replay without OpenRouter
|
|
28
|
+
- inspect qN+ approval streams, drawdown, winrate, profit factor, or cadence
|
|
29
|
+
- check time stability, symbol concentration, or direction-specific pockets
|
|
30
|
+
- compare current results with previous TrendLine / ReverseTrendLine style investigations
|
|
31
|
+
- break down false positives / false negatives
|
|
32
|
+
- save each conclusion in a new
|
|
33
|
+
`$PROJECT_CWD/notes/<Strategy>/YYYY-MM-DD-<short-kebab-slug>.md` research record
|
|
34
|
+
- tune approval cadence toward roughly 2-3 approved trades per day when possible, with ~1 approved trade per day as the practical lower bound for narrow high-quality pockets; if a gate approves more, look for filters that lower approvals and raise winrate
|
|
35
|
+
|
|
36
|
+
## Reusable Research Tooling
|
|
37
|
+
|
|
38
|
+
When AI-gate work follows a raw-core experiment, first read the verified
|
|
39
|
+
`data/research/core/<researchId>/spec.json`, `result.json`, and normalized
|
|
40
|
+
`trades.jsonl` produced by `yarn research:core`. Treat that bundle as the
|
|
41
|
+
immutable source for raw-core ALL/LONG/SHORT economics, selected config lineage,
|
|
42
|
+
and causal setup attribution. Do not rerun core selection inside gate tooling or
|
|
43
|
+
rewrite its target/aggregate verdict. The gate study is a new hypothesis stage:
|
|
44
|
+
evaluate LONG and SHORT approved streams separately, preserve the core bundle
|
|
45
|
+
research ID/config SHA/export lineage in the gate note, and make any
|
|
46
|
+
direction-aware gate explicit. A weak raw-core side may be filtered by a later
|
|
47
|
+
gate only after its own timestamp-grouped validation; never hide or retroactively
|
|
48
|
+
disable it in the core result.
|
|
49
|
+
|
|
50
|
+
Use `scripts/ai-gate-ablation.mjs` for custom deterministic gate filters,
|
|
51
|
+
exclusions, recovery additions, gate replacements, feature inventory, and
|
|
52
|
+
baseline-vs-candidate tables. Read `references/gate-ablation.md` for its
|
|
53
|
+
expression grammar and report contract.
|
|
54
|
+
|
|
55
|
+
Mandatory rule:
|
|
56
|
+
|
|
57
|
+
- Do not create `/tmp` parsers, heredoc ESM replays, or strategy-specific
|
|
58
|
+
one-off scripts for work covered by this tool.
|
|
59
|
+
- If a recurring analysis is missing, extend the permanent script, add or update
|
|
60
|
+
`scripts/ai-gate-ablation.test.mjs`, and document the behavior in the
|
|
61
|
+
reference. Run `node --test scripts/ai-gate-ablation.test.mjs` from the skill
|
|
62
|
+
directory.
|
|
63
|
+
- Build changed strategy/node/CLI packages before running the tool because it
|
|
64
|
+
reconstructs current gate context from `dist`.
|
|
65
|
+
- Keep `yarn ai-train --localOnly --json -n 0` as the authoritative baseline;
|
|
66
|
+
do not interpret variants until baseline qN+ support, PnL, PF, max drawdown,
|
|
67
|
+
strict loss, and loss streak match.
|
|
68
|
+
|
|
69
|
+
## Mandatory reporting contract
|
|
70
|
+
|
|
71
|
+
Before returning AI-gate metrics in chat or writing a dated notes entry, read
|
|
72
|
+
`references/reporting.md` and follow its section order, metric names, windows,
|
|
73
|
+
rounding, and `n/a` rules exactly. Use the full contract unless the user
|
|
74
|
+
explicitly asks for one narrow metric. Do not improvise a shorter alternative
|
|
75
|
+
or silently omit unavailable metrics.
|
|
76
|
+
|
|
77
|
+
For every approved-stream summary, calculate `PnL/trade` as total approved PnL
|
|
78
|
+
divided by completed approved trades. Never substitute the backtest CLI progress
|
|
79
|
+
`avg`, which is PnL per completed test/symbol. Use `n/a` when `N = 0`.
|
|
80
|
+
|
|
81
|
+
## AI Gate Pocket Hygiene
|
|
82
|
+
|
|
83
|
+
Do not move a discovered pocket into a deterministic AI gate just because it
|
|
84
|
+
improves aggregate backtest PnL. Treat every candidate rule as overfit until it
|
|
85
|
+
survives the checks below.
|
|
86
|
+
|
|
87
|
+
Hard rule:
|
|
88
|
+
|
|
89
|
+
- Do not use data-availability or sample-count fields as approval evidence.
|
|
90
|
+
Examples include derivatives `points`, `rows`, `latestIndex`, source array
|
|
91
|
+
`.length`, coverage counts, shard counts, or "how much context was loaded".
|
|
92
|
+
These may be used only as data-quality guards that block or mark data as
|
|
93
|
+
missing/stale; they must not promote quality or unlock approval pockets.
|
|
94
|
+
- Event counts that are genuine market structure features, such as trendline
|
|
95
|
+
touches, zone `hitCount`, bars since a detected setup, or pivot counts, are
|
|
96
|
+
allowed only when they measure the setup itself and are causal at signal time.
|
|
97
|
+
Do not confuse them with "number of rows available in the dataset".
|
|
98
|
+
- Do not reject `baseContext.derivatives.intervals` as an AI-gate input only
|
|
99
|
+
because the historical export has partial coverage. In TradeJS exports these
|
|
100
|
+
target derivative interval fields may be unavailable for older history and
|
|
101
|
+
cannot always be backfilled to a longer period, but they are causal live
|
|
102
|
+
market-state fields when present and may be used for deterministic AI-gate
|
|
103
|
+
approval after validation. Treat missing/stale interval data as a quality
|
|
104
|
+
guard, not as approval evidence.
|
|
105
|
+
- Treat independent decision timestamps or documented market episodes as the
|
|
106
|
+
support unit for gate selection. Rows and symbols sharing one timestamp are
|
|
107
|
+
correlated fan-out, not independent observations.
|
|
108
|
+
- Keep every timestamp group wholly inside one partition. Never split rows from
|
|
109
|
+
the same timestamp across train, tuning, validation, or test.
|
|
110
|
+
- Treat any partition used to rank, select, or refine a pocket as tuning data.
|
|
111
|
+
Production readiness requires a later untouched chronological test.
|
|
112
|
+
|
|
113
|
+
Before implementing a pocket:
|
|
114
|
+
|
|
115
|
+
- Audit existing gate conditions before proposing new ones. Inventory current
|
|
116
|
+
approval, downgrade, recovery, and block pockets in the strategy adapter /
|
|
117
|
+
guardrails, including constants, high-precision thresholds, env-sensitive
|
|
118
|
+
fields, and data-count fields.
|
|
119
|
+
- Revalidate old pockets under the same export, live env assumptions, and metric
|
|
120
|
+
table used for any new candidate. Do not assume existing gate rules are still
|
|
121
|
+
valid after data provider, context, lookback, interval, target/reference, or
|
|
122
|
+
adapter changes.
|
|
123
|
+
- For each existing pocket, classify it as `keep`, `round`, `replace`,
|
|
124
|
+
`disable`, or `needs-more-data`, and explain why.
|
|
125
|
+
- Require time-ordered validation, not only full-sample or train metrics.
|
|
126
|
+
- Require at least `25` independent approved events in train and `25` in the
|
|
127
|
+
untouched test, with support across at least two folds or calendar months.
|
|
128
|
+
If support is lower, classify the pocket as `needs-more-data` and
|
|
129
|
+
`research-only` / passive-only regardless of row count or aggregate PnL.
|
|
130
|
+
- Check stability by direction, month/quarter, and symbol. Avoid rules where the
|
|
131
|
+
result depends on one short period, one side, or a few symbols.
|
|
132
|
+
- Record each pocket field's scope as `target`, `benchmark`, or `global`.
|
|
133
|
+
Benchmark/global approval pockets require a fan-out stress test plus either a
|
|
134
|
+
target-specific discriminator or an enforced portfolio throttle.
|
|
135
|
+
- Treat a new export as revalidation only for independent timestamps after the
|
|
136
|
+
prior selection cutoff. Overlapping historical rows are not new evidence.
|
|
137
|
+
- Compare q4+ and q5+ streams before and after the rule. A pocket that improves
|
|
138
|
+
total PnL but worsens drawdown, loss streak, or losing months usually should
|
|
139
|
+
not become live approval logic.
|
|
140
|
+
- Run an ablation: show the baseline gate, the new pocket alone, and the final
|
|
141
|
+
gate with the pocket included.
|
|
142
|
+
- Run threshold sensitivity around each numeric cutoff. Test adjacent rounded
|
|
143
|
+
values and a small band around the discovered value; prefer rules that remain
|
|
144
|
+
useful after rounding.
|
|
145
|
+
|
|
146
|
+
Threshold implementation rules:
|
|
147
|
+
|
|
148
|
+
- Do not paste high-precision search cutoffs directly into gate code unless
|
|
149
|
+
there is a strong documented reason. Values like `0.416874`, `-0.00904779`,
|
|
150
|
+
`4.6069`, or `-0.5906` should be treated as search artifacts first.
|
|
151
|
+
- Convert discovered thresholds to coarser, defensible boundaries before
|
|
152
|
+
implementation, then rerun replay metrics. Examples: use human-scale values
|
|
153
|
+
such as `0.42`, `-0.01`, `4.7`, `-0.6`, or a clearly named domain threshold
|
|
154
|
+
instead of copying the exact optimizer boundary.
|
|
155
|
+
- Round approval thresholds in the stricter direction by default so rounding
|
|
156
|
+
does not silently expand the approved set. For `>=` approval cutoffs, round
|
|
157
|
+
upward; for `<=` approval cutoffs, round downward. If a relaxed rounded value
|
|
158
|
+
is desired, validate it explicitly as a separate candidate.
|
|
159
|
+
- If rounding materially changes cadence, PF, drawdown, or month stability, do
|
|
160
|
+
not implement the pocket until a stable rounded threshold is found.
|
|
161
|
+
- Name constants by their market meaning and validation scope, not by the search
|
|
162
|
+
output. Good names mention the feature, direction, and intent, for example
|
|
163
|
+
`SHORT_BREADTH_SHOCK_MARKET_RETURN_MAX`.
|
|
164
|
+
|
|
165
|
+
Documentation requirement for any new AI-gate pocket:
|
|
166
|
+
|
|
167
|
+
- Report the exact export/merge id and shard count.
|
|
168
|
+
- Report train, tuning, and untouched-test metrics; independent-event support;
|
|
169
|
+
direction and month/quarter splits; symbol and event concentration; PF;
|
|
170
|
+
drawdown; and max loss streak.
|
|
171
|
+
- Report trades and events per day, active-day ratio, trades per event, p95/max
|
|
172
|
+
batch size, and the largest event's shares of approved count and PnL.
|
|
173
|
+
- Report capacity stress at the real production cap or, when unknown, at
|
|
174
|
+
capacities `1`, `3`, and `5`, including rejected overflow. Calculate
|
|
175
|
+
simultaneous stop-risk only from the historical effective `MAX_LOSS_VALUE`
|
|
176
|
+
used by the backtest that produced the export. Prefer an immutable resolved
|
|
177
|
+
config snapshot or archived backtest checkpoint referenced by
|
|
178
|
+
`backtestRunId`/`backtestTestKey`. Do not substitute the current named Redis
|
|
179
|
+
config, a current strategy default, or a production value unless lineage
|
|
180
|
+
proves it matches the export. When the historical value cannot be recovered,
|
|
181
|
+
report stop-risk as `unknown`/`n/a`.
|
|
182
|
+
- State the raw discovered threshold and the rounded implemented threshold.
|
|
183
|
+
- State whether the rounded rule was rerun and whether it stayed stable.
|
|
184
|
+
- If the rule uses a context field whose semantics can change with env settings
|
|
185
|
+
such as lookback, interval list, target/reference mode, or data provider, call
|
|
186
|
+
that out explicitly and avoid using the field for approval unless the rule is
|
|
187
|
+
validated under the intended live env.
|
|
188
|
+
|
|
189
|
+
Documentation requirement for existing AI-gate pockets:
|
|
190
|
+
|
|
191
|
+
- Include an "Existing Gate Audit" section in the report or notes whenever gate
|
|
192
|
+
tuning is requested.
|
|
193
|
+
- List each existing pocket or threshold group with file/line references where
|
|
194
|
+
practical.
|
|
195
|
+
- For every old high-precision threshold, state whether it should stay exact,
|
|
196
|
+
be rounded and rerun, or be removed.
|
|
197
|
+
- For every old data-count or env-sensitive condition, state whether it is only
|
|
198
|
+
a data-quality guard or whether it currently affects approval. If it affects
|
|
199
|
+
approval, recommend replacing it with market-state features unless validation
|
|
200
|
+
proves it is stable under the intended live env.
|
|
201
|
+
- If old rules are not revalidated, mark the final recommendation as incomplete
|
|
202
|
+
and do not present new pockets as production-ready.
|
|
203
|
+
|
|
204
|
+
Suggested old-gate audit commands:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
rg -n "pocket|calibrated|q4|q5|recovery|approvalAllowedNow|deterministicQuality|hardBlockReasons|softBlockReasons|[0-9]+\\.[0-9]{3,}|\\.points|\\.length" packages/strategies/src/<Strategy>
|
|
208
|
+
rg -n "DERIVATIVES_CONTEXT|targetContext|targetDerived|referenceContexts|points|rows|lookback|intervals" packages/strategies/src/<Strategy> packages/core/src packages/node/src
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Mandatory validation sections for gate work:
|
|
212
|
+
|
|
213
|
+
- **Live-env parity**: record the intended live env and compare it with the
|
|
214
|
+
export/replay assumptions. Include at least `AI_MODE`, `MIN_AI_QUALITY`,
|
|
215
|
+
interval/timeframe, strategy config name, derivatives lookback/intervals/
|
|
216
|
+
target mode, CMC windows, and any provider/context toggles that can affect
|
|
217
|
+
gate fields. If parity is unknown, mark the recommendation as not ready for
|
|
218
|
+
production.
|
|
219
|
+
- **Feature provenance**: for every field used by an old or new pocket, list
|
|
220
|
+
the source path, whether it is causal at signal time, whether it is
|
|
221
|
+
market-state, setup-event-count, or data-availability, whether its scope is
|
|
222
|
+
target/benchmark/global, and whether it depends on
|
|
223
|
+
lookback/window/cache/provider settings.
|
|
224
|
+
- **Walk-forward validation**: when the export spans enough history, validate
|
|
225
|
+
across multiple chronological folds or at least month/quarter buckets. Prefer
|
|
226
|
+
pockets that survive changing market regimes over pockets that win only in a
|
|
227
|
+
single terminal validation split.
|
|
228
|
+
- **Acceptance gates**: define minimum validation support, maximum symbol
|
|
229
|
+
and event concentration, acceptable losing months, max loss streak,
|
|
230
|
+
PF/drawdown improvement, and cadence/capacity bounds before recommending
|
|
231
|
+
implementation. Require `>=25` independent events in both train and untouched
|
|
232
|
+
test; no symbol or timestamp may provide more than one third of approved count
|
|
233
|
+
or PnL; no batch may exceed the declared live capacity; no new losing-month
|
|
234
|
+
cluster or worse loss streak is allowed. A miss is unconditionally
|
|
235
|
+
`research-only` / passive-only until new evidence resolves it.
|
|
236
|
+
- **Negative control**: for suspiciously strong or highly specific pockets, run
|
|
237
|
+
a sanity check such as shuffled labels/profits or a nearby nonsense feature.
|
|
238
|
+
A pocket that still looks good under a negative control is overfit or the
|
|
239
|
+
script is wrong.
|
|
240
|
+
- **Boundary tests**: require unit tests for implemented gate changes at the
|
|
241
|
+
threshold boundary, just above/below it, with missing/null fields, and with
|
|
242
|
+
rounded thresholds rather than raw optimizer cutoffs.
|
|
243
|
+
- **Passive rollout**: add new or changed gate logic in observation mode first.
|
|
244
|
+
Log old decision, new decision, reason deltas, and per-timestamp fan-out. Do
|
|
245
|
+
not present or enforce a candidate that fails independent-event support or
|
|
246
|
+
capacity gates as historically production-ready. The sole exception is an
|
|
247
|
+
operator-directed prospective test explicitly authorized through
|
|
248
|
+
`$strategy-forward-start` for one checksum-reproducible candidate at
|
|
249
|
+
`MAX_LOSS_VALUE=1`; keep its classification `research-only`, retain contrary
|
|
250
|
+
evidence, and let that skill enforce the immutable target, package, runtime,
|
|
251
|
+
and rollback boundaries.
|
|
252
|
+
- **Old-gate cleanup**: when an old pocket is replaced or disabled, remove dead
|
|
253
|
+
constants/prompt fields/tests, update notes, and explain the migration path.
|
|
254
|
+
|
|
255
|
+
## Workflow
|
|
256
|
+
|
|
257
|
+
1. Confirm the latest merged dataset exists.
|
|
258
|
+
|
|
259
|
+
Use the shard-aware permanent discovery command:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
node .codex/skills/ai-train-local-research/scripts/ai-gate-ablation.mjs --list --strategy <Strategy>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Important shard-aware rule:
|
|
266
|
+
|
|
267
|
+
- merged exports may now be split into `-part1 ... -partN` files
|
|
268
|
+
- treat all files with the same `strategy token + merge id` as one logical export
|
|
269
|
+
- do not assume the latest export is a single `...-merged-<ts>.jsonl` file
|
|
270
|
+
- `yarn ai-train` already groups matching part files automatically when:
|
|
271
|
+
- no explicit `--file` is given and it selects the latest merge id
|
|
272
|
+
- or `--file` points to any one shard like `...-part1.jsonl`
|
|
273
|
+
- `yarn ai-pocket-search` follows the same shard grouping convention and treats a `--file ...-part1.jsonl` argument as the whole merge group
|
|
274
|
+
- when reporting the export used, list the merge id and shard count, not only the first shard path
|
|
275
|
+
|
|
276
|
+
2. If the user wants config analysis, read the real Redis config instead of guessing from defaults.
|
|
277
|
+
|
|
278
|
+
Use:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
docker exec inv-redis redis-cli JSON.GET users:root:backtests:configs:<Strategy>:ai
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
3. Decide replay mode.
|
|
285
|
+
|
|
286
|
+
- If the user explicitly says `without OpenRouter`, use `--localOnly`.
|
|
287
|
+
- If the goal is deterministic gate research, also prefer `--localOnly`.
|
|
288
|
+
- If the user explicitly wants model behavior, run normal `ai-train` with the default GPT-5 Mini model unless they name another model.
|
|
289
|
+
- Interpret replay mode against runtime `AI_MODE` explicitly:
|
|
290
|
+
- `yarn ai-train --localOnly` matches `AI_MODE=gate` behavior for approval logic, because both use the local deterministic strategy AI gate and the same `MIN_AI_QUALITY` threshold.
|
|
291
|
+
- normal `yarn ai-train` is the closer proxy for `AI_MODE=llm`, because approval depends on provider/model output instead of only the local deterministic gate.
|
|
292
|
+
- do not describe `--localOnly` findings as expected `AI_MODE=llm` production behavior.
|
|
293
|
+
|
|
294
|
+
4. Run the replay.
|
|
295
|
+
|
|
296
|
+
Examples:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
yarn ai-train --strategy TrendLine -n 500 --localOnly
|
|
300
|
+
yarn ai-train --strategy ReverseTrendLine -n 500 --localOnly
|
|
301
|
+
yarn ai-train --strategy VolumeDivergence -n 500 --localOnly
|
|
302
|
+
yarn ai-train --strategy TrendLine -n 0 --localOnly --terminalWindows=180,90,30,7 --output data/ai/output/trendline-ai-train.json
|
|
303
|
+
yarn ai-pocket-search --strategy TrendLine -n 0 --maxDepth 2 --minSupport 25
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Freshness and terminal-window gate
|
|
307
|
+
|
|
308
|
+
For any current/live cadence conclusion, run all selected rows so one execution
|
|
309
|
+
produces the full result and terminal summaries:
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
yarn ai-train --strategy <Strategy> -n 0 --localOnly --terminalWindows=180,90,30,7
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Terminal windows are anchored to the maximum dataset timestamp. Whenever a
|
|
316
|
+
period comparison table is shown, it must include the full export plus `180d`,
|
|
317
|
+
`90d`, `30d`, and `7d`, including windows with zero approvals. Use
|
|
318
|
+
`--terminalWindows=180,90,30,11,7` when the production comparison additionally
|
|
319
|
+
uses an 11-day window. Do not run the provider repeatedly for these windows;
|
|
320
|
+
the command derives them from the same evaluated rows. If the export is shorter
|
|
321
|
+
than 180 days, keep the `180d` row and mark it as incomplete/overlapping the
|
|
322
|
+
available full export rather than silently omitting it.
|
|
323
|
+
|
|
324
|
+
Before stating expected production cadence:
|
|
325
|
+
|
|
326
|
+
- record dataset min/max timestamps and `dataLagDays`
|
|
327
|
+
- require the export to overlap the production window under discussion
|
|
328
|
+
- report full history and every terminal window, including zero approvals
|
|
329
|
+
- period tables must always show rows for the full export, `180d`, `90d`,
|
|
330
|
+
`30d`, and `7d`
|
|
331
|
+
- when comparing a new candidate/gate with a baseline or previous result, show
|
|
332
|
+
terminal-window metrics as a comparison table for every row (`full`, `180d`,
|
|
333
|
+
`90d`, `30d`, `7d`) rather than only the candidate values. Include baseline
|
|
334
|
+
and candidate N, WR, PF, PnL, Max DD, max loss streak, losing months, and
|
|
335
|
+
trades/day
|
|
336
|
+
- for the same terminal rows, include events/day, active-day ratio, unique
|
|
337
|
+
events, trades/event, p95/max batch, and largest-event count/PnL shares
|
|
338
|
+
- use terminal `approvedPerCalendarDay`, not the full-history average, as the
|
|
339
|
+
current cadence evidence
|
|
340
|
+
- record git SHA, dirty state, gate fingerprint, config-id fingerprint, and
|
|
341
|
+
context fingerprint from the report
|
|
342
|
+
- compare runtime only when gate/config/context lineage and `MIN_AI_QUALITY`
|
|
343
|
+
match; otherwise label it a different experiment
|
|
344
|
+
- inspect terminal top reject reasons before changing a threshold
|
|
345
|
+
- if the export tail is stale, report current live cadence as unknown and build
|
|
346
|
+
a fresh export
|
|
347
|
+
|
|
348
|
+
Context semantics rule:
|
|
349
|
+
|
|
350
|
+
- top-level derivatives fields are BTC benchmark context
|
|
351
|
+
- `targetContext` / `targetDerived` are target-symbol context
|
|
352
|
+
- when `DERIVATIVES_CONTEXT_TARGET_ENABLED=false`, target fields must be absent;
|
|
353
|
+
downloaded target rows or membership in extra reference symbols may expose the
|
|
354
|
+
symbol only through `referenceContexts`
|
|
355
|
+
- do not rename benchmark evidence as target evidence in reports
|
|
356
|
+
- do not switch an existing gate from benchmark to target behavior without a
|
|
357
|
+
new export, terminal validation, and updated notes
|
|
358
|
+
|
|
359
|
+
After any gate-code change, rerun the command and create a new research file at
|
|
360
|
+
`notes/<Strategy>/YYYY-MM-DD-<short-kebab-slug>.md`. Never append the run to an
|
|
361
|
+
older research file. Metrics from an older gate fingerprint are historical
|
|
362
|
+
context only.
|
|
363
|
+
|
|
364
|
+
Shard-aware examples:
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
yarn ai-train --strategy TrendShift --localOnly --json -n 0
|
|
368
|
+
yarn ai-train --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl --localOnly --json -n 0
|
|
369
|
+
yarn ai-train --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl --localOnly --json -n 0 --dumpEvaluations /tmp/trendshift-evals.jsonl
|
|
370
|
+
yarn ai-train --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl --localOnly --json -n 0 --dumpEvaluations /tmp/trendshift-evals.jsonl --dumpFeatures gateFeatures
|
|
371
|
+
yarn ai-pocket-search --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl -n 0 --maxDepth 2 --minSupport 25
|
|
372
|
+
yarn ai-pocket-search --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl -n 0 --scope approved --maxDepth 2 --minSupport 5
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Interpretation:
|
|
376
|
+
|
|
377
|
+
- both commands above should evaluate the full shard group for that merge id, not only `part1`
|
|
378
|
+
- if a partial replay is genuinely needed, use native `ai-train` selection
|
|
379
|
+
options rather than assuming one shard equals one isolated window
|
|
380
|
+
- `yarn ai-train --localOnly --json` is the baseline source of truth for current deterministic gate metrics
|
|
381
|
+
- Release evidence with an explicit one-side gate must pass
|
|
382
|
+
`--directionPolicy long_only|short_only`. This flag is evidence metadata, not
|
|
383
|
+
a filter: `ai-train` rejects the report unless the actual evaluated gate has
|
|
384
|
+
zero approved rows for the suppressed direction in full and terminal
|
|
385
|
+
windows. Use `both` (default) or `direction_aware` for policies that retain
|
|
386
|
+
both approved sides.
|
|
387
|
+
- `yarn ai-pocket-search` is the default pocket discovery tool for future AI-gate rules. It reconstructs current strategy AI payloads, excludes outcome/current gate-output fields by default, shows progress bars, deduplicates equivalent row-selection pockets, and writes a Markdown report under `data/ai/output`.
|
|
388
|
+
- `ai-pocket-search` uses a time-ordered row holdout by default
|
|
389
|
+
(`--validationSplit 0.25`) and ranks candidates on that holdout. Treat it as
|
|
390
|
+
tuning evidence, not an untouched test. For direction-specific discovery use
|
|
391
|
+
`--direction LONG` or `--direction SHORT`. For release research, reserve a
|
|
392
|
+
timestamp-grouped tail with `--testSplit ... --sealTest`; the report retains
|
|
393
|
+
only its timestamp/count bounds and excludes its rows from current-gate and
|
|
394
|
+
pocket economics. Open it once later with a frozen `ai-gate-ablation.mjs`
|
|
395
|
+
spec. Plain `--testSplit` still prints test metrics and is therefore an opened
|
|
396
|
+
historical test, not sealed release evidence. Use `--validationSplit 0` only
|
|
397
|
+
for legacy full-sample exploration.
|
|
398
|
+
- `ai-pocket-search` uses `--coverageMode auto` by default. It keeps the
|
|
399
|
+
full-history search for non-provider features and runs separate CMC and
|
|
400
|
+
Coinalyze cohorts over rows where that context is usable. Each cohort gets
|
|
401
|
+
its own timestamp-grouped train/tuning/test split, and every reported cohort
|
|
402
|
+
pocket must contain a predicate from that provider family. Use
|
|
403
|
+
`--coverageMode full` only when intentionally reproducing the legacy single
|
|
404
|
+
full-period search.
|
|
405
|
+
- `ai-pocket-search` uses `--cadenceMode auto` by default. For a sparse train
|
|
406
|
+
partition it scales discovery-only `minSupport` / `minEvents` down from the
|
|
407
|
+
legacy 20 / 10 defaults using the number of independent timestamp events.
|
|
408
|
+
A train partition below 200 events uses
|
|
409
|
+
`minSupport=clamp(ceil(events*0.1),3,20)` and
|
|
410
|
+
`minEvents=clamp(ceil(minSupport*0.5),3,10)`; the default maximum event share
|
|
411
|
+
relaxes only as far as one third. Each provider coverage cohort gets its own
|
|
412
|
+
thresholds. Explicit
|
|
413
|
+
`--minSupport`, `--minEvents`, `--minValidationSupport`,
|
|
414
|
+
`--minValidationEvents`, and `--maxEventCountShare` values always win. Use
|
|
415
|
+
`--cadenceMode fixed` to reproduce the legacy fixed thresholds.
|
|
416
|
+
- Adaptive thresholds make low-cadence hypothesis discovery possible; they do
|
|
417
|
+
not lower the production evidence bar. Every pocket is marked
|
|
418
|
+
`research-only` when it has fewer than 25 independent train events, fewer
|
|
419
|
+
than 25 matching events in the untouched test, or no untouched test at all.
|
|
420
|
+
`production-candidate` means only that these sample-size prerequisites were
|
|
421
|
+
met, not that the pocket is automatically safe to ship.
|
|
422
|
+
- Coverage flags, coverage start/end, and cohort sizes are data-quality
|
|
423
|
+
metadata only. They select the research cohort and appear in the report, but
|
|
424
|
+
they are never eligible pocket predicates. Missing or stale provider context
|
|
425
|
+
must not be flattened into fallback market states such as derivatives
|
|
426
|
+
`pressure=neutral`.
|
|
427
|
+
- use `--includeGateContext` only for auditing existing gate output fields, not for discovering new future approval rules
|
|
428
|
+
- use `--scope approved` with a smaller `--minSupport` to find sub-pockets inside the current qN+ approved stream; use `--scope all` or `--scope candidates` to look for expansion candidates
|
|
429
|
+
- when doing offline pocket research, prefer `--dumpEvaluations` for the evaluated rows
|
|
430
|
+
- when the research needs signal-time gate inputs such as CMC, MTF, ATR bucket, benchmark conflict, participation, execution, or strategy-specific `*GateFeatures`, add `--dumpFeatures gateFeatures`; this writes the current `baseContext.gateFeatures` and strategy gate features into each dump row
|
|
431
|
+
- when broader context is needed, use `--dumpFeatures baseContext`; it writes compact current base-context sections (`regime`, `structure`, `participation`, `relative`, `derivatives`, `mtf`, `gateFeatures`) without the bulky `raw` section
|
|
432
|
+
- join/compare extra fields from the original dataset only when they are not available through `--dumpFeatures`, and treat those joined fields as explanatory features rather than current gate truth after adapter changes
|
|
433
|
+
- use `scripts/ai-gate-ablation.mjs` for custom rule ablations and verify its
|
|
434
|
+
baseline against `yarn ai-train --localOnly --json` for the same export/window
|
|
435
|
+
|
|
436
|
+
5. Read these sections first:
|
|
437
|
+
|
|
438
|
+
- `OUTCOME`
|
|
439
|
+
- `BY DIRECTION`
|
|
440
|
+
- `DETERMINISTIC FLOW`
|
|
441
|
+
- `QUALITY BREAKDOWN`
|
|
442
|
+
|
|
443
|
+
6. Always show quality-cadence metrics for the main approved bucket.
|
|
444
|
+
|
|
445
|
+
Default naming convention:
|
|
446
|
+
|
|
447
|
+
- `qN+` means the effective `MIN_AI_QUALITY=N` approved stream, so it includes every approval with quality `>= N`.
|
|
448
|
+
- Examples:
|
|
449
|
+
- `q3+` includes `q3`, `q4`, `q5`
|
|
450
|
+
- `q4+` includes `q4`, `q5`
|
|
451
|
+
- `q5+` includes only `q5`
|
|
452
|
+
- Do not default to plain `q1` / `q2` / `q3` / `q4` / `q5` wording unless the user explicitly asks for the isolated subset.
|
|
453
|
+
|
|
454
|
+
For the default `q4+` approved stream, report:
|
|
455
|
+
|
|
456
|
+
- `winrate` / `precision_approved`
|
|
457
|
+
- `profit_factor`
|
|
458
|
+
- `max_drawdown`
|
|
459
|
+
- `max_drawdown_pct_of_gross_profit`
|
|
460
|
+
- `max_drawdown_pct_of_total_profit`
|
|
461
|
+
- `max_consecutive_losses` / `max loss streak`
|
|
462
|
+
- losing approved months count, and list the losing months when the count is non-zero
|
|
463
|
+
- `avg_profit_approved_per_day`
|
|
464
|
+
- `avg_profit_approved_per_month`
|
|
465
|
+
- `avg_approved_trades_per_day`
|
|
466
|
+
- `avg_approved_trades_per_week`
|
|
467
|
+
- unique approved event timestamps
|
|
468
|
+
- approved events per day and active-day ratio
|
|
469
|
+
- trades per event, p95/max approved batch size
|
|
470
|
+
- largest-event shares of approved count and PnL
|
|
471
|
+
|
|
472
|
+
Use the same period logic as `packages/cli/src/lib/aiTrainMetrics.ts`: `(max timestamp - min timestamp) / 1 day`, with a minimum of `1` day. If useful, also mention the full-window normalization separately, but the required table is for the default approved stream named in `qN+` notation. If `q5+` or another threshold is important for the strategy, include it too. If the user explicitly asks for isolated `q1` / `q2` / `q3` / `q4` / `q5`, report those separately and label them clearly.
|
|
473
|
+
|
|
474
|
+
7. For deeper FP/FN and gate-ablation analysis, use the permanent tool.
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
node .codex/skills/ai-train-local-research/scripts/ai-gate-ablation.mjs \
|
|
478
|
+
--file data/ai/export/ai-dataset-<token>-merged-<ts>-part1.jsonl \
|
|
479
|
+
--variant 'name::filter::additionalIndicators.baseContext.<path> <= <value>' \
|
|
480
|
+
--featurePattern '<field-regex>' \
|
|
481
|
+
--output data/ai/output/<strategy>-gate-ablation.md
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
- It streams shards in part order, rebuilds the current payload after plugin
|
|
485
|
+
registration, and keeps outcome labels separate from decision features.
|
|
486
|
+
- Use repeated `--variant` arguments or a JSON `--spec` to compare hypotheses
|
|
487
|
+
in one pass.
|
|
488
|
+
- Use `filter`, `exclude`, `add@quality`, or `replace@quality` according to the
|
|
489
|
+
ablation semantics documented in `references/gate-ablation.md`.
|
|
490
|
+
- Do not use `--includeGateContext` for discovery; it is audit-only.
|
|
491
|
+
- If its baseline differs materially from `ai-train`, stop and fix the permanent
|
|
492
|
+
tool before interpreting hypotheses.
|
|
493
|
+
|
|
494
|
+
8. For strategy AI investigations, always look for these questions:
|
|
495
|
+
|
|
496
|
+
- Is the strategy core firing earlier than the adapter wants?
|
|
497
|
+
- Is a stricter threshold such as `q5+` actually better than the broader default stream such as `q4+`?
|
|
498
|
+
- Is one direction much worse than the other?
|
|
499
|
+
- Is one direction responsible for most drawdown?
|
|
500
|
+
- Are the best pockets counter-trend or aligned?
|
|
501
|
+
- Is there a field mismatch between `core.ts` and `adapters/ai.ts`?
|
|
502
|
+
- Is the backtest config exploring the detector or only TP/SL?
|
|
503
|
+
|
|
504
|
+
9. For gate tuning, validate candidate rules beyond aggregate profit.
|
|
505
|
+
|
|
506
|
+
Minimum checks:
|
|
507
|
+
|
|
508
|
+
- audit existing gate pockets and thresholds before adding new ones
|
|
509
|
+
- revalidate existing approval/recovery/downgrade/block rules on the same export
|
|
510
|
+
and env assumptions used for the proposed change
|
|
511
|
+
- classify old pockets as `keep`, `round`, `replace`, `disable`, or
|
|
512
|
+
`needs-more-data`
|
|
513
|
+
- include live-env parity and feature provenance tables in the analysis
|
|
514
|
+
- run walk-forward or month/quarter stability checks when history allows it
|
|
515
|
+
- define acceptance gates before treating a pocket as production-ready
|
|
516
|
+
- use a negative control for unusually strong or highly specific pockets
|
|
517
|
+
- reject approval rules based on data-count or availability fields such as
|
|
518
|
+
derivatives `points`, row counts, `.length`, coverage counts, or loaded-window
|
|
519
|
+
size; use those only as missing/stale-data guards
|
|
520
|
+
- reject high-precision pocket thresholds until they have been rounded to a
|
|
521
|
+
defensible value and replayed again
|
|
522
|
+
- run sensitivity checks around each proposed numeric threshold
|
|
523
|
+
- report train and validation support separately when using `ai-pocket-search`
|
|
524
|
+
or a custom split, but label any partition used for selection as tuning
|
|
525
|
+
- group partitions by timestamp and report independent-event support separately
|
|
526
|
+
for train, tuning, and untouched test
|
|
527
|
+
- report event clustering and capacity stress for every terminal window
|
|
528
|
+
- require a target-specific discriminator or portfolio throttle for
|
|
529
|
+
benchmark/global pockets that can approve many symbols on one timestamp
|
|
530
|
+
- include an ablation table: baseline, pocket-only when applicable, and final
|
|
531
|
+
gate
|
|
532
|
+
- require boundary tests and a passive-rollout plan for implemented gate changes
|
|
533
|
+
- clean up old disabled pockets instead of leaving dead constants or prompt
|
|
534
|
+
fields behind
|
|
535
|
+
- compare q4+ and q5+ separately
|
|
536
|
+
- report winrate as a percentage
|
|
537
|
+
- report max drawdown both as an absolute value and as percentages of gross profit and total profit
|
|
538
|
+
- report Sharpe, Sortino, and Calmar for the approved stream when available,
|
|
539
|
+
and include a one-sentence conclusion: whether the candidate improved
|
|
540
|
+
risk-adjusted quality, merely reduced trades, or worsened tail risk
|
|
541
|
+
- always report max consecutive losses / max loss streak for the approved stream
|
|
542
|
+
- always report losing approved months count for the approved stream; when non-zero, include the month ids and monthly approved PnL
|
|
543
|
+
- split by direction
|
|
544
|
+
- split by quarter or month when the export spans enough time
|
|
545
|
+
- check symbol concentration; avoid rules where most profit comes from only a few symbols
|
|
546
|
+
- prefer candidate pockets that improve profit factor or drawdown without destroying cadence
|
|
547
|
+
- for live-style approval gates, usually aim for about 2-3 approved trades per day, but accept narrow high-quality pockets down to ~1 approved trade per day when profit factor/drawdown materially improve; if a strategy approves substantially more, assume there is likely room to lower approvals and raise winrate with additional filters
|
|
548
|
+
- treat tiny added slices as unstable even when aggregate profit improves
|
|
549
|
+
- if the candidate depends on env-sensitive context construction, such as
|
|
550
|
+
derivatives lookback, interval selection, target/reference mode, or CMC window
|
|
551
|
+
availability, validate it under the intended live env before recommending code
|
|
552
|
+
changes
|
|
553
|
+
|
|
554
|
+
Risk-adjusted metric convention:
|
|
555
|
+
|
|
556
|
+
- `sharpe_ratio` and `sortino_ratio` in TradeJS AI-gate research are computed
|
|
557
|
+
from approved trade PnL, annualized by approved-trade cadence over the
|
|
558
|
+
evaluated period. Treat them as PnL-stream quality metrics, not capital-return
|
|
559
|
+
ratios.
|
|
560
|
+
- `calmar_ratio` is annualized approved PnL divided by approved max drawdown.
|
|
561
|
+
- When comparing gates, prefer candidates where Sharpe/Sortino/Calmar improve
|
|
562
|
+
together with PF/maxDD. If only Sharpe improves because many trades were
|
|
563
|
+
removed while 30d/7d tail risk remains, state that explicitly.
|
|
564
|
+
|
|
565
|
+
## Notes format
|
|
566
|
+
|
|
567
|
+
Read both `references/reporting.md` and
|
|
568
|
+
`../strategy-backtest-research/references/research-notes.md` before writing a
|
|
569
|
+
note. The shared contract controls storage, one-research-per-file boundaries,
|
|
570
|
+
frontmatter, resolved config, and the machine-readable metric snapshot. The AI
|
|
571
|
+
reporting contract controls tables, metric names, validation, threshold,
|
|
572
|
+
rollout, and cleanup sections.
|
|
573
|
+
|
|
574
|
+
Every new AI-gate study must:
|
|
575
|
+
|
|
576
|
+
- create one new file under `notes/<Strategy>/`, never update a rolling log;
|
|
577
|
+
- keep that file local-only and ignored by Git; never stage, commit, or
|
|
578
|
+
force-add anything under `notes/`;
|
|
579
|
+
- embed the complete `ai-train --localOnly --json` result and structured
|
|
580
|
+
ablation/partition summaries needed to rebuild every displayed metric;
|
|
581
|
+
- embed the secret-free resolved backtest/runtime/context configuration instead
|
|
582
|
+
of only naming a Redis key or current config;
|
|
583
|
+
- list export/output paths and SHA-256 values as disposable artifact inventory,
|
|
584
|
+
not as the only metric evidence;
|
|
585
|
+
- downgrade `reproduction` from `complete` when any displayed metric or lineage
|
|
586
|
+
cannot be recovered from the note after export deletion.
|
|
587
|
+
|
|
588
|
+
## Current repo conventions
|
|
589
|
+
|
|
590
|
+
- Prefer `GPT-5 Mini` by default for non-local AI replay unless the user names another model.
|
|
591
|
+
- When the strategy already has deterministic adapter fields like:
|
|
592
|
+
- `approvalAllowedNow`
|
|
593
|
+
- `deterministicQuality`
|
|
594
|
+
- `structuralHardBlockReasons`
|
|
595
|
+
local replay is the preferred research mode.
|
|
596
|
+
- If these fields are missing, add them before trusting `--localOnly`.
|