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 requestsStep 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 opportunitiesStep 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 stakesStep 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 limitsImportant Considerations
- Latency matters — odds can move in seconds. Use the WebSocket feed for faster detection
- Rate limits — the BASIC plan has 100 requests/month. Upgrade to PRO for unlimited
- Bookmaker limits — bookmakers may limit accounts that consistently arb
- 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