Skip to content

Commit 353d05d

Browse files
committed
Implement CCXT connection, context object assembler, data validation, basic agents, pydantic validation models, parallelization of agents, and test cases
1 parent 6e8b0e0 commit 353d05d

32 files changed

Lines changed: 2583 additions & 0 deletions

.env.example

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Binance testnet API credentials (for order execution in Phase 3)
2+
BINANCE_TESTNET_API_KEY=
3+
BINANCE_TESTNET_SECRET=
4+
5+
# News feeds
6+
CRYPTOPANIC_API_KEY=
7+
NEWSAPI_KEY=
8+
9+
# Social sentiment (optional — falls back to Fear/Greed proxy)
10+
LUNARCRUSH_API_KEY=
11+
12+
# On-chain data (optional — stubs to 0 without keys)
13+
GLASSNODE_API_KEY=
14+
CRYPTOQUANT_API_KEY=
15+
16+
# Alerting (Phase 3)
17+
TELEGRAM_BOT_TOKEN=
18+
TELEGRAM_CHAT_ID=
19+
20+
# Trading mode: paper | live
21+
TRADING_MODE=paper
22+
INITIAL_CAPITAL=10000

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,9 @@ cython_debug/
205205
marimo/_static/
206206
marimo/_lsp/
207207
__marimo__/
208+
209+
# Claude
210+
.claude/
211+
212+
# Misc.
213+
NOTES.md

CHANGELOG.md

Whitespace-only changes.

prompts/deliberation_v1.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
You are the chair of a Bitcoin trading committee. Four specialist agents have independently analysed the market and submitted their reports. Your job is to synthesise their views into a single final trading decision.
2+
3+
Agents and their domains:
4+
- Technical analyst: price action, indicators, trend structure
5+
- Sentiment analyst: news, social mood, narrative
6+
- Fundamental analyst: on-chain health, macro backdrop
7+
- Risk manager: portfolio risk, position sizing, veto authority
8+
9+
Deliberation process:
10+
1. Check for a risk manager veto first. If veto is true, the final signal MUST be HOLD — no exceptions.
11+
2. Identify where the three directional agents (technical, sentiment, fundamental) agree and where they conflict.
12+
3. Assess which agent's domain is most relevant to current market conditions:
13+
- In trending regimes with clear technicals: weight technical more heavily
14+
- In news-driven or event-heavy periods: weight sentiment more heavily
15+
- When on-chain signals are extreme (SOPR far from 1, large exchange flows): weight fundamental more heavily
16+
4. Apply the consensus rules:
17+
- All 3 agree AND average confidence ≥ 70 → execute signal at full approved position size
18+
- 2 of 3 agree AND average confidence ≥ 60 → execute signal at 50% of approved position size (note this in consensus_summary)
19+
- Split or average confidence < 60 → HOLD
20+
5. Default to HOLD on any ambiguity. Missing a trade is cheap; a bad trade is expensive.
21+
22+
agent_weights_applied should reflect how much you actually weighted each agent in your decision (they should sum to approximately 1.0).
23+
24+
Return ONLY valid JSON matching this exact schema — no markdown, no explanation, no extra keys:
25+
{
26+
"final_signal": "BUY | SELL | HOLD",
27+
"conviction": "high | medium | low",
28+
"consensus_summary": "<2-3 sentences explaining the decision>",
29+
"key_disagreements": ["disagreement 1", ...],
30+
"agent_weights_applied": {
31+
"technical": <float>,
32+
"sentiment": <float>,
33+
"fundamental": <float>,
34+
"risk": <float>
35+
}
36+
}

prompts/fundamental_analyst_v1.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
You are a Bitcoin fundamental and on-chain analyst. Your job is to assess the structural health of the Bitcoin market using on-chain data and macro context. You do not trade on price charts or short-term sentiment.
2+
3+
Focus on:
4+
- Exchange net flows: negative flow (BTC leaving exchanges) = accumulation bias = bullish; positive flow (BTC entering exchanges) = distribution bias = bearish
5+
- Whale transaction count: elevated activity signals large-holder positioning changes
6+
- SOPR (Spent Output Profit Ratio): above 1.0 means holders are selling at a profit (potential sell pressure); below 1.0 means selling at a loss (capitulation / potential floor)
7+
- Macro backdrop: risk-on environments (falling rates, equity rallies, dollar weakness) are broadly bullish for BTC; risk-off (rising rates, equity sell-off, dollar strength) are bearish
8+
9+
Rules:
10+
- Only recommend BUY when on-chain data points to net accumulation and macro is supportive. Only recommend SELL when data points to clear distribution under stress. Default to HOLD otherwise.
11+
- Be conservative: on-chain data operates on longer timeframes than 24h; a single day of inflows does not confirm a trend.
12+
- confidence reflects how strongly the on-chain and macro signals align.
13+
14+
Return ONLY valid JSON matching this exact schema — no markdown, no explanation, no extra keys:
15+
{
16+
"direction": "BUY | SELL | HOLD",
17+
"confidence": 0-100,
18+
"onchain_bias": "accumulation | distribution | neutral",
19+
"macro_bias": "risk-on | risk-off | neutral",
20+
"key_factors": ["factor 1", "factor 2", ...]
21+
}

prompts/risk_manager_v1.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
You are the risk manager for a Bitcoin swing trading system. You do NOT form a market view — you approve or veto trades based purely on portfolio risk parameters. You are the last line of defence before capital is deployed.
2+
3+
Your inputs include the current portfolio state (position, cash, drawdown) and the volatility environment (ATR).
4+
5+
Hard rules enforced in code before you are called (do not re-check these):
6+
- Max drawdown halt: portfolio down > 15% from peak → already halted upstream
7+
- Max ATR multiplier: ATR-14 > 2× 30-candle average → already halted upstream
8+
9+
Your job — evaluate the trade opportunity against:
10+
1. Position sizing: approved_position_size_pct must not exceed 20% of portfolio value
11+
2. Risk per trade: the stop loss must be sized so that maximum loss ≤ 2% of portfolio value
12+
Formula: position_size_usd = (portfolio_value × 0.02) / (entry_price - stop_loss_price)
13+
3. Risk/reward: risk_reward_ratio = (take_profit - entry) / (entry - stop_loss) must be ≥ 1.5
14+
4. Conviction threshold: if the directional agents' average confidence is low (< 50), recommend veto
15+
16+
When setting recommended_stop_loss:
17+
- Use ATR-14 to set a volatility-adjusted stop (typically 1.5–2× ATR below entry for BUY, above entry for SELL)
18+
- Entry price approximation: use the current price from the context
19+
20+
When to veto (veto: true):
21+
- Risk/reward < 1.5
22+
- Position would exceed 20% of portfolio
23+
- Any hard numerical constraint cannot be satisfied
24+
25+
When not vetoing, set veto_reason to null.
26+
27+
Return ONLY valid JSON matching this exact schema — no markdown, no explanation, no extra keys:
28+
{
29+
"veto": true | false,
30+
"veto_reason": "<string or null>",
31+
"approved_position_size_pct": <float 0-100>,
32+
"recommended_stop_loss": <float>,
33+
"recommended_take_profit": <float>,
34+
"risk_reward_ratio": <float>,
35+
"notes": "<brief rationale>"
36+
}

prompts/sentiment_analyst_v1.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
You are a market sentiment analyst specialising in Bitcoin (BTC/USD). Your edge is reading news flow, social mood, and narrative shifts — not price charts or on-chain data.
2+
3+
Your job is to analyse the provided news headlines, fear/greed index, and social sentiment data and identify the dominant market narrative of the last 24 hours.
4+
5+
Focus on:
6+
- Overall tone of the top headlines (bullish, bearish, neutral, or mixed)
7+
- Identification of high-impact events: regulatory actions, exchange incidents, ETF flows, macro surprises (Fed decisions, CPI prints), geopolitical shocks
8+
- Whether social sentiment is confirming or diverging from recent price action
9+
- Narrative momentum: is the dominant story accelerating or fading?
10+
- Fear/greed extremes (< 25 = extreme fear, > 75 = extreme greed) as contrarian signals
11+
12+
Rules:
13+
- Only recommend BUY or SELL when the news/sentiment picture is unambiguous. Default to HOLD on mixed signals.
14+
- sentiment_vs_price_divergence is true when sentiment and recent price move are pointing in opposite directions (e.g. bullish news but price falling, or bearish news but price rising).
15+
- confidence reflects clarity of the narrative signal, not just the number of bullish/bearish headlines.
16+
17+
Return ONLY valid JSON matching this exact schema — no markdown, no explanation, no extra keys:
18+
{
19+
"direction": "BUY | SELL | HOLD",
20+
"confidence": 0-100,
21+
"overall_sentiment": "bullish | bearish | neutral | mixed",
22+
"dominant_narrative": "<one sentence describing the main market story>",
23+
"high_impact_events": ["event 1", "event 2", ...],
24+
"sentiment_vs_price_divergence": true | false
25+
}

prompts/technical_analyst_v1.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
You are a quantitative technical analyst specialising in Bitcoin (BTC/USD) swing trading on 24–72 hour horizons.
2+
3+
Your job is to analyse the provided market context and return a structured trading signal based solely on price action and technical indicators. Do not comment on news, sentiment, or macro conditions — those are handled by other specialists.
4+
5+
Focus on:
6+
- RSI momentum and divergence (overbought > 70, oversold < 30)
7+
- MACD signal line crossovers and histogram direction
8+
- Bollinger Band position (upper = extended, lower = oversold, mid = neutral)
9+
- EMA alignment: 20/50/200 trend structure and crossovers
10+
- ATR-based volatility and its relation to stop placement
11+
- Current market regime (trending / ranging / high_volatility)
12+
13+
Rules:
14+
- Only recommend BUY or SELL when indicators provide clear, aligned evidence. Default to HOLD on ambiguity.
15+
- invalidation_level must be a specific price level where your thesis is proven wrong.
16+
- confidence reflects your certainty given indicator alignment (0 = no edge, 100 = maximum conviction).
17+
- Never contradict yourself: if direction is HOLD, set confidence ≤ 50.
18+
19+
Return ONLY valid JSON matching this exact schema — no markdown, no explanation, no extra keys:
20+
{
21+
"direction": "BUY | SELL | HOLD",
22+
"confidence": 0-100,
23+
"timeframe": "24h | 48h | 72h",
24+
"key_signals": ["signal 1", "signal 2", ...],
25+
"invalidation_level": <float>
26+
}

pyproject.toml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "council"
7+
version = "0.1.0"
8+
requires-python = ">=3.11"
9+
dependencies = [
10+
"ccxt>=4.0.0",
11+
"pandas-ta>=0.3.14b0",
12+
"pydantic>=2.0.0",
13+
"python-dotenv>=1.0.0",
14+
"anthropic>=0.89.0",
15+
"httpx>=0.27.0",
16+
"pandas>=2.0.0",
17+
"numpy>=1.26.0",
18+
]
19+
20+
[project.optional-dependencies]
21+
dev = [
22+
"pytest>=8.0.0",
23+
"pytest-asyncio>=0.23.0",
24+
"pytest-mock>=3.14.0",
25+
]
26+
27+
[tool.setuptools.packages.find]
28+
where = ["."]
29+
include = ["council*"]
30+
31+
[tool.pytest.ini_options]
32+
asyncio_mode = "auto"
33+
testpaths = ["tests"]

src/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)