Skip to content

colfin22/magpie

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

45 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ¦β€β¬› Magpie

Version CI License: MIT

An autonomous, self-hosted crypto trading bot with an LLM for a brain. You give it a small stake on Kraken and an API key for the LLM of your choice; it manages the money on its own schedule, keeps a full written diary of every thought, and pushes you a daily digest. Your only control is the halt button β€” by design.

⚠️ This is an experiment, not a product. An LLM has no proven trading edge. Magpie is built for people who want to watch an AI manage a toy stake with real rails around it β€” not for money you can't afford to lose. Expect anything from slow bleed to pleasant surprise. The house always takes 0.4% a trade.

πŸ‘‰ New to this, or on Windows? Jump to the step-by-step Windows guide β€” install to uninstall, no coding needed.

The Magpie dashboard β€” the dynamic alt universe, equity vs buy-and-hold, the four sleeves holding SOL/XRP/TRX/BTC, closed alt trades, vault skims, the monthly lessons note and the decision diary including a top-10 sell-floor auto-exit
Dashboard a few months in, trading the top-5 alt universe (simulated preview data β€” a fresh install starts humbler).

How it thinks

Four sleeves, each an independent sub-portfolio with its own books, its own mandate, and its own decision cadence:

Sleeve Horizon Decides Funded by
swing ~1–3 days every 6 h β…“ of the stake
fortnight 1–2 weeks daily β…“ of the stake
quarter weeks–3 months Mondays β…“ of the stake
vault a year+ 1st of month profits only

Each decision cycle, the engine builds a context pack β€” that sleeve's holdings, market data with computed indicators (EMA 20/50/200, RSI, multi-horizon returns), its own recent decision history, and a fee reminder β€” and asks its LLM for a strict-JSON decision: buy / sell / hold, pair, fraction, confidence, reasoning.

The validation layer is the real boundary: only whitelisted pairs, spot only, long only, exchange minimums enforced, balances reconciled β€” and any malformed, out-of-universe or errored answer resolves to HOLD. The model's words never touch the exchange; only validated orders do.

The vault starts empty. Whenever an active sleeve's value exceeds its high-water mark, half of the realised profit (EUR actually banked, not paper gains) is skimmed into the vault, and the mark ratchets up. The vault accumulates long-term positions out of house winnings only β€” losing sleeves are never refilled from it.

It learns from itself. Once a month it re-reads its own diary β€” every decision, what it reasoned at the time, and what actually happened β€” and writes itself a lessons note that is injected into all future prompts. The only memory it carries forward is the one it earns.

It trades like a local. Orders go in as post-only limits at the touch (maker fee ~0.25%) with a patient window before falling back to market (~0.40%) β€” a guaranteed saving on every fill that patience can win. Decisions see daily and 4-hour indicators, the live spread, and the Crypto Fear & Greed index; the slow sleeves think with a stronger model than the fast ones.

It keeps score against a hodler. From its first sight of capital it tracks a phantom buy-and-hold portfolio of the same money (topped up in lockstep) β€” the dashboard and daily digest always show whether the AI is beating doing nothing, and the monthly self-review is confronted with the number. Closed trades are FIFO-paired into round trips (win rate, average win/loss, hold time), and a nightly reconciliation keeps the virtual sleeve books honest against real exchange balances.

Top-ups: deposit more EUR to the exchange whenever you like. The bot notices the surplus at its next cycle, splits it equally across the three active sleeves, and raises their high-water marks so fresh cash is never mistaken for profit.

The brain β€” pick your LLM

Magpie isn't wed to one model. LLM_PROVIDER chooses who makes the call:

Provider LLM_PROVIDER API key from
Gemini (Google) β€” default gemini aistudio.google.com
OpenAI (ChatGPT) openai platform.openai.com
Anthropic (Claude) anthropic console.anthropic.com
Perplexity perplexity perplexity.ai β†’ API
Grok (xAI) grok x.ai
DeepSeek deepseek platform.deepseek.com
GitHub Models (Copilot) github github.com personal access token
OpenRouter β€” one key, any model above and more openrouter openrouter.ai

Each provider uses its own key β€” set the one for the brain you pick. The prompt and the strict-JSON safety layer are identical whichever model answers, so a model that formats badly simply resolves to HOLD. LLM_MODEL / LLM_MODEL_DEEP override the per-provider default models (the deep one runs the slow sleeves and the monthly self-review; the fast one runs the rest). Switch live from the settings page β€” dropdown, key, Test active brain, save; no restart.

A paid ChatGPT / Perplexity / Copilot subscription is not an API key β€” each needs a developer key from the provider's platform, billed per token. Gemini's free tier is enough to run Magpie outright.

Safety rails (the non-negotiables)

  • The API key cannot withdraw. Create it with query + trade permissions only. Worst-case compromise of the box = bad trades, never stolen funds. (The repo's verification snippet in docs/ probes this.)
  • It can never deposit β€” there is no payment integration. The stake you fund is the ceiling.
  • Spot only, long only, whitelisted pairs only β€” no leverage, no derivatives, no liquidations.
  • Kill switch: POST /api/halt (or the big red button on the dashboard) stops all ordering until POST /api/resume.
  • Total auditability: every prompt sent to the model and every raw response is stored. The dashboard diary shows what it saw, what it thought, and what it did β€” for every cent that moves.

There is deliberately no auto-stop-loss and no position cap β€” the operator takes the risk knowingly and holds the halt button. Add your own guardrails if that's not your temperament.

Run

You need: Docker, a dedicated Kraken account that holds only the money you want Magpie to manage, a trade-only API key (see above), and an API key for one supported LLM β€” Gemini is the default and its free tier is plenty to start (the bot makes only a handful of calls a day). See The brain for the alternatives.

⚠️ Use an empty Kraken account. On its first live cycle Magpie treats the entire balance of the account as its starting stake and splits it across the sleeves, and its nightly reconciliation pulls any coin sitting on the account into its own books. So fund a fresh account with nothing else in it β€” just the stake you're giving Magpie. Don't point it at an account holding coins or cash you don't want it trading.

cp .env.example .env     # fill in your Kraken + LLM keys; leave TRADING_ENABLED=false
docker compose up -d --build

The bot starts in paper mode: identical code path, live market data, simulated fills against a pretend stake. Watch the diary at http://<host>:8000 until you trust it, then set TRADING_ENABLED=true and recreate the container. At its first live cycle it treats your entire exchange EUR balance as the opening top-up and splits it across the sleeves.

Schedule the heartbeat (systemd timer or cron):

0 0,6,12,18 * * *  curl -s -X POST http://localhost:8000/api/cycle
5 18 * * *         curl -s -X POST http://localhost:8000/api/digest
45 5 * * *         curl -s -X POST http://localhost:8000/api/reconcile
30 5 1 * *         curl -s -X POST http://localhost:8000/api/review

The cycle endpoint is safe to call at any hour β€” sleeve cadences are gated internally (fortnight only acts on the 06:00 call, quarter on Monday's, the vault on the 1st of the month).

Running on Windows

Magpie runs anywhere Docker does. On Windows β€” or if you're not very technical β€” follow the complete step-by-step Windows guide: install, run, schedule, go live, update and uninstall, all click-by-click with no coding.

API

  • GET /health β€” liveness, mode, halt state, last decision
  • GET /api/state β€” full portfolio, sleeve breakdown, decision diary, skims
  • POST /api/cycle β€” run a decision tick
  • POST /api/digest β€” push the daily summary
  • POST /api/review β€” run the monthly self-review (writes the lessons note)
  • POST /api/reconcile β€” absorb drift between the sleeve books and exchange reality
  • GET /settings β€” a page to enter/change keys and Home Assistant details (secrets masked; test buttons for each integration). Web-entered settings persist and override the env.
  • POST /api/halt / POST /api/resume β€” the only human controls
  • POST /api/topup?amount= β€” paper mode only; live deposits are auto-detected

Configuration

Base currency. Magpie trades against and values everything in one currency β€” EUR by default, or USD, GBP, etc. It's a one-time choice at initial setup (Settings β†’ Base currency): the moment you set it β€” and automatically once the bot has traded β€” it locks permanently, because switching it on a funded account would leave your holdings and exchange balance in the wrong currency. Choose it before funding.

Timezone. Set TIMEZONE (an IANA name like America/New_York, default Europe/Dublin) β€” or pick it on the settings page β€” so the daily 06:00, Monday and 1st-of-month decision slots run on your local clock. It's safe to change anytime; align it with the schedule you set below.

Everything else is env vars β€” see .env.example. Notables: LLM_PROVIDER (which brain; default gemini) and its matching API key, LLM_MODEL / LLM_MODEL_DEEP (optional model overrides), PAIRS (the base tradeable universe, default BTC/EUR + ETH/EUR), and SKIM_FRACTION (profit share skimmed to the vault, default 0.5).

Notifications

Magpie can push every event β€” trades, top-ups, the daily digest, error alerts and the monthly self-review β€” to as many channels as you like. Set the ones you want (in .env or on the settings page); each fires only when its keys are present, and every alert fans out to all configured channels at once:

Channel Config
Home Assistant push HA_URL + HA_TOKEN + HA_NOTIFY_SERVICE
Pushover PUSHOVER_TOKEN + PUSHOVER_USER
Pushbullet PUSHBULLET_TOKEN
Discord (rich embed) DISCORD_WEBHOOK_URL
Telegram TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID
ntfy NTFY_TOPIC (+ NTFY_SERVER, default ntfy.sh)

HA_NOTIFY_CLICK_URL (e.g. your dashboard URL) becomes the tap-to-open link on every channel that supports it, and the settings page's Test button sends a test to all configured channels at once. Configure nothing and Magpie just runs quietly β€” one channel failing never blocks the others.

Dynamic universe (optional)

With DYNAMIC_UNIVERSE=true, the tradeable set is your base pairs plus the top-DYNAMIC_TOP_N (default 5) altcoins by market cap that trade against EUR on Kraken β€” stablecoins and wrapped/staked tokens excluded. It refreshes on a weekly timer (POST /api/universe/refresh) and pushes a heads-up when the set changes.

It never strands a position, and never churns fees on a ranking reshuffle: a held coin that slips out of the top-DYNAMIC_TOP_N stays sellable at the bot's own discretion, and only once it falls past DYNAMIC_SELL_FLOOR_N (default 10) is it force-sold at the weekly refresh β€” the band between the two is a grace zone the model manages itself. Base pairs are never auto-sold, and sub-€1 dust is left in place. GET /api/universe shows the current set.

Pin your own coins. Beyond the base pairs and the auto-tracked alts, add any coin that trades against EUR on Kraken from the settings page's Custom coins card (or MANUAL_PAIRS / POST /api/pairs/add {symbol}). Each is validated against Kraken before it's saved, is always tradeable regardless of the rankings, and β€” because you chose it deliberately β€” is exempt from the sell floor.

Login (optional)

Set DASHBOARD_PASSWORD (env or the settings page's Security card) to require a password for the dashboard, portfolio view and controls. It's a single-password cookie login; the health check and the timer-triggered action endpoints stay open (they expose no data). Leave it blank to run open on a trusted LAN or behind your own reverse-proxy auth.

Two-factor (TOTP). Once a password is set, turn on 2FA from the Security card: scan the QR into Google Authenticator / Authy / 1Password, confirm a code, and every login then needs the 6-digit code as well as the password. It's standard TOTP, verified at login before the session cookie is issued.

Enabling 2FA hands you 10 single-use backup codes (shown once, stored hashed). Any one works in the login's code field in place of your authenticator and is then spent β€” the way back in if you lose your phone. Regenerate the set anytime from the Security card (needs a current code). If you lose the authenticator and the codes, the last resort clears it from the container: docker exec magpie sqlite3 /data/magpie.db "DELETE FROM settings WHERE key IN ('totp_enabled','totp_secret','totp_backup_codes')".

Licence

MIT Β© 2026 Colm Finn.


Built by Colm Finn. The magpie trades alone; the consequences are its keeper's.

About

πŸ¦β€β¬› Autonomous self-hosted crypto trading bot with a pluggable LLM brain β€” Gemini, ChatGPT, Claude, Perplexity, Grok, DeepSeek, Copilot or OpenRouter decides, hard rails execute, you hold the halt button

Topics

Resources

License

Stars

3 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors