create-tradejs 3.1.22 → 3.1.23
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,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backtest-config-redis
|
|
3
|
+
description: Fetch a TradeJS backtest or strategy configuration from the local RedisJSON users configuration namespace by config name, including named variants such as Grid:ai or TrendLine:research. Use for inspecting, reproducing, or recording Redis-backed strategy grids.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backtest Config from Redis
|
|
7
|
+
|
|
8
|
+
## Use
|
|
9
|
+
|
|
10
|
+
- Ask for the config name if not provided.
|
|
11
|
+
- Read the RedisJSON value from
|
|
12
|
+
`users:<user>:backtests:configs:<config>` and return the config object as-is
|
|
13
|
+
unless the user asks to edit or reformat it. The default user is `root`.
|
|
14
|
+
- Prefer using the script `scripts/get_backtest_config.sh` to access Redis via Docker.
|
|
15
|
+
- If the container name differs from `inv-redis`, ask for the correct name.
|
|
16
|
+
- For research lineage, embed the returned JSON and a canonical checksum in the
|
|
17
|
+
note. The mutable Redis key alone is not reproduction evidence.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
if [[ $# -lt 1 ]]; then
|
|
5
|
+
echo "Usage: $0 <config> [user] [container]" >&2
|
|
6
|
+
exit 1
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
config="$1"
|
|
10
|
+
user_name="${2:-root}"
|
|
11
|
+
container="${3:-inv-redis}"
|
|
12
|
+
key="users:${user_name}:backtests:configs:${config}"
|
|
13
|
+
|
|
14
|
+
# RedisJSON returns one root match in an array. Print the config object itself.
|
|
15
|
+
payload="$(docker exec "$container" redis-cli --raw JSON.GET "$key" '$')"
|
|
16
|
+
if [[ -z "$payload" ]]; then
|
|
17
|
+
echo "Backtest config not found: ${key}" >&2
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
printf '%s\n' "$payload" | jq 'if type == "array" and length == 1 then .[0] else . end'
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: runtime-parity-mismatch-analysis
|
|
3
|
+
description: Analyze TradeJS runtime parity mismatch JSON files produced by runtime-parity notifications, identify root causes of runtime vs replay/backtest divergences, group them by cause, and point to the exact evidence fields and code paths to inspect next.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Runtime Parity Mismatch Analysis
|
|
7
|
+
|
|
8
|
+
Use this skill when the user asks to:
|
|
9
|
+
|
|
10
|
+
- analyze a `runtime-parity-mismatches-*.json` file
|
|
11
|
+
- explain why runtime and replay/backtest diverged
|
|
12
|
+
- investigate `runtimeOnly` / `backtestOnly` parity cases
|
|
13
|
+
- summarize mismatch causes from Telegram parity artifacts
|
|
14
|
+
- tell whether a divergence is caused by strategy core, gate/AI/ML, order failure, drift/tolerance, or missing evaluation
|
|
15
|
+
|
|
16
|
+
This skill is for reading the mismatch JSON artifact first. Do not rerun parity unless the user explicitly asks for a new replay.
|
|
17
|
+
|
|
18
|
+
## Expected input
|
|
19
|
+
|
|
20
|
+
Prefer one of these:
|
|
21
|
+
|
|
22
|
+
- a local `runtime-parity-mismatches-*.json` file
|
|
23
|
+
- an attached JSON artifact from Telegram
|
|
24
|
+
- raw JSON pasted into the chat
|
|
25
|
+
|
|
26
|
+
Start with:
|
|
27
|
+
|
|
28
|
+
- `cases`
|
|
29
|
+
|
|
30
|
+
Fallback only if needed:
|
|
31
|
+
|
|
32
|
+
- `mismatches.runtimeOnly`
|
|
33
|
+
- `mismatches.backtestOnly`
|
|
34
|
+
|
|
35
|
+
## Analysis priority
|
|
36
|
+
|
|
37
|
+
For each case, use this order:
|
|
38
|
+
|
|
39
|
+
1. `why.classification`
|
|
40
|
+
2. `why.reason`
|
|
41
|
+
3. `decisionTrace`
|
|
42
|
+
4. `timing`
|
|
43
|
+
5. `artifacts`
|
|
44
|
+
|
|
45
|
+
Treat `why.classification` as the primary label, not as a hint.
|
|
46
|
+
|
|
47
|
+
## Canonical cause mapping
|
|
48
|
+
|
|
49
|
+
Map each case to one of these buckets:
|
|
50
|
+
|
|
51
|
+
- `strategy_core`
|
|
52
|
+
- usually `core_skipped`
|
|
53
|
+
- replay/runtime core did not emit a signal
|
|
54
|
+
- `gate_ai_ml`
|
|
55
|
+
- usually `gated_out`
|
|
56
|
+
- signal existed but gate / AI / ML / skip logic blocked entry
|
|
57
|
+
- `order_placement`
|
|
58
|
+
- usually `order_failed`
|
|
59
|
+
- signal existed but order path failed
|
|
60
|
+
- `tolerance_or_drift`
|
|
61
|
+
- usually `backtest_drift`
|
|
62
|
+
- nearest trade exists but is outside allowed timing tolerance
|
|
63
|
+
- `missing_evaluation`
|
|
64
|
+
- usually `not_evaluated`
|
|
65
|
+
- no nearby runtime/replay evaluation was produced
|
|
66
|
+
- `true_mismatch`
|
|
67
|
+
- usually `true_mismatch`
|
|
68
|
+
- both paths evaluated the setup but still disagree
|
|
69
|
+
|
|
70
|
+
## What to conclude from each classification
|
|
71
|
+
|
|
72
|
+
- `core_skipped`
|
|
73
|
+
- First suspect strategy core conditions, candle history, preload window, or config mismatch.
|
|
74
|
+
- `gated_out`
|
|
75
|
+
- First inspect `orderSkipReason`, AI/ML thresholds, and runtime-vs-replay gate inputs.
|
|
76
|
+
- `order_failed`
|
|
77
|
+
- First inspect order simulation / connector / placement path rather than strategy core.
|
|
78
|
+
- `backtest_drift`
|
|
79
|
+
- First inspect timestamp alignment, preload history, tolerance bars, and exchange candle differences.
|
|
80
|
+
- `not_evaluated`
|
|
81
|
+
- First inspect target coverage, filtering, persistence, or missing evaluation generation.
|
|
82
|
+
- `true_mismatch`
|
|
83
|
+
- First inspect direction, statuses, and signal/evaluation artifacts on both sides.
|
|
84
|
+
|
|
85
|
+
## TradeJS-specific inspection paths
|
|
86
|
+
|
|
87
|
+
If the JSON alone is not enough, inspect these code areas:
|
|
88
|
+
|
|
89
|
+
- mismatch builder and classifications:
|
|
90
|
+
- `packages/cli/src/scripts/runtimeParity.ts`
|
|
91
|
+
- parity entry extraction and matching:
|
|
92
|
+
- `packages/cli/src/lib/runtimeParity.ts`
|
|
93
|
+
- runtime signal persistence/loading:
|
|
94
|
+
- `packages/cli/src/lib/runtimeSignalsLoader.ts`
|
|
95
|
+
- strategy runtime and signal/evaluation flow:
|
|
96
|
+
- `packages/node/src/testing.ts`
|
|
97
|
+
- `packages/node/src/strategyHelpers/runtime.ts`
|
|
98
|
+
- `packages/node/src/signals.ts`
|
|
99
|
+
- strategy implementation:
|
|
100
|
+
- `packages/strategies/**/core.ts`
|
|
101
|
+
- `packages/strategies/**/adapters/ai.ts`
|
|
102
|
+
|
|
103
|
+
When a case says `core_skipped`, inspect the strategy `core.ts` before blaming Telegram, Redis, or the connector.
|
|
104
|
+
|
|
105
|
+
## Output format
|
|
106
|
+
|
|
107
|
+
For each case, provide:
|
|
108
|
+
|
|
109
|
+
1. `Case`
|
|
110
|
+
- strategy / symbol / direction / signalId
|
|
111
|
+
2. `Root cause`
|
|
112
|
+
- one short sentence
|
|
113
|
+
3. `Evidence`
|
|
114
|
+
- cite the exact JSON fields that support the conclusion
|
|
115
|
+
4. `Bucket`
|
|
116
|
+
- one of the canonical cause buckets above
|
|
117
|
+
5. `Next checks`
|
|
118
|
+
- 1-3 concrete checks in code or config
|
|
119
|
+
|
|
120
|
+
If there are many cases, group them by:
|
|
121
|
+
|
|
122
|
+
- `why.classification`
|
|
123
|
+
- then by strategy
|
|
124
|
+
|
|
125
|
+
If all cases share one cause, say that explicitly before listing details.
|
|
126
|
+
|
|
127
|
+
## What not to do
|
|
128
|
+
|
|
129
|
+
- Do not default to generic “timing issue” wording if `why.classification` already says `gated_out` or `core_skipped`.
|
|
130
|
+
- Do not treat `recommendedChecks` as proof; use them only as follow-up guidance.
|
|
131
|
+
- Do not ignore `decisionTrace` when `orderStatus` or `orderSkipReason` is present.
|
|
132
|
+
- Do not rerun backtests or parity automatically.
|
|
133
|
+
|
|
134
|
+
## Example prompt
|
|
135
|
+
|
|
136
|
+
Use this prompt shape when the user gives you a mismatch artifact:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
Analyze this runtime parity mismatch JSON.
|
|
140
|
+
For each case:
|
|
141
|
+
1. Name the root cause.
|
|
142
|
+
2. Cite the exact fields that prove it.
|
|
143
|
+
3. Classify it as strategy_core, gate_ai_ml, order_placement, tolerance_or_drift, missing_evaluation, or true_mismatch.
|
|
144
|
+
4. Give the next 1-3 checks in the TradeJS codebase.
|
|
145
|
+
If several cases share one cause, group them.
|
|
146
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: save-strategy-config-from-backtest
|
|
3
|
+
description: Promote a TradeJS backtest config grid from research Redis into the Git-owned runtime declaration in TradeJS-Project tradejs.config.ts. Use when the user asks to copy, promote, or save a backtest candidate for runtime or forward testing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Promote Strategy Config From Backtest
|
|
7
|
+
|
|
8
|
+
## Repository boundary
|
|
9
|
+
|
|
10
|
+
Run from `/Users/aleksnick/dev/tradejs/tradejs-project`. This repository owns
|
|
11
|
+
`tradejs.config.ts`, the exact package dependencies, and the runtime image.
|
|
12
|
+
Research Redis is only the source of the backtest candidate; production Redis
|
|
13
|
+
must never receive strategy config, deployment documents, or version pointers.
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
1. Resolve the exact user, strategy, source backtest config, target deployment,
|
|
18
|
+
and intended risk. Default the research user to `root`, but never guess a
|
|
19
|
+
production account or deployment.
|
|
20
|
+
2. Read the source grid from
|
|
21
|
+
`users:<user>:backtests:configs:<Strategy>:<name>` with RedisJSON. A missing
|
|
22
|
+
source is a blocker; do not fall back to `users:*:strategies:*:config`.
|
|
23
|
+
3. Convert the grid to one plain strategy config. Unwrap one-element arrays.
|
|
24
|
+
For multi-value arrays, resolve the exact winning result/config id or ask the
|
|
25
|
+
user; never choose a value arbitrarily. Preserve nested `LONG`, `SHORT`, AI,
|
|
26
|
+
detector, and risk objects.
|
|
27
|
+
4. Remove operational/mode fields: `ENABLE`, `ACCOUNT_ID`, `DEPLOYMENT_ID`,
|
|
28
|
+
`ENV`, `MAKE_ORDERS`, `RECORD_RUNTIME_TRADES`, and `AI_REPLAY_ANALYSES`.
|
|
29
|
+
Keep `INTERVAL`, `UNIVERSE`, `POLICY_PROFILE_ID`, execution semantics, AI
|
|
30
|
+
mode, thresholds, and the complete strategy behavior config. For an
|
|
31
|
+
authorized micro-forward use `MAX_LOSS_VALUE=1`; otherwise preserve the
|
|
32
|
+
explicitly selected risk.
|
|
33
|
+
5. Update the strategy entry under
|
|
34
|
+
`runtime.deployments.<deployment>.strategies.<Strategy>` in
|
|
35
|
+
`tradejs.config.ts`. Store exactly `{ generation?, enabled, selection?,
|
|
36
|
+
config }`. `generation` is optional human metadata. Never add or increment a
|
|
37
|
+
technical version: Project validation computes `strategyRevision` and
|
|
38
|
+
`deploymentCompositionId`. Keep account, connector, tickers, and asset
|
|
39
|
+
classes at deployment level.
|
|
40
|
+
6. Ensure `package.json` and `yarn.lock` select the exact stable strategy
|
|
41
|
+
package containing the candidate. Normal development verifies a beta first;
|
|
42
|
+
committed Project and production use the protected stable promotion.
|
|
43
|
+
7. Run Project validation, record the computed revisions, and run
|
|
44
|
+
`yarn runtime-control verify`. A production-like image smoke must prove that
|
|
45
|
+
the config loads with no controls key, pause creates only
|
|
46
|
+
`users:<user>:runtime:controls`, and resume removes it.
|
|
47
|
+
|
|
48
|
+
## Safety
|
|
49
|
+
|
|
50
|
+
- Never write a runtime strategy config to Redis.
|
|
51
|
+
- Never copy credentials into `tradejs.config.ts` or research evidence.
|
|
52
|
+
- Do not overwrite another strategy or deployment while promoting one
|
|
53
|
+
candidate.
|
|
54
|
+
- A UI pause is an optional Redis override; desired activation remains the
|
|
55
|
+
committed `enabled` value.
|
|
56
|
+
- Commit and push only when the user requested the rollout through the active
|
|
57
|
+
`$strategy-forward-start` workflow, which owns the complete forward-test
|
|
58
|
+
handshake.
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: strategy-backtest-research
|
|
3
|
+
description: Execute a scoped TradeJS strategy implementation or preregistered core-backtest experiment, including StrategyAPI checks, figures, Redis configs, cache-only runs, metric reconciliation, and AI export preparation. Use strategy-improvement-research instead to choose hypothesis families or orchestrate a multi-round candidate lineage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Strategy Backtest Research
|
|
7
|
+
|
|
8
|
+
Run operational research commands from `TradeJS-Project`, with `PROJECT_CWD`
|
|
9
|
+
as the artifact/config root and `TRADEJS_SOURCE_REPOSITORY_ROOT` as the Git and
|
|
10
|
+
build lineage root. Store `data/` and ignored `notes/` only under the project
|
|
11
|
+
root.
|
|
12
|
+
|
|
13
|
+
When research will apply and compare alternative strategy source edits, create
|
|
14
|
+
one dedicated worktree from the frozen baseline SHA for that immutable lineage.
|
|
15
|
+
Keep the canonical strategy checkout clean, point
|
|
16
|
+
`TRADEJS_SOURCE_REPOSITORY_ROOT` at the worktree, and run source checks there.
|
|
17
|
+
Pure config, artifact, reporting, or read-only backtest work does not require a
|
|
18
|
+
worktree. Before replacing a rejected source candidate, preserve its exact diff,
|
|
19
|
+
build hash, resolved config, and run outcome in Project-owned evidence; restore
|
|
20
|
+
only the disposable worktree. Commit only a selected candidate, and remove a
|
|
21
|
+
no-winner worktree only after evidence is frozen. A worktree does not isolate a
|
|
22
|
+
temporary package overlay in `TradeJS-Project/node_modules`, which must be
|
|
23
|
+
restored separately to the verified stable package.
|
|
24
|
+
|
|
25
|
+
Use this skill when working on strategy implementation, figures, backtest
|
|
26
|
+
configuration, or one already-preregistered core experiment in the owning
|
|
27
|
+
standalone strategy repository.
|
|
28
|
+
|
|
29
|
+
This is an execution skill, not the end-to-end improvement orchestrator. It
|
|
30
|
+
does not invent a multi-round research budget, choose competing hypothesis
|
|
31
|
+
families, rank the global candidate ledger, or freeze the final composition.
|
|
32
|
+
Use `$strategy-improvement-research` for those decisions. Do not use this skill
|
|
33
|
+
for general `ai-train --localOnly` gate research; use
|
|
34
|
+
`$ai-train-local-research` for a frozen core/export.
|
|
35
|
+
|
|
36
|
+
## Strategy Shape
|
|
37
|
+
|
|
38
|
+
- `core.ts` must use `StrategyAPI`; do not call AI/ML providers or order placement directly.
|
|
39
|
+
- Geometry-based strategies should keep visual artifacts in the strategy package.
|
|
40
|
+
- `figures.ts` should include the lines/points needed to inspect why a trade happened.
|
|
41
|
+
- `adapters/ai.ts` should carry strategy-specific context into the AI payload when backtest exports need AI context, but local gate tuning belongs to `ai-train-local-research`.
|
|
42
|
+
|
|
43
|
+
## DoubleTap Notes
|
|
44
|
+
|
|
45
|
+
When the strategy is `DoubleTap`, `engine.ts` ports the Bjorgum Double Tap pattern mechanics:
|
|
46
|
+
|
|
47
|
+
- maintain swing pivots from rolling highest/lowest windows
|
|
48
|
+
- detect double bottom on close above neckline
|
|
49
|
+
- detect double top on close below neckline
|
|
50
|
+
- derive target from `DOUBLETAP_TARGET_FIB_PCT`
|
|
51
|
+
- derive stop from invalidation pivot and `DOUBLETAP_STOP_FIB_PCT`
|
|
52
|
+
- `figures.ts` is required. Include pattern zig-zag, neckline, target, stop, pivot points, and entry marker.
|
|
53
|
+
|
|
54
|
+
## Backtest Workflow
|
|
55
|
+
|
|
56
|
+
1. Prepare or update Redis backtest config under `users:root:backtests:configs:<Strategy>:<name>`.
|
|
57
|
+
- When a research config includes `MAX_LOSS_VALUE`, set it to `10`.
|
|
58
|
+
- When updating a backtest `:ai` config, enable both `LONG` and `SHORT`; let the AI gate disable a side later if needed.
|
|
59
|
+
2. Start with small cache-only runs: `yarn backtest -c <Strategy>:<name> -d 30 --cacheOnly --fast`.
|
|
60
|
+
3. Tune strategy-specific grid fields first.
|
|
61
|
+
|
|
62
|
+
When a symmetric candidate loses in aggregate but its reconciled LONG/SHORT
|
|
63
|
+
attribution shows a material improvement on only one side, do not discard or
|
|
64
|
+
globally enable it automatically. Register a new direction-specific follow-up
|
|
65
|
+
with explicit `_LONG` and `_SHORT` fields, keep both directions enabled, and
|
|
66
|
+
screen the combined policy against the same control. The follow-up is a new
|
|
67
|
+
hypothesis lineage; preserve the rejected symmetric run and preregister the
|
|
68
|
+
directional rule before testing it.
|
|
69
|
+
|
|
70
|
+
For DoubleTap, prioritize:
|
|
71
|
+
|
|
72
|
+
- `DOUBLETAP_PIVOT_LENGTH`
|
|
73
|
+
- `DOUBLETAP_PIVOT_TOLERANCE_PCT`
|
|
74
|
+
- `DOUBLETAP_TARGET_FIB_PCT`
|
|
75
|
+
- `DOUBLETAP_STOP_FIB_PCT`
|
|
76
|
+
- `DOUBLETAP_MIN_PATTERN_HEIGHT_PCT`
|
|
77
|
+
- `DOUBLETAP_MAX_BREAKOUT_DISTANCE_PCT`
|
|
78
|
+
- side `minRiskRatio`
|
|
79
|
+
|
|
80
|
+
4. Once a config is stable across 20+ tickers on `-d 30`, use it for year-scale `--ai` exports. Analyze exported local AI gate behavior with `ai-train-local-research`.
|
|
81
|
+
|
|
82
|
+
For detailed metrics from a non-`--fast` backtest run, use:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
yarn node -r dotenv/config .codex/skills/strategy-backtest-research/scripts/backtest-run-metrics.mjs --run <run-id> --json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The report reconstructs completed trades from cached order artifacts and shows
|
|
89
|
+
full/365d/180d/90d/30d/7d metrics where applicable, including PF, drawdown, strict
|
|
90
|
+
loss, loss streak, losing months, cadence, and scale-in levels 2/3/4. Use a
|
|
91
|
+
matching no-scale-in run to separate sizing effects from scale-in effects.
|
|
92
|
+
|
|
93
|
+
For portfolio metrics from a `--fast --ai` core export, use the completed-trade
|
|
94
|
+
JSONL instead of treating the per-symbol Redis drawdown as portfolio MaxDD:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
yarn node -r dotenv/config .codex/skills/strategy-backtest-research/scripts/fast-ai-export-metrics.mjs \
|
|
98
|
+
--file <merged-export.jsonl> --run <run-id> --json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`--file` may be repeated for disjoint export shards. If the Redis run manifest
|
|
102
|
+
is unavailable, pass its frozen end explicitly with `--end <epoch-ms|ISO>`.
|
|
103
|
+
The default core-screen terminal matrix is `1100d/365d/180d/90d/30d`, anchored strictly to
|
|
104
|
+
that manifest end rather than the newest export row. Windows are half-open
|
|
105
|
+
`[manifestEnd - days, manifestEnd)`, matching the backtest manifest. The report uses only
|
|
106
|
+
`tradeResult.netProfit`, `tradeResult.exitTimestamp`, direction, symbol, and
|
|
107
|
+
signal identity; it never consumes AI/LLM/gate decisions. It reports N/W/L,
|
|
108
|
+
WR, PF, PnL, PnL/trade, deterministic portfolio MaxDD, exact calendar-day
|
|
109
|
+
observed cadence, and LONG/SHORT breakdowns. With `--run`, it filters rows to
|
|
110
|
+
that run and separately reconciles export N/W/L/PnL against Redis
|
|
111
|
+
`result.stat`; Redis cannot supply export PF or portfolio MaxDD. Once N/W/L
|
|
112
|
+
and PnL reconcile within the documented per-symbol rounding tolerance, use the
|
|
113
|
+
row-level export as the authoritative trade-economic total instead of swapping
|
|
114
|
+
in the cent-rounded Redis aggregate.
|
|
115
|
+
|
|
116
|
+
For a `$strategy-improvement-research` final composition, extend the same permanent report
|
|
117
|
+
to `1095d/1460d/1825d-or-exact-maximum/365d/180d/90d/30d/7d`. When cached
|
|
118
|
+
coverage is shorter than 1825 days, report the exact covered duration (for
|
|
119
|
+
example 1800d) and do not label it a complete five-year window. Reuse this
|
|
120
|
+
tool's full ALL/LONG/SHORT statistics; do not replace them with a compact custom
|
|
121
|
+
parser. The release workflow must then run `ai-train --localOnly --chart -n 0`
|
|
122
|
+
on the exact full export so the UI chart and structured gate statistics share
|
|
123
|
+
the finalist lineage.
|
|
124
|
+
|
|
125
|
+
## Required Core Metric Cohorts
|
|
126
|
+
|
|
127
|
+
For every reported config and full or terminal window, present one table with
|
|
128
|
+
these rows in fixed order:
|
|
129
|
+
|
|
130
|
+
1. `ALL (aggregate portfolio)`
|
|
131
|
+
2. `LONG`
|
|
132
|
+
3. `SHORT`
|
|
133
|
+
|
|
134
|
+
Every row must contain `N`, `PnL`, `PnL/trade`, `PF`, `WR`, `realized MaxDD`,
|
|
135
|
+
and `cadence/day`. Use these definitions consistently:
|
|
136
|
+
|
|
137
|
+
- `N`: completed trades in the cohort.
|
|
138
|
+
- `PnL`: sum of completed-trade net realized PnL.
|
|
139
|
+
- `PnL/trade`: `PnL / N`, or `n/a` for `N = 0`.
|
|
140
|
+
- `PF`: gross winning PnL divided by absolute gross losing PnL.
|
|
141
|
+
- `WR`: winning completed trades divided by `N`.
|
|
142
|
+
- `realized MaxDD`: maximum peak-to-trough decline of the chronological
|
|
143
|
+
completed-trade net-PnL equity curve for that cohort and window. Label LONG
|
|
144
|
+
and SHORT values `side-only realized MaxDD` because each equity curve
|
|
145
|
+
contains only that direction's trades; label ALL as `aggregate portfolio
|
|
146
|
+
realized MaxDD`.
|
|
147
|
+
- `cadence/day`: cohort `N / exact calendar days` in the reported window.
|
|
148
|
+
|
|
149
|
+
Filter rows to LONG or SHORT before computing side metrics. Compute aggregate
|
|
150
|
+
`PnL/trade` as `(LONG PnL + SHORT PnL) / (LONG N + SHORT N)`; never average the
|
|
151
|
+
side `PnL/trade` values. Keep both directions enabled in raw-core configs even
|
|
152
|
+
when one is negative, and never omit the weak cohort from a table. AI-gate
|
|
153
|
+
research happens later and evaluates LONG and SHORT cohorts explicitly. Record
|
|
154
|
+
the baseline/candidate assessment status independently for ALL, LONG, and
|
|
155
|
+
SHORT; an aggregate label is not a directional label.
|
|
156
|
+
|
|
157
|
+
For a direction-targeted hypothesis, preregister the target direction, the
|
|
158
|
+
unaffected direction, matched control, metric thresholds, identity comparison,
|
|
159
|
+
rounding tolerance, possible shared-position occupancy path, non-target
|
|
160
|
+
non-regression rule, and aggregate portfolio guardrails. Judge the causal
|
|
161
|
+
hypothesis primarily on the target cohort. Require that cohort to satisfy the
|
|
162
|
+
preregistered improvements in PnL, PnL/trade, PF, WR, and side-only realized
|
|
163
|
+
MaxDD, with lower drawdown being better. Require exact signal/trade identities,
|
|
164
|
+
exact N, and PnL equality within only the documented reconciliation-rounding
|
|
165
|
+
tolerance on the non-target side only when the architecture makes it invariant.
|
|
166
|
+
If shared position occupancy, cooldown, order lifecycle, or another interaction
|
|
167
|
+
can affect it, report occupancy spillover explicitly: added and removed trade
|
|
168
|
+
identities, N/cadence delta, and PnL, PnL/trade, PF, WR, and side-only MaxDD
|
|
169
|
+
deltas. Apply the preregistered non-regression rule to that evidence. Report the
|
|
170
|
+
target-side causal verdict and the aggregate portfolio-promotion verdict
|
|
171
|
+
separately. Aggregate portfolio PnL and aggregate portfolio realized MaxDD are
|
|
172
|
+
guardrails, not substitutes for the target-side verdict.
|
|
173
|
+
|
|
174
|
+
For full-universe core robustness research:
|
|
175
|
+
|
|
176
|
+
1. Freeze the ordered eligible ticker list and checksum, exact UTC start/end,
|
|
177
|
+
resolved config grids, git/dirty lineage, connector, interval, fees,
|
|
178
|
+
slippage, and entry delay before comparing strategies or variants.
|
|
179
|
+
Audit every non-candle membership input (wallet registry, top-symbol/perp
|
|
180
|
+
universe, benchmark basket, allowlist) too. Resolve an effective-dated
|
|
181
|
+
version at or before each decision timestamp. If only a later/current
|
|
182
|
+
snapshot exists, label the long-window study blocked for point-in-time
|
|
183
|
+
robustness and do not optimize from it.
|
|
184
|
+
2. Use observed portfolio cadence = completed trades / exact calendar days.
|
|
185
|
+
Do not divide a full-universe cadence by symbol count or extrapolate it to an
|
|
186
|
+
approximate exchange count. If the experiment intentionally samples the
|
|
187
|
+
universe, show any linear projection separately with both universe sizes.
|
|
188
|
+
3. For a wide parameter family, first use a clearly labelled all-universe
|
|
189
|
+
180d screening grid, then rerun only shortlisted cells on one continuous
|
|
190
|
+
long window. A short screen is selection evidence, never robustness
|
|
191
|
+
evidence. Report terminal 365d/180d/90d/30d slices from the long run,
|
|
192
|
+
anchored to its immutable manifest end as half-open intervals, including
|
|
193
|
+
zero-activity slices. At
|
|
194
|
+
a 0.2/day floor, require at least 220/73/36/18/6 completed trades on
|
|
195
|
+
1100/365/180/90/30d respectively.
|
|
196
|
+
4. Keep each grid `configId` separate and require identical planned/completed
|
|
197
|
+
symbol counts. Never add metrics from several parameter buckets together.
|
|
198
|
+
Run shortlisted long-window cells as isolated single-config runs. Avoid a
|
|
199
|
+
multi-cell 1100d full-universe fan-out: it increases peak heap use and may
|
|
200
|
+
contaminate lifecycle/execution state when a strategy's shared-state key
|
|
201
|
+
does not cover the full resolved config. Use a multi-cell 180d screen only
|
|
202
|
+
after an explicit state-isolation test; otherwise split that screen too.
|
|
203
|
+
An OOM or partial manifest is a failed experiment, not a smaller sample.
|
|
204
|
+
Parallelism is a host-wide budget: count tester workers from every active
|
|
205
|
+
run and inspect memory pressure/swap before launching another batch. If two
|
|
206
|
+
batches already sustain pressure, wait or reduce `-p`; a per-worker heap cap
|
|
207
|
+
does not make a third batch safe.
|
|
208
|
+
5. Confirm shortlisted variants without `--fast`. For stateful strategies,
|
|
209
|
+
also run standalone shorter horizons to measure reset/preload sensitivity;
|
|
210
|
+
a terminal slice and a cold-start horizon answer different questions.
|
|
211
|
+
6. Save rejected as well as accepted hypotheses with the causal claim, full
|
|
212
|
+
resolved config, exact runs, structured metrics, and artifact checksums.
|
|
213
|
+
Do not repeat an old threshold sweep without a new causal rationale.
|
|
214
|
+
If a rejected symmetric lifecycle improves only LONG or only SHORT, record
|
|
215
|
+
that attribution and test at most one preregistered `_LONG`/`_SHORT`
|
|
216
|
+
follow-up with both directions still enabled before abandoning the family.
|
|
217
|
+
|
|
218
|
+
Use two explicit outcome labels. `Strictly robust` requires non-negative PnL,
|
|
219
|
+
PF >= 1, and the requested cadence floor in the full run and every required
|
|
220
|
+
terminal window. `Improved research candidate` is allowed for a still-negative
|
|
221
|
+
core only when full-window PnL and PnL/trade improve against the frozen control,
|
|
222
|
+
cadence survives every required window, and all terminal PnL/PF/MaxDD
|
|
223
|
+
regressions are disclosed. An aggregate win cannot hide a collapsed tail.
|
|
224
|
+
|
|
225
|
+
The `--ai` flag on a BACKTEST run may be used only as raw completed-core-trade
|
|
226
|
+
transport for the terminal metric tool: BACKTEST entry policy bypasses AI
|
|
227
|
+
quality. State this explicitly so the result is never mistaken for an AI-gated
|
|
228
|
+
backtest.
|
|
229
|
+
|
|
230
|
+
Treat row-level economics as acceptance-grade only when every config bucket
|
|
231
|
+
has a complete manifest, exact Redis N/W/L reconciliation, and only the allowed
|
|
232
|
+
per-symbol rounding delta in PnL. A missing row or conflicting duplicate makes
|
|
233
|
+
that bucket's PF, PnL/trade, terminal windows, and portfolio MaxDD invalid.
|
|
234
|
+
Never fill the gap from aggregate stats; repair the capture/export path and
|
|
235
|
+
rerun the affected cell.
|
|
236
|
+
|
|
237
|
+
Do not invoke `ai-export` while the selected run manifest is `running`, whether
|
|
238
|
+
the run id is explicit or found through latest-run discovery. Workers may still
|
|
239
|
+
own open append streams. The exporter must retain chunks by default and reject
|
|
240
|
+
active runs; cleanup is a separate post-run operation after reconciliation.
|
|
241
|
+
|
|
242
|
+
For all backtest summaries, calculate and report average trade PnL as
|
|
243
|
+
`total PnL / completed trades` and label it `PnL/trade`. The live CLI progress
|
|
244
|
+
`avg` is PnL per completed test/symbol, not PnL/trade; do not use it as a trade
|
|
245
|
+
quality metric. If it is useful operationally, label it `PnL/test` or
|
|
246
|
+
`PnL/symbol`. Report `PnL/trade` as `n/a` when `N = 0`.
|
|
247
|
+
|
|
248
|
+
For every AI export handed to gate research, record the merge id, shard count,
|
|
249
|
+
minimum and maximum timestamps, backtest config ids, git SHA, and the context env
|
|
250
|
+
used to construct derivatives/CMC inputs. A year-scale export without a fresh
|
|
251
|
+
terminal tail is suitable for historical research but not for a current live
|
|
252
|
+
cadence claim.
|
|
253
|
+
|
|
254
|
+
## Core experiment execution
|
|
255
|
+
|
|
256
|
+
For every new core control-versus-candidate experiment, use the versioned
|
|
257
|
+
contour in `CORE_RESEARCH.md`:
|
|
258
|
+
|
|
259
|
+
1. Create and edit a spec with `yarn research:core init ...`.
|
|
260
|
+
2. Freeze the causal claim, family, target direction, ordered universe hash,
|
|
261
|
+
full resolved configs plus their canonical hashes, window, execution model,
|
|
262
|
+
variants, selection rules, and explicit
|
|
263
|
+
stage (`screen`, `isolated_long`, or `confirmation`) before runs. Never
|
|
264
|
+
infer the stage from period length or the presence of a run ID. Later stages
|
|
265
|
+
must name `parentResearchIds`; regenerate the family stage index.
|
|
266
|
+
3. Run `prepare`, then `analyze` completed exports or `run` explicit isolated
|
|
267
|
+
commands. Never discover a mutable latest run implicitly.
|
|
268
|
+
4. Require completed-manifest/full-checkpoint/one-config reconciliation.
|
|
269
|
+
Inspect setup matching, ALL/LONG/SHORT, terminal/fold/month/regime matrices,
|
|
270
|
+
cluster bootstrap, family-aware Holm, DSR/PBO diagnostics, and cost stress.
|
|
271
|
+
5. Run `verify` before the immutable note. Link bundle hashes, while still
|
|
272
|
+
embedding the complete resolved config and structured metrics required by
|
|
273
|
+
the note schema.
|
|
274
|
+
|
|
275
|
+
When `$strategy-improvement-research` invokes this skill, execute only the
|
|
276
|
+
preregistered experiment and return its reconciled evidence. The orchestrator
|
|
277
|
+
owns parent/child selection, research-budget accounting, belief updates, and
|
|
278
|
+
the decision to run another candidate.
|
|
279
|
+
|
|
280
|
+
After changing the contour itself, use its public test seam:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
yarn research:core:test
|
|
284
|
+
yarn research:core:coverage
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The coverage command enforces the checked-in floor. Test observable immutable
|
|
288
|
+
specs/results/artifacts and selection decisions; mock only Redis, child-process,
|
|
289
|
+
time/randomness, or filesystem boundaries. Do not mock internal metric,
|
|
290
|
+
comparison, or statistics modules. Preserve single-pass streaming JSONL ingest,
|
|
291
|
+
stable non-empty trade identities, one semantic threshold evaluator across full/
|
|
292
|
+
terminal/cost-stress windows, unconditional terminal cadence floors, and bounded
|
|
293
|
+
SVG rendering. Visual downsampling must never alter full-resolution metrics,
|
|
294
|
+
matching, reconciliation, or `trades.jsonl`.
|
|
295
|
+
|
|
296
|
+
Reuse already chronological trades instead of sorting each cohort/window again,
|
|
297
|
+
group regimes in one pass, and stream normalized trade/match artifacts with
|
|
298
|
+
backpressure. Do not build one export-sized output string in memory.
|
|
299
|
+
|
|
300
|
+
Bootstrap the complete immutable calendar window, including zero-trade
|
|
301
|
+
clusters; do not sample only active clusters. Report CSCV/PBO as unavailable
|
|
302
|
+
when fold vectors are identical and there is no meaningful model ranking.
|
|
303
|
+
|
|
304
|
+
Use `--researchTrace` only when the question needs the setup/entry/skip funnel.
|
|
305
|
+
It writes compact events plus per-test skip summaries and adds deterministic
|
|
306
|
+
setup identity to AI rows; keep it off when completed trades answer the question.
|
|
307
|
+
|
|
308
|
+
Before writing research results, read `references/research-notes.md` and follow
|
|
309
|
+
it exactly.
|
|
310
|
+
|
|
311
|
+
- Store strategy research at
|
|
312
|
+
`notes/<Strategy>/YYYY-MM-DD-<short-kebab-slug>.md`.
|
|
313
|
+
- Keep `notes/` local-only. Never stage, commit, or force-add its contents; the
|
|
314
|
+
directory must remain ignored by Git.
|
|
315
|
+
- Create one file per research question and immutable run/export lineage. Never
|
|
316
|
+
append another dated study to an existing rolling notes file.
|
|
317
|
+
- Put repository-wide work in `notes/Shared/` and genuine multi-strategy
|
|
318
|
+
comparisons in `notes/CrossStrategy/`; never place files directly in
|
|
319
|
+
`notes/`.
|
|
320
|
+
- Embed the complete secret-free resolved config and the authoritative
|
|
321
|
+
structured metrics JSON. Paths to Redis, cached orders, exports, or output
|
|
322
|
+
reports are not enough because those artifacts may be deleted.
|
|
323
|
+
- Use `reproduction: complete` only when the note alone preserves every
|
|
324
|
+
reported aggregate metric and its lineage. Mark missing historical evidence
|
|
325
|
+
`partial` or `blocked`; never reconstruct it from current defaults.
|
|
326
|
+
- Run
|
|
327
|
+
`node .codex/skills/strategy-backtest-research/scripts/research-notes-check.mjs`
|
|
328
|
+
after creating or editing research records.
|
|
329
|
+
|
|
330
|
+
## Validation
|
|
331
|
+
|
|
332
|
+
- Run the affected strategy tests after strategy edits, for example `yarn jest packages/strategies/src/<StrategyName> --runInBand`.
|
|
333
|
+
- Run `yarn prettify` before broader verification.
|
|
334
|
+
- Run `yarn checks` before final handoff when practical.
|