Skip to content

Commit 6ac8851

Browse files
authored
Merge pull request #1 from cpparnell/feature/v1
v1.0
2 parents 195b51e + 6b2f288 commit 6ac8851

67 files changed

Lines changed: 7027 additions & 441 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.DS_Store

6 KB
Binary file not shown.

.env.example

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
# Anthropic API key (required for all LLM agent calls)
22
ANTHROPIC_API_KEY=
33

4-
# Trading mode: paper (Binance testnet, default) | live (Binance mainnet)
4+
# Trading mode: paper (DRY_RUN, default) | live (Kraken mainnet)
55
TRADING_MODE=paper
66
# Required when TRADING_MODE=live — safety gate to prevent accidental live trading
77
# COUNCIL_LIVE_CONFIRMED=1
88

9-
# Binance testnet API credentials (paper trading)
10-
BINANCE_TESTNET_API_KEY=
11-
BINANCE_TESTNET_SECRET=
9+
# Kraken API credentials (required for live order execution only)
10+
# Not needed for backtesting or paper trading (DRY_RUN=1)
11+
KRAKEN_API_KEY=
12+
KRAKEN_SECRET=
1213

13-
# News feeds
14+
# News feeds (optional — falls back to empty list without keys)
1415
CRYPTOPANIC_API_KEY=
1516
NEWSAPI_KEY=
1617

@@ -25,15 +26,11 @@ CRYPTOQUANT_API_KEY=
2526
TELEGRAM_BOT_TOKEN=
2627
TELEGRAM_CHAT_ID=
2728

28-
# Binance mainnet credentials (live trading only — set TRADING_MODE=live)
29-
# BINANCE_API_KEY=
30-
# BINANCE_SECRET=
31-
3229
# Starting capital in USD (used to seed portfolio_state on first run)
3330
INITIAL_CAPITAL=10000
3431

3532
# SQLite database path (default: ./council.db)
3633
# COUNCIL_DB_PATH=council.db
3734

38-
# Set to 1 to skip order execution and log only (useful for debugging cycles)
35+
# Set to 1 to skip order execution and log only (paper trading mode)
3936
# DRY_RUN=0

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,9 @@ __marimo__/
210210
.claude/
211211

212212
# Misc.
213-
NOTES.md
213+
NOTES.md
214+
CHANGELOG.md
215+
216+
# Temporary files
217+
tmp/
218+
prompts/personal/

CHANGELOG.md

Lines changed: 176 additions & 4 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 102 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,38 @@
11
# Council — BTC LLM Trading Bot
22

3-
A Bitcoin swing trading bot that uses a council of specialised LLM agents to generate daily BUY/SELL/HOLD signals and execute them against Binance testnet (paper) or mainnet (live).
3+
A Bitcoin swing trading framework built around a **council of LLM agents** that vote on daily BUY/SELL/HOLD signals. Fully configurable — define your own agents, weights, and risk rules in a single YAML file without writing code.
44

55
## Architecture
66

77
```
8-
Data Pipeline (CCXT/Binance, CryptoPanic, Alternative.me, Glassnode)
8+
strategy.yaml (agents, weights, SL/TP rules, validation thresholds)
9+
10+
11+
Data Pipeline (CCXT/Kraken, GDELT news, Alternative.me, CoinMetrics, yfinance)
912
1013
1114
Tier-0 Validation (price freshness, news count, drawdown halt, ATR halt)
15+
│ ↑ thresholds from strategy.yaml
16+
17+
Generic Council Runner — agents defined in strategy.yaml, run in parallel
18+
├── Directional agents (any number, any model, user-defined prompts)
19+
└── Veto agent (optional; forces HOLD if veto=true)
1220
1321
14-
Council of LLMs (parallel)
15-
├── Technical Analyst (claude-haiku-4-5)
16-
├── Sentiment Analyst (claude-haiku-4-5)
17-
├── Fundamental Analyst (claude-haiku-4-5)
18-
└── Risk Manager (claude-sonnet-4-6)
22+
Deterministic Scorer (confidence-weighted signed-score from strategy weights)
1923
2024
21-
Deliberation / Chair (claude-sonnet-4-6) → BUY / SELL / HOLD
25+
Optional Deliberation (narrative synthesis, claude-sonnet-4-6) → BUY / SELL / HOLD
2226
2327
24-
Execution Layer (Binance testnet/mainnet) + SQLite Logging
28+
Execution Layer (Kraken paper/live) + SQLite Logging
2529
2630
├── Reflection Loop (post-trade analysis, claude-sonnet-4-6)
2731
└── Weekly Summary (performance review, claude-sonnet-4-6)
2832
```
2933

34+
The default strategy (`strategies/default.yaml`) reproduces the original v2 council: Technical (40%) + Sentiment (25%) + Fundamental (35%) + Risk veto.
35+
3036
## Setup
3137

3238
```bash
@@ -35,14 +41,56 @@ pip install -e ".[dev]"
3541
cp .env.example .env # fill in ANTHROPIC_API_KEY at minimum
3642
```
3743

44+
## Custom Strategies (v3)
45+
46+
Define a strategy as a YAML file — no Python required.
47+
48+
```yaml
49+
# strategies/my_strategy.yaml
50+
name: "My Momentum Strategy"
51+
agents:
52+
- name: trend
53+
model: claude-haiku-4-5
54+
prompt: prompts/agent_template.txt # copy & customise
55+
weight: 0.60
56+
- name: macro
57+
model: claude-haiku-4-5
58+
prompt: prompts/agent_template.txt
59+
weight: 0.40
60+
- name: risk_guard
61+
model: claude-sonnet-4-6
62+
prompt: prompts/veto_agent_template.txt
63+
is_veto: true
64+
scoring:
65+
confidence_floor: 30
66+
trade_threshold: 0.25
67+
risk:
68+
stop_loss:
69+
type: atr_multiple
70+
value: 2.0
71+
take_profit:
72+
type: fixed_pct
73+
value: 0.08
74+
max_position_pct: 15.0
75+
validation:
76+
max_drawdown_pct: 12.0
77+
atr_spike_multiplier: 2.5
78+
```
79+
80+
Start from `strategies/example.yaml` (fully commented) and `prompts/agent_template.txt` / `prompts/veto_agent_template.txt`.
81+
3882
## Running
3983

4084
```bash
41-
# One-shot cycle (run once and exit)
85+
# One-shot cycle — default v2 council
4286
python -m src.main
4387
88+
# One-shot cycle — custom strategy
89+
python -m src.main --strategy strategies/my_strategy.yaml
90+
4491
# Dry run (logs council decision, no orders placed)
4592
DRY_RUN=1 python -m src.main
93+
DRY_RUN=1 python -m src.main --strategy strategies/my_strategy.yaml
4694
4795
# Daily scheduler (00:05 UTC) + weekly summary (Sunday 08:00 UTC)
4896
python -m src.main --schedule
@@ -51,26 +99,65 @@ python -m src.main --schedule
5199
python -m src.main --weekly
52100
```
53101

102+
## Backtesting
103+
104+
Run the LLM council against historical BTC data without executing real orders:
105+
106+
```bash
107+
# Backtest over 2024 — default council
108+
python -m src.backtest.engine \
109+
--start 2024-01-01 \
110+
--end 2025-01-01 \
111+
--capital 250000
112+
113+
# Backtest with a custom strategy
114+
python -m src.backtest.engine \
115+
--start 2023-01-01 \
116+
--end 2024-01-01 \
117+
--capital 250000 \
118+
--strategy strategies/my_strategy.yaml
119+
120+
# Quick smoke test
121+
python -m src.backtest.engine \
122+
--start 2024-06-01 \
123+
--end 2024-09-01 \
124+
--capital 250000 \
125+
--no-save-csv
126+
```
127+
128+
**Cost:** ~$10–15 in Anthropic API calls per year of daily cycles (~365 × ~$0.03).
129+
130+
**Capital note:** Set `--capital` high enough that 20% position sizing can buy at least 1 BTC. At ~$50k/BTC you need at least `--capital 250000`.
131+
132+
Each run creates a timestamped folder under `tmp/YYYYMMDD_HHMMSS/` containing:
133+
- `backtest_signals_<start>_<end>.csv` — per-day signal log, written one row per cycle (flushed immediately) so it survives a kill
134+
- `run.log` — full console output, written continuously (line-buffered) so it survives a kill
135+
136+
Output includes Return%, Sharpe, Max Drawdown, Win Rate, Avg Trade, and Expectancy.
137+
54138
## Testing
55139

56140
```bash
57-
pytest -v # all 203 tests
141+
pytest -v # all 344 tests
58142
pytest tests/test_db.py -v # DB layer
59143
pytest tests/test_execution.py -v # execution + router
60144
pytest tests/test_reporting.py -v # metrics + weekly summary
61145
pytest tests/test_agents.py -v # agent framework
146+
pytest tests/test_backtest.py -v # backtesting module
62147
pytest tests/test_agents.py::test_run_council_hold_on_veto -v # single test
148+
pytest tests/test_strategy_loader.py -v # strategy YAML loader
149+
pytest tests/test_strategy_scoring.py -v # generic scoring + SL/TP rules
150+
pytest tests/test_strategy_runner.py -v # generic council runner
151+
pytest tests/test_strategy_parity.py -v # legacy vs generic scorer parity
63152
```
64153

65154
## Environment Variables
66155

67156
| Variable | Required | Default | Description |
68157
|---|---|---|---|
69158
| `ANTHROPIC_API_KEY` | Yes | — | Claude API key |
70-
| `BINANCE_TESTNET_API_KEY` | Paper mode || Binance testnet key |
71-
| `BINANCE_TESTNET_SECRET` | Paper mode || Binance testnet secret |
72-
| `BINANCE_API_KEY` | Live mode || Binance mainnet key |
73-
| `BINANCE_SECRET` | Live mode || Binance mainnet secret |
159+
| `KRAKEN_API_KEY` | Live mode | — | Kraken API key |
160+
| `KRAKEN_SECRET` | Live mode | — | Kraken private key |
74161
| `COUNCIL_DB_PATH` | No | `./council.db` | SQLite database path |
75162
| `INITIAL_CAPITAL` | No | `10000` | Starting paper capital (USD) |
76163
| `TRADING_MODE` | No | `paper` | `paper` (testnet) or `live` (mainnet) |
@@ -80,20 +167,3 @@ pytest tests/test_agents.py::test_run_council_hold_on_veto -v # single test
80167
| `LUNARCRUSH_API_KEY` | No | — | Sentiment (falls back to Fear/Greed proxy) |
81168
| `GLASSNODE_API_KEY` | No | — | On-chain data (falls back to zeros) |
82169

83-
## Development Phases
84-
85-
- **Phase 1** ✅ Data pipeline + Tier-0 validation
86-
- **Phase 2** ✅ Agent framework (4 agents + deliberation)
87-
- **Phase 3** ✅ Execution layer + SQLite logging + reflection loop
88-
- **Phase 4** ✅ Performance metrics + weekly summary agent
89-
- **Phase 5** Paper trading (60 days minimum on live data with simulated capital)
90-
- **Phase 6** Live deployment (≤ $500 initial capital)
91-
92-
## Success Targets (Phase 5 evaluation)
93-
94-
| Metric | Target |
95-
|---|---|
96-
| Sharpe ratio | ≥ 1.5 |
97-
| Max drawdown | < 20% |
98-
| Expectancy | Positive |
99-
| Council consistency | ≥ 40% unanimous cycles |

prompts/agent_template.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
You are a [DESCRIBE YOUR AGENT ROLE] for a Bitcoin swing trading system.
2+
3+
[DESCRIBE WHAT YOUR AGENT FOCUSES ON — e.g., technical price action, news sentiment, on-chain activity, macro conditions, or a combination. Be specific about which sections of the market context are most relevant to your analysis.]
4+
5+
Your output must be a JSON object with exactly these fields:
6+
7+
direction — "BUY", "SELL", or "HOLD"
8+
BUY = you believe price is likely to rise over the next 1–3 days
9+
SELL = you believe price is likely to fall, or the position should be closed
10+
HOLD = insufficient conviction, conflicting signals, or no clear edge
11+
12+
confidence — integer 0 to 100
13+
Calibration guide:
14+
80–100: very strong signal, clear and aligned evidence
15+
60–79: solid signal, most evidence points one way
16+
40–59: moderate signal, some evidence but notable uncertainty
17+
20–39: weak signal, mixed or thin evidence
18+
0–19: near-neutral, use HOLD direction at this range
19+
20+
Avoid defaulting to 50. Use the full scale. Low confidence should
21+
be reflected in HOLD direction, not in a 50-confidence BUY/SELL.
22+
23+
reasoning — string (2–4 sentences)
24+
Explain WHY you chose this direction and confidence. Cite the
25+
specific data from the context that drove your conclusion.
26+
Mention what would change your view (invalidation conditions).
27+
28+
Available context sections (from the market context block):
29+
PRICE — current price, 24h change, volume
30+
TECHNICAL INDICATORS — RSI, MACD, Bollinger Bands, EMAs, ATR, regime
31+
NEWS — recent headlines with source and timestamp
32+
SENTIMENT — Fear/Greed index, Reddit sentiment, social volume
33+
ON-CHAIN — exchange flows, whale transactions, MVRV
34+
MACRO — VIX, DXY, SPX trend, 10Y yield, macro bias
35+
PORTFOLIO — current position, cash, drawdown
36+
37+
Focus your analysis on the sections most relevant to your role.

prompts/deliberation_v1.txt

Lines changed: 0 additions & 36 deletions
This file was deleted.

prompts/fundamental_analyst_v1.txt

Lines changed: 0 additions & 21 deletions
This file was deleted.

prompts/reflection_v1.txt

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)