Add cross-run learning via run ledger and compare endpoint

Persist strategy + run_id to results/run_ledger.jsonl after each backtest.
On startup, load the ledger, fetch metrics via the new compare endpoint
(batched in groups of 50), group by strategy, rank by avg Sharpe, and
inject a summary of the top 5 and worst 3 prior strategies into the
iteration-1 prompt.

Also consumes the enriched result_summary fields from swym patch e47c18:
sortino_ratio, calmar_ratio, max_drawdown, pnl_return, avg_win, avg_loss,
max_win, max_loss, avg_hold_duration_secs. Sortino and max_drawdown are
appended to summary_line() when present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 13:05:39 +02:00
parent 609d64587b
commit a0316be798
3 changed files with 292 additions and 5 deletions

View File

@@ -493,9 +493,14 @@ CRITICAL: `apply_func` uses `"input"`, not `"expr"`. Writing `"expr":` will be r
}
/// Build the user message for the first iteration (no prior results).
pub fn initial_prompt(instruments: &[String], candle_intervals: &[String]) -> String {
/// `prior_summary` contains a formatted summary of results from previous runs, if any.
pub fn initial_prompt(instruments: &[String], candle_intervals: &[String], prior_summary: Option<&str>) -> String {
let prior_section = match prior_summary {
Some(s) => format!("{s}\n\n"),
None => String::new(),
};
format!(
r#"Design a trading strategy for crypto spot markets.
r#"{prior_section}Design a trading strategy for crypto spot markets.
Available instruments: {}
Available candle intervals: {}