@neural-trader/sports-betting
v2.1.1
Published
Sports betting for Neural Trader - arbitrage detection, Kelly sizing, syndicate management
Maintainers
Readme
@neural-trader/sports-betting
Advanced sports betting strategies with Kelly Criterion position sizing, arbitrage detection, and risk management for Neural Trader. Optimize bet sizing and find profitable opportunities across bookmakers.
Features
- Kelly Criterion: Mathematically optimal bet sizing for long-term growth
- Arbitrage Detection: Find risk-free betting opportunities across bookmakers
- Syndicate Management: Coordinate group betting pools with profit distribution
- Multi-Bookmaker Analysis: Compare odds across 50+ betting providers
- Risk Management: Position limits, bankroll protection, and drawdown controls
- Real-Time Odds: Live odds updates and line movement tracking
- Market Analysis: Identify value bets and market inefficiencies
- Rust Performance: Sub-millisecond arbitrage detection
Installation
npm install @neural-trader/sports-betting @neural-trader/core @neural-trader/riskQuick Start
Kelly Criterion Bet Sizing
import { RiskManager } from '@neural-trader/sports-betting';
const riskManager = new RiskManager({
confidenceLevel: 0.95,
lookbackPeriods: 100,
method: 'historical'
});
// Calculate Kelly Criterion for a bet
const kelly = riskManager.calculateKelly(
0.55, // 55% win probability (your model's prediction)
2.0, // 2.0x payout on win (decimal odds)
1.0 // 1.0x loss on lose (stake)
);
console.log(`Full Kelly: ${(kelly.kellyFraction * 100).toFixed(2)}%`);
console.log(`Half Kelly (recommended): ${(kelly.halfKelly * 100).toFixed(2)}%`);
console.log(`Quarter Kelly (conservative): ${(kelly.quarterKelly * 100).toFixed(2)}%`);
// For a $10,000 bankroll
const bankroll = 10000;
const betSize = bankroll * kelly.halfKelly;
console.log(`Recommended bet: $${betSize.toFixed(2)}`);Arbitrage Detection
import { ArbitrageDetector } from '@neural-trader/sports-betting';
const detector = new ArbitrageDetector({
minProfitMargin: 0.01, // 1% minimum profit
maxStake: 5000,
bookmakers: ['bet365', 'draftkings', 'fanduel', 'betmgm']
});
// Find arbitrage opportunities for an NFL game
const arbs = await detector.findArbitrage({
sport: 'americanfootball_nfl',
market: 'h2h', // moneyline
event: 'chiefs-vs-bills'
});
for (const arb of arbs) {
console.log(`Arbitrage Opportunity: ${arb.profitMargin.toFixed(2)}% profit`);
console.log(`Bet ${arb.stakes.outcome1} on ${arb.bookmaker1} (${arb.odds1})`);
console.log(`Bet ${arb.stakes.outcome2} on ${arb.bookmaker2} (${arb.odds2})`);
console.log(`Guaranteed profit: $${arb.profit.toFixed(2)}`);
}Real-World Use Cases
1. NFL Betting with Kelly Criterion
import { RiskManager, OddsAnalyzer } from '@neural-trader/sports-betting';
// Your predictive model gives Chiefs 60% win probability
const modelProbability = 0.60;
const oddsData = await OddsAnalyzer.getOdds('americanfootball_nfl', 'chiefs-vs-bills');
// Best available odds: Chiefs -150 (1.67 decimal)
const bestOdds = 1.67;
// Calculate implied probability from odds
const impliedProbability = 1 / bestOdds; // 0.598 (59.8%)
// We have an edge: 60% > 59.8%
const edge = modelProbability - impliedProbability; // 0.002 (0.2% edge)
// Kelly Criterion calculation
const kelly = riskManager.calculateKelly(
modelProbability, // 60% win rate
bestOdds - 1, // 0.67 (win amount)
1.0 // 1.0 (loss amount)
);
// With $50,000 bankroll
const bankroll = 50000;
const fullKelly = bankroll * kelly.kellyFraction; // $600 (risky)
const halfKelly = bankroll * kelly.halfKelly; // $300 (recommended)
const quarterKelly = bankroll * kelly.quarterKelly; // $150 (conservative)
console.log(`Edge: ${(edge * 100).toFixed(2)}%`);
console.log(`Recommended bet (Half Kelly): $${halfKelly.toFixed(2)}`);2. Multi-Leg Arbitrage (Guaranteed Profit)
import { ArbitrageDetector, SyndicateManager } from '@neural-trader/sports-betting';
const detector = new ArbitrageDetector({
minProfitMargin: 0.02, // 2% minimum
maxStake: 10000,
bookmakers: ['bet365', 'draftkings', 'fanduel', 'pinnacle']
});
// Tennis match: Djokovic vs Nadal
const arb = await detector.findArbitrage({
sport: 'tennis',
market: 'h2h',
event: 'djokovic-vs-nadal'
});
if (arb) {
console.log('=== Arbitrage Opportunity ===');
console.log(`Sport: ${arb.sport}`);
console.log(`Event: ${arb.event}`);
console.log(`Profit Margin: ${(arb.profitMargin * 100).toFixed(2)}%`);
// Djokovic at DraftKings: 1.95
console.log(`\nBet 1: ${arb.player1} at ${arb.bookmaker1}`);
console.log(`Odds: ${arb.odds1}`);
console.log(`Stake: $${arb.stakes.player1.toFixed(2)}`);
// Nadal at Bet365: 2.10
console.log(`\nBet 2: ${arb.player2} at ${arb.bookmaker2}`);
console.log(`Odds: ${arb.odds2}`);
console.log(`Stake: $${arb.stakes.player2.toFixed(2)}`);
// Guaranteed profit
console.log(`\nTotal Stake: $${arb.totalStake.toFixed(2)}`);
console.log(`Guaranteed Profit: $${arb.profit.toFixed(2)}`);
console.log(`ROI: ${(arb.roi * 100).toFixed(2)}%`);
}3. Syndicate Betting Pool
import { SyndicateManager } from '@neural-trader/sports-betting';
const syndicate = new SyndicateManager({
id: 'nfl-week-1-pool',
name: 'NFL Week 1 Betting Pool',
totalCapital: 100000,
distributionModel: 'hybrid', // Combines contribution and performance
minProfitMargin: 0.01,
maxPositionSize: 0.1 // Max 10% per bet
});
// Add members with capital contributions
await syndicate.addMember({
id: 'member1',
name: 'John',
email: '[email protected]',
contribution: 40000,
role: 'lead-analyst'
});
await syndicate.addMember({
id: 'member2',
name: 'Sarah',
email: '[email protected]',
contribution: 30000,
role: 'data-scientist'
});
await syndicate.addMember({
id: 'member3',
name: 'Mike',
email: '[email protected]',
contribution: 30000,
role: 'trader'
});
// Find best opportunities across bookmakers
const opportunities = await syndicate.findOpportunities({
sport: 'americanfootball_nfl',
minEdge: 0.02, // 2% minimum edge
minProfitMargin: 0.01
});
// Allocate capital using Kelly Criterion
const allocation = await syndicate.allocateFunds(opportunities, {
strategy: 'kelly_criterion',
riskFactor: 0.5 // Half Kelly
});
console.log('=== Syndicate Allocation ===');
for (const bet of allocation.bets) {
console.log(`${bet.event}: $${bet.stake.toFixed(2)} at ${bet.bookmaker}`);
console.log(`Expected ROI: ${(bet.expectedROI * 100).toFixed(2)}%`);
}
// After week 1: Distribute profits
const weeklyProfit = 8500; // $8,500 profit
const distribution = await syndicate.distributeProfits(weeklyProfit, {
model: 'hybrid',
performanceWeight: 0.3,
contributionWeight: 0.7
});
console.log('\n=== Profit Distribution ===');
for (const member of distribution.members) {
console.log(`${member.name}: $${member.share.toFixed(2)}`);
console.log(`ROI: ${(member.roi * 100).toFixed(2)}%`);
}Kelly Criterion Deep Dive
Understanding the Formula
The Kelly Criterion calculates the optimal bet size as a fraction of your bankroll:
f* = (bp - q) / b
Where:
f* = fraction of bankroll to bet
b = odds received (decimal odds - 1)
p = probability of winning
q = probability of losing (1 - p)Kelly Variations
const kelly = riskManager.calculateKelly(winRate, avgWin, avgLoss);
// Full Kelly (maximum growth, high volatility)
const fullKelly = kelly.kellyFraction;
// Half Kelly (recommended - reduces volatility by 50%)
const halfKelly = kelly.halfKelly;
// Quarter Kelly (conservative - reduces volatility by 75%)
const quarterKelly = kelly.quarterKelly;Example Calculations
// Scenario 1: Strong Edge
// 60% win rate, 2.0x odds
const strong = riskManager.calculateKelly(0.60, 2.0, 1.0);
// Full Kelly: 20% of bankroll
// Half Kelly: 10% of bankroll
// Scenario 2: Moderate Edge
// 52% win rate, 1.95x odds
const moderate = riskManager.calculateKelly(0.52, 1.95, 1.0);
// Full Kelly: 4% of bankroll
// Half Kelly: 2% of bankroll
// Scenario 3: Slight Edge
// 51% win rate, 2.0x odds
const slight = riskManager.calculateKelly(0.51, 2.0, 1.0);
// Full Kelly: 2% of bankroll
// Half Kelly: 1% of bankrollRisk Management Integration
Position Limits and Drawdown Controls
import { RiskManager } from '@neural-trader/sports-betting';
import { PortfolioRiskManager } from '@neural-trader/risk';
const portfolioRisk = new PortfolioRiskManager({
maxDrawdown: 0.20, // 20% max drawdown
maxPositionSize: 0.10, // 10% max per bet
maxDailyLoss: 0.05, // 5% max daily loss
maxCorrelation: 0.7 // Limit correlated bets
});
const sportsRisk = new RiskManager({
confidenceLevel: 0.95,
lookbackPeriods: 100,
method: 'historical'
});
// Calculate bet with risk constraints
async function placeBetWithRiskManagement(
event: string,
winProbability: number,
odds: number,
bankroll: number
) {
// Kelly calculation
const kelly = sportsRisk.calculateKelly(winProbability, odds - 1, 1.0);
const rawBetSize = bankroll * kelly.halfKelly;
// Check risk limits
const riskCheck = await portfolioRisk.validatePosition({
size: rawBetSize,
type: 'sports_bet',
event: event,
expectedReturn: (odds - 1) * winProbability - (1 - winProbability)
});
if (!riskCheck.approved) {
console.log(`Bet rejected: ${riskCheck.reason}`);
return null;
}
// Adjust bet size based on risk limits
const adjustedBetSize = Math.min(
rawBetSize,
riskCheck.maxSize,
bankroll * 0.10 // Hard limit: 10% max
);
console.log(`Kelly Recommended: $${rawBetSize.toFixed(2)}`);
console.log(`Risk-Adjusted: $${adjustedBetSize.toFixed(2)}`);
console.log(`Risk Score: ${riskCheck.riskScore.toFixed(2)}/10`);
return {
event,
betSize: adjustedBetSize,
odds,
expectedValue: adjustedBetSize * ((odds - 1) * winProbability - (1 - winProbability))
};
}Correlation Analysis
// Avoid overexposure to correlated outcomes
const correlationMatrix = await portfolioRisk.analyzeCorrelation([
{ event: 'chiefs-vs-bills', bet: 'chiefs_ml' },
{ event: 'chiefs-vs-bills', bet: 'over_54.5' },
{ event: 'chiefs-vs-bills', bet: 'chiefs_-3' }
]);
// These bets are highly correlated - limit total exposure
if (correlationMatrix.maxCorrelation > 0.7) {
console.log('Warning: High correlation detected');
console.log('Reducing total position size...');
}API Reference
RiskManager
class RiskManager {
constructor(config: RiskConfig);
calculateKelly(
winRate: number,
avgWin: number,
avgLoss: number
): KellyResult;
calculateVaR(
positions: Position[],
confidenceLevel: number
): number;
calculateExpectedValue(
probability: number,
odds: number,
stake: number
): number;
}
interface KellyResult {
kellyFraction: number; // Full Kelly
halfKelly: number; // Recommended
quarterKelly: number; // Conservative
expectedGrowth: number; // Expected bankroll growth rate
risk: number; // Volatility measure
}ArbitrageDetector
class ArbitrageDetector {
constructor(config: ArbitrageConfig);
findArbitrage(options: {
sport: string;
market: string;
event: string;
}): Promise<Arbitrage[]>;
calculateStakes(
odds1: number,
odds2: number,
totalStake: number
): { stake1: number; stake2: number };
monitorOpportunities(
callback: (arb: Arbitrage) => void
): void;
}
interface Arbitrage {
sport: string;
event: string;
bookmaker1: string;
bookmaker2: string;
odds1: number;
odds2: number;
stakes: { outcome1: number; outcome2: number };
profit: number;
profitMargin: number;
roi: number;
}SyndicateManager
class SyndicateManager {
constructor(config: SyndicateConfig);
addMember(member: Member): Promise<void>;
allocateFunds(
opportunities: Opportunity[],
options: AllocationOptions
): Promise<Allocation>;
distributeProfits(
totalProfit: number,
model: DistributionModel
): Promise<Distribution>;
getStatus(): SyndicateStatus;
}
interface SyndicateConfig {
id: string;
name: string;
totalCapital: number;
distributionModel: 'proportional' | 'hybrid' | 'performance';
minProfitMargin: number;
maxPositionSize: number;
}Supported Sports and Markets
| Sport | Markets | Bookmakers | |-------|---------|------------| | NFL | Moneyline, Spread, Totals, Props | 50+ | | NBA | Moneyline, Spread, Totals, Props | 50+ | | MLB | Moneyline, Run Line, Totals | 50+ | | Soccer | 1X2, Over/Under, Both Teams Score | 50+ | | Tennis | Moneyline, Set Betting, Game Totals | 40+ | | MMA | Moneyline, Method of Victory | 30+ |
Performance
- Arbitrage Detection: <10ms per market scan
- Kelly Calculation: <1ms per calculation
- Odds Comparison: 50+ bookmakers in parallel
- Real-Time Updates: Sub-second latency
- Rust WASM: 10-50x faster than JavaScript
Best Practices
- Use Half Kelly: Full Kelly is too aggressive; half Kelly reduces volatility
- Verify Edge: Only bet when you have a proven edge (model accuracy >52%)
- Track Performance: Monitor actual vs expected results
- Manage Bankroll: Never bet more than 5% on a single event
- Account for Correlation: Limit exposure to correlated outcomes
- Monitor Limits: Stay under bookmaker betting limits
- Tax Considerations: Track all bets for tax reporting
Examples
See /examples directory for:
kelly-criterion-nfl.ts- NFL betting with Kelly sizingarbitrage-tennis.ts- Tennis arbitrage detectionsyndicate-pool.ts- Group betting pool managementrisk-management.ts- Advanced risk controlscorrelation-analysis.ts- Portfolio correlation
Dependencies
@neural-trader/core- Core trading engine@neural-trader/risk- Risk management and VaRodds-api- Real-time odds datawasm-pack- Rust WASM bindings
License
MIT OR Apache-2.0
