TutorialArbitragePython

Building an Arbitrage Betting Bot with PulseScore API

8 min read

What is Arbitrage Betting?

Arbitrage betting (or "arbing") exploits price differences between bookmakers to guarantee a profit regardless of the outcome. When one bookmaker offers higher odds on Team A and another offers higher odds on Team B, you can bet on both and lock in a margin.

Why PulseScore for Arbitrage?

  • 2-second refresh rate — odds are fresh enough to act on before they move
  • Multiple markets — compare across 50+ market types
  • WebSocket feed — get instant updates without polling

Setting Up the Bot

First, install the required Python packages:

bash
pip install requests

Step 1: Fetch Live Odds

python
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.pulsescore.net/api/v2/bet365"

def get_live_odds(sport="soccer"):
    response = requests.get(
        f"{BASE_URL}/live-events",
        headers={"X-Secret": API_KEY},
        params={"sport": sport}
    )
    return response.json()

Step 2: Calculate Arbitrage Margin

The key formula: if the sum of (1/odds) for all outcomes is less than 1, an arbitrage opportunity exists.

python
def find_arbitrage(events):
    opportunities = []

    for event in events:
        # Find the "Fulltime Result" market group
        ft_mg = None
        for mg in event.get("mg", []):
            if mg["name"].lower() in ["fulltime result", "to win"]:
                ft_mg = mg
                break

        if not ft_mg or len(ft_mg.get("ma", [])) < 2:
            continue

        # Extract decimal odds from each market action
        odds = []
        for ma in ft_mg["ma"]:
            if ma.get("pa") and len(ma["pa"]) > 0:
                odds.append(float(ma["pa"][0]["decimal"]))

        if any(o <= 0 for o in odds) or len(odds) < 2:
            continue

        margin = sum(1/o for o in odds)

        if margin < 1:
            profit_pct = (1 - margin) * 100
            opportunities.append({
                "match": f"{event['home']} vs {event['away']}",
                "league": event["league"],
                "odds": odds,
                "names": [ma["name"] for ma in ft_mg["ma"]],
                "margin": round(margin, 4),
                "profit": round(profit_pct, 2),
            })

    return opportunities

Step 3: Calculate Optimal Stakes

python
def calculate_stakes(odds, names, total_stake=100):
    margin = sum(1/o for o in odds)

    stakes = {}
    for name, odd in zip(names, odds):
        stakes[name] = round(total_stake * (1/odd) / margin, 2)

    stakes["guaranteed_return"] = round(total_stake / margin, 2)
    stakes["profit"] = round((total_stake / margin) - total_stake, 2)
    return stakes

Step 4: Run Continuously

python
import time

while True:
    events = get_live_odds("soccer")
    arbs = find_arbitrage(events)

    for arb in arbs:
        stakes = calculate_stakes(arb["odds"], arb["names"])
        print(f"ARBITRAGE FOUND: {arb['match']}")
        print(f"  Profit: {arb['profit']}%")
        print(f"  Stakes: {stakes}")
        print()

    time.sleep(5)  # Respect rate limits

Important Considerations

  1. Latency matters — odds can move in seconds. Use the WebSocket feed for faster detection
  2. Rate limits — the BASIC plan has 100 requests/month. Upgrade to PRO for unlimited
  3. Bookmaker limits — bookmakers may limit accounts that consistently arb
  4. This is educational — always do your own research before betting

Going Further

  • Use the WebSocket feed for sub-second detection with the PRO or MAX plan
  • Combine PulseScore data with other bookmaker APIs for cross-bookmaker arbitrage
  • Add Telegram notifications for new opportunities