Skip to content

Latest commit

 

History

History
159 lines (134 loc) · 8.85 KB

File metadata and controls

159 lines (134 loc) · 8.85 KB

Configuration

There are two layers of configuration:

  • .env — secrets, endpoints, and the live-trading switches. Loaded once at startup (src/config.js). Gitignored — never commit it.
  • runtime-config.json — the live, hot-reloadable knobs the dashboard's ⚙ CONFIG panel controls (src/settings.js). Owned by the running bot: edit it through the panel, not by hand, or the running engine will overwrite your manual edits on its next save.

.env reference

Variable Purpose
PRIVATE_KEY Wallet private key. Required only for live; paper runs unsigned.
WALLET_ADDRESS The bot's wallet address.
TARGET_WALLET Default wallet the Copy Bot mirrors (changeable in the UI).
POLYGON_RPC_URL, …_2, …_FALLBACK HTTP RPCs (Alchemy → Infura → public failover).
POLYGON_WS_RPC_URL, …_2, …_FALLBACK WebSocket RPCs for fast on-chain detection.
ONCHAIN_DETECT Enable on-chain detection (default true).
CLOB_HOST, GAMMA_HOST, DATA_HOST Polymarket API hosts (defaults provided).
PAPER_TRADING true = paper (default). false is half of the live switch.
LIVE_ARMED Second live switch — live needs both PAPER_TRADING=false and LIVE_ARMED=true.
STARTING_BANKROLL Paper bankroll (default 1000).
BOT_VERSION Initial version to load (defaults to the latest implemented).
DASHBOARD_PORT Dashboard server port (default 8787).
RUN_SECONDS Optional bounded run length (0 = run until Ctrl-C).
Risk / sizing defaults MAX_CLIP_USD, MAX_OPEN_USD, DAILY_LOSS_LIMIT_USD, MAX_ENTRY_PRICE, CLIP_USD, etc. (also editable live).
POLY_RTDS Use Polymarket's live RTDS WebSocket — the exact Chainlink price its UI shows (no key, ~1s ticks). Default true for crypto on 5m/15m/4h.
POLY_RTDS_SYMBOLS / POLY_RTDS_URL Extra base tickers / socket URL override.
POLY_PRICE Fallback (when POLY_RTDS=false): Chainlink-candles endpoint — exact open, Binance-anchored live.
POLY_OFFSET_MS / POLY_PRICE_SYMBOLS / POLY_PRICE_HOST Basis refresh interval (15000ms), extra base tickers, host override.
CHAINLINK_ONCHAIN On-chain Chainlink Data Feed pricing (no key). Default true; false forces Binance.
CHAINLINK_FEED_BTC / _ETH / … Override/add Polygon aggregator addresses (BTC/ETH built in).
CHAINLINK_STREAMS_API_KEY / _API_SECRET Optional. Data Streams — exact match, needs Chainlink-issued creds.
CHAINLINK_STREAM_BTC / _ETH / _SOL / _XRP / _DOGE Per-asset Data Streams feed IDs (0x…).

Crypto price source (matching Polymarket)

Polymarket prices crypto Up/Down per window: Chainlink for short windows (5m / 15m / 4h) and Binance for hourly / daily. A Binance spot price can differ from Chainlink by tens of dollars, so the bot mirrors Polymarket's choice per window and prices both live ticks and the window open ("Price to Beat") from it (falling back to Binance on any error). The card tags the active source:

  1. Polymarket (POLYMARKET) — the exact live price Polymarket shows, no API key. Connects to Polymarket's public RTDS WebSocket (wss://ws-live-data.polymarket.com, topic crypto_prices_chainlink) — the same live Chainlink feed its UI uses. One socket streams all symbols (~1/sec); the live price matches Polymarket tick-for-tick and the window open ("Price to Beat") comes from the Chainlink-candles endpoint (also exact). Default for crypto on 5m/15m/4h. Disable with POLY_RTDS=false (then it falls back to the candle + Binance-anchor source — exact open, anchored live).
  2. Data Streams (CHAINLINK) — exact, sub-second, but needs Chainlink-issued credentials (CHAINLINK_STREAMS_API_KEY/_API_SECRET + a CHAINLINK_STREAM_* ID).
  3. On-chain Data Feed (CHAINLINK·FEED) — no API key, reads Chainlink's aggregator over your Polygon RPC (~27s heartbeat). CHAINLINK_ONCHAIN=true.
  4. Binance (BINANCE) — used for hourly/daily windows (Polymarket does too) and as the universal fallback.

Short-window priority: Polymarket → Data Streams → on-chain feed → Binance. Long windows (1h/1d) use Binance. Verify with npm run streams:check.

runtime-config.json (the ⚙ CONFIG panel)

All of these apply live, without a restart.

Everything is per-bot now. Each bot version is fully independent. Stored under bots["1"], bots["2"], … (keyed by major version): Mode (paper/live) · Markets · Assets toggle · Paused (Start/Stop) · Betting · Exit · Gates · Risk — and strategy2 (Strategy Bot only). Editing any of them, adding/removing a market, or arming live changes only the bot you're in. Switching bots swaps the tracked market set live (feeds reconcile) and re-derives paper/live from the incoming bot's mode.

Per-bot live safety: switching into a bot that's set to LIVE runs the funding preflight; if the wallet isn't ready it falls back to PAPER (and reverts that bot's saved mode) — a switch can never silently start live trading. The only shared setting is targetWallet (only the Copy Bot uses it). The ⚙ panel header shows which bot you're editing. A legacy runtime-config.json is migrated into the Copy Bot's slot automatically.

Core

  • version — the active bot (set by entering a version in the Manager).
  • modepaper (dry) or live (real money). Switching to live runs the funding preflight and refuses if the wallet isn't funded/approved.
  • paused — kill switch; no new buys. (Exits still run — see below.)
  • targetWallet — the Copy Bot's target (also set via Scout "Use →").

Betting (clip sizing)

  • modefixed ($ per clip) · ratio (× the target's bet) · full (match the target) · bankroll (% of cash).
  • maxClipUsd — hard cap on any single clip.
  • bumpToMin — when a copy would size below the 5-share market minimum, bump it up to the minimum (capped by maxClipUsd) instead of skipping. On by default; prevents the bias of dropping the target's small cheap buys.

Exit

  • modesell (sell-to-recycle near close for instant cash) or hold (keep to resolution, then redeem). For an actively-selling target, hold lets you capture the $1.00 redemption on winners while copy-sell mirrors their exits.
  • secondsBeforeClose / minPrice — when to recycle, and the dust floor.

Entry gates

  • maxEntryPrice — don't copy a side trading above this (avoids chasing 0.9+ near-certain, tiny-edge buys).
  • noTradeTailSeconds — stop entering this many seconds before close.
  • maxClipsPerWindowPerSide, minClipIntervalMs — anti-spam caps.

Risk

  • dailyLossLimitUsd — halt on realized loss.
  • maxOpenUsd — halt on open exposure.

Markets & per-version params

  • markets — the live market list (add/remove from the dashboard).
  • strategy2 — v2.0 Strategy Bot parameters (see v2-strategy-bot.md).

Exits are not gated by paused. Pausing stops new buys, but the bot still manages existing positions (copy-sells + sell-to-recycle) — pausing is risk-off, never risk-on.

Going live — step by step

Live trading is off by default and deliberately multi-step.

  1. Fund the wallet with collateral (pUSD/USDC on Polygon) and a little POL for gas.
  2. Approve the Exchange contracts (one-time on-chain tx):
    npm run live:approve
  3. Verify readiness (read-only — balances + allowances):
    npm run live:check
  4. Arm both switches in .env: PAPER_TRADING=false and LIVE_ARMED=true.
  5. npm start. The engine runs a funding preflight and refuses to start if the wallet isn't funded/approved. You can also flip mode → live in the ⚙ panel (same preflight).

Risk controls apply in live and paper (for parity): MAX_CLIP_USD, MAX_OPEN_USD, DAILY_LOSS_LIMIT_USD, MAX_ENTRY_PRICE. When a limit trips, the dashboard shows a TRADING HALTED banner and no new clips are placed.

⚠️ Live P&L is a notional ledger (fills + expected payouts). Winning positions must be redeemed on-chain after resolution to realize collateral; sell-to-recycle sidesteps this by exiting before close. Start small.

Money mechanics (Polymarket, post-April-2026)

  • Collateral migrated USDC.e → pUSD with a new CTF Exchange V2.
  • "Cash" = free pUSD; portfolio = cash + position mark-to-market.
  • Redeem only credits after on-chain UMA finalization (~2 h even for 15m markets) — which is why sell-to-recycle is the default exit for short windows: it frees collateral instantly for a small spread cost.
  • The bot's wallet (a fresh EOA, signature type 0) is separate from a Magic/email web account; funds don't move between them automatically.