Skip to content

olkuznetsov/llm-trading-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Multi-Agent LLM Trading Agent — Architecture Case Study

An experimental autonomous trading agent built on a multi-agent LLM architecture: four specialized language-model "brains" that observe the market, open and manage positions, learn from outcomes, and rewrite their own configuration from real performance data — a closed learning loop.

This repository is an architecture & engineering case study of a personal research project. It documents the system design and the interesting problems solved. It is not trading advice, and the live implementation (keys, strategy parameters, execution) is kept private.


Why this project is interesting

It's a small, real, always-on system that exercises the hard parts of applied LLM engineering:

  • Multi-agent orchestration — specialized agents with distinct roles and a shared state contract
  • A self-improving control loop — an optimizer agent tunes the parameters that drive the other agents
  • LLM reliability engineering — a 7-provider fallback chain, malformed-output recovery, rate-limit handling
  • Guarding against reward-hacking — keeping a self-tuning agent from optimizing a proxy metric to a degenerate extreme
  • Scientific validation — historical replay backtesting and path-dependent analysis to avoid biased conclusions

The trading domain is really just a demanding test-bed: real-time data, irreversible actions, money on the line, and an adversarial environment. The value is the systems engineering, not the P&L.


System overview

                     ┌──────────────────────────────────────────────┐
   market data ─────▶│  Brain 1 — Entry Analyst                     │
   (prices, funding, │  scores setups → direction + confidence      │──▶ open position
    order book,      └──────────────────────────────────────────────┘
    sentiment)       ┌──────────────────────────────────────────────┐
   open positions ──▶│  Brain 2 — Position Monitor                   │──▶ hold / exit
                     │  manages live trades against the thesis       │
                     └──────────────────────────────────────────────┘
   closed trades ───▶┌──────────────────────────────────────────────┐
                     │  Brain 3 — Strategy Learner                   │──▶ pattern insights
                     │  mines outcomes for what works / fails        │
                     └──────────────────────────────────────────────┘
                     ┌──────────────────────────────────────────────┐
   full history ────▶│  Brain 4 — Meta-Optimizer                    │──▶ writes config
                     │  self-tunes the config the others read        │      (closed loop)
                     └──────────────────────────────────────────────┘
                                        │
                                        ▼
                           shared config  ◀── read by Brain 1 & 2 every cycle

Each brain is a focused LLM call with its own system prompt, output schema, and validation. They communicate through structured state (a shared config file + a trade journal), not free text — so the system is inspectable and each agent's contribution is auditable.


Engineering highlights

1. A self-improving control loop

The meta-optimizer (Brain 4) reads the real closed-trade history every cycle and writes the parameter file that Brains 1 & 2 consume — entry thresholds, exit timing, per-instrument biases. The system therefore adapts to changing regimes without human retuning. This is the core idea: the agents don't just act, they close the loop on their own behavior.

2. "Fix the prompt, not the clamp"

When the optimizer made a poor choice, the discipline was to fix the root cause in its prompt or its input data, never to bolt on a hard-coded constraint — because a clamp treats the symptom and quietly defeats the adaptive behavior that makes the system valuable. Safety bounds are acceptable rails; restrictive floors that force an outcome are not.

3. Guarding a self-tuner against its own metric (reward-hacking, in miniature)

A memorable failure: the optimizer was fed a signal that looked monotonic ("lower this value rescues more losing trades") and walked the parameter straight to its bound — past the point that made sense. The fix wasn't to constrain it, but to ship the stop-condition alongside the signal as data: the target value, and an explicit note that the metric's monotonic appearance was an artifact. Lesson that generalizes to any optimizer: a directional signal without its floor gets optimized to the extreme.

4. LLM reliability as a first-class concern

Free-tier models are flaky, so the call layer is a resilient fallback chain (7 providers). It handles: per-model rate limits, reasoning models that spend the token budget on chain-of-thought, and malformed / truncated JSON. One concrete bug: a reasoning model pretty-prints JSON, so it truncated at a token budget that fit a compact-JSON provider — silently failing on the preferred provider every call. Fixed by sizing the budget to the model's actual verbosity.

5. Validation you can trust

Strategy changes are gated by a kline-replay backtester, and — importantly — by path-dependent analysis. A naive "what-if" sweep over historical trades over-credited outcomes it couldn't actually have achieved; decomposing effects by their true price-path ordering exposed which conclusions were real. Several intuitively-appealing ideas were rejected this way before shipping.

6. Production safety reflexes

Small details that matter when actions are irreversible: idempotent order submission, a guard against a failed data fetch being misread as "everything closed" (which once caused a phantom position close), and consistent timezone handling across data sources.


Tech stack

  • Python — async event loop, one control cycle per interval
  • LLMs — multi-provider (Cerebras / Mistral / SambaNova / Gemini / Groq / local), OpenAI-compatible APIs
  • Exchangeccxt (live, exchange demo/paper, and offline backtest modes share one code path)
  • Data — OHLCV klines, funding, order-book, open-interest, plus news/sentiment signals
  • Ops — runs as a long-lived service; structured logging; a change-log ("wave") discipline for every modification

What I'd highlight from building this

  • Designing specialized agents + a shared, inspectable state contract beats one mega-prompt: each agent stays simple, testable, and independently improvable.
  • The highest-leverage work in an LLM system is often the data you feed the model and the reliability layer around it, not the model choice.
  • A self-tuning system needs guardrails expressed as information, not hard limits — or it optimizes the letter of the metric, not the intent.

Personal research project. Not financial advice.

About

Multi-agent LLM trading agent — architecture & engineering case study

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors