Skip to content

Latest commit

Β 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Dual-Market Arbitrage Bot

A professional TypeScript-based arbitrage detection and execution bot that connects to Kalshi and Polymarket prediction markets. The bot identifies cross-platform arbitrage opportunities and can automatically execute trades with comprehensive safety features.

🎯 Overview

This bot continuously monitors prediction markets on both Kalshi and Polymarket, normalizes prices to a common probability scale (0-1), applies realistic fee and gas cost models, maps equivalent markets across platforms, and identifies arbitrage opportunities with net edge calculations. It supports both paper trading (simulation) and live trading (real money) modes.

Key Features

  • βœ… Dual Platform Connection - Authenticated API connections to Kalshi and Polymarket
  • βœ… Complete Market Fetching - Fetches up to 1500 markets per platform from Sports and Politics categories
  • βœ… Price Normalization - Converts all prices to 0-1 probability range for cross-platform comparison
  • βœ… Fee + Gas Model - Realistic cost modeling (Kalshi: 0.5% fee, Polymarket: 0.7% fee + 0.1% gas)
  • βœ… Market Mapping - Text normalization to match equivalent markets across platforms
  • βœ… Arbitrage Detection - Finds opportunities with net edge calculation (after fees + gas)
  • βœ… Paper Trading - Simulated trading with P&L tracking and position management
  • βœ… Live Trading - Real trade execution with hedged execution and safety features
  • βœ… Web Dashboard - Real-time monitoring dashboard with WebSocket updates
  • βœ… 24/7 Operation - Designed for continuous operation with error handling
  • βœ… Structured Logging - Winston-based logging to separate files
  • βœ… Dynamic Intervals - 5-minute base interval, switches to 1-minute in final hour

πŸ“‹ Table of Contents

πŸš€ Installation

Prerequisites

  • Node.js 18+ (ES2022 modules support)
  • npm or yarn
  • Kalshi API Key (get from Kalshi API)

Setup Steps

  1. Clone the repository:

    git clone <repository-url>
    cd arbitrage-bot
  2. Install dependencies:

    npm install
  3. Create .env file:

    cp .env.example .env
    # Edit .env with your configuration
  4. Build the project:

    npm run build

βš™οΈ Configuration

Environment Variables

Create a .env file in the project root with the following variables:

# ============================================
# API Configuration (Required)
# ============================================
KALSHI_API_KEY=your_kalshi_api_key_here
KALSHI_API_KEY_ID=your_kalshi_api_key_id_here
KALSHI_BASE_URL=https://trading-api.kalshi.com/trade-api/v2
POLY_GAMMA_URL=https://gamma-api.polymarket.com
POLY_CLOB_URL=https://clob.polymarket.com

# ============================================
# Polymarket Live Trading (Optional)
# ============================================
POLYMARKET_PRIVATE_KEY=your_ethereum_private_key_here

# ============================================
# Bot Settings
# ============================================
# Run mode: true = run once and exit, false = continuous loop (24-hour mode)
RUN_ONCE=false

# Active categories to fetch (comma-separated)
ACTIVE_CATEGORIES=sports,politics

# Market limits
TARGET_MARKETS_PER_PLATFORM=1500  # Markets per platform (1000-2000 recommended)

# Time filtering (optional)
MIN_MINUTES_TO_END=5      # Ignore markets resolving sooner than 5 minutes
MAX_HOURS_TO_END=720      # Ignore markets resolving later than 30 days

# ============================================
# Trading Configuration
# ============================================
# Enable paper trading (simulation mode)
PAPER_TRADING_ENABLED=true

# Enable live trading (real money - USE WITH CAUTION)
LIVE_TRADING_ENABLED=false

# Minimum net arbitrage edge to trade (0.01 = 1%)
MIN_ARBITRAGE_EDGE=0.01

# Safety limits
MAX_EXPOSURE=10.0          # Maximum total exposure
MAX_POSITION_SIZE=1.0      # Maximum position size per trade

# ============================================
# Fee & Gas Configuration
# ============================================
# Trading fees (as probability adjustments, e.g., 0.005 = 0.5%)
KALSHI_FEE_PROB=0.005          # 0.5% trading fee
POLYMARKET_FEE_PROB=0.007      # 0.7% trading fee

# Gas costs (blockchain transaction costs)
KALSHI_GAS_PROB=0              # 0% (centralized platform, no gas)
POLYMARKET_GAS_PROB=0.001      # 0.1% (Polygon gas cost)

# ============================================
# Web Dashboard
# ============================================
WEB_SERVER_PORT=3000

Configuration Details

API Configuration

  • KALSHI_API_KEY (Required): Your Kalshi API key. Get it from Kalshi Trading API.
  • KALSHI_API_KEY_ID (Required for live trading): Your Kalshi API key ID.
  • KALSHI_BASE_URL: Kalshi API base URL (default provided).
  • POLY_GAMMA_URL: Polymarket Gamma API URL for market discovery (default provided).
  • POLY_CLOB_URL: Polymarket CLOB API URL for orderbook data (default provided).
  • POLYMARKET_PRIVATE_KEY (Required for live trading): Your Ethereum wallet private key for Polymarket.

Bot Settings

  • RUN_ONCE: Set to true to run one cycle and exit (useful for testing). Default: false (24-hour continuous mode).
  • ACTIVE_CATEGORIES: Comma-separated list of categories to fetch. Options: sports, politics. Default: sports,politics.
  • TARGET_MARKETS_PER_PLATFORM: Number of markets to fetch per platform. Default: 1500. Recommended: 1000-2000.
  • MIN_MINUTES_TO_END: Ignore markets resolving sooner than this many minutes. Default: 5.
  • MAX_HOURS_TO_END: Ignore markets resolving later than this many hours. Default: 720 (30 days).

Trading Configuration

  • PAPER_TRADING_ENABLED: Enable paper trading (simulation mode). Default: true (recommended for testing).
  • LIVE_TRADING_ENABLED: Enable live trading (real money). Default: false. Use with extreme caution!
  • MIN_ARBITRAGE_EDGE: Minimum net edge (after fees + gas) to trade. Default: 0.01 (1%).
  • MAX_EXPOSURE: Maximum total exposure across all positions. Default: 10.0.
  • MAX_POSITION_SIZE: Maximum position size per trade. Default: 1.0.

Fee & Gas Configuration

  • KALSHI_FEE_PROB: Kalshi trading fee as probability adjustment. Default: 0.005 (0.5%).
  • POLYMARKET_FEE_PROB: Polymarket trading fee as probability adjustment. Default: 0.007 (0.7%).
  • KALSHI_GAS_PROB: Kalshi gas cost (always 0, centralized platform). Default: 0.
  • POLYMARKET_GAS_PROB: Polymarket gas cost (Polygon blockchain). Default: 0.001 (0.1%).

πŸ“– Usage

Running the Bot

Continuous Mode (24-Hour Production)

Run the bot continuously for 24 hours:

npm start

The bot will:

  1. Start web dashboard on http://localhost:3000
  2. Fetch up to 1500 markets per platform from Sports and Politics categories
  3. Detect arbitrage opportunities
  4. Execute paper trades (if enabled) or live trades (if enabled)
  5. Wait 5 minutes before next cycle (or 1 minute in final hour)
  6. Continue for 24 hours, then automatically complete

Single Run Mode (Testing)

Run the bot once and exit:

RUN_ONCE=true npm start

Development Mode (Auto-reload)

Run with auto-reload on file changes:

npm run dev:bot

🌐 Web Dashboard

The bot includes a real-time web dashboard for monitoring:

Access Dashboard

Open your browser to:

http://localhost:3000

Dashboard Features

  • βœ… Real-time Status - Bot running/stopped status
  • βœ… Market Statistics - Live market counts from both platforms
  • βœ… Arbitrage Opportunities - Recent opportunities with details
  • βœ… Trade History - Paper and live trades with P&L
  • βœ… Live Updates - WebSocket-based real-time updates
  • βœ… Cycle Information - Current cycle progress and timing

API Endpoints

  • GET /api/status - Bot status and statistics
  • GET /api/opportunities - Recent arbitrage opportunities
  • GET /api/trades - Recent trades (paper and live)
  • GET /api/dashboard - Complete dashboard data

πŸ’° Trading Modes

Paper Trading (Simulation)

Paper trading mode simulates trades without using real money:

Features:

  • βœ… Simulated trade execution
  • βœ… P&L tracking
  • βœ… Position management
  • βœ… Win rate calculation
  • βœ… Exposure limits

Enable:

PAPER_TRADING_ENABLED=true

Live Trading (Real Money)

Live trading executes real trades on both platforms:

⚠️ WARNING: Use with extreme caution!

Features:

  • βœ… Real trade execution
  • βœ… Hedged execution (simultaneous buy/sell)
  • βœ… Safety features (circuit breakers, slippage guards)
  • βœ… Position tracking
  • βœ… Error handling and recovery

Enable:

LIVE_TRADING_ENABLED=true
POLYMARKET_PRIVATE_KEY=your_private_key_here
KALSHI_API_KEY_ID=your_key_id_here

Safety Features:

  • Maximum exposure limits
  • Position size limits
  • Slippage protection
  • Circuit breakers
  • Automatic error recovery

Real-Time Log Viewing with Frontail

View logs in real-time in your browser using Frontail:

  1. Install Frontail globally (one-time setup):

    npm install -g frontail
  2. Start the log viewer (in a separate terminal):

    npm run logs

    This will watch both logs/bot.log and logs/arbitrage.log

  3. Open your browser:

    http://localhost:9001
    
  4. View specific log files:

    # View only bot.log
    npm run logs:bot
    
    # View only arbitrage.log
    npm run logs:arbitrage

Frontail provides a beautiful web interface to view log files in real-time with:

  • Auto-refresh as new logs are written
  • Search and filtering capabilities
  • Color-coded log levels
  • Multiple log file support

Note: Keep Frontail running in a separate terminal while your bot is running to see logs in real-time.

Output

The bot outputs to:

  • Console: Real-time progress and results
  • logs/bot.log: Bot lifecycle events
  • logs/market_fetcher.log: Market fetching details
  • logs/arbitrage.log: Arbitrage opportunities (structured JSON)

Example Output

======================================================================
πŸ€– Dual-Market Bot 
======================================================================
πŸ“Š Fetching ALL markets from Kalshi and Polymarket (no pagination limits)
🏷️  Active Categories: SPORTS, POLITICS
⏱️  Update interval: 300 seconds
======================================================================

[2025-12-17T15:00:00.000Z] Starting market fetch cycle...
Active Categories: SPORTS, POLITICS
======================================================================

[KALSHI] Starting market fetch...
[KALSHI] Fetching ALL markets from Sports and Politics categories (no limit)
[KALSHI] Fetching page 1... (0 normalized so far, 0 total fetched)
[KALSHI] Page 1: Received 1000 markets (Total fetched so far: 1000)
[KALSHI] [1] Processing: "Will Team A win the championship?"
...

[POLYMARKET] Starting market fetch...
[POLYMARKET] Fetching ALL open markets from Sport and Politics categories (no limit)
[POLYMARKET API] Requesting markets from https://gamma-api.polymarket.com/markets for category=Sport (active=true&closed=false)
[POLYMARKET API] Requesting markets from https://gamma-api.polymarket.com/markets for category=Politics (active=true&closed=false)
...

======================================================================
πŸ“Š FINAL SUMMARY
======================================================================
Kalshi Markets:     245
Polymarket Markets: 189
Total Markets:      434
======================================================================

πŸ’° Arbitrage opportunities found: 3

πŸ’‘ Arbitrage opportunity on "Will Team A win?" [YES]:
   BUY  KALSHI @ eff=0.5050 (raw ask=0.5000, fee=0.50% + gas=0.00%)
   SELL POLYMARKET @ eff=0.4920 (raw bid=0.5000, fee=0.70% + gas=0.10%)
   Raw edge: 0.00%  |  Net edge (after fees+gas): 1.30%

⏸️  3 arbitrage opportunity/opportunities found. Pausing for 300 seconds (5 minutes) before next cycle...

πŸ—οΈ Architecture

Project Structure

arbitrage-bot/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ api/                           # API clients
β”‚   β”‚   β”œβ”€β”€ kalshiApi.ts              # Kalshi Trading API
β”‚   β”‚   β”œβ”€β”€ polymarketGamma.ts        # Polymarket Gamma API (market discovery)
β”‚   β”‚   └── polymarketClobClient.ts   # Polymarket CLOB API (orderbooks)
β”‚   β”‚
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   └── settings.ts                # Configuration & environment variables
β”‚   β”‚
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── NormalizedMarket.ts       # Market data model
β”‚   β”‚
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ marketFetcher.ts          # Market fetching & normalization
β”‚   β”‚   β”œβ”€β”€ arbitrageFinder.ts        # Arbitrage detection with fee/gas model
β”‚   β”‚   β”œβ”€β”€ paperTrading.ts           # Paper trading engine
β”‚   β”‚   └── liveTrading.ts           # Live trading engine
β”‚   β”‚
β”‚   β”œβ”€β”€ server/
β”‚   β”‚   └── webServer.ts              # Web dashboard server (Express + WebSocket)
β”‚   β”‚
β”‚   β”œβ”€β”€ types/
β”‚   β”‚   └── index.ts                  # TypeScript type definitions
β”‚   β”‚
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ logger.ts                 # Winston logger setup
β”‚   β”‚   β”œβ”€β”€ priceNormalizer.ts        # Price normalization functions
β”‚   β”‚   β”œβ”€β”€ marketFilter.ts           # Category-based market filtering
β”‚   β”‚   β”œβ”€β”€ polymarketSigning.ts      # EIP-712 signing for Polymarket
β”‚   β”‚   └── kalshiSigning.ts          # RSA signing for Kalshi
β”‚   β”‚
β”‚   └── bot.ts                        # Main bot entry point
β”‚
β”œβ”€β”€ public/
β”‚   └── index.html                    # Web dashboard frontend
β”‚
β”œβ”€β”€ logs/                             # Log files
β”‚   β”œβ”€β”€ bot.log                       # Bot lifecycle events
β”‚   β”œβ”€β”€ market_fetcher.log            # Market fetching details
β”‚   β”œβ”€β”€ arbitrage.log                 # Arbitrage opportunities (JSON)
β”‚   β”œβ”€β”€ paper_trading.log             # Paper trading activity
β”‚   └── live_trading.log              # Live trading activity
β”œβ”€β”€ dist/                             # Compiled JavaScript (generated)
β”œβ”€β”€ .env                              # Environment variables
β”œβ”€β”€ tsconfig.json                     # TypeScript configuration
β”œβ”€β”€ package.json                      # Dependencies & scripts
└── README.md                         # This file

Execution Flow

START
  ↓
[Load Config] β†’ [Initialize Logging] β†’ [Start Web Server] β†’ [Check Run Mode]
  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         MARKET FETCH CYCLE               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Fetch Kalshi Markets (Parallel)  β”‚  β”‚
β”‚  β”‚  - Paginate through pages         β”‚  β”‚
β”‚  β”‚  - Filter: Sports + Politics      β”‚  β”‚
β”‚  β”‚  - Fetch orderbooks               β”‚  β”‚
β”‚  β”‚  - Normalize prices (0-100 β†’ 0-1) β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Fetch Polymarket Markets (Parallel)β”‚
β”‚  β”‚  - Fetch open Sport markets       β”‚  β”‚
β”‚  β”‚  - Fetch open Politics markets    β”‚  β”‚
β”‚  β”‚  - Fetch orderbooks (CLOB)        β”‚  β”‚
β”‚  β”‚  - Normalize prices (clamp 0-1)   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Combine Markets                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      ARBITRAGE DETECTION                 β”‚
β”‚  - Map equivalent markets               β”‚
β”‚  - Apply fees + gas model               β”‚
β”‚  - Compute net arbitrage edge           β”‚
β”‚  - Filter by MIN_ARBITRAGE_EDGE        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      TRADE EXECUTION                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Paper Trading (if enabled)      β”‚  β”‚
β”‚  β”‚  - Simulate trade execution       β”‚  β”‚
β”‚  β”‚  - Track P&L                       β”‚  β”‚
β”‚  β”‚  - Update positions                β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Live Trading (if enabled)       β”‚  β”‚
β”‚  β”‚  - Execute hedged trades          β”‚  β”‚
β”‚  β”‚  - Apply safety features          β”‚  β”‚
β”‚  β”‚  - Track positions                β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  ↓
[Update Web Dashboard] β†’ [Display Results]
  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Wait Dynamic Interval                  β”‚
β”‚  - Base: 5 minutes                     β”‚
β”‚  - Final Hour: 1 minute                β”‚
β”‚  β†’ Loop back                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Components

  1. API Clients (src/api/): Function-based API clients for Kalshi and Polymarket
  2. Market Fetcher (src/services/marketFetcher.ts): Orchestrates fetching and normalization
  3. Arbitrage Finder (src/services/arbitrageFinder.ts): Detects opportunities with fee/gas model
  4. Paper Trading (src/services/paperTrading.ts): Simulated trading engine with P&L tracking
  5. Live Trading (src/services/liveTrading.ts): Real trade execution with safety features
  6. Web Server (src/server/webServer.ts): Express server with WebSocket for real-time dashboard
  7. Price Normalizer (src/utils/priceNormalizer.ts): Converts prices to 0-1 range
  8. Market Filter (src/utils/marketFilter.ts): Category-based filtering for Kalshi
  9. Signing Utils (src/utils/): EIP-712 (Polymarket) and RSA (Kalshi) signing for live trading

πŸ“š API Reference

Core Functions

fetchNormalizedKalshiMarkets(fastMode?: boolean): Promise<NormalizedMarket[]>

Fetches and normalizes Kalshi markets.

Parameters:

  • fastMode (optional): If true, skips orderbook fetching for speed. Default: false.

Returns: Array of normalized Kalshi markets.

Example:

const markets = await fetchNormalizedKalshiMarkets(true);

fetchNormalizedPolymarketMarkets(): Promise<NormalizedMarket[]>

Fetches and normalizes Polymarket markets from Sport and Politics categories. Only fetches open markets (active=true&closed=false) to reduce markets with no price data.

Returns: Array of normalized Polymarket markets.

Example:

const markets = await fetchNormalizedPolymarketMarkets();

findArbitrageOpportunities(markets: NormalizedMarket[]): ArbitrageOpportunity[]

Detects arbitrage opportunities in a set of normalized markets.

Parameters:

  • markets: Array of normalized markets from both platforms.

Returns: Array of arbitrage opportunities.

Example:

const opportunities = findArbitrageOpportunities(allMarkets);

computeEffectivePrices(market: NormalizedMarket): EffectivePrices

Computes effective prices after applying fees and gas costs.

Parameters:

  • market: Normalized market object.

Returns: Object with raw and effective prices, plus fee and gas breakdown.

Example:

const prices = computeEffectivePrices(market);
// prices.effBid = market.best_bid - fee - gas
// prices.effAsk = market.best_ask + fee + gas

Data Models

NormalizedMarket

interface NormalizedMarket {
  platform: 'kalshi' | 'polymarket';
  market_id: string;
  question: string;                    // Market question/title
  outcome: 'YES' | 'NO' | 'UP' | 'DOWN' | string;
  best_bid: number | null;             // Normalized to 0-1
  best_ask: number | null;             // Normalized to 0-1
  implied_probability: number | null;  // Normalized to 0-1
  effective_bid?: number | null;       // After fees + gas
  effective_ask?: number | null;        // After fees + gas
}

ArbitrageOpportunity

interface ArbitrageOpportunity {
  eventKey: string;                    // Normalized event identifier
  buyLeg: {
    platform: 'kalshi' | 'polymarket';
    market_id: string;
    question: string;
    outcome: string;
    side: 'BUY';
    price: number;                      // Raw ask price
    effectivePrice: number;             // After fees + gas
  };
  sellLeg: {
    platform: 'kalshi' | 'polymarket';
    market_id: string;
    question: string;
    outcome: string;
    side: 'SELL';
    price: number;                      // Raw bid price
    effectivePrice: number;             // After fees + gas
  };
  rawEdge: number;                     // sellBid - buyAsk (before fees)
  netEdge: number;                     // sellEffBid - buyEffAsk (after fees + gas)
}

πŸ’‘ Examples

Example 1: Basic Usage

# Set up .env file with your API key
echo "KALSHI_API_KEY=your_key_here" > .env

# Run the bot
npm start

Example 2: Test Mode (Single Run)

# Run once and exit
RUN_ONCE=true npm start

Example 3: Custom Configuration

# .env file
KALSHI_API_KEY=your_key_here
FETCH_INTERVAL_SECONDS=600          # Wait 10 minutes when opportunities found
MIN_ARBITRAGE_EDGE=0.02             # Only log opportunities with 2%+ net edge
ACTIVE_CATEGORIES=sports             # Only fetch sports markets

Example 4: Development with Auto-reload

# Watch for file changes and auto-reload
npm run dev:bot

πŸ”§ Troubleshooting

Common Issues

1. "KALSHI_API_KEY is required"

Problem: Missing or invalid Kalshi API key.

Solution:

  • Ensure .env file exists in project root
  • Add KALSHI_API_KEY=your_key_here to .env
  • Get your API key from Kalshi API Documentation

2. "No markets returned from API"

Problem: API endpoint issue or no markets matching filters.

Solution:

  • Check API URLs in .env are correct
  • Verify ACTIVE_CATEGORIES includes valid categories (sports, politics)
  • Check network connectivity
  • Review logs/market_fetcher.log for detailed error messages

3. "Polymarket markets: 0"

Problem: Polymarket API not returning markets.

Solution:

  • Verify POLY_GAMMA_URL is correct: https://gamma-api.polymarket.com
  • Check that categories are correct: Sport and Politics (case-sensitive in API)
  • Note: The bot only fetches open markets (active=true&closed=false) to reduce markets with no price data
  • Review logs/market_fetcher.log for API response details

4. "TypeError: Cannot read property..."

Problem: TypeScript compilation issue or missing build.

Solution:

# Rebuild the project
npm run build

# Or clean and rebuild
npm run clean
npm run build

5. Bot runs too fast/slow

Problem: Loop timing not optimal.

Solution:

  • Adjust FETCH_INTERVAL_SECONDS in .env
  • When opportunities found, bot waits this many seconds
  • When no opportunities, bot continues immediately

Log Files

Check log files for detailed information:

  • logs/bot.log: Bot lifecycle, errors, and general events
  • logs/market_fetcher.log: Market fetching details, API responses, filtering stats
  • logs/arbitrage.log: Arbitrage opportunities in structured JSON format

Debug Mode

Enable verbose logging by modifying src/utils/logger.ts:

// Change log level to 'debug'
const logger = setupLogger('bot', 'logs/bot.log', 'debug');

πŸ› οΈ Development

Building

# Build TypeScript to JavaScript
npm run build

# Output goes to dist/ directory

Development Scripts

# Watch mode (auto-rebuild on changes)
npm run dev

# Watch mode with auto-reload bot
npm run dev:bot

# Clean build artifacts
npm run clean

Code Structure

  • Function-based: No classes (except error classes), pure functions
  • TypeScript: Full type safety with strict mode
  • Modular: Clear separation of concerns
  • Read-only: All operations are GET requests, no trading

Adding New Features

  1. New Category: Add keywords to MARKET_CATEGORIES in src/config/settings.ts
  2. New Platform: Create API client in src/api/, add to marketFetcher.ts
  3. New Filter: Add function to src/utils/marketFilter.ts
  4. New Normalizer: Add function to src/utils/priceNormalizer.ts

Testing

Currently, use RUN_ONCE=true mode for testing:

RUN_ONCE=true npm start

This runs one complete cycle and exits, useful for:

  • Testing configuration
  • Verifying API connections
  • Checking market fetching
  • Validating arbitrage detection

πŸ“ License

ISC

🀝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test thoroughly
  5. Submit a pull request

πŸ“ž Support

For issues, questions, or contributions:

  • Check logs/ directory for detailed error messages
  • Review CODEBASE_SUMMARY.md for architecture details
  • Open an issue on GitHub

πŸš€ Deployment

24/7 Production Deployment

The bot is designed for continuous operation. For production deployment:

  1. Install PM2 (process manager):

    npm install -g pm2
  2. Build the project:

    npm run build
  3. Start with PM2:

    pm2 start dist/bot.js --name arbitrage-bot
  4. Monitor:

    pm2 logs arbitrage-bot
    pm2 monit
  5. Auto-start on reboot:

    pm2 save
    pm2 startup

Docker Deployment

# Build
docker build -t arbitrage-bot .

# Run
docker run -d --name arbitrage-bot --restart unless-stopped \
  -v $(pwd)/.env:/app/.env \
  -v $(pwd)/logs:/app/logs \
  -p 3000:3000 \
  arbitrage-bot

🎯 Milestone Status

Milestone 1: Read-only Arbitrage Detector βœ… COMPLETE

  • βœ… Full Data Ingestion
  • βœ… Normalized Markets/Orderbooks
  • βœ… Fee/Gas Modeling
  • βœ… Mapped Equivalent Markets
  • βœ… Net Arbitrage Edge Calculation
  • βœ… Logged Signals

Milestone 2: Paper Trading βœ… COMPLETE

  • βœ… Simulated Trade Execution
  • βœ… P&L Tracking
  • βœ… Position Management
  • βœ… Statistics and Reporting

Milestone 3: Live Trading βœ… COMPLETE

  • βœ… Real Trade Execution
  • βœ… Hedged Execution
  • βœ… Safety Features
  • βœ… Error Handling
  • βœ… Position Tracking

Note: The bot supports both paper trading (simulation) and live trading (real money). Always test with paper trading first before enabling live trading.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages