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 = 0.4 # Reserve this % per order for Kraken's taker fee (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"