A-share multi-agent trading research system. 4 AI agents (Analyst/Trader/Risk Manager/Reviewer) collaborate on "analyze → decide → audit → review" using LangGraph, with 7 pluggable skills, ChromaDB memory, and a self-built backtest engine.
Research & historical backtesting only. Not investment advice. Does not connect to live trading.
Analyst → Trader → Risk Manager ⇄ Defense → Reviewer
│ │ │ │
3 skills 2 skills 2 skills ChromaDB + SQLite
(parallel)(parallel) (serial) (memory layer)
| Agent | Role | Skills |
|---|---|---|
| Analyst | Integrates multi-dimension data → structured report | Technical (MACD/RSI/MA), Fundamental (ROE/margin/growth), Sentiment (news/north-bound/margin) |
| Trader | Report → structured trade proposal | Timing, Position Sizing |
| Risk Manager | Risk assessment + rule checking + adversarial questioning (max 2 rounds) | VaR/Drawdown, Threshold Rules |
| Reviewer | Writes trade journal, stores market feature vectors | None (pure state → journal) |
Risk questioning mechanism: When the trader's proposal violates a medium-severity rule, the Risk Manager asks a question → Trader defends → Risk Manager reviews. High-severity violations are rejected immediately without LLM. Max 2 rounds, then forced rejection.
Hybrid backtest strategy: LLM analysis every 5 trading days (deep reasoning) + rule engine on the other 4 days (<0.1s per day). 22 trading days ≈ 4-5 LLM calls.
Python 3.11+, Node.js 18+.
# Backend
pip install -e ".[dev]"
cp .env.example .env # then edit .env with your DEEPSEEK_API_KEY
uvicorn src.api.app:app --host 127.0.0.1 --port 8000 --reload
# Frontend (new terminal)
cd web && npm install && npm run devOpen http://localhost:5173. Type any 6-digit A-share code, pick a date, click Analyze. Click ▶ Backtest for strategy simulation.
# CLI alternative
curl -X POST http://127.0.0.1:8000/analyze \
-H "Content-Type: application/json" \
-d '{"ticker":"000858","date":"2026-07-03"}'
curl -X POST http://127.0.0.1:8000/backtest \
-H "Content-Type: application/json" \
-d '{"tickers":["000858"],"start_date":"2024-09-20","end_date":"2024-10-15","initial_capital":1000000}'| Ticker | Period | Trades | Return | Sharpe |
|---|---|---|---|---|
| 000858 | 2024-09-20 → 2024-10-15 | 10 | +11.9% | 1.89 |
| 000858 | 2026-06-01 → 2026-07-01 | 20 | -6.6% | -2.99 |
| 600519 | 2026-06-01 → 2026-07-01 | 0 | 0% | 0 |
├── config/ # YAML: strategy, risk_rules, llm, agent_skills
├── src/
│ ├── api/ # FastAPI: /analyze, /backtest, /kline, /ws
│ ├── graph/ # LangGraph state + 6 nodes
│ ├── agents/ # Pydantic schemas + System Prompts
│ ├── skills/ # 7 pluggable BaseTool skills
│ ├── data/ # AKShare client + CSV cache
│ ├── memory/ # SQLite + ChromaDB + 12-dim feature vector
│ ├── backtest/ # Self-built engine: Broker + Metrics
│ └── utils/ # LLM factory, config loader, EventBus
├── web/ # React + TypeScript + ECharts frontend
├── tests/ # 50 unit + integration tests
└── docs/ # Architecture spec + testing plan
All strategy parameters in config/strategy.yaml:
rule:
threshold: 0.10 # signal sensitivity (lower = more trades)
max_position: 0.30 # max position per trade
llm:
batch_size: 5 # LLM analysis every N trading daysRisk rules in config/risk_rules.yaml (hot-reload on each request). LLM model in config/llm.yaml. Skills mapped to agents in config/agent_skills.yaml.
- Skills never call LLM — pure functions, backtest-reproducible, zero token cost
- PydanticOutputParser over structured_output — DeepSeek doesn't support json_schema mode
- Self-built backtest engine — Lot-level FIFO, T+1, limit-up/down, commissions; ~150 lines
- AKShare (East Money) for all data — free, stable, no auth required
- ChromaDB with handcrafted features — 12-dim financial vectors, cosine similarity; no embedding model needed
pytest tests/ -v # 50 passed