# === THE BRAIN (required for decisions; without a key every cycle logs a HOLD) === # Pick ONE provider and set its key. Default is gemini. A paid ChatGPT/Perplexity/ # Copilot subscription is NOT an API key — get a developer key from the platform. #LLM_PROVIDER=gemini # gemini|openai|anthropic|perplexity|grok|deepseek|github|openrouter #LLM_MODEL= # override the provider's default model (blank = default) #LLM_MODEL_DEEP= # override for the slow sleeves + monthly review (blank = default) GEMINI_API_KEY= # aistudio.google.com (free tier works, but is rate-limited) #GEMINI_MODEL=gemini-2.5-flash # frequent decisions (swing, fortnight) #GEMINI_MODEL_DEEP=gemini-2.5-flash # rare decisions (quarter, vault) + the monthly review # Want a stronger brain on the slow sleeves? Set GEMINI_MODEL_DEEP=gemini-pro-latest. # Use the -latest ALIAS, never a pinned id: gemini-2.5-pro is already retired and 404s. #OPENAI_API_KEY= # platform.openai.com (ChatGPT) #ANTHROPIC_API_KEY= # console.anthropic.com (Claude) #PERPLEXITY_API_KEY= # perplexity.ai -> API #GROK_API_KEY= # x.ai (xAI Grok) #DEEPSEEK_API_KEY= # platform.deepseek.com #GITHUB_TOKEN= # github.com PAT (GitHub Models / Copilot) #OPENROUTER_API_KEY= # openrouter.ai (one key, any model) # === THE EXCHANGE (live mode only — paper mode needs no account at all) === # Create the API key with TRADE + QUERY permissions ONLY. Never grant withdrawal. KRAKEN_API_KEY= KRAKEN_API_SECRET= TRADING_ENABLED=false # true + keys above = real money. Flip deliberately. # === PORTFOLIO === #BASE_CURRENCY=EUR # the currency it trades against + values in (EUR/USD/GBP/…). Pre-lock default only — choose it once on the Settings page at first setup; it then locks permanently. NEVER change on a funded account. #TIMEZONE=Europe/Dublin # IANA timezone the daily/weekly/monthly decision slots run on (e.g. America/New_York). Match it to your scheduler. Also on the Settings page; safe to change. #PAIRS=BTC/EUR,ETH/EUR # base pairs — always tradeable (default follows BASE_CURRENCY) #MANUAL_PAIRS= # pin any extra EUR coins (e.g. ADA/EUR,LINK/EUR); exempt from the sell floor. Add from the Settings page too. #START_BALANCE_EUR=50 # paper-mode starting stake #MAKER_FEE=0.0025 # post-only limit fee — the bot's preferred fill #LIMIT_FILL_WAIT_S=90 # patience at the touch before falling back to market #TAKER_FEE=0.004 #SKIM_FRACTION=0.5 #DYNAMIC_UNIVERSE=false # auto-track the top-N altcoins by market cap (Kraken EUR pairs) #DYNAMIC_TOP_N=5 # how many top alts the bot may BUY #DYNAMIC_SELL_FLOOR_N=10 # a held alt that falls past this rank is force-sold at the weekly refresh # === STOP-LOSSES (#35) — resting protective orders AT the exchange === # A stop that lives at Kraken still works when the bot does not: between cycles, through # an LLM outage, a crashed container, while you sleep. The brain proposes the distance # when it buys; these clamps decide what is sane. OFF by default. #STOP_LOSS_ENABLED=false #STOP_LOSS_PCT=8 # default distance below entry if the brain does not choose #STOP_LOSS_MIN_PCT=2 # tighter than this and ordinary noise stops you out for a certain loss #STOP_LOSS_MAX_PCT=30 #STOP_REENTRY_COOLDOWN_H=48 # after a stop fires, that sleeve can't buy that pair again for this long (0 = off) # NB a HALT does not cancel resting stops — they are protective, and cancelling them would # leave positions naked while trading is paused. POST /api/stops/cancel to clear them. # === RICHER CONTEXT (#34) — what the brain gets to see === #CONTEXT_FUNDING=true # perp funding rate + open interest (Kraken public futures book, no key). # Read-only sentiment: crowded-long/short. The bot never trades a perp. #CONTEXT_DEPTH=true # resting bid vs ask size within 1% of mid (order-book imbalance) #NEWS_RSS_URL= # any RSS feed of headlines. OFF by default and deliberately so: # crypto headlines are mostly noise, LLMs are suggestible, and this is # the one context source that can plausibly make decisions WORSE. # A/B it with a shadow arm rather than assuming it helps. # === SHADOW ARMS (optional) — rival strategies traded in SIMULATION for comparison === # `name:kind:spec`, comma-separated. Rule arms cost nothing: no API key, no real orders. # Rule arms cost nothing (no API key, no real orders): # ema20 (dumb momentum) | dca (fixed slice, never sells) | random (a coin flip — the bar to clear) # LLM arms run a RIVAL BRAIN on the IDENTICAL prompt — `provider@model` (model optional). # One OpenRouter key reaches Claude, GPT, Grok, DeepSeek and the rest, so a bake-off needs # one account, not five. Each llm arm costs ~1 API call per due sleeve per cycle. #SHADOW_ARMS=ema:rule:ema20,dca:rule:dca,coinflip:rule:random,claude:llm:openrouter@anthropic/claude-sonnet-5,deepseek:llm:openrouter@deepseek/deepseek-chat # === NOTIFICATIONS (optional, Home Assistant) === #HA_URL=http://homeassistant.local:8123 #HA_TOKEN=your-long-lived-token #HA_NOTIFY_SERVICE=notify.mobile_app_myphone #HA_NOTIFY_CLICK_URL=http://192.168.1.10:8000 # notifications open this URL when tapped (all channels) # extra channels — set any you want; every alert goes to ALL configured channels #PUSHOVER_TOKEN= # pushover.net app token #PUSHOVER_USER= # pushover user/group key #PUSHBULLET_TOKEN= # pushbullet access token #DISCORD_WEBHOOK_URL= # a Discord channel webhook URL #TELEGRAM_BOT_TOKEN= #TELEGRAM_CHAT_ID= #NTFY_TOPIC= # ntfy topic; #NTFY_SERVER=https://ntfy.sh (default) # === LOGIN (optional) === #DASHBOARD_PASSWORD= # set to require login for the dashboard + controls; blank = open (LAN/your own proxy)