Jarvis is a Django-based automated trading system for Binance Futures. It previously used a Genetic Algorithm (GA) to evolve trading strategies, but now uses an LLM (Claude Sonnet 4.6) as the sole decision-maker.
Key Facts:
- Market: Binance Futures (perpetual contracts)
- Assets: ~10 coins (BTC, ETH, SOL, PAXG, etc.)
- Accounts: 3 independent accounts managed in a single LLM call
- Interval: Decisions every 1 hour (Celery Beat at :05)
- Leverage: 3x per position
- LLM Model: Claude Sonnet 4.6 (
claude-sonnet-4-6) - Confidence Threshold: 0.75 (positions only opened if LLM confidence ≥ 75%)
- Commission: 0.05% taker fee per side → ~0.30% round-trip at 3x
┌─────────────────────────────────────────────────────┐
│ CELERY BEAT │
│ (every hour at :05) │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ TRADE TASK │
│ 1. Get active strategies (symbol list) │
│ 2. Get current positions per account │
│ 3. Call LLMSignalProvider.get_signals_multi() │
│ 4. Execute signals (open/close on Binance) │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ LLM SIGNAL PROVIDER │
│ │
│ Step 1: PREFETCH market data (parallel) │
│ - Per symbol: price, candles(4h×20), RSI, MACD, │
│ ADX, Bollinger Bands, ATR │
│ - General: Fear&Greed, news (3 categories), │
│ funding rates, economic calendar, US30 │
│ → All fetched from local "simsar" REST API │
│ (thin proxy over Binance + data APIs) │
│ │
│ Step 2: BUILD prompt │
│ - System prompt (Turkish) with rules │
│ - User prompt with all market data + portfolio │
│ │
│ Step 3: CALL Claude Sonnet 4.6 │
│ - Tool-calling loop (max 10 iterations) │
│ - LLM can call `call_api` tool for extra data │
│ (OI, L/S ratio, stochastic, EMA, etc.) │
│ - Retry with exponential backoff on rate limits │
│ │
│ Step 4: PARSE response │
│ - Extract JSON array from response text │
│ - Apply confidence threshold (≥ 0.75) │
│ - Convert to Signal objects │
│ - Save LLMDecision to DB (for audit) │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ BINANCE EXECUTION │
│ - OPEN_LONG → futures market buy + set stop-loss │
│ - OPEN_SHORT → futures market sell + set stop-loss │
│ - CLOSE → close position at market │
│ - HOLD → do nothing │
└─────────────────────────────────────────────────────┘
Before calling the LLM, we pre-fetch ~20 data points per symbol in parallel:
| Data | Source | Per Symbol |
|---|---|---|
| Current price | Binance via simsar | ✓ |
| Last 20 candles (4h OHLCV) | Binance via simsar | ✓ |
| RSI(14) | Calculated | ✓ |
| MACD (12/26/9) | Calculated | ✓ |
| ADX(14) | Calculated | ✓ |
| Bollinger Bands (20,2) | Calculated | ✓ |
| ATR(14) | Calculated | ✓ |
| Funding Rate | Binance Futures | ✓ |
| Fear & Greed Index | Alternative.me | Global |
| News (general + crypto + forex) | Finnhub | Global |
| Economic Calendar | Finnhub | Global |
| US30 (Dow Jones) quote + candles | Yahoo Finance via simsar | Global |
The LLM also has a call_api tool to fetch additional data on-demand:
- Open Interest, Long/Short Ratio, Top Trader Ratio
- Stochastic, EMA, SMA, OBV, MFI, CCI, Williams %R
Sen Jarvis, bir kripto futures portföy yönetim ajanısın.
## Görevin
Birden fazla hesap için karar veriyorsun. Her hesabın pozisyon durumu farklı olabilir.
Piyasa analizini bir kez yap, ama kararları her hesabın mevcut pozisyonuna göre ayrı ayrı ver.
## Sana Sağlanan Veriler
- Her coin için: güncel fiyat, RSI, MACD, ADX, Bollinger Bands, ATR, funding rate, son 20 mum (4h OHLCV)
- Makro göstergeler (trade etmezsin): US30 (Dow Jones) fiyat/mumlar
- Genel: Fear & Greed, haberler (finans + kripto + forex), ekonomik takvim
- Her hesabın mevcut pozisyonları (ayrı ayrı gösterilir)
Ek veri gerekirse (OI, L/S ratio, stochastic vb.) call_api tool'unu kullanabilirsin.
## Piyasa Bilgisi
Aşağıdaki bilgiler kural değil — karar verirken göz önünde bulundurman gereken bağlam:
- US30 (Dow Jones) ABD borsasının nabzını tutar. BTC ve kripto piyasası genellikle ABD borsasıyla
pozitif korelasyon gösterir — borsa düşüşe geçtiğinde kripto da etkilenme eğilimindedir.
- PAXG altın fiyatının Binance'deki proxy'sidir ve trade edilebilir. Altın geleneksel olarak güvenli
liman varlığıdır — savaş, jeopolitik kriz, ekonomik belirsizlik dönemlerinde yatırımcılar altına
yönelir. Risk-off ortamda kripto düşerken PAXG LONG düşünülebilir. Tersine, risk-on ortamda altından
çıkış (PAXG SHORT veya CLOSE) mantıklı olabilir.
- Genel haberler (savaş, jeopolitik kriz, petrol fiyatları) kripto piyasasını doğrudan etkilemese de
yatırımcı psikolojisi üzerinden dolaylı etki yaratır. Risk-off ortamında agresif pozisyonlardan
kaçınmak mantıklı olabilir.
- Funding rate tek başına contrarian sinyal değildir, trend ile birlikte anlam kazanır.
Trend up + funding yüksek → continuation olabilir. Range + funding yüksek → squeeze ihtimali artar.
- Mum formasyonları (doji, engulfing, hammer, shooting star, double top/bottom, head & shoulders,
support/resistance) tek başına karar sebebi değildir ama diğer göstergelerle birlikte
değerlendirdiğinde resmi netleştirir.
- Fear & Greed extreme seviyelerdeyse (< 20 veya > 80) contrarian fırsatlar olabilir — ama her
extreme seviye dönüş demek değildir.
- Piyasa uzun süredir (haftalar/aylar) aynı Fear & Greed aralığında kalabilir. Bu durumda mevcut
Fear & Greed seviyesi tek başına "bekle" sebebi olamaz — o ortam artık "yeni normal"dır.
Mevcut koşullarda trade edilebilir fırsatlar ara.
- BTC ve altcoin'ler genelde koreledir — aynı anda hepsine aynı yönde girmek riski katlar. PAXG ise
ters korelasyon gösterme eğilimindedir, portföy çeşitlendirmesi sağlayabilir.
## İşlem Maliyetleri
- Taker komisyon: %0.05 (her alım ve satımda)
- Round-trip maliyet (aç + kapat): %0.05 × 2 = %0.10
- Kaldıraçlı maliyet: %0.10 × kaldıraç (örn: 3x → %0.30)
- Yani 3x kaldıraçla bir pozisyon açıp kapatmak en az %0.30 kâr etmezse zarardır
- Bu maliyeti her karar öncesi hesaba kat — düşük kâr potansiyeli olan trade'lere girme
- Sık trade yapmak (her saat pozisyon değiştirmek) komisyon maliyetlerini katlar
## Pozisyon Yönetimi
- Pozisyonu OLMAYAN coin: LONG, SHORT veya NO_TRADE
- Pozisyonu OLAN coin: HOLD veya CLOSE
- REVERSE desteklenmiyor — önce CLOSE, sonraki döngüde yeni yön
- Stop-loss %10 olarak Binance'de otomatik ayarlı — zarar kesme senin görevin değil
- CLOSE kararını kâr alma veya teknik dönüş sinyali için ver
- Bir pozisyonu kapatmak, başka bir coin'de pozisyon açmaya engel değildir. Her coin bağımsız
değerlendirilir. "Önce portföyü temizle" gibi genel muhafazakârlık yapma — coin bazında teknik
sinyal varsa işlem aç.
## Çıktı Formatı
Önce düşünce sürecini <analysis> bloğunda yaz (maksimum 10-15 satır), sonra JSON kararlarını ver.
JSON'u ASLA kesme — tüm hesap×coin kombinasyonları için karar olmak ZORUNDA.
Her hesap için ayrı karar ver. Aynı coin için farklı hesaplarda farklı kararlar olabilir
(biri LONG pozisyonda → HOLD/CLOSE, diğerinde pozisyon yok → LONG/SHORT/NO_TRADE).
<analysis>
1. Risk değerlendirmesi: US30 trendi, PAXG trendi ve güvenli liman dinamiği, haberler, genel risk ortamı
2. Piyasa özeti: teknik ve momentum durumu
3. Formasyon tespitleri (varsa)
4. Portföy dengesi notu
</analysis>
```json
[
{
"account": "hesap_adi",
"symbol": "BTCUSDT",
"decision": "LONG | SHORT | NO_TRADE | HOLD | CLOSE",
"confidence": 0.0-1.0,
"reason": "teknik veya makro gerekçe (1-2 cümle, boş bırakma)",
"market_bias": "bullish | bearish | neutral",
"risk_note": "varsa risk notu"
}
]
### User Prompt Template (Django Template)
```django
{% autoescape off %}
## Portföy Durumu
{% for acct in accounts %}
### {{ acct.name }}
{% for p in acct.portfolio %}
{% if not p.has_position %}
- **{{ p.symbol }}** ({{ p.leverage }}x): Pozisyon YOK
{% elif p.pnl_str %}
- **{{ p.symbol }}** ({{ p.leverage }}x): {{ p.side }} @ ${{ p.entry_price }} (PnL: {{ p.pnl_str }}, süre: {{ p.duration }})
{% else %}
- **{{ p.symbol }}** ({{ p.leverage }}x): {{ p.side }}
{% endif %}
{% endfor %}
{% endfor %}
{% if has_market_data %}
## Piyasa Verileri
### Genel Piyasa
Fear & Greed: {{ fg_value }} ({{ fg_class }})
[News items...]
[Calendar items...]
### [SYMBOL]
Fiyat: $...
RSI(14): ...
MACD: ... / sinyal: ... / hist: ...
ADX(14): ...
BB: lower — middle — upper
ATR(14): ...
Mumlar (4h OHLCV): [last 20 candles]
Funding: ...
### Makro Göstergeler
US30 (Dow Jones): $... (+/-...%)
[5-day US30 candles]
{% endif %}
## Görev
Yukarıdaki verileri analiz et ve her hesap×coin kombinasyonu için JSON formatında karar döndür.
{% endautoescape %}
class LLMSignalProvider(SignalProvider):
def get_signals_multi(self, strategies, all_positions, all_open_positions, accounts, dry_run=False):
# 1. Pre-fetch market data for all symbols in parallel (ThreadPoolExecutor, 20 workers)
symbols = [s.symbol for s in strategies]
market_data = _prefetch_market_data(symbols)
# 2. Build user message from Django template
user_message = _build_user_message_multi(strategies, all_positions, all_open_positions, account_names, market_data)
# 3. Single LLM call with tool-calling loop
adapter = get_llm_adapter() # ClaudeAdapter(model="claude-sonnet-4-6")
result = adapter.chat_with_tools(
system_prompt=_get_system_prompt(),
user_message=user_message,
tools=[CALL_API_TOOL], # LLM can request extra data
tool_executor=_tool_executor, # Routes to simsar API
max_iterations=10,
)
# 4. Parse multi-account decisions from response
decisions_per_account = _parse_decisions_multi(result.text)
# 5. Convert to signals with confidence threshold
confidence_threshold = 0.75
for account in accounts:
acct_decisions = decisions_per_account.get(account.name, [])
signals = _decisions_to_signals(acct_decisions, strategies, positions, confidence_threshold)
# Save LLMDecision to DB for audit trail
return signals_per_accountdef _decisions_to_signals(decisions, strategies, positions, confidence_threshold):
for d in decisions:
decision = d.get("decision", "NO_TRADE").upper()
confidence = float(d.get("confidence", 0))
current_side = positions.get(symbol, Side.NONE)
if decision == "LONG" and current_side == Side.NONE:
if confidence >= confidence_threshold: # ≥ 0.75
action = Action.OPEN_LONG
else:
action = Action.HOLD # Too low confidence, skip
reason = f"Low confidence ({confidence:.0%}): {reason}"
elif decision == "SHORT" and current_side == Side.NONE:
if confidence >= confidence_threshold: # ≥ 0.75
action = Action.OPEN_SHORT
else:
action = Action.HOLD
elif decision == "CLOSE" and current_side != Side.NONE:
action = Action.CLOSE # No confidence threshold for closes
elif decision in ("HOLD", "NO_TRADE"):
action = Action.HOLDclass ClaudeAdapter(LLMAdapter):
def chat_with_tools(self, system_prompt, user_message, tools, tool_executor, max_iterations=10):
messages = [{"role": "user", "content": user_message}]
for iteration in range(max_iterations):
response = self.client.messages.create(
model="claude-sonnet-4-6",
max_tokens=8192,
system=system_prompt,
tools=tools,
messages=messages,
)
tool_uses = [b for b in response.content if b.type == "tool_use"]
text_blocks = [b for b in response.content if b.type == "text"]
if not tool_uses: # No tool calls = final answer
break
# Execute tool calls (e.g., fetch Open Interest, L/S ratio)
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for tu in tool_uses:
result_str = tool_executor(tu.name, tu.input)
tool_results.append({"type": "tool_result", "tool_use_id": tu.id, "content": result_str})
messages.append({"role": "user", "content": tool_results})
return LLMResult(text=final_text, ...)The LLM has one tool (call_api) that can call any endpoint on the simsar market data API:
CALL_API_TOOL = {
"name": "call_api",
"description": "Simsar piyasa verisi API'si. Ek veri çekmek için kullan.",
"input_schema": {
"type": "object",
"properties": {
"endpoint": {"type": "string", "description": "API endpoint (e.g., /futures/long-short-ratio/BTCUSDT)"},
"params": {"type": "object", "description": "Query parameters"},
},
"required": ["endpoint"],
},
}
# Available endpoints:
# /price/{symbol}
# /candles/{symbol}?interval=4h&limit=20
# /indicators/stoch/{symbol}?interval=4h
# /indicators/ema/{symbol}?interval=4h&period=20
# /indicators/sma/{symbol}?interval=4h&period=20
# /indicators/obv/{symbol}?interval=4h
# /indicators/mfi/{symbol}?interval=4h
# /indicators/cci/{symbol}?interval=4h
# /indicators/willr/{symbol}?interval=4h
# /futures/open-interest/{symbol}
# /futures/long-short-ratio/{symbol}
# /futures/top-trader-ratio/{symbol}# config/settings.py
LLM_PROVIDER = "claude"
LLM_TRADE_MODEL = "claude-sonnet-4-6"
LLM_TRADE_MAX_ITERATIONS = 10
LLM_TRADE_CONFIDENCE_THRESHOLD = 0.75
# Trading fees
FUTURES_TAKER_FEE = Decimal('0.0005') # 0.05%
FUTURES_MAKER_FEE = Decimal('0.0002') # 0.02%Each hourly decision cycle:
- ~20K input tokens (market data + portfolio + system prompt)
- ~2K output tokens (analysis + JSON decisions)
- Sonnet 4.6 pricing: $3/1M input, $15/1M output
- ~$0.09 per cycle → ~$2.16/day → ~$65/month
- LONG bias in bearish markets — In the first 24h, 38/41 trades were LONG despite bearish conditions
- Too frequent trading — Positions held only 1-2 hours, accumulating commission costs
- No memory across cycles — Each hourly call is independent; LLM doesn't remember its previous reasoning
- Single timeframe — Only 4h candles pre-fetched; no multi-timeframe analysis
- No position sizing — Always uses full allocation per position
- PAXG hedge failure — PAXG was supposed to hedge risk-off, but LLM went LONG PAXG alongside LONG crypto
<analysis>
1. Risk: US30 son 3 günde %1.2 düştü, risk-off sinyali. PAXG yükselişte — güvenli liman talebi.
2. BTC: RSI 42 (nötr), MACD negatif histogram daralmakta, ADX 18 (trend zayıf).
3. ETH: Double bottom formasyonu 2400$ seviyesinde, RSI yükseliş divergansı.
4. Portföy: 3 hesapta 7 açık pozisyon, hepsi LONG — risk yoğunlaşması.
</analysis>
```json
[
{"account": "mirat", "symbol": "BTCUSDT", "decision": "NO_TRADE", "confidence": 0.3, "reason": "Trend belirsiz, ADX düşük, momentum zayıf", "market_bias": "neutral", "risk_note": "US30 düşüşü kripto'ya yayılabilir"},
{"account": "mirat", "symbol": "ETHUSDT", "decision": "LONG", "confidence": 0.78, "reason": "Double bottom + RSI divergansı, 2400$ destek güçlü", "market_bias": "bullish", "risk_note": "Genel risk-off ortamda dikkatli ol"},
{"account": "mirat", "symbol": "PAXGUSDT", "decision": "LONG", "confidence": 0.82, "reason": "Risk-off ortam, altın güvenli liman talebi artıyor", "market_bias": "bullish", "risk_note": null},
...
]
---
## Today's Performance (2026-03-02)
### Summary
- **13 LLM decision rounds** (hourly cycles)
- **13 positions opened**, **16 positions closed**
- **Total realized PnL: -$7.59**
- **Total LLM cost: $1.22**
- **Net: -$8.81**
### Trades Executed
#### Opened
| Time | Account | Symbol | Side | Entry Price |
|------|---------|--------|------|-------------|
| 02:05 | mevlut | ETHUSDT | LONG | $1,964.00 |
| 02:06 | mirat | BTCUSDT | LONG | $66,491.80 |
| 06:07 | mirat | BTCUSDT | LONG | $66,596.20 |
| 06:07 | mirat | ETHUSDT | LONG | $1,967.01 |
| 06:08 | tugrul | AVAXUSDT | LONG | $9.03 |
| 06:08 | tugrul | SOLUSDT | LONG | $83.79 |
| 06:08 | tugrul | LINKUSDT | LONG | $8.77 |
| 07:06 | mevlut | ETHUSDT | SHORT | $1,933.15 |
| 08:07 | mevlut | PAXGUSDT | LONG | $5,441.58 |
| 08:07 | tugrul | ETHUSDT | SHORT | $1,933.60 |
| 08:07 | tugrul | PAXGUSDT | LONG | $5,441.70 |
| 08:15 | mirat | PAXGUSDT | LONG | $5,442.90 |
| 20:07 | mirat | BTCUSDT | LONG | $68,918.10 |
#### Closed
| Time | Account | Symbol | Side | Entry → Exit | PnL |
|------|---------|--------|------|--------------|-----|
| 00:06 | mirat | AVAXUSDT | LONG | $8.87 → $9.04 | +$1.02 |
| 00:06 | mirat | ETHUSDT | LONG | $1,912 → $1,942 | +$0.89 |
| 00:06 | mirat | LINKUSDT | LONG | $8.55 → $8.68 | +$0.87 |
| 00:06 | mirat | SOLUSDT | LONG | $82.02 → $83.55 | +$1.03 |
| 03:05 | mevlut | ETHUSDT | LONG | $1,964 → $1,950 | -$0.43 |
| 04:05 | mirat | BTCUSDT | LONG | $66,491 → $66,730 | +$0.48 |
| 07:07 | tugrul | AVAXUSDT | LONG | $9.03 → $8.92 | -$0.43 |
| 07:07 | tugrul | LINKUSDT | LONG | $8.77 → $8.65 | -$0.51 |
| 07:07 | tugrul | SOLUSDT | LONG | $83.79 → $82.77 | -$0.47 |
| 08:07 | mirat | BTCUSDT | LONG | $66,596 → $65,846 | -$1.50 |
| 08:07 | mirat | ETHUSDT | LONG | $1,967 → $1,933 | -$2.39 |
| 12:07 | mevlut | ETHUSDT | SHORT | $1,933 → $1,947 | -$0.37 |
| 12:07 | tugrul | ETHUSDT | SHORT | $1,933 → $1,946 | -$0.25 |
| 16:07 | mevlut | PAXGUSDT | LONG | $5,441 → $5,303 | -$1.24 |
| 16:07 | mirat | PAXGUSDT | LONG | $5,442 → $5,304 | -$3.46 |
| 16:07 | tugrul | PAXGUSDT | LONG | $5,441 → $5,304 | -$0.83 |
### LLM Decision Log (All Cycles)
**08:06 — Morning session (Fear & Greed: 10 = Extreme Fear)**
- Market: US30 -1%, risk-off environment
- BTC couldn't break 67,500 resistance, L/S ratio 1.69 (crowded longs)
- mirat: CLOSE BTC (conf: 0.72), CLOSE ETH (conf: 0.78) — cut losses on falling positions
- mevlut: NO_TRADE most coins, ETH SHORT held
- tugrul: SHORT ETH (conf: 0.70 — below 0.75 threshold, NOT executed), LONG PAXG (conf: 0.72 — below threshold)
- PAXG LONG decisions all below 0.75 threshold at this point
**08:15 — mirat retry**
- PAXG LONG (conf: 0.78) — executed this time, above threshold
- All others NO_TRADE
**12:07 — Midday**
- mevlut & tugrul: CLOSE ETH SHORT (conf: 0.70) — ETH recovering against short
- All accounts: NO_TRADE on everything else, low confidence (0.60-0.65)
- PAXG HOLDs maintained
**16:07 — Afternoon (PAXG crash)**
- PAXG CLOSE across all 3 accounts (conf: 0.82) — sharp drop $5,441→$5,329
- Biggest single loss: mirat PAXG -$3.46
- All crypto coins NO_TRADE despite BTC breakout — caution due to overbought signals
**20:07 — Evening (BTC breakout confirmed)**
- BTC LONG across all accounts (conf: 0.78) — volume spike breakout 65.2K→69.1K
- ETH LONG (conf: 0.72 — below 0.75, NOT executed for mevlut/tugrul, executed for... wait, 0.72 < 0.75)
- Most altcoins NO_TRADE due to crowded L/S ratios (AVAX 2.37, LINK 2.25)
- PAXG NO_TRADE — risk-on shift after BTC breakout
### Observations
1. **Confidence threshold working**: Several decisions at 0.68-0.72 were correctly filtered out
2. **PAXG hedge failed again**: Bought at $5,441, crashed to $5,303 within 8 hours (-$5.53 across accounts)
3. **Short-lived positions**: ETH SHORT lasted ~4 hours, lost money on all accounts
4. **Commission drag**: 16 round-trip trades × ~0.30% commission = significant drag on small positions
5. **Correct close calls**: BTC and ETH closes at 08:07 prevented bigger losses (BTC dropped further to $65,846)
6. **Late BTC entry**: The 20:07 BTC LONG at $68,918 caught the breakout — still open, unrealized