Commit Graph
5 Commits
Author SHA1 Message Date
Haozhe Wu d3c76819c3 fix: complete October 11-12 maintenance and research updates
Fix live option guards, grounding operand evidence, source-bound benchmarks, trade artifacts, attribution, drawdowns, valuation tolerances, and SEC point-in-time factor inputs.

Add Brazil research data and market support, 13 fundamental and valuation factors, channel progress forwarding, and opt-in ZimaOS templates. Update seven README News sections with three visible dates.

Validation: 17,635 backend tests passed; 1,084 final targeted tests and 103 frontend tests passed. Frontend build, package build, documentation checks, and CI gates passed.
2026-10-12 02:29:46 +08:00
Haozhe WuandClaude Opus 5 759dfab924 fix: close the two gaps found reviewing #1368 and #1369
#1368 relaxed the benchmark availability check from the whole run to the
regime's own bars, but `_bar_returns` reads `series[index - 1]` — the
anchor bar is outside `bar_indices` by construction, so verifying the
regime's own bars verifies nothing about it. A single unparseable
benchmark cell before a regime's first bar then reached `previous <= 0`
as None; `rebuild_evidence`'s except swallowed the TypeError and the
WHOLE run produced no evidence rows. A missing endpoint now yields no
return for that bar, exactly as a non-finite one already did.

#1369 fixed the bare `M2K` form but not its dated contracts: `M2KZ4`
still extracted `M` and silently took the `_MULTIPLIER.get(product, 50)`
default. Resolve a symbol against the multiplier table first, longest
match wins — which subsumes the PR's own month-code-collision special
case (MYM2503, FESX2503), covers the embedded-digit forms it missed, and
keeps SILZ4 as micro silver rather than SI. A product absent from the
table still falls through to the shape regexes.

Mutation-checked both ways: reverting the None guard fails the two new
strategy-discovery tests with the original TypeError; dropping the
listed-product lookup fails six global-futures cases.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 02:01:42 +08:00
Lanre Shittu 189f4d0551 fix(strategy-discovery): resolve position size per regime, not once for the whole run
compute_evidence_for_run resolved exposure-derived position sizing a
single time before the per-regime loop, so every regime's breakeven
fee calculation used the same whole-run average exposure. A strategy
that runs small in a bear regime and large in a bull regime got one
blended size applied to both, understating breakeven costs for the
regime that actually ran smaller and overstating them for the one
that ran larger.

Move the position-size resolution inside the loop so each regime uses
only its own bars' exposure. This also fixes read_equity_series, whose
exposure column was returned as a compacted list with entries dropped
for non-positive or missing values, so it no longer lined up
positionally with bar index. Exposure is now aligned to bar position
like the existing benchmark column, with None marking bars that lack a
usable value, so per-regime slicing by bar index is correct.

Also scopes the benchmark-completeness check for excess return to the
regime's own bar_indices instead of the whole run's benchmark list.

Signed-off-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com>
2026-09-06 05:37:55 +00:00
shadowinlife ae68820a71 feat(agent): add evidence population, decay monitoring and stale refusal to strategy discovery
Implements #969 Phase 2 over the Phase 1 facade (#978). The evidence cache
is no longer empty-by-construction and no longer silent about age:

- refresh_strategy_evidence: agent tool (primary, scheduler-reachable) +
  MCP wrapper + 'vibe-trading strategy-evidence refresh --manifest' CLI.
  Manifest-driven only — runs carry no attribution, so explicit
  {strategy_id, run_dir, position_size} specs are the honest path; entries
  outside the runtime runs root / allowed run roots are skipped with a
  stable path-outside-allowed-roots reason. Writes only the disposable
  facade-owned cache.
- backtest-diagnose hookup: the skill's Hard-Gate Checklist becomes the
  evidence ingestion gate — state.json success, metrics.csv present,
  trade_count > 0, equity present and NaN-free, each with a stable
  hard-gate:* skip token. NaN-equity runs are refused entirely instead of
  yielding partial-curve evidence (fixes the Phase-1 silent-skip latent).
- atomic rebuild: compute all rows first, then one transaction swaps the
  store — a failed rebuild can no longer leave the cache empty.
- decay status surfaced in query_strategies / get_strategy_evidence:
  freshness computed at read time from the evidence-window age
  (fresh/aging/stale, 90/180-day thresholds tied to the quarterly
  re-backtest cadence; last_verified reported but never gating). Stale rows
  fail closed out of default recommendations (include_stale opt-out);
  sdm:* rows mirror the SDM lifecycle (decayed/disabled never recommended,
  sdm-lifecycle: prefix); unparseable windows fail closed to stale.
  Decay is never persisted — a stored decay field would go stale by
  definition.
- docs + count sync: strategy-discovery SKILL.md gains the Decay &
  Freshness Contract and Populating & Refreshing Evidence sections;
  backtest-diagnose SKILL.md documents the gate hookup; phantom-guard test
  now asserts every tool named in the SKILL.md recipe is registered;
  MCP tools 73 -> 74 across five READMEs + agent/SKILL.md (65 -> 66
  decorators).
2026-08-19 15:04:15 +08:00
shadowinlife bbfd82c87d feat(agent): add evidence-gated strategy discovery facade 2026-08-19 14:57:06 +08:00