TypeScript automation for my Polymarket reverse strategy on 15-minute BTC/ETH Up or Down markets.
| Profile | @odahoa |
| Username | odahoa |
| Proxy wallet | 0xe2511c9e41c5e762887e538b1d6e7221807aa237 |
| Markets | btc-updown-15m, eth-updown-15m |
All activity, positions, and PnL live on my profile:
https://polymarket.com/@odahoa?tab=activity
This bot trades from that account — it automates what I already do manually. It is not copy trading and does not watch any other wallet.
Polymarket runs 15-minute windows like:
Bitcoin Up or Down — 1:45PM–2:00PM ET
Each window has two tokens:
| Token | Wins when |
|---|---|
| Up | Price at end ≥ price at start |
| Down | Price at end < price at start |
Winning tokens pay $1.00. Losing tokens pay $0.00.
My strategy — the reverse bot — posts limit BUY orders on both sides every window:
That is the same pattern visible on my activity tab: round limit prices (7¢, 8¢, 10¢ … 95¢), 20–90 shares per fill, no sells — hold to resolution.
Early in a window, price often trends one way:
BTC pumps in first 10 minutes
→ Up token ~90–97¢ (favorite)
→ Down token ~3–10¢ (underdog)
The crowd prices the underdog as nearly dead. The reverse bet is: it flips before the window closes.
| Leg | Outcome | Entry | If it wins |
|---|---|---|---|
| Reverse | Underdog | 7–10¢ | ~10–14× |
| Hedge | Favorite | 90–95¢ | ~5–11% |
Only one side pays $1 per window. I run both legs because:
From my account history:
| Pattern | Detail |
|---|---|
| Markets | BTC & ETH 15m Up/Down only |
| Order type | Limit BUY only — never sell |
| Cheap leg | Fills at 7–10¢ (sometimes 5–25¢) on underdog |
| Hedge leg | Fills at 90–95¢ on favorite |
| Both sides | Same window — e.g. Down @ 95¢ and Up @ 15¢ |
| Size | 20–90 shares per order |
The bot replaces hand-placing every limit order each window.
Every 5 seconds (configurable):
1. Scan active btc-updown-15m / eth-updown-15m markets
2. Load Up & Down order books (CLOB API)
3. Underdog = outcome with lower best ask
4. Favorite = the other outcome
5. Post limit BUYs on underdog @ 7¢, 8¢, 9¢, 10¢
6. Post limit BUYs on favorite @ 90¢–95¢ (if hedge enabled)
7. Skip price levels already posted this session
Down best ask = 4¢ → bot bids 7¢, 8¢, 9¢, 10¢ on Down
If Down reverses and wins:
90 shares × 8¢ = $7.20 in
90 shares × $1 = $90.00 out → +$82.80 (~1,150%)
Up best ask = 97¢ → bot bids 90¢–95¢ on Up
If Up holds and wins:
52 shares × 95¢ = $49.40 in
52 shares × $1 = $52.00 out → +$2.60 (~5%)
Market: Bitcoin Up or Down — 1:45–2:00 PM ET
BTC pumped early → Up favored, Down cheap
| Token | Book | Bot posts |
|---|---|---|
| Up (favorite) | ask 97¢ | BUY limits @ 90–95¢ |
| Down (underdog) | ask 4¢ | BUY limits @ 7–10¢ |
| Result | Cheap leg | Hedge leg |
|---|---|---|
| Up wins | Down → $0 | Up → small profit |
| Down reverses | Down → big profit | Up → $0 |
| Buy price | Payout | Return if win |
|---|---|---|
| 7¢ | $1.00 | +1,329% |
| 8¢ | $1.00 | +1,150% |
| 9¢ | $1.00 | +1,011% |
| 10¢ | $1.00 | +900% |
| 95¢ | $1.00 | +5% |
Most 7–10¢ bets go to zero. Edge comes from occasional reversals at high multiples.
git clone https://github.com/KadamParikhe/polymarket-reverse-arbitrage-bot
cd reverse-bot
npm install
cp .env.example .env
npm start # dry-run: logs orders, no submission
DRY_RUN=false
PRIVATE_KEY=0x... # account signing key
FUNDER_ADDRESS=0xe2511c9e41c5e762887e538b1d6e7221807aa237 # @odahoa proxy wallet
SIGNATURE_TYPE=2
SIGNATURE_TYPE |
Use for |
|---|---|
0 |
EOA / MetaMask |
2 |
Gnosis Safe proxy (typical Polymarket account) |
3 |
POLY_1271 deposit wallet |
| Variable | Default | Description |
|---|---|---|
CHEAP_BUY_MIN |
0.07 |
Low end of reversal bids |
CHEAP_BUY_MAX |
0.10 |
High end of reversal bids |
CHEAP_ORDER_USDC |
10 |
USDC per cheap limit order |
ENABLE_EXPENSIVE_HEDGE |
true |
Post 90–95¢ favorite bids |
EXPENSIVE_BUY_MIN |
0.90 |
Low end of hedge bids |
EXPENSIVE_BUY_MAX |
0.95 |
High end of hedge bids |
EXPENSIVE_ORDER_USDC |
50 |
USDC per hedge limit order |
MAX_SHARES_PER_ORDER |
90 |
Max shares per order |
| Variable | Default | Description |
|---|---|---|
MARKET_SLUG_PREFIXES |
btc-updown-15m,eth-updown-15m |
Markets to scan |
POLL_INTERVAL_MS |
5000 |
Scan interval |
MINUTES_BEFORE_CLOSE_MIN |
0 |
Start trading N min into window |
MINUTES_BEFORE_CLOSE_MAX |
15 |
Stop trading N min before close |
Trade only late window (when cheap tokens show up):
MINUTES_BEFORE_CLOSE_MIN=3
MINUTES_BEFORE_CLOSE_MAX=12
| Variable | Default | Description |
|---|---|---|
DRY_RUN |
true |
Log only — no real orders |
reverse-bot/
├── src/
│ ├── index.ts # main loop
│ ├── market-scanner.ts # active 15m markets + books
│ ├── strategy.ts # underdog/favorite + limit prices
│ ├── trader.ts # CLOB order submission
│ └── config.ts
├── .env.example
└── package.json
npm start # run bot
npm run dev # run with hot reload
npm run build # compile TypeScript
DRY_RUN=true first.$ claude mcp add yutaila \
-- python -m otcore.mcp_server <graph>