create-tradejs 3.1.26 → 3.1.27-beta.245
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/dist/skill-bundle/.codex/skills/strategy-improvement-research/scripts/final-composition-board.mjs +27 -13
- package/dist/skill-bundle/.codex/skills/strategy-improvement-research/scripts/final-composition-board.test.mjs +3 -0
- package/dist/skill-bundle/.codex/tradejs-skill-bundle.json +3 -3
- package/package.json +1 -1
|
@@ -619,18 +619,32 @@ const equitySvg = (board) => {
|
|
|
619
619
|
const position = y(value);
|
|
620
620
|
return `<line x1="${left}" x2="${width - right}" y1="${position}" y2="${position}" class="grid"/><text x="${left - 18}" y="${position + 5}" text-anchor="end" class="axis">${escapeXml(formatCompact(value))}</text>`;
|
|
621
621
|
}).join('');
|
|
622
|
-
const
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
622
|
+
const spanDays = (maxTime - minTime) / 86_400_000;
|
|
623
|
+
const xTicks = Array.from({ length: 6 }, (_, index) => {
|
|
624
|
+
const timestamp = Math.round(
|
|
625
|
+
minTime + ((maxTime - minTime) * index) / 5,
|
|
626
|
+
);
|
|
627
|
+
const date = new Date(timestamp);
|
|
628
|
+
const label =
|
|
629
|
+
spanDays >= 730
|
|
630
|
+
? `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`
|
|
631
|
+
: spanDays >= 90
|
|
632
|
+
? date.toLocaleDateString('en-CA', {
|
|
633
|
+
timeZone: 'UTC',
|
|
634
|
+
year: 'numeric',
|
|
635
|
+
month: 'short',
|
|
636
|
+
})
|
|
637
|
+
: date.toLocaleDateString('en-CA', {
|
|
638
|
+
timeZone: 'UTC',
|
|
639
|
+
month: 'short',
|
|
640
|
+
day: '2-digit',
|
|
641
|
+
});
|
|
642
|
+
return { label, timestamp };
|
|
643
|
+
});
|
|
644
|
+
const xGrid = xTicks
|
|
645
|
+
.map(({ label, timestamp }) => {
|
|
632
646
|
const position = x(timestamp);
|
|
633
|
-
return `<line x1="${position}" x2="${position}" y1="${top}" y2="${height - bottom}" class="grid faint"/><text x="${position}" y="${height - bottom + 34}" text-anchor="middle" class="axis">${
|
|
647
|
+
return `<line x1="${position}" x2="${position}" y1="${top}" y2="${height - bottom}" class="grid faint"/><text x="${position}" y="${height - bottom + 34}" text-anchor="middle" class="axis">${escapeXml(label)}</text>`;
|
|
634
648
|
})
|
|
635
649
|
.join('');
|
|
636
650
|
const curves = board.candidates
|
|
@@ -652,12 +666,12 @@ const equitySvg = (board) => {
|
|
|
652
666
|
const column = index % columns;
|
|
653
667
|
const row = Math.floor(index / columns);
|
|
654
668
|
const lx = left + column * legendWidth;
|
|
655
|
-
const ly = height - bottom +
|
|
669
|
+
const ly = height - bottom + 110 + row * 58;
|
|
656
670
|
return `<g transform="translate(${lx},${ly})"><rect width="18" height="18" rx="3" fill="${candidate.color}"/><text x="28" y="15" class="legendLabel">${escapeXml(truncate(candidate.label, 35))}</text><text x="28" y="37" class="legendMetric">N=${candidate.metrics.trades} · PnL=${formatNumber(candidate.metrics.pnl, 1)} · DD=${formatNumber(candidate.metrics.maxDrawdown, 1)}</text></g>`;
|
|
657
671
|
})
|
|
658
672
|
.join('');
|
|
659
673
|
const selected = board.candidates.find(({ id }) => id === board.selectedId);
|
|
660
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" role="img" aria-label="${escapeXml(board.strategy)} final composition equity"><style>.bg{fill:#fff}.title{font:700 36px Arial,sans-serif;fill:#172033}.subtitle{font:18px Arial,sans-serif;fill:#687184}.axis{font:15px Arial,sans-serif;fill:#687184}.grid{stroke:#e2e6eb;stroke-width:1.5}.faint{opacity:.55}.legendLabel{font:600 17px Arial,sans-serif;fill:#263044}.legendMetric{font:15px Arial,sans-serif;fill:#687184}.axisTitle{font:17px Arial,sans-serif;fill:#394459}</style><rect width="100%" height="100%" class="bg"/><text x="${left}" y="58" class="title">${escapeXml(board.title)}</text><text x="${left}" y="92" class="subtitle">Baseline = production core + current AI-gate · candidates = core + own deterministic gate</text><text x="${left}" y="120" class="subtitle">Selected: ${escapeXml(selected.label)} · ${escapeXml(board.subtitle)}</text>${yGrid}${xGrid}<line x1="${left}" x2="${width - right}" y1="${y(0)}" y2="${y(0)}" stroke="#aab2bd" stroke-width="1.5"/>${curves}<line x1="${left}" x2="${left}" y1="${top}" y2="${height - bottom}" stroke="#7d8795" stroke-width="1.5"/><line x1="${left}" x2="${width - right}" y1="${height - bottom}" y2="${height - bottom}" stroke="#7d8795" stroke-width="1.5"/><text x="30" y="${top + plotHeight / 2}" transform="rotate(-90 30 ${top + plotHeight / 2})" text-anchor="middle" class="axisTitle">Cumulative PnL (${escapeXml(board.normalization.pnlUnit)})</text>${legend}</svg>`;
|
|
674
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" role="img" aria-label="${escapeXml(board.strategy)} final composition equity"><style>.bg{fill:#fff}.title{font:700 36px Arial,sans-serif;fill:#172033}.subtitle{font:18px Arial,sans-serif;fill:#687184}.axis{font:15px Arial,sans-serif;fill:#687184}.grid{stroke:#e2e6eb;stroke-width:1.5}.faint{opacity:.55}.legendLabel{font:600 17px Arial,sans-serif;fill:#263044}.legendMetric{font:15px Arial,sans-serif;fill:#687184}.axisTitle{font:17px Arial,sans-serif;fill:#394459}</style><rect width="100%" height="100%" class="bg"/><text x="${left}" y="58" class="title">${escapeXml(board.title)}</text><text x="${left}" y="92" class="subtitle">Baseline = production core + current AI-gate · candidates = core + own deterministic gate</text><text x="${left}" y="120" class="subtitle">Selected: ${escapeXml(selected.label)} · ${escapeXml(board.subtitle)}</text>${yGrid}${xGrid}<line x1="${left}" x2="${width - right}" y1="${y(0)}" y2="${y(0)}" stroke="#aab2bd" stroke-width="1.5"/>${curves}<line x1="${left}" x2="${left}" y1="${top}" y2="${height - bottom}" stroke="#7d8795" stroke-width="1.5"/><line x1="${left}" x2="${width - right}" y1="${height - bottom}" y2="${height - bottom}" stroke="#7d8795" stroke-width="1.5"/><text x="${left + plotWidth / 2}" y="${height - bottom + 67}" text-anchor="middle" class="axisTitle">Exit date (UTC)</text><text x="30" y="${top + plotHeight / 2}" transform="rotate(-90 30 ${top + plotHeight / 2})" text-anchor="middle" class="axisTitle">Cumulative PnL (${escapeXml(board.normalization.pnlUnit)})</text>${legend}</svg>`;
|
|
661
675
|
};
|
|
662
676
|
|
|
663
677
|
const verifyCandidateArtifacts = async (board, artifactRoot) => {
|
|
@@ -176,6 +176,9 @@ test('verifies candidate artifacts and renders the dashboard and equity board',
|
|
|
176
176
|
assert.match(dashboard, /Final compositions: PnL ↔ drawdown/u);
|
|
177
177
|
assert.match(equity, /production core \+ current AI-gate/u);
|
|
178
178
|
assert.match(equity, /candidate \+ own gate/u);
|
|
179
|
+
assert.match(equity, /Exit date \(UTC\)/u);
|
|
180
|
+
assert.match(equity, /Nov 2023/u);
|
|
181
|
+
assert.match(equity, /Mar 2024/u);
|
|
179
182
|
});
|
|
180
183
|
|
|
181
184
|
test('renders an additional terminal comparison without changing selectedId', async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "tradejs-skill-bundle/v1",
|
|
3
3
|
"source": "TradeJS-Dev/TradeJS:.codex/skills",
|
|
4
|
-
"bundleSha256": "
|
|
4
|
+
"bundleSha256": "80078cbf06c8239edffb266a36db3a9b7127000a26001381f7fa99b92aa3e4eb",
|
|
5
5
|
"skills": [
|
|
6
6
|
"ai-train-local-research",
|
|
7
7
|
"backtest-config-redis",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
".codex/skills/strategy-improvement-research/references/final-composition-board.md": "05b49ea4aba85792ccea0aeaf4ee2637b808157962f0a38631d6468c342349d6",
|
|
45
45
|
".codex/skills/strategy-improvement-research/scripts/build-final-composition-spec.mjs": "b51873691fafbcf2dd70d8c9a6da842fec5f8358346c632cfe79211db08b18ba",
|
|
46
46
|
".codex/skills/strategy-improvement-research/scripts/build-final-composition-spec.test.mjs": "85d06b8fe09ee7611a3fb989173c361ba32f0e9364422925ff221bfe127b2bfa",
|
|
47
|
-
".codex/skills/strategy-improvement-research/scripts/final-composition-board.mjs": "
|
|
48
|
-
".codex/skills/strategy-improvement-research/scripts/final-composition-board.test.mjs": "
|
|
47
|
+
".codex/skills/strategy-improvement-research/scripts/final-composition-board.mjs": "759ed89f0afcfdff8c710a13d907b959f9bce648d185a15d16034b898656deda",
|
|
48
|
+
".codex/skills/strategy-improvement-research/scripts/final-composition-board.test.mjs": "9bcb15f7a53ca9c55a1e45fc80f6030135952c69cc71179a18f0a714e21be38c",
|
|
49
49
|
".codex/skills/strategy-improvement-research/scripts/freeze-gate-variants.mjs": "17b3c868880ddd5b326d309e6e42eaeef1ea22d625a5db947997ac73b221ad6d",
|
|
50
50
|
".codex/skills/strategy-improvement-research/scripts/freeze-gate-variants.test.mjs": "963e1c64ab3deef11fd48a96e10f3827af38036dfe2eb28daf7849f19dd414d8",
|
|
51
51
|
".codex/skills/strategy-improvement-research/SKILL.md": "6964eb154e40b0b775aa2735b2ebbe998984479f46333ed03eab88d2ee150d48",
|