Evaluation methodology, integrity controls, and reward design. Every claim on this site is either backed by a measured number or clearly marked as design intent.
All training data is restricted to dates before May 1, 2025. The subsequent 12+ months constitute the evaluation window that no model has seen during training.
test_oos_leakage.py runs 5 tests in the CI pipeline:
.sql files; any query referencing 19 known training tables must include WHERE <date_col> < '2025-05-01'JoinedStr nodes); same filter requirement@oos-eval-only pragma (for evaluation code that intentionally reads OOS data) must only appear in allowlisted filesbq_safe.py provides a TrainingBQClient wrapper that raises OOSLeakageError if a query touches a training table without the cutoff filter — defence-in-depth for dynamically constructed queries that static analysis might miss.
| Table | Total Rows | Pre-Cutoff | Removed | % |
|---|---|---|---|---|
| sentinel1_weekly_tank_features | 5,124 | 4,578 | 546 | 10.7% |
| calendar_spreads | 20,276 | 19,804 | 472 | 2.3% |
| market_prices | 40,014 | 39,062 | 952 | 2.4% |
| release_clock | 1,148 | 1,099 | 49 | 4.3% |
| cot_positions | 327 | 75 | 252 | 77.1% |
During out-of-sample replay, the agent traverses historical decision points chronologically. Without safeguards, memory retrieval could access episodes recorded after the simulated timestamp — letting the agent "remember the future."
All 8 memory retrieval paths accept an optional query_ts parameter. When provided, each path applies a strict less-than filter:
| Retrieval Site | Filter | Column |
|---|---|---|
| EpisodicMemory._bq_keyword_search() | AND ts < @query_ts | ts |
| EpisodicMemory.get_recent() | WHERE ts < @query_ts | ts |
| EpisodicMemory._local_search() | ep.timestamp < query_ts | timestamp |
| SemanticMemory._bq_search() | AND first_observed < @query_ts | first_observed |
| SemanticMemory.retrieve_relevant() | fact.first_observed < query_ts | first_observed |
| ProceduralMemory._bq_lookup() | AND last_used < @query_ts | last_used |
| ProceduralMemory.get_best_sequences() | record.last_used < query_ts | last_used |
| compare_to_history skill | AND trade_date < @query_ts | trade_date |
Enforced by 16 dedicated tests in test_causal_leakage.py that verify local cache filtering, backward compatibility, and BQ query source code analysis.
R_total = R_directional + α·R_task + β·R_memory + γ·R_consistency + δ·R_retention − λ·C_cost + penalties
Default weights: α = 1.0, β = 0.5, γ = 0.3, δ = 0.2, λ = 0.1
| Component | Definition | Signal Source |
|---|---|---|
| R_directional | tanh(pnl_realized / 10.0) | Environment — subsequent price movement |
| R_task | Skill completion quality [0,1] | LLM judge or heuristic |
| R_memory | reward_with − reward_without memory | Counterfactual differential |
| R_consistency | Directional agreement across turns | Internal coherence |
| R_retention | probe_pass_count / probe_total | Retention probe tests |
| C_cost | clip(cost / $0.50, 0, 1) | API costs |
Preference pairs are generated from environment feedback (not human annotation): trajectories whose recommended direction aligns with subsequent price movement are preferred. Target base model: Qwen 2.5 7B. Infrastructure is built; execution is deferred pending strategy refinement to ensure the P&L signal carries sufficient edge.
random_state=42 across 22 model constructorsv0.2.0-oos-clean