@neural-trader/sports-betting
Version:
Sports betting for Neural Trader - arbitrage detection, Kelly sizing, syndicate management
518 lines (410 loc) • 14.4 kB
Markdown
[](https://www.npmjs.com/package/@neural-trader/sports-betting)
[](https://github.com/ruvnet/neural-trader)
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.
- **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
```bash
npm install @neural-trader/sports-betting @neural-trader/core @neural-trader/risk
```
```typescript
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)}`);
```
```typescript
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)}`);
}
```
```typescript
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)}`);
```
```typescript
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)}%`);
}
```
```typescript
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: 'john@example.com',
contribution: 40000,
role: 'lead-analyst'
});
await syndicate.addMember({
id: 'member2',
name: 'Sarah',
email: 'sarah@example.com',
contribution: 30000,
role: 'data-scientist'
});
await syndicate.addMember({
id: 'member3',
name: 'Mike',
email: 'mike@example.com',
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)}%`);
}
```
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
```typescript
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;
```
```typescript
// 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 bankroll
```
```typescript
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))
};
}
```
```typescript
// 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...');
}
```
```typescript
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
}
```
```typescript
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;
}
```
```typescript
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;
}
```
| 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+ |
- **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
1. **Use Half Kelly**: Full Kelly is too aggressive; half Kelly reduces volatility
2. **Verify Edge**: Only bet when you have a proven edge (model accuracy >52%)
3. **Track Performance**: Monitor actual vs expected results
4. **Manage Bankroll**: Never bet more than 5% on a single event
5. **Account for Correlation**: Limit exposure to correlated outcomes
6. **Monitor Limits**: Stay under bookmaker betting limits
7. **Tax Considerations**: Track all bets for tax reporting
## Examples
See `/examples` directory for:
- `kelly-criterion-nfl.ts` - NFL betting with Kelly sizing
- `arbitrage-tennis.ts` - Tennis arbitrage detection
- `syndicate-pool.ts` - Group betting pool management
- `risk-management.ts` - Advanced risk controls
- `correlation-analysis.ts` - Portfolio correlation
## Dependencies
- `@neural-trader/core` - Core trading engine
- `@neural-trader/risk` - Risk management and VaR
- `odds-api` - Real-time odds data
- `wasm-pack` - Rust WASM bindings
## License
MIT OR Apache-2.0