🔭 AlphaAgent
An asset-agnostic, multi-agent stock & crypto screening framework — with an honest backtest and a leakage-aware agent layer.
Pluggable pools → cheap quant filter → multi-agent due diligence → rule-based entry timing.
🚧 Pre-alpha. APIs may still change. Nothing here is investment advice — see the disclaimer.
TL;DR — AlphaAgent is an open-source, multi-agent framework for screening stocks and crypto with LLMs, built to avoid the lookahead bias / data leakage that quietly fakes most LLM trading backtests. A point-in-time guard (PIT-Guard) bounds every agent to as-of data, and the profit-proving backtest runs on deterministic rules only — the LLM is never in the measured loop. Runs fully offline with make demo (zero keys, zero network).
Why another trading-agent repo?
Most LLM trading bots share the same two blind spots: they can't be honestly backtested, and their agents quietly read the future (the model already knows what happened; live web/tool calls return post-date data). AlphaAgent is built around fixing exactly that.
Four things it's built around:
| What it means | |
|---|---|
| 🧱 Mechanical / agent separation | The number that proves edge (backtest) runs on deterministic rules only — the LLM is bypassed, so agent hallucination can't inflate your equity curve. |
| 🔌 Pluggable collaboration | panel (parallel experts + judge), debate (bull vs bear), vote — swap the multi-agent topology from config, don't rebuild the orchestration. |
| 🪙 Asset-agnostic | Stocks and crypto through one symbol-routing + provider registry. Add a market = drop one loader file. |
| 🛡️ PIT-Guard | A point-in-time middleware that intercepts every agent tool call, enforces data timestamp ≤ as-of date, and mitigates the model's own parametric leakage (anonymization + evidence-grounding + a leakage probe). |
What is "leakage-aware" (point-in-time) LLM evaluation?
Lookahead bias (a.k.a. data leakage) is when a backtest or an agent uses information it could not have had at decision time — future prices, restated fundamentals, or news published after the as-of date. It makes results look brilliant on paper and fail live.
For LLM trading agents the problem is worse than in classical quant: the model's weights already encode what happened after any historical date, and live web/tool calls return post-date data. Point-in-time (PIT) correctness means every input is filtered to timestamp ≤ as-of date. AlphaAgent enforces this at the tool boundary and additionally bounds the model's parametric memory (anonymization, evidence-grounding, a leakage probe) — collectively PIT-Guard.
How it works
Two independent gates — AI for the qualitative call, rules for the timing — never mixed:
flowchart TD
CLI["CLI · run screen / run backtest / demo"] --> ORCH["Pipeline Orchestrator"]
subgraph S1["① Selection chain"]
POOL["PoolSource registry<br/>watchlist · strategy · reddit …"] --> FILTER["QuantFilter<br/>cheap, backtestable rules"]
FILTER --> PANEL["AgentPanel<br/>multi-agent, tool-using"]
end
subgraph S2["② Entry chain"]
ENTRY["EntryTiming<br/>pure rules / technical signals"]
end
ORCH --> POOL
PANEL -->|"Verdict: rating + rationale + risks"| ENTRY
ENTRY --> REPORT["📄 Report + Entry signal"]
ORCH --> BT["📊 Backtest<br/>(mechanical layer only, OSS framework)"]
DATA["DataProvider registry<br/>symbol routing → yfinance / CoinGecko …"] -.-> S1
DATA -.-> S2
LLM["LLM abstraction<br/>bring-your-own-key, vendor-agnostic"] -.-> PANEL
PIT["🛡️ PIT-Guard middleware"] -.-> PANEL
- Pool — pluggable sources produce a candidate universe (multi-source hits are flagged as signal resonance).
- Filter — cheap quantitative rules compress the pool to a handful; output is a scored table, not pass/fail.
- Agents — only survivors go to the expensive layer: specialist agents (fundamental / technical / sentiment / risk) analyze in parallel via tools, a judge aggregates a structured
Verdict. - Entry — pure technical/rule signals decide when —
buy / wait / pass+ trigger price. No LLM here.
Quickstart
git clone https://github.com/kamendula/AlphaAgent.git && cd AlphaAgent
make demo # runs the whole chain on bundled offline snapshots — zero keys, zero network, zero install
Want live data + a real LLM? Point at a config (free sources like yfinance need no key; set FMP_API_KEY / OPENROUTER_API_KEY in .env for FMP + OpenRouter):
python -m alphaagent screen --config configs/real.toml
python -m alphaagent backtest --symbol NVDA --config configs/demo.toml
The multi-agent panel runs in the demo via a deterministic offline mock LLM — no keys needed. Swap
llm = "mock"→"openrouter"/"openai"in the config for real reasoning. Configs are TOML (parsed by the stdlib on Python 3.11+, so the demo needs no YAML library).
Sample run
A live run (configs/real.toml: FMP market data + fundamentals + news, the HY model via OpenRouter, PIT-Guard on). The mechanical filter ranks the universe, then only the top candidates go to the agent panel; entry timing is pure rules:
# SYMBOL TYPE SCORE FACTORS SOURCES
1 AAPL equity 0.644 trend=0.82 momentum=0.91 not_overbought=0.20 real
2 GOOGL equity 0.594 trend=0.47 momentum=0.82 not_overbought=0.50 real
3 NVDA equity 0.584 trend=0.21 momentum=0.65 not_overbought=0.90 real
...
Agent panel verdicts
--------------------
AAPL -> BUY (confidence 0.31)
· fundamental cautious High net margin (26.6%) & revenue +16.6%, but EPS not accelerating and PE 30.8 rich.
· technical bullish Above 50-day SMA (313.9 vs 295.1), 60d momentum +20.5%, RSI 61.8 — strong, not overbought.
· sentiment neutral Mildly positive mega-cap tech tone; no symbol-specific catalyst.
· risk neutral ATR 2.8%, 60d drawdown -12.7%, RSI not crowded — clean.
GOOGL -> AVOID (confidence 0.28)
· fundamental neutral Revenue +21.8%, net margin 56.9%, PE 13.9 reasonable — but EPS decelerating.
· technical cautious Below the 50-day SMA; mixed momentum.
· risk cautious 16.2% drawdown + elevated ATR 3.2%.
Entry signals (rule-based, no agent)
-----------------------------------
AAPL WAIT trigger=300.10 extended 4.6% above EMA — wait for a pullback
GOOGL PASS uptrend broken (close 369.69 <= sma50)
🛡️ PIT-Guard: leakage probe 0.00 (clean); agent tools bounded to as-of, evidence-grounded.
The offline make demo produces the same shape instantly (mock LLM + bundled snapshots), so anyone can reproduce the flow with zero setup.
The moat: PIT-Guard 🛡️
| Typical LLM trading bot | AlphaAgent | |
|---|---|---|
| Does the backtest include the LLM? | Yes → hallucination inflates returns | No → mechanical layer only |
| Are agents limited to as-of data? | Rarely enforced | Enforced at the tool boundary |
| Handles the model "already knowing the future"? | Ignored | Anonymization + evidence-grounding + leakage probe |
| Reproducible offline? | Needs keys / network | make demo, zero keys |
Leakage comes in two flavors. AlphaAgent treats them separately:
① Tool/data leakage — 100% enforceable. A middleware sits at the tool boundary and guarantees every agent only sees data timestamped on or before the as-of date: price series truncated, news date-filtered, fundamentals served as point-in-time snapshots (as-reported, not restated).
② Parametric leakage — the model already knows the future. You can't delete it from the weights, so AlphaAgent bounds it:
- Anonymization — strip ticker/company name; the agent judges "this anonymous security with these features", not "NVDA, which I know 10×'d".
- Evidence-grounding — every claim must cite an
evidence_reffrom a guarded tool; ungrounded recall is rejected. - Post-cutoff evaluation + leakage probe — historical agent eval runs only on dates after the model's training cutoff, with a probe that measures residual contamination.
And crucially: the headline backtest never includes the agent, so parametric leakage can't touch it.
Extending it (one file + one line)
Every extension point is a registry plugin:
from alphaagent.data import register, DataProvider
@register("myexchange")
class MyExchangeProvider(DataProvider):
def get(self, kind, symbol, as_of): ...
The same pattern works for PoolSource, QuantFilter, Analyst roles, CollaborationPolicy, and EntryRule. See examples/ for a reference implementation of each, and CONTRIBUTING.md.
Optional: MCP server
AlphaAgent ships a thin, optional MCP server so clients like Claude Code can call it directly. It exposes get_prices, classify_symbol, screen, and list_providers, delegating to the same code the CLI uses. It is not imported by any default path and needs the mcp SDK only when actually run.
pip install "alphaagent[mcp]"
python -m alphaagent.mcp # serves over stdio
// e.g. Claude Code / Claude Desktop MCP config
{ "mcpServers": { "alphaagent": { "command": "python", "args": ["-m", "alphaagent.mcp"] } } }
🗺️ Roadmap
- M0 — core registries + data model + yfinance provider +
make demo - M1 — selection chain: pool + filter +
panel/vote/llm_judgecollaboration + 4 analysts + vendor-agnostic LLM (offline mock) + FMP provider - M2 — entry rules (
breakout/pullback) + backtest adapters (simplestdlib + optionalbacktesting.py) + mechanical-layer report +alphaagent backtest - M3 — PIT-Guard: boundary (
GuardedRouter) + anonymization + evidence-grounding + leakage probe - M4 —
debatepolicy · optional MCP server · editable prompt files (agents/prompts/*.md) · reference examples for every extension point
FAQ
Does AlphaAgent prevent lookahead bias / data leakage?
Yes — it's the core design. PIT-Guard filters every agent tool call to timestamp ≤ as-of, and the performance backtest excludes the LLM entirely, so agent leakage can't touch the headline number.
How is this different from a normal LLM trading backtest? Most LLM backtests run the model inside the historical loop, so its future knowledge (and post-date news) silently leaks in. AlphaAgent separates a deterministic, backtestable mechanical layer from the (non-backtested) agent layer, and guards the agent layer point-in-time.
Which LLMs does it work with? Any — it's vendor-agnostic. Built-in clients for OpenAI and OpenRouter (including free models), plus a deterministic offline mock LLM so the demo needs no API key.
Does it place real trades? No. It outputs research + rule-based entry signals only. Not investment advice.
Does it support stocks and crypto? Both, through one symbol-routing + provider registry. Data via FMP or yfinance, or bundled offline snapshots for the demo.
Can I add my own data source, strategy, or agent? Yes — every extension point is a one-file, one-decorator plugin: data providers, pool sources, quant filters, analyst roles, collaboration policies, and entry rules.
⚠️ Disclaimer
AlphaAgent is a research and educational framework. It does not place real orders and is not investment advice. Markets are risky; you are responsible for your own decisions.
License
MIT — see LICENSE.
Release files for alphaagent-quant 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| alphaagent_quant-0.1.0.tar.gz | 107.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| alphaagent_quant-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 191.5 kB
Release files / alphaagent_quant-0.1.0.tar.gz
| Download URL | alphaagent_quant-0.1.0.tar.gz |
|---|---|
| Size | 107.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
86de1cba24552c5914a8f09f3918e853e4bb6bc1f8efb17cfcdbe37eabd37432
|
|
BLAKE2b-256 checksum How to use checksums |
e4e1ece514585d02cd9ac4156fd5a06145eb5d236d8723648be6b99ee7e85b55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.4
|
Release files / alphaagent_quant-0.1.0-py3-none-any.whl
| Download URL | alphaagent_quant-0.1.0-py3-none-any.whl |
|---|---|
| Size | 83.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
05be09e4a7688f5663bb564a7aab184d344904bdeb11e725160541ccf6e99aac
|
|
BLAKE2b-256 checksum How to use checksums |
14df846730debacfe1c9e2fe4872903fa89f1c92ffca3cb8ce05b89558339e16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.4
|