Setup guide
From a blank server
to a running bot
Six steps to a paper bot, about ten minutes. Three more only if you decide to trade real money — nothing moves until you do.
- What you need
- A VPS with Ubuntu, and your seat token
- What it costs
- Any $5/month box — it uses almost nothing
- Where the keys live
- In a file on that server. Never with us
Jump to a step+
Pick a server, and pick where it is
Any provider works — Hetzner, DigitalOcean, Vultr. The smallest box is enough.
Choose the region deliberately. Polymarket refuses orders from some countries and says so before it looks at the order — a server in a restricted region cannot trade live, whatever else is correct. Paper mode works anywhere.
Two regions we have measured ourselves, by sending real orders rather than by reading a list: Singapore is refused and Indonesia is accepted. Singapore is a common default on Asian providers, so it is worth checking rather than accepting.
We do not publish a full list. Ours would be the two above plus guesses, and a wrong entry costs you a server. Polymarket's own terms are the source; if your region turns out to be refused, the runner says so by name on the first live order and paper keeps working meanwhile.
ssh root@your-server-ipInstall Node
Ubuntu's own package is too old. This is the official installer.
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -apt-get install -y nodejsnode --versionDownload the runner with your seat token
The same token that reads the signal fetches the code: no registry account, no deploy key, and one place to revoke. Paste yours in place of $TOKEN.
export TOKEN='eyJ...' mkdir -p ~/ramalogy && cd ~/ramalogycurl -fsSL -H "Authorization: Bearer $TOKEN" \ https://api.ramalogy.xyz/v1/runner/download -o runner.tgztar xzf runner.tgz --strip-components=1npm install && npm run buildPut the token in a file, not in a command
ps shows command arguments to every user on the box, and your shell keeps them in history. The runner refuses to start if either file is readable by anyone but you.
mkdir -p ~/.ramalogyprintf '%s' "$TOKEN" > ~/.ramalogy/tokenchmod 600 ~/.ramalogy/tokenunset TOKENRun it in paper mode
Paper is the default and cannot be configured away. Nothing reaches the exchange; the gate runs and every window is recorded.
Ctrl-C when you have seen a few. It all lands in ~/.ramalogy/history.db, and npm start -- --history reads it back — declined windows included, because a record of only the trades taken cannot say whether the skips would have won.
cd ~/ramalogy && npm start -- --windows 5Keep it running after you log out
An SSH session ends when you close the laptop. systemd does not.
Do not add Nice= or IOSchedulingClass=idle to that file. Throttling this process delays its heartbeat enough that the feed stops streaming while the process stays up and every health check still passes.
cat >/etc/systemd/system/ramalogy.service <<'EOF'[Unit]Description=ramalogy runnerAfter=network-online.target [Service]ExecStart=/usr/bin/node /root/ramalogy/dist/index.jsRestart=alwaysRestartSec=10WorkingDirectory=/root/ramalogy [Install]WantedBy=multi-user.targetEOF systemctl enable --now ramalogyjournalctl -u ramalogy -fFund a deposit wallet
optionalOnly when you want real orders. Deposit into Polymarket once through their own flow — that creates the deposit wallet, which is the only kind of maker the exchange accepts.
Check the printed address against the one Polymarket shows you before sending anything to it. It is derived from your key, not read from your account — if the two disagree, stop and ask rather than editing the file to match.
cp credentials.example.json ~/.ramalogy/credentials.jsonchmod 600 ~/.ramalogy/credentials.jsonnano ~/.ramalogy/credentials.json # your signing key goes here npm start -- --setup-deposit-walletGo live, deliberately
optionalPick a level, check the size it produces, copy the command. The confirmation phrase is required on every run, not once.
Live mode reads your wallet balance at startup and refuses to start if the bankroll you claim is larger than what you hold. --bankroll auto takes the balance instead of a number that stops being true.
Read the measured results before this step. The strategy did not beat the market in testing: the out-of-sample log score is worse than the market's, its confidence interval excludes zero, and the pre-registered evaluation expects a stop. Start with an amount you would not mind losing entirely.
The runner's default, and what the backtest was measured at.
Clears the exchange's $1 minimum. The gate still declines most windows — this is the size when it does not.
npm start -- --live \ --confirm "I ACCEPT THE MEASURED EDGE IS NOT SIGNIFICANT" \ --bankroll 500 --max-fraction 0.02Rest below the ask, knowing it lost
optionalBy default the runner takes the ask the moment the gate fires. --limit-offset rests a buy below it instead, in dollars. It was measured against taking the ask on 372 windows before it was built, and it lost: net −0.046 per dollar staked, CI [−0.062, −0.032]. At 30c below the ask the fills win 39%.
Waiting does not buy a better price on the same bet — it sorts the bets. You get filled at a discount on the windows turning against you, and are left chasing the ones turning your way. The flag exists because it was asked for, not because the evidence supports it; the runner logs limit-offset.measured-worse on every run that sets it. A resting order is also cancelled when its window closes, and needs 5 shares rather than $1 — the share floor binds a resting order even though it does not bind a taker.
npm start -- --live \ --confirm "I ACCEPT THE MEASURED EDGE IS NOT SIGNIFICANT" \ --bankroll 500 --max-fraction 0.02 \ --limit-offset 0.01| Branch | Win rate | Price paid |
|---|---|---|
| Took the ask | 76.9% | the ask |
| Rested, filled | 72.3% | 1c below |
| Rested, unfilled, crossed late | 86.7% | 12.9c above |
If something is wrong
Pick what your terminal said.
Tap a code for what it means and what to do.
The full reference ships inside the download, as README.md — every flag, what each log line means, and the reasoning behind the execution rules.