Files
crypto-trader/config.py

57 lines
2.5 KiB
Python

import os
from dataclasses import dataclass, field
@dataclass
class Config:
# Kraken API credentials — set via .env or environment variables
api_key: str = field(default_factory=lambda: os.getenv("KRAKEN_API_KEY", ""))
api_secret: str = field(default_factory=lambda: os.getenv("KRAKEN_API_SECRET", ""))
# Quote currency to scan (only USD pairs)
quote_currency: str = "USD"
# Volume filter: minimum 24h traded volume in USD
# Filters out illiquid/dead coins
min_volume_usd: float = 500_000
# Momentum filter: 24h price change must be in this range
# Below 3% = noise; above 15% = likely already overextended
min_price_change_pct: float = 3.0
max_price_change_pct: float = 15.0
# Portfolio limits
max_positions: int = 5 # Maximum concurrent holdings
min_order_usd: float = 15.0 # Kraken minimum is ~$10; keep a small buffer
taker_fee_pct: float = 1.5 # Reserve this % of balance for fees/rounding (Kraken actual ~0.26%)
# ── Risk management ──────────────────────────────────────────────────────
# Trailing stop: sell if price drops this % below its peak since purchase.
# Example: buy at $100, peaks at $130 → stop triggers at $119.60
trailing_stop_pct: float = 8.0
# Hard stop: sell if price drops this % below entry price, regardless of peak.
# Protects against gapping down before the trailing stop can trigger.
hard_stop_pct: float = 12.0
# Take profit: sell when price is this % above entry.
take_profit_pct: float = 5.0
# Time limit: sell after this many hours if no stop/TP was hit.
# Prevents dead money from tying up capital indefinitely.
max_hold_hours: int = 72
# Cooldown: hours to wait before re-buying a pair that was just sold.
# Prevents immediately re-entering a coin whose momentum has stalled or reversed.
sold_cooldown_hours: float = 4.0
# ── Execution ────────────────────────────────────────────────────────────
# ALWAYS start with paper_trading=True and verify behaviour before going live.
# Set to False only after you understand the bot's decisions.
paper_trading: bool = True
# Path for persisting open positions across runs
positions_file: str = "positions.json"
log_file: str = "bot.log"