OUTRIDER docs
v1.1.0
Live demo Get help
● Set up · config.json · environment

Configuration
where every setting lives.

Three places hold settings: config.json for the whole desk, the console for the main switches, and environment variables for keys and the server. This page says which one wins and lists the keys you are most likely to change.

01Where settings live

Which terminal

The commands on this page are written for the shell of macOS and Linux (bash or zsh). On Windows, run them in WSL (Windows Subsystem for Linux, Ubuntu) or Git Bash; in PowerShell, set a variable with $env:NAME="value" instead of export NAME=value. The node and npm commands work in any of them.

PlaceWhat goes thereWhen it applies
src/defaults.mjsEvery default, with a comment on each key. Do not edit it; read it. (src/config.mjs loads and type-checks your settings.)Always, unless overridden
config.jsonYour overrides of any key from src/defaults.mjs. Created from config.example.json, ignored by git.At start. Restart after a change.
Console (/admin)Mode, bankroll, limits, lanes, smart-wallet rules, liquidation map, research refresh, keys; the leverage profile with the perps module.At start and immediately after each save. A console value overrides config.json once you change it from the console default (table).
Environment variablesKeys, Telegram ids, dashboard port and password, console secret key.At start. Keys in the environment win over keys stored in the console.

02How config.json works

  • You only write the keys you change. Nested objects are merged with the defaults, so {"limits": {"maxOpen": 3}} keeps every other limit.
  • Lists replace the default list entirely (for example news.feeds).
  • A value of the wrong type is rejected at start with one clear line, for example config: …config.json: bankrollSol: expected number, got string ("10"). Invalid JSON is reported with the file name.
  • mode must be paper, alert or live. Anything else stops the desk at start, and live refuses to start until its checks pass (Live trading).
  • node src/cli.mjs doctor prints warnings for contradictions: zero or negative limits, placeholder wallets, a stop at or above the entry, exposure caps that make the last slots unreachable, and more.

The example file:

{
  "mode": "paper",
  "bankrollSol": 10,
  "modules": { "perps": false, "polymarket": false, "jev": false },
  "whales": { "wallets": ["PASTE_A_SOLANA_WALLET_YOU_FOLLOW"] },
  "news": {
    "feeds": [
      "https://cointelegraph.com/rss",
      "https://www.coindesk.com/arc/outboundfeeds/rss/",
      "https://decrypt.co/feed"
    ]
  }
}
Replace the placeholder

PASTE_A_SOLANA_WALLET_YOU_FOLLOW is a placeholder. Replace it or make the list empty (how).

03The keys you will change most

KeyDefaultWhat it does
modepaperpaper: trades on paper with live data. alert: notifies only, no paper book. live: real orders with your keys (Live trading).
modulesall falseThe optional modules perps, polymarket and jev. While a module is off, its books do not run and the dashboard and console hide them (Optional modules).
bankrollSol10Starting paper bankroll of the memecoin book, in SOL.
loopSeconds20Seconds between desk cycles (kept at 5 or more).
dataDirdataWhere state, journal, recordings and the console database are written.
solanaRpcpublic mainnetSolana HTTP RPC for wallet reads and FOMO collection.
pump.wsUrlpublic mainnet WSWebSocket for the real-time pump.fun stream. Use a private one (below).
telegram.readChannelsfalseOpt-in for channel reading: SHILL reads the channels below only when this is true. Reading channel pages may be against Telegram's terms of service and the channel owners' wishes (read this first).
telegram.channels[]Public Telegram channels read through their public web preview page for contract addresses and $TICKERs, while telegram.readChannels is on. Bare names only.
whales.wallets[]Solana wallets whose buys count as a confirming signal. Empty by default; add wallets you follow, or use the smart-wallet list.
news.feeds6 RSS feedsNews sources. Add X accounts through your own RSSHub or nitter instance.
news.llmclaude-opus-5, effort low, 8 per cycleClaude model used when ANTHROPIC_API_KEY is set.
ev.minEv, ev.kellyFraction, ev.maxPerTokenPct0.03, 0.2, 2The core EV gate: minimum expected return after costs, fraction of Kelly, and hard cap per token in % of bankroll.
limitsmaxOpen 5, dailyLossPct 10, cooldownMinutes 60, maxExposurePct 10Memecoin book limits.
protections.hardStop.redPct20Drawdown from the equity peak at which everything is sold and the desk latches (kill switch).
portfolio.maxGrossUsd8000Cap on gross USD notional across all perp books (perps module).
<book>.enabledtrueTurns a book or agent off: security, pump, wallets, liqmap, research, alloc. The books of the optional modules (macro, hlcopy, trend, basis, xarb, funding, flow, polymarket, polymm, jev) run only while their module is on; then their own enabled flag applies.

Every other key (lane thresholds, exit ladders, allocator, books) is documented by the comment next to it in src/defaults.mjs, and the important ones on the page of the feature they belong to.

04Console fields and the config keys they set

config.json is the base. With the console on (npm start, npm run dash), a console field overrides its config key only when its value differs from the console default in the table below, that is, once you really changed it. Exception: Desk → Mode and every Live trading field always come from the console while it is running (defaults included): a mode: "live" or live.* in config.json is used only when the console is off (DASH=0 or DESK_ADMIN=0). See Live trading. The check runs at start and after every save. If you set a field back to its console default, the config.json value (or the built-in default) applies again.

Console fieldConfig keyConsole default
Desk → Paper bankroll (SOL)bankrollSol10
Desk → Max open memecoin positionslimits.maxOpen5
Desk → Daily loss stop (%)limits.dailyLossPct10
Memecoin lanes → Moonshot / Graduation / Revival / Smart money lanepump.lanes.<lane>.enabledon
Memecoin lanes → … ticket (% of paper equity)pump.lanes.<lane>.stakePct1 (graduation 1.5)
Smart wallets → Rounds before a wallet can be smartwallets.minRounds8
Smart wallets → Minimum mean hold (s)wallets.minMeanHoldSec60
Smart wallets → Smart wallets needed for a consensuspump.lanes.smart.minWallets3
Smart wallets → Live candidate feedswallets.feedsempty
Liquidation map → Refresh the map in the backgroundliqmap.enabledon
Liquidation map → Coinsliqmap.coinsBTC ETH SOL HYPE XRP DOGE SUI BNB
Liquidation map → Accounts read per refreshliqmap.wallets2000
Liquidation map → Refresh every (min)liqmap.everyMinutes30
Liquidation map → Alert when price is within (%)liqmap.alertWithinPct1.5
Liquidation map → …holding at least (USD)liqmap.alertMinUsd5,000,000
Research → Refresh research in the backgroundresearch.enabledon
Research → Wallet book every (min)research.walletsEveryMinutes60
Research → Backtests and lane replay every (hours)research.fullEveryHours24
Desk → Modemodepaper (also alert, live)
Live trading → confirmation, Dry run, pump.fun / Hyperliquid on, capslive.*empty, on, off, 0.1 SOL / $100 / $500 (all caps)
Trend & leverage → Leverage profile (perps module)leverage.defaultProfilegrowth
Command-line tools read config.json

One-off commands such as liq, wallets, replay or leverage do not start the console, so they use config.json and the defaults only. If you changed a value in the console, set the same value in config.json when you want those commands to match the running desk.

05Solana RPC and the pump.fun WebSocket

The public Solana endpoint drops heavy logsSubscribe streams. For a stable pump.fun stream, create a free endpoint at Helius, QuickNode or Chainstack and set it in one of two places:

  • Console (owner): Integrations → Solana RPC / WebSocket URL. Enter the https:// URL. The desk uses it as solanaRpc and derives the WebSocket (pump.wsUrl) by replacing http with ws, at start and right after each save. The console's Solana RPC health check tests the same URL. When filled in, it wins over config.json.
  • config.json, if your provider's WebSocket URL is not simply the HTTP URL with ws:
{
  "solanaRpc": "https://<your-rpc-host>/?api-key=<key>",
  "pump": { "wsUrl": "wss://<your-rpc-host>/?api-key=<key>" }
}
The URL contains your key

RPC URLs usually contain an API key, so the console stores this field as a secret: encrypted at rest, set by the owner only, never shown back after saving. If you put the URL in config.json instead, keep that file out of any public repository.

06Environment variables

VariablePurpose
ANTHROPIC_API_KEYClaude news scoring and the AI analyst.Optional
TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_IDAlerts and commands (Telegram bot).Optional
TELEGRAM_OWNER_IDYour Telegram user id; required for commands in a group chat.Optional
TYPESAFE_API_KEYThe Jev forecaster (jev module).Optional
SOLANA_PRIVATE_KEYLive pump.fun trading wallet (Live trading).Live only
HL_API_WALLET_KEY, HL_ACCOUNT_ADDRESSLive Hyperliquid API wallet and the account it trades for (perps module).Live only
ADMIN_SECRET_KEYEncrypts the console's stored secrets. Generate one with openssl rand -hex 32. If unset, a key is generated into data/.admin-secret-key. Losing it makes stored secrets unreadable (Secrets and backups).Recommended on a server
ADMIN_SETUP_TOKENThe one-time secret that creates the console owner at /admin: at least 24 characters, for example openssl rand -hex 24. Once the owner exists it is never accepted again; remove it. Left empty, the server prints a one-time setup code to its log instead (Create the owner).Recommended on a server
DASH_PORTDashboard and console port. Default 8790.Optional
DASH_HOSTAddress the dashboard listens on. Default 127.0.0.1; the Docker setup uses 0.0.0.0 inside the container.Optional
DASH_TOKENExtra dashboard password (?token= or Authorization: Bearer). Needed when the console is off.Optional
DASH_ALLOWED_HOSTSPublic host names the dashboard answers behind a reverse proxy, comma-separated (Deployment). Without it, only loopback hosts are answered.Optional
TRUST_PROXY_HOPSNumber of reverse proxies in front of the console (usually 1 behind Caddy or nginx), so sign-in limits count each visitor by their own address (Deployment). Empty = 0.Optional
DASH=0npm start without dashboard and console.Optional
DESK_ADMIN=0Dashboard without the console.Optional
DASH_DATAnpm run dash reads this data folder instead of data/ (for replays).Optional

The desk loads .env next to package.json on start (cp .env.example .env); a variable already set in your shell or process manager wins. You can also export them in your shell, or set them in your process manager (Deployment).

export TELEGRAM_BOT_TOKEN=<token>
export TELEGRAM_CHAT_ID=<chat id>
npm start

07Temporary overrides for research

replay and sweep accept --set key=value, repeatable, without touching config.json. Values are read as JSON when they parse (numbers, true/false, lists). A key that does not exist is refused, so a typo cannot silently change nothing.

node src/cli.mjs replay --set pump.lanes.moonshot.enabled=false --set ev.minEv=0.05