@tangle-network/agent-bench 0.11.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/HARNESS.md +6 -2
  3. package/README.md +1 -4
  4. package/dist/benchmarks/swe-bench.js +4 -9
  5. package/dist/benchmarks/swe-bench.js.map +1 -1
  6. package/package.json +5 -5
  7. package/scripts/run-package-tests.mjs +2 -2
  8. package/src/benchmarks/swe-bench.test.mts +49 -0
  9. package/src/benchmarks/swe-bench.ts +4 -9
  10. package/src/quant-arena/README.md +0 -144
  11. package/src/quant-arena/backtest.test.mts +0 -135
  12. package/src/quant-arena/backtest.ts +0 -218
  13. package/src/quant-arena/data.test.mts +0 -44
  14. package/src/quant-arena/data.ts +0 -141
  15. package/src/quant-arena/driver.test.mts +0 -253
  16. package/src/quant-arena/driver.ts +0 -219
  17. package/src/quant-arena/fixtures/data/PROVENANCE.md +0 -26
  18. package/src/quant-arena/fixtures/data/holdout/IDX.csv +0 -523
  19. package/src/quant-arena/fixtures/data/holdout/S01.csv +0 -523
  20. package/src/quant-arena/fixtures/data/holdout/S02.csv +0 -523
  21. package/src/quant-arena/fixtures/data/holdout/S03.csv +0 -523
  22. package/src/quant-arena/fixtures/data/holdout/S04.csv +0 -523
  23. package/src/quant-arena/fixtures/data/holdout/S05.csv +0 -523
  24. package/src/quant-arena/fixtures/data/holdout/S06.csv +0 -523
  25. package/src/quant-arena/fixtures/data/holdout/S07.csv +0 -523
  26. package/src/quant-arena/fixtures/data/holdout/S08.csv +0 -523
  27. package/src/quant-arena/fixtures/data/holdout/S09.csv +0 -523
  28. package/src/quant-arena/fixtures/data/holdout/S10.csv +0 -523
  29. package/src/quant-arena/fixtures/data/insample/IDX.csv +0 -2087
  30. package/src/quant-arena/fixtures/data/insample/S01.csv +0 -2087
  31. package/src/quant-arena/fixtures/data/insample/S02.csv +0 -2087
  32. package/src/quant-arena/fixtures/data/insample/S03.csv +0 -2087
  33. package/src/quant-arena/fixtures/data/insample/S04.csv +0 -2087
  34. package/src/quant-arena/fixtures/data/insample/S05.csv +0 -2087
  35. package/src/quant-arena/fixtures/data/insample/S06.csv +0 -2087
  36. package/src/quant-arena/fixtures/data/insample/S07.csv +0 -2087
  37. package/src/quant-arena/fixtures/data/insample/S08.csv +0 -2087
  38. package/src/quant-arena/fixtures/data/insample/S09.csv +0 -2087
  39. package/src/quant-arena/fixtures/data/insample/S10.csv +0 -2087
  40. package/src/quant-arena/fixtures/demo-campaign/cost-ledger.jsonl +0 -16
  41. package/src/quant-arena/fixtures/demo-campaign/notebook.jsonl +0 -5
  42. package/src/quant-arena/fixtures/demo-campaign/rollout-manifest.json +0 -171
  43. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-001-default-author/strategy.ts +0 -119
  44. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-002-default-author/strategy.ts +0 -119
  45. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-003-quant-researcher/strategy.ts +0 -105
  46. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-004-quant-researcher/strategy.ts +0 -102
  47. package/src/quant-arena/fixtures/demo-campaign-v2/cost-ledger.jsonl +0 -4
  48. package/src/quant-arena/fixtures/demo-campaign-v2/notebook.jsonl +0 -2
  49. package/src/quant-arena/fixtures/demo-campaign-v2/rollout-manifest.json +0 -84
  50. package/src/quant-arena/fixtures/demo-campaign-v2/strategies/cand-001-quant-researcher/strategy.ts +0 -117
  51. package/src/quant-arena/holdout-certify.mts +0 -206
  52. package/src/quant-arena/holdout-certify.test.mts +0 -82
  53. package/src/quant-arena/leak-audit.test.mts +0 -79
  54. package/src/quant-arena/leak-audit.ts +0 -95
  55. package/src/quant-arena/make-fixtures.mts +0 -161
  56. package/src/quant-arena/multiplicity.test.mts +0 -68
  57. package/src/quant-arena/multiplicity.ts +0 -87
  58. package/src/quant-arena/nautilus-certify.ts +0 -31
  59. package/src/quant-arena/oms.ts +0 -90
  60. package/src/quant-arena/profiles/quant-researcher.profile.json +0 -12
  61. package/src/quant-arena/python/pyproject.toml +0 -8
  62. package/src/quant-arena/python/uv.lock +0 -1297
  63. package/src/quant-arena/python/vbt-worker.py +0 -192
  64. package/src/quant-arena/quant-loop.mts +0 -840
  65. package/src/quant-arena/quant-loop.test.mts +0 -75
  66. package/src/quant-arena/strategies/buy-hold-index/strategy.ts +0 -11
  67. package/src/quant-arena/strategies/equal-weight/strategy.ts +0 -20
  68. package/src/quant-arena/strategies/sma-crossover/strategy.ts +0 -42
  69. package/src/quant-arena/types.ts +0 -133
  70. package/src/quant-arena/vbt-client.ts +0 -321
  71. package/src/quant-arena/vbt-parity.test.mts +0 -183
  72. package/src/quant-arena/windows.test.mts +0 -45
  73. package/src/quant-arena/windows.ts +0 -54
  74. package/src/rollout-ledger/backfill-swe-arena.mts +0 -610
  75. package/src/rollout-ledger/backfill-swe-arena.test.mts +0 -347
  76. package/src/rollout-ledger/settle-capture.mts +0 -448
  77. package/src/rollout-ledger/settle-capture.test.mts +0 -270
  78. package/src/swe-arena/activation.mts +0 -225
  79. package/src/swe-arena/activation.test.mts +0 -300
  80. package/src/swe-arena/analyze.ts +0 -211
  81. package/src/swe-arena/arms.ts +0 -862
  82. package/src/swe-arena/bootstrap-meta.mts +0 -188
  83. package/src/swe-arena/bootstrap-meta.test.mts +0 -51
  84. package/src/swe-arena/briefing.mts +0 -217
  85. package/src/swe-arena/briefing.test.mts +0 -179
  86. package/src/swe-arena/calibrate.ts +0 -217
  87. package/src/swe-arena/capabilities.mts +0 -76
  88. package/src/swe-arena/capabilities.test.mts +0 -57
  89. package/src/swe-arena/capacity.ts +0 -198
  90. package/src/swe-arena/cell-evidence.mts +0 -437
  91. package/src/swe-arena/cell-evidence.test.mts +0 -248
  92. package/src/swe-arena/diagnosis-ensemble.test.mts +0 -210
  93. package/src/swe-arena/diagnosis-ensemble.ts +0 -523
  94. package/src/swe-arena/execution.test.mts +0 -1171
  95. package/src/swe-arena/factory-command-container.ts +0 -284
  96. package/src/swe-arena/factory-judge-child.mts +0 -228
  97. package/src/swe-arena/factory.test.mts +0 -645
  98. package/src/swe-arena/fixtures/analyze.py +0 -80
  99. package/src/swe-arena/fixtures/excludes.txt +0 -8
  100. package/src/swe-arena/fixtures/factory/agent-eval-309/calibration.md +0 -51
  101. package/src/swe-arena/fixtures/factory/agent-eval-309/manifest.json +0 -29
  102. package/src/swe-arena/fixtures/factory/agent-eval-309/spec.md +0 -64
  103. package/src/swe-arena/fixtures/factory/agent-runtime-232/calibration.md +0 -48
  104. package/src/swe-arena/fixtures/factory/agent-runtime-232/manifest.json +0 -29
  105. package/src/swe-arena/fixtures/factory/agent-runtime-232/spec.md +0 -48
  106. package/src/swe-arena/fixtures/factory/loops-28/calibration.md +0 -47
  107. package/src/swe-arena/fixtures/factory/loops-28/manifest.json +0 -30
  108. package/src/swe-arena/fixtures/factory/loops-28/spec.md +0 -50
  109. package/src/swe-arena/fixtures/gen1-salvage/README.md +0 -45
  110. package/src/swe-arena/fixtures/gen1-salvage/cand0-e6d7361.diff +0 -116
  111. package/src/swe-arena/fixtures/gen1-salvage/cand1-76a8590.diff +0 -293
  112. package/src/swe-arena/fixtures/holdout-preregister.log +0 -12
  113. package/src/swe-arena/fixtures/holdout.json +0 -44
  114. package/src/swe-arena/fixtures/instances.json +0 -146
  115. package/src/swe-arena/fixtures/ledger.jsonl +0 -12
  116. package/src/swe-arena/fixtures/patches/pallets__flask-5014.solo.patch +0 -36
  117. package/src/swe-arena/fixtures/patches/pydata__xarray-4687.sup.patch +0 -33
  118. package/src/swe-arena/fixtures/rejudge.jsonl +0 -15
  119. package/src/swe-arena/fixtures/rematch.jsonl +0 -3
  120. package/src/swe-arena/fixtures/rematch2.jsonl +0 -3
  121. package/src/swe-arena/fixtures/rematch3.jsonl +0 -3
  122. package/src/swe-arena/fixtures/run-report/README.md +0 -43
  123. package/src/swe-arena/fixtures/run-report/factory-agent-eval-309-FSUP0.json +0 -173
  124. package/src/swe-arena/fixtures/run-report/factory-agent-eval-309-FSUP0.md +0 -100
  125. package/src/swe-arena/fixtures/run-report/gen3-rollup.json +0 -551
  126. package/src/swe-arena/fixtures/run-report/gen3-rollup.md +0 -64
  127. package/src/swe-arena/fixtures/sup-journal-true.json +0 -19
  128. package/src/swe-arena/fixtures/verify/astropy__astropy-13033.sh +0 -48
  129. package/src/swe-arena/fixtures/verify/django__django-11532.sh +0 -50
  130. package/src/swe-arena/fixtures/verify/matplotlib__matplotlib-20826.sh +0 -76
  131. package/src/swe-arena/fixtures/verify/pydata__xarray-4687.sh +0 -44
  132. package/src/swe-arena/fixtures/verify/pytest-dev__pytest-6197.sh +0 -32
  133. package/src/swe-arena/fixtures/verify/sphinx-doc__sphinx-9658.sh +0 -51
  134. package/src/swe-arena/fixtures/worker-tokens.json +0 -42
  135. package/src/swe-arena/fixtures.ts +0 -237
  136. package/src/swe-arena/gepa-seat.mts +0 -886
  137. package/src/swe-arena/gepa-seat.test.mts +0 -1136
  138. package/src/swe-arena/holdout-certify.mts +0 -408
  139. package/src/swe-arena/holdout-certify.test.mts +0 -160
  140. package/src/swe-arena/implementation-ref.test.mts +0 -64
  141. package/src/swe-arena/implementation-ref.ts +0 -62
  142. package/src/swe-arena/judge-child.mts +0 -37
  143. package/src/swe-arena/ledger-orphans.mts +0 -77
  144. package/src/swe-arena/ledger-orphans.test.mts +0 -149
  145. package/src/swe-arena/manifest.mts +0 -293
  146. package/src/swe-arena/manifest.test.mts +0 -169
  147. package/src/swe-arena/materialize.ts +0 -142
  148. package/src/swe-arena/outer-loop.mts +0 -2854
  149. package/src/swe-arena/outer-loop.test.mts +0 -714
  150. package/src/swe-arena/parity.test.mts +0 -87
  151. package/src/swe-arena/premeasured-from-cells.mts +0 -296
  152. package/src/swe-arena/premeasured-from-cells.test.mts +0 -201
  153. package/src/swe-arena/proc.test.mts +0 -172
  154. package/src/swe-arena/proc.ts +0 -260
  155. package/src/swe-arena/profiles/deepseek-author.profile.json +0 -12
  156. package/src/swe-arena/profiles/default-author.profile.json +0 -12
  157. package/src/swe-arena/proposer-fanout.mts +0 -736
  158. package/src/swe-arena/proposer-fanout.test.mts +0 -660
  159. package/src/swe-arena/proposer-provenance.mts +0 -176
  160. package/src/swe-arena/proposer-provenance.test.mts +0 -106
  161. package/src/swe-arena/reconcile.ts +0 -0
  162. package/src/swe-arena/replay.mts +0 -183
  163. package/src/swe-arena/replay.test.mts +0 -300
  164. package/src/swe-arena/run-experiment.mts +0 -729
  165. package/src/swe-arena/run-report.mts +0 -75
  166. package/src/swe-arena/run-supervisor.mjs +0 -297
  167. package/src/swe-arena/run-supervisor.test.mts +0 -539
  168. package/src/swe-arena/score-split.mts +0 -140
  169. package/src/swe-arena/score-split.test.mts +0 -123
  170. package/src/swe-arena/scratch-worktree-serialization.test.mts +0 -72
  171. package/src/swe-arena/scratch-worktree.test.mts +0 -56
  172. package/src/swe-arena/scratch-worktree.ts +0 -64
  173. package/src/swe-arena/serialized-judge.ts +0 -414
  174. package/src/swe-arena/types.ts +0 -218
@@ -1,219 +0,0 @@
1
- /**
2
- * Incremental strategy driver — the v2 harness. Feeds a `Strategy` one bar
3
- * at a time and enforces history visibility STRUCTURALLY: before every
4
- * `onBar(ctx)` call the bar arrays are physically sliced to `[0..t]`, so
5
- * data after the decision day does not exist in anything the strategy can
6
- * reach. (A Proxy that throws on out-of-range reads was the alternative;
7
- * slicing was chosen because it is simpler, allocation-cheap at this scale
8
- * — slices copy references, not bars — and gives the harder guarantee:
9
- * future bars are ABSENT, not merely guarded. The truncation leak audit
10
- * stays in place on top of this as defense in depth, and because the v1
11
- * batch contract can still leak.)
12
- *
13
- * Portfolio state shown to the strategy (ctx.weights / ctx.equity) evolves
14
- * under EXACTLY the engine's execution model (see backtest.ts): a decision
15
- * at the close of day t fills at day t+1's open, fees in bps of traded
16
- * dollars, positions drift in between. `driver.test.mts` asserts the
17
- * driver's equity path is bit-identical to `runBacktest` on the collected
18
- * decisions.
19
- *
20
- * Outputs per run:
21
- * - `decisions` — the decision record [(t, weights)], one row per rebalance;
22
- * this is what the scorers (vectorbt worker, TS prefilter) consume.
23
- * - `orders` — the OMS order stream produced by the SHARED rebalancer
24
- * (oms.ts) from those decisions. Strategies never emit orders.
25
- * - `equityByDay` — the driver's own equity path (close-marked).
26
- */
27
-
28
- import { pathToFileURL } from 'node:url'
29
- import { assertAligned } from './backtest.ts'
30
- import { rebalance, targetsToWeights } from './oms.ts'
31
- import type { Bar, GenerateSignals, Order, Signal, Strategy, StrategyContext, TargetPosition } from './types.ts'
32
-
33
- export interface DriverConfig {
34
- /** One-way transaction cost, basis points of traded dollars. */
35
- costBps: number
36
- /** One-way slippage, basis points of traded dollars. */
37
- slippageBps: number
38
- /** Universe tickers; symbols[0] is the index. Length must match bars. */
39
- symbols: string[]
40
- /** Provenance tag stamped on every order (e.g. the candidate id). */
41
- tag?: string
42
- }
43
-
44
- export interface DriverRun {
45
- /** The decision record: one Signal per rebalance, in day order. */
46
- decisions: Signal[]
47
- /** OMS orders from the shared rebalancer, in emission order. */
48
- orders: Order[]
49
- /** Equity at each day's close under the engine's execution model. */
50
- equityByDay: number[]
51
- }
52
-
53
- export function runIncremental(bars: Bar[][], strategy: Strategy, config: DriverConfig): DriverRun {
54
- assertAligned(bars)
55
- const N = bars.length
56
- if (config.symbols.length !== N) {
57
- throw new Error(`driver: ${config.symbols.length} symbols for ${N} bar series`)
58
- }
59
- if (typeof strategy?.onBar !== 'function') {
60
- throw new Error('driver: strategy does not implement onBar(ctx)')
61
- }
62
- const T = bars[0]!.length
63
- const feeRate = (config.costBps + config.slippageBps) / 10_000
64
-
65
- const decisions: Signal[] = []
66
- const orders: Order[] = []
67
- const equityByDay: number[] = new Array(T).fill(0)
68
- let cash = 1
69
- const pos: number[] = new Array(N).fill(0)
70
- /** Weights of the decision made at day t-1, pending its fill at t's open. */
71
- let pendingFill: number[] | null = null
72
-
73
- for (let t = 0; t < T; t++) {
74
- if (t > 0) {
75
- // Overnight: yesterday's close -> today's open (same as backtest.ts).
76
- for (let k = 0; k < N; k++) {
77
- pos[k] = pos[k]! * (bars[k]![t]!.open / bars[k]![t - 1]!.close)
78
- }
79
- if (pendingFill !== null) {
80
- let equityOpen = cash
81
- for (let k = 0; k < N; k++) equityOpen += pos[k]!
82
- if (equityOpen <= 0) throw new Error(`driver: equity wiped out at t=${t}`)
83
- let traded = 0
84
- for (let k = 0; k < N; k++) {
85
- const desired = pendingFill[k]! * equityOpen
86
- const delta = desired - pos[k]!
87
- traded += Math.abs(delta)
88
- cash -= delta
89
- pos[k] = desired
90
- }
91
- cash -= traded * feeRate
92
- pendingFill = null
93
- }
94
- // Intraday: today's open -> today's close.
95
- for (let k = 0; k < N; k++) {
96
- pos[k] = pos[k]! * (bars[k]![t]!.close / bars[k]![t]!.open)
97
- }
98
- }
99
- let equity = cash
100
- for (let k = 0; k < N; k++) equity += pos[k]!
101
- equityByDay[t] = equity
102
-
103
- // Decision time: the close of day t. History is physically truncated.
104
- const ctx: StrategyContext = {
105
- symbols: config.symbols,
106
- t,
107
- history: bars.map((series) => series.slice(0, t + 1)),
108
- weights: pos.map((p) => (equity > 0 ? p / equity : 0)),
109
- equity,
110
- }
111
- const targets = strategy.onBar(ctx)
112
- if (targets === null || targets === undefined) continue
113
- if (!Array.isArray(targets)) {
114
- throw new Error(`driver: onBar at t=${t} returned ${typeof targets} — expected TargetPosition[] or null`)
115
- }
116
- const weights = targetsToWeights(targets, config.symbols)
117
- decisions.push({ t, weights })
118
- const prices = bars.map((series) => series[t]!.close)
119
- orders.push(
120
- ...rebalance({
121
- targets,
122
- symbols: config.symbols,
123
- equity,
124
- prices,
125
- positionValues: [...pos],
126
- t,
127
- ...(config.tag !== undefined ? { tag: config.tag } : {}),
128
- }),
129
- )
130
- if (t < T - 1) pendingFill = weights
131
- // A decision on the final bar is recorded but can never fill — the same
132
- // truth the batch engine encodes by never reading fills for t = T-1.
133
- }
134
-
135
- return { decisions, orders, equityByDay }
136
- }
137
-
138
- // ---------------------------------------------------------------------------
139
- // Batch-compat shims.
140
- // ---------------------------------------------------------------------------
141
-
142
- /** Wrap a v1 batch strategy (`generateSignals`) as a v2 `Strategy` so the
143
- * pinned baselines and legacy fixtures run UNCHANGED under the incremental
144
- * harness. At every bar the batch function sees only the truncated history
145
- * (the structural guarantee applies to it too) and the shim emits the
146
- * signal it produced for today, if any.
147
- *
148
- * Note the intended consequence: a batch strategy that leaks through
149
- * whole-series statistics computes them over the TRUNCATED history here,
150
- * i.e. the shim converts that leak into a causal (if different) strategy.
151
- * The v1 truncation audit on the raw `generateSignals` remains the guard
152
- * that catches such code as written. */
153
- export function strategyFromGenerateSignals(generateSignals: GenerateSignals): Strategy {
154
- return {
155
- onBar(ctx: StrategyContext): TargetPosition[] | null {
156
- const signals = generateSignals(ctx.history)
157
- const today = signals.filter((s) => s.t === ctx.t)
158
- if (today.length === 0) return null
159
- if (today.length > 1) throw new Error(`batch shim: ${today.length} signals for t=${ctx.t}`)
160
- const weights = today[0]!.weights
161
- if (weights.length !== ctx.symbols.length) {
162
- throw new Error(`batch shim: ${weights.length} weights for ${ctx.symbols.length} symbols at t=${ctx.t}`)
163
- }
164
- // Emit every symbol explicitly (zero weight = sell to flat) so the
165
- // decision is a complete portfolio statement, exactly like v1.
166
- return ctx.symbols.map((symbol, k) => ({ symbol, weight: weights[k]! }))
167
- },
168
- }
169
- }
170
-
171
- /** Adapt a v2 `Strategy` to the v1 batch shape so the existing scoring and
172
- * leak-audit plumbing (`truncationInvariance`, `runBacktest`) consume it
173
- * unchanged. Fees do not alter decisions unless the strategy conditions on
174
- * its own equity path, so the audit drives with the campaign's default
175
- * costs. */
176
- export function generateSignalsFromStrategy(
177
- strategy: Strategy,
178
- opts?: { symbols?: string[]; costBps?: number; slippageBps?: number },
179
- ): GenerateSignals {
180
- return (bars: Bar[][]): Signal[] => {
181
- const symbols = opts?.symbols ?? bars.map((_, k) => (k === 0 ? 'IDX' : `T${String(k).padStart(2, '0')}`))
182
- return runIncremental(bars, strategy, {
183
- costBps: opts?.costBps ?? 10,
184
- slippageBps: opts?.slippageBps ?? 5,
185
- symbols,
186
- }).decisions
187
- }
188
- }
189
-
190
- // ---------------------------------------------------------------------------
191
- // Module loading — one entry point for both contract generations.
192
- // ---------------------------------------------------------------------------
193
-
194
- export interface LoadedStrategy {
195
- kind: 'v2-onBar' | 'v1-batch'
196
- /** Batch view of the strategy; v2 modules are wrapped through the
197
- * incremental driver so the structural history guarantee applies. */
198
- generateSignals: GenerateSignals
199
- }
200
-
201
- /** Import a strategy module from disk and normalize it to the batch shape
202
- * the scoring + leak-audit plumbing consumes. v2 (`onBar`) wins when a
203
- * module exports both. Throws when neither contract is implemented. */
204
- export async function loadStrategyFile(
205
- strategyPath: string,
206
- opts?: { symbols?: string[]; costBps?: number; slippageBps?: number },
207
- ): Promise<LoadedStrategy> {
208
- const mod = (await import(pathToFileURL(strategyPath).href)) as {
209
- onBar?: Strategy['onBar']
210
- generateSignals?: GenerateSignals
211
- }
212
- if (typeof mod.onBar === 'function') {
213
- return { kind: 'v2-onBar', generateSignals: generateSignalsFromStrategy({ onBar: mod.onBar }, opts) }
214
- }
215
- if (typeof mod.generateSignals === 'function') {
216
- return { kind: 'v1-batch', generateSignals: mod.generateSignals }
217
- }
218
- throw new Error(`strategy module exports neither onBar(ctx) nor generateSignals(bars): ${strategyPath}`)
219
- }
@@ -1,26 +0,0 @@
1
- # Data provenance
2
-
3
- Every series in this directory is **synthetic**.
4
- It was produced by `../../make-fixtures.mts` with fixed seed `20260722`; regenerate and diff at any time with:
5
-
6
- ```
7
- tsx src/quant-arena/make-fixtures.mts
8
- ```
9
-
10
- ## Why not real bars
11
-
12
- We wanted ~10 years of real daily bars for ~10 liquid US tickers plus SPY from Stooq (`https://stooq.com/q/d/l/?s=spy.us&i=d`).
13
- Two blockers, verified on 2026-07-22:
14
-
15
- 1. Stooq's terms state the data are for personal use; committing their bars to a redistributable repository is not clearly permitted.
16
- 2. The download endpoint sits behind a JavaScript anti-bot challenge and returned `Access denied` to non-browser clients.
17
-
18
- So the repo ships clearly-labeled synthetic series instead: an index `IDX` (the buy-and-hold benchmark, SPY's role) and ten stocks `S01`-`S10`, generated by a regime-switching market factor plus per-stock beta, idiosyncratic volatility, and rare jumps.
19
- The generator's model and parameters are documented in `make-fixtures.mts` itself.
20
-
21
- If you have the right to use real data locally, drop your own Stooq-format CSVs (`Date,Open,High,Low,Close,Volume`, one file per ticker, `IDX.csv` = your benchmark) into `insample/` and `holdout/` — every consumer reads only this directory layout.
22
-
23
- ## Split
24
-
25
- - `insample/` — weekdays 2016-07-01 .. 2024-06-28 (2086 days). The only data the research loop can see.
26
- - `holdout/` — weekdays 2024-07-01 .. 2026-06-30 (522 days, the final 2 years). Read **only** by the certification command (`holdout-certify.mts`), never by the research loop.