A Val Town Deno/TypeScript paper-trading bot that scans Binance for triangular arbitrage opportunities among today's top-gaining tokens. It only simulates trades — no real money is ever at risk.
- Discovery — fetches
/api/v3/ticker/24hr, keeps symbols quoted in USDT, filters to those that also have an activeTOKEN/ETHpair, then takes the top N by 24h % change. - Cross-rate analysis — for each top-gainer token it concurrently fetches the
three legs of the triangle (
TOKENUSDT,TOKENETH,ETHUSDT) via/api/v3/ticker/bookTicker, computes both triangular directions, applies a 0.1% fee on each leg (0.3% total), and reports the gross %, net $ profit, and route. - Paper execution — when net profit clears the 0.1% threshold and the $1000 paper wallet has funds, the trade is logged to SQLite and a real-time Telegram alert is sent for every trade (small or large), including the updated total balance and running PnL.
- Reporting — additionally, at most every 10 minutes a throttled Telegram summary is sent covering balance, PnL, win rate, scan count, and the last 10 minutes of trades.
Binance's primary API (api.binance.com) can return HTTP 451 from data-center
IPs (a regional block). This bot uses data-api.binance.vision, which serves the
identical /api/v3 endpoints globally — same quotes, no geo-lock.
bot.ts— the cron job (binanceTriangularBot). Runs every minute and performs 12 fast scan rounds ~4s apart. The top-gainer list is cached and refreshed once a minute (the 24h call is heavy), while the cheap order-book scans run every few seconds — fast scanning without hitting Binance rate limits. Sends a real-time alert per executed trade plus a 10-minute summary. ExportsbuildReport()for reuse by the webhook.webhook.ts— HTTP handler responding to Telegram/start,/stats, and/reportcommands.
-
Optionally set the two env vars to enable Telegram reporting:
TELEGRAM_BOT_TOKEN— from @BotFatherTELEGRAM_CHAT_ID— your chat id (ask @userinfobot)
-
Point Telegram at the webhook (replace
<TOKEN>with your bot token) so/statsworks in-chat:https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://binance-arb-bot.val.run/
All knobs live at the top of bot.ts:
| Constant | Default | Meaning |
|---|---|---|
FEE_PER_LEG | 0.001 | fee per leg (0.1%); use 0.00075 for 0.075% |
TRADE_AMOUNT_USDT | 100 | simulated $ per triangular loop |
MIN_NET_PROFIT_PCT | 0.1 | min net % to execute |
TOP_GAINERS_N | 20 | top gainers analyzed per scan |
SCAN_ROUNDS | 12 | scans per cron run |
COOLDOWN_MS | 4000 | seconds between scans (4s) |
REFRESH_GAINERS_MS | 60000 | how often the top-gainer list is re-fetched |
⚠️ Real-time per-trade alerts mean Telegram can be chatty during volatile windows. If that's too much, raise
MIN_NET_PROFIT_PCTor dropSCAN_ROUNDS.
Live Binance spreads plus 0.3% total fees mean real trades are rare — that's correct behavior; opportunities appear during volatile moves.