trader.strategies.llm_strategy module¶
A local LLM as a trading strategy.
It implements the same Strategy Protocol as RSI or Turtle, which is the entire point: the model’s decisions flow through the guardrails, executor, and reconciliation that Slice 2 already built and tested. There is no separate authority path for the model to take, so requirements §6.2’s “no strategy bypasses §8” holds structurally rather than by convention.
Not a frozen dataclass, unlike the rule strategies: this one holds collaborators and records what the last call saw, so the pipeline can persist it.
- class trader.strategies.llm_strategy.LlmStrategy(id, llm, news_provider, max_news_items=10, lookback_bars=30, company_aliases=(), max_news_age_hours=72.0, max_reuse_age_minutes=240.0, reuse_price_band_pct=1.0, decision_memory=None, clock=None, alias_resolver=None, analyst_provider=None, earnings_provider=None)[source]¶
Bases:
objectAsks a language model for a long-only decision.
- Parameters:
id (str)
llm (LlmProvider)
news_provider (NewsProvider)
max_news_items (int)
lookback_bars (int)
company_aliases (Sequence[str])
max_news_age_hours (float)
max_reuse_age_minutes (float)
reuse_price_band_pct (float)
decision_memory (DecisionMemory | None)
clock (Callable[[], datetime] | None)
alias_resolver (Callable[[str], Sequence[str]] | None)
analyst_provider (AnalystProvider | None)
earnings_provider (EarningsProvider | None)
- backtestable = False¶
- warmup_bars()[source]¶
Enough bars to fill the lookback window.
The model tolerates fewer — it is shown whatever exists — but the pipeline uses this to size its fetch.
- Return type:
int
- set_benchmark_bars(bars, symbol)[source]¶
Give this cycle’s benchmark bars to the next evaluate() call.
Deliberately not a constructor parameter or an evaluate() argument: the Strategy Protocol’s evaluate(bars, position) signature is shared by four strategy classes and two callers, and CLAUDE.md records how expensive changing it atomically was last time. This is a duck-typed hook instead — run_once.py’s _process_symbol calls it via getattr(strategy, “set_benchmark_bars”, None) immediately before evaluate(), the mirror image of the getattr(strategy, “last_inputs”, {}) read it already does immediately after. A caller that never calls this (replay, most tests, llm-check) leaves both fields None, which build_technical_summary already renders as “Relative strength: not available.” — the same degrade-to-absent contract every other advisory input in this class uses.
- Parameters:
bars (Sequence[Bar] | None)
symbol (str | None)
- Return type:
None