Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
/**
* News-Driven Trading with Neural Trader
*
* Demonstrates using @neural-trader/news-trading for:
* - Real-time news sentiment analysis
* - Event-driven trading strategies
* - Earnings reaction patterns
* - Breaking news detection
* - Social media sentiment integration
*/
// News trading configuration
const newsConfig = {
// Sentiment thresholds
sentiment: {
strongBullish: 0.8,
bullish: 0.6,
neutral: [0.4, 0.6],
bearish: 0.4,
strongBearish: 0.2
},
// Trading parameters
trading: {
maxPositionSize: 0.05,
newsReactionWindow: 300, // 5 minutes
stopLoss: 0.02,
takeProfit: 0.05,
holdingPeriodMax: 3600 // 1 hour max
},
// News sources
sources: ['Reuters', 'Bloomberg', 'CNBC', 'WSJ', 'Twitter/X', 'Reddit'],
// Event types
eventTypes: ['earnings', 'fda', 'merger', 'macro', 'executive', 'legal']
};
// Sample news events
const sampleNews = [
{
id: 'news_001',
timestamp: '2024-12-31T09:30:00Z',
headline: 'Apple Reports Record Q4 Revenue, Beats Estimates by 8%',
source: 'Bloomberg',
symbols: ['AAPL'],
eventType: 'earnings',
sentiment: {
score: 0.85,
magnitude: 0.92,
keywords: ['record', 'beats', 'revenue growth', 'strong demand']
},
priceImpact: {
immediate: 0.035, // 3.5% immediate move
t5min: 0.042,
t15min: 0.038,
t1hour: 0.045
}
},
{
id: 'news_002',
timestamp: '2024-12-31T10:15:00Z',
headline: 'Fed Officials Signal Pause in Rate Cuts Amid Inflation Concerns',
source: 'Reuters',
symbols: ['SPY', 'QQQ', 'TLT'],
eventType: 'macro',
sentiment: {
score: 0.35,
magnitude: 0.78,
keywords: ['pause', 'inflation', 'concerns', 'hawkish']
},
priceImpact: {
immediate: -0.012,
t5min: -0.018,
t15min: -0.015,
t1hour: -0.008
}
},
{
id: 'news_003',
timestamp: '2024-12-31T11:00:00Z',
headline: 'NVIDIA Announces Next-Gen AI Chip With 3x Performance Improvement',
source: 'CNBC',
symbols: ['NVDA', 'AMD', 'INTC'],
eventType: 'product',
sentiment: {
score: 0.88,
magnitude: 0.95,
keywords: ['next-gen', 'breakthrough', 'AI', 'performance']
},
priceImpact: {
immediate: 0.048,
t5min: 0.062,
t15min: 0.055,
t1hour: 0.071
}
},
{
id: 'news_004',
timestamp: '2024-12-31T12:30:00Z',
headline: 'Tesla Recalls 500,000 Vehicles Over Safety Concerns',
source: 'WSJ',
symbols: ['TSLA'],
eventType: 'legal',
sentiment: {
score: 0.22,
magnitude: 0.85,
keywords: ['recall', 'safety', 'concerns', 'investigation']
},
priceImpact: {
immediate: -0.028,
t5min: -0.035,
t15min: -0.032,
t1hour: -0.025
}
},
{
id: 'news_005',
timestamp: '2024-12-31T13:45:00Z',
headline: 'Biotech Company Receives FDA Fast Track Designation for Cancer Drug',
source: 'Reuters',
symbols: ['MRNA'],
eventType: 'fda',
sentiment: {
score: 0.82,
magnitude: 0.88,
keywords: ['FDA', 'fast track', 'breakthrough', 'cancer']
},
priceImpact: {
immediate: 0.085,
t5min: 0.125,
t15min: 0.098,
t1hour: 0.115
}
}
];
// Social media sentiment data
const socialSentiment = {
'AAPL': { twitter: 0.72, reddit: 0.68, mentions: 15420, trend: 'rising' },
'NVDA': { twitter: 0.85, reddit: 0.82, mentions: 28350, trend: 'rising' },
'TSLA': { twitter: 0.45, reddit: 0.38, mentions: 42100, trend: 'falling' },
'MRNA': { twitter: 0.78, reddit: 0.75, mentions: 8920, trend: 'rising' },
'SPY': { twitter: 0.52, reddit: 0.55, mentions: 35600, trend: 'stable' }
};
async function main() {
console.log('='.repeat(70));
console.log('News-Driven Trading - Neural Trader');
console.log('='.repeat(70));
console.log();
// 1. Display configuration
console.log('1. Trading Configuration:');
console.log('-'.repeat(70));
console.log(` Reaction Window: ${newsConfig.trading.newsReactionWindow}s (${newsConfig.trading.newsReactionWindow / 60}min)`);
console.log(` Max Position: ${newsConfig.trading.maxPositionSize * 100}%`);
console.log(` Stop Loss: ${newsConfig.trading.stopLoss * 100}%`);
console.log(` Take Profit: ${newsConfig.trading.takeProfit * 100}%`);
console.log(` News Sources: ${newsConfig.sources.join(', ')}`);
console.log();
// 2. News feed analysis
console.log('2. Live News Feed Analysis:');
console.log('='.repeat(70));
for (const news of sampleNews) {
console.log();
console.log(` 📰 ${news.headline}`);
console.log('-'.repeat(70));
console.log(` Time: ${news.timestamp} | Source: ${news.source} | Type: ${news.eventType}`);
console.log(` Symbols: ${news.symbols.join(', ')}`);
console.log();
// Sentiment analysis
const sentimentLabel = getSentimentLabel(news.sentiment.score);
console.log(' Sentiment Analysis:');
console.log(` Score: ${news.sentiment.score.toFixed(2)} (${sentimentLabel})`);
console.log(` Magnitude: ${news.sentiment.magnitude.toFixed(2)}`);
console.log(` Keywords: ${news.sentiment.keywords.join(', ')}`);
console.log();
// Price impact analysis
console.log(' Price Impact Analysis:');
console.log(' Window | Expected Move | Confidence | Signal');
console.log(' ' + '-'.repeat(50));
const impacts = [
{ window: 'Immediate', move: news.priceImpact.immediate, conf: 0.85 },
{ window: 'T+5 min', move: news.priceImpact.t5min, conf: 0.78 },
{ window: 'T+15 min', move: news.priceImpact.t15min, conf: 0.65 },
{ window: 'T+1 hour', move: news.priceImpact.t1hour, conf: 0.52 }
];
impacts.forEach(impact => {
const moveStr = impact.move >= 0 ? `+${(impact.move * 100).toFixed(2)}%` : `${(impact.move * 100).toFixed(2)}%`;
const signal = getSignal(impact.move, impact.conf);
console.log(` ${impact.window.padEnd(12)} | ${moveStr.padStart(13)} | ${(impact.conf * 100).toFixed(0).padStart(9)}% | ${signal}`);
});
console.log();
// Trading recommendation
const recommendation = generateRecommendation(news);
console.log(' 📊 Trading Recommendation:');
console.log(` Action: ${recommendation.action.toUpperCase()}`);
console.log(` Symbol: ${recommendation.symbol}`);
console.log(` Size: ${(recommendation.size * 100).toFixed(1)}% of portfolio`);
console.log(` Stop Loss: ${(recommendation.stopLoss * 100).toFixed(2)}%`);
console.log(` Target: ${(recommendation.target * 100).toFixed(2)}%`);
console.log(` Expected: ${(recommendation.expectedReturn * 100).toFixed(2)}%`);
}
// 3. Social sentiment dashboard
console.log();
console.log('3. Social Media Sentiment Dashboard:');
console.log('='.repeat(70));
console.log(' Symbol | Twitter | Reddit | Mentions | Trend | Combined');
console.log('-'.repeat(70));
Object.entries(socialSentiment).forEach(([symbol, data]) => {
const combined = (data.twitter + data.reddit) / 2;
const twitterStr = getSentimentEmoji(data.twitter) + ` ${(data.twitter * 100).toFixed(0)}%`;
const redditStr = getSentimentEmoji(data.reddit) + ` ${(data.reddit * 100).toFixed(0)}%`;
console.log(` ${symbol.padEnd(6)} | ${twitterStr.padEnd(7)} | ${redditStr.padEnd(7)} | ${data.mentions.toLocaleString().padStart(8)} | ${data.trend.padEnd(7)} | ${getSentimentLabel(combined)}`);
});
console.log();
// 4. Event-type performance
console.log('4. Historical Performance by Event Type:');
console.log('-'.repeat(70));
const eventStats = calculateEventTypeStats(sampleNews);
console.log(' Event Type | Avg Move | Win Rate | Avg Duration | Best Time');
console.log('-'.repeat(70));
Object.entries(eventStats).forEach(([type, stats]) => {
console.log(` ${type.padEnd(12)} | ${formatMove(stats.avgMove).padStart(9)} | ${(stats.winRate * 100).toFixed(0).padStart(7)}% | ${stats.avgDuration.padStart(12)} | ${stats.bestTime}`);
});
console.log();
// 5. Pattern recognition
console.log('5. Historical Pattern Recognition (RuVector):');
console.log('-'.repeat(70));
const patterns = findSimilarPatterns(sampleNews[0]);
console.log(` Finding patterns similar to: "${sampleNews[0].headline.substring(0, 50)}..."`);
console.log();
console.log(' Similar Events:');
patterns.forEach((pattern, i) => {
console.log(` ${i + 1}. ${pattern.headline.substring(0, 45)}...`);
console.log(` Date: ${pattern.date} | Move: ${formatMove(pattern.move)} | Similarity: ${(pattern.similarity * 100).toFixed(0)}%`);
});
console.log();
// 6. Real-time alerts
console.log('6. Alert Configuration:');
console.log('-'.repeat(70));
console.log(' Active Alerts:');
console.log(' - Earnings beats/misses > 5%');
console.log(' - FDA decisions for watchlist stocks');
console.log(' - Sentiment score change > 0.3 in 15 min');
console.log(' - Unusual social media volume (3x average)');
console.log(' - Breaking news with magnitude > 0.8');
console.log();
// 7. Performance summary
console.log('7. News Trading Performance Summary:');
console.log('-'.repeat(70));
const perfSummary = calculatePerformance(sampleNews);
console.log(` Total Trades: ${perfSummary.totalTrades}`);
console.log(` Win Rate: ${(perfSummary.winRate * 100).toFixed(1)}%`);
console.log(` Avg Winner: +${(perfSummary.avgWin * 100).toFixed(2)}%`);
console.log(` Avg Loser: ${(perfSummary.avgLoss * 100).toFixed(2)}%`);
console.log(` Profit Factor: ${perfSummary.profitFactor.toFixed(2)}`);
console.log(` Sharpe (news): ${perfSummary.sharpe.toFixed(2)}`);
console.log(` Best Event Type: ${perfSummary.bestEventType}`);
console.log();
console.log('='.repeat(70));
console.log('News-driven trading analysis completed!');
console.log('='.repeat(70));
}
// Get sentiment label from score
function getSentimentLabel(score) {
if (score >= newsConfig.sentiment.strongBullish) return 'STRONG BULLISH';
if (score >= newsConfig.sentiment.bullish) return 'Bullish';
if (score <= newsConfig.sentiment.strongBearish) return 'STRONG BEARISH';
if (score <= newsConfig.sentiment.bearish) return 'Bearish';
return 'Neutral';
}
// Get sentiment emoji
function getSentimentEmoji(score) {
if (score >= 0.7) return '🟢';
if (score >= 0.55) return '🟡';
if (score <= 0.3) return '🔴';
if (score <= 0.45) return '🟠';
return '⚪';
}
// Get trading signal
function getSignal(move, confidence) {
const absMove = Math.abs(move);
if (absMove < 0.01 || confidence < 0.5) return 'HOLD';
if (move > 0 && confidence > 0.7) return '🟢 LONG';
if (move > 0) return '🟡 WEAK LONG';
if (move < 0 && confidence > 0.7) return '🔴 SHORT';
return '🟠 WEAK SHORT';
}
// Format price move
function formatMove(move) {
return move >= 0 ? `+${(move * 100).toFixed(2)}%` : `${(move * 100).toFixed(2)}%`;
}
// Generate trading recommendation
function generateRecommendation(news) {
const mainSymbol = news.symbols[0];
const sentiment = news.sentiment.score;
const magnitude = news.sentiment.magnitude;
const expectedMove = news.priceImpact.t5min;
let action = 'HOLD';
let size = 0;
if (sentiment >= newsConfig.sentiment.bullish && magnitude > 0.7) {
action = 'BUY';
size = Math.min(magnitude * newsConfig.trading.maxPositionSize, newsConfig.trading.maxPositionSize);
} else if (sentiment <= newsConfig.sentiment.bearish && magnitude > 0.7) {
action = 'SHORT';
size = Math.min(magnitude * newsConfig.trading.maxPositionSize, newsConfig.trading.maxPositionSize);
}
return {
action,
symbol: mainSymbol,
size,
stopLoss: action === 'BUY' ? -newsConfig.trading.stopLoss : newsConfig.trading.stopLoss,
target: action === 'BUY' ? newsConfig.trading.takeProfit : -newsConfig.trading.takeProfit,
expectedReturn: expectedMove * (action === 'SHORT' ? -1 : 1)
};
}
// Calculate event type statistics
function calculateEventTypeStats(news) {
const stats = {
earnings: { avgMove: 0.042, winRate: 0.68, avgDuration: '45 min', bestTime: 'Pre-market' },
fda: { avgMove: 0.085, winRate: 0.72, avgDuration: '2-4 hours', bestTime: 'Any' },
macro: { avgMove: 0.015, winRate: 0.55, avgDuration: '1-2 hours', bestTime: 'Morning' },
merger: { avgMove: 0.12, winRate: 0.65, avgDuration: '1 day', bestTime: 'Pre-market' },
product: { avgMove: 0.048, winRate: 0.62, avgDuration: '1 hour', bestTime: 'Market hours' },
legal: { avgMove: -0.025, winRate: 0.45, avgDuration: '30 min', bestTime: 'Any' }
};
return stats;
}
// Find similar historical patterns
function findSimilarPatterns(currentNews) {
// Simulated pattern matching (RuVector integration)
return [
{ headline: 'Apple Q3 2024 earnings beat by 6%, iPhone sales strong', date: '2024-08-01', move: 0.038, similarity: 0.92 },
{ headline: 'Apple Q2 2024 revenue exceeds expectations', date: '2024-05-02', move: 0.029, similarity: 0.87 },
{ headline: 'Apple Q4 2023 sets new revenue record', date: '2023-11-02', move: 0.045, similarity: 0.84 },
{ headline: 'Apple Services revenue beats by 10%', date: '2024-02-01', move: 0.032, similarity: 0.79 }
];
}
// Calculate overall performance
function calculatePerformance(news) {
return {
totalTrades: 127,
winRate: 0.64,
avgWin: 0.032,
avgLoss: -0.018,
profitFactor: 1.85,
sharpe: 1.92,
bestEventType: 'FDA Approvals'
};
}
// Run the example
main().catch(console.error);

View File

@@ -0,0 +1,317 @@
/**
* Prediction Markets with Neural Trader
*
* Demonstrates using @neural-trader/prediction-markets for:
* - Polymarket integration
* - Expected value calculations
* - Market making strategies
* - Arbitrage across platforms
* - Event probability analysis
*/
// Prediction market configuration
const marketConfig = {
platforms: ['Polymarket', 'Kalshi', 'PredictIt'],
initialCapital: 10000,
maxPositionSize: 0.10,
minEdge: 0.03,
fees: {
Polymarket: 0.02,
Kalshi: 0.02,
PredictIt: 0.10
}
};
// Sample market data
const predictionMarkets = [
{
id: 'fed-rate-jan-2025',
question: 'Will the Fed cut rates in January 2025?',
category: 'Economics',
endDate: '2025-01-31',
platforms: {
Polymarket: { yes: 0.22, no: 0.78, volume: 1250000 },
Kalshi: { yes: 0.24, no: 0.76, volume: 850000 }
},
modelProbability: 0.18
},
{
id: 'btc-100k-jan-2025',
question: 'Will Bitcoin reach $100,000 by January 31, 2025?',
category: 'Crypto',
endDate: '2025-01-31',
platforms: {
Polymarket: { yes: 0.65, no: 0.35, volume: 5200000 },
Kalshi: { yes: 0.62, no: 0.38, volume: 2100000 }
},
modelProbability: 0.70
},
{
id: 'sp500-6000-q1-2025',
question: 'Will S&P 500 close above 6000 in Q1 2025?',
category: 'Markets',
endDate: '2025-03-31',
platforms: {
Polymarket: { yes: 0.58, no: 0.42, volume: 980000 },
Kalshi: { yes: 0.55, no: 0.45, volume: 1450000 }
},
modelProbability: 0.62
},
{
id: 'ai-regulation-2025',
question: 'Will the US pass major AI regulation in 2025?',
category: 'Politics',
endDate: '2025-12-31',
platforms: {
Polymarket: { yes: 0.35, no: 0.65, volume: 750000 },
PredictIt: { yes: 0.38, no: 0.62, volume: 420000 }
},
modelProbability: 0.28
},
{
id: 'eth-merge-upgrade-2025',
question: 'Will Ethereum complete Pectra upgrade by March 2025?',
category: 'Crypto',
endDate: '2025-03-31',
platforms: {
Polymarket: { yes: 0.72, no: 0.28, volume: 890000 }
},
modelProbability: 0.75
}
];
async function main() {
console.log('='.repeat(70));
console.log('Prediction Markets Analysis - Neural Trader');
console.log('='.repeat(70));
console.log();
// 1. Display configuration
console.log('1. Configuration:');
console.log('-'.repeat(70));
console.log(` Capital: $${marketConfig.initialCapital.toLocaleString()}`);
console.log(` Max Position: ${marketConfig.maxPositionSize * 100}%`);
console.log(` Min Edge: ${marketConfig.minEdge * 100}%`);
console.log(` Platforms: ${marketConfig.platforms.join(', ')}`);
console.log();
// 2. Market overview
console.log('2. Market Overview:');
console.log('-'.repeat(70));
console.log(' Market | Category | End Date | Volume');
console.log('-'.repeat(70));
predictionMarkets.forEach(market => {
const totalVolume = Object.values(market.platforms)
.reduce((sum, p) => sum + p.volume, 0);
console.log(` ${market.question.substring(0, 40).padEnd(40)} | ${market.category.padEnd(10)} | ${market.endDate} | $${(totalVolume / 1e6).toFixed(2)}M`);
});
console.log();
// 3. Analyze each market
console.log('3. Market Analysis:');
console.log('='.repeat(70));
const opportunities = [];
for (const market of predictionMarkets) {
console.log();
console.log(` 📊 ${market.question}`);
console.log('-'.repeat(70));
console.log(` Category: ${market.category} | End: ${market.endDate} | Model P(Yes): ${(market.modelProbability * 100).toFixed(0)}%`);
console.log();
// Platform comparison
console.log(' Platform | Yes Price | No Price | Implied P | Spread | Volume');
console.log(' ' + '-'.repeat(60));
for (const [platform, data] of Object.entries(market.platforms)) {
const impliedYes = data.yes;
const spread = Math.abs(data.yes + data.no - 1);
console.log(` ${platform.padEnd(12)} | $${data.yes.toFixed(2).padStart(8)} | $${data.no.toFixed(2).padStart(8)} | ${(impliedYes * 100).toFixed(1).padStart(8)}% | ${(spread * 100).toFixed(1)}% | $${(data.volume / 1e6).toFixed(2)}M`);
}
console.log();
// Calculate EV opportunities
console.log(' Expected Value Analysis:');
console.log(' Position | Platform | Price | Model P | EV | Action');
console.log(' ' + '-'.repeat(60));
for (const [platform, data] of Object.entries(market.platforms)) {
const fee = marketConfig.fees[platform];
// YES position
const yesEV = calculateEV(market.modelProbability, data.yes, fee);
const yesAction = yesEV > marketConfig.minEdge ? '✅ BUY YES' : 'PASS';
console.log(` ${'YES'.padEnd(11)} | ${platform.padEnd(12)} | $${data.yes.toFixed(2).padStart(5)} | ${(market.modelProbability * 100).toFixed(0).padStart(6)}% | ${formatEV(yesEV).padStart(8)} | ${yesAction}`);
// NO position
const noEV = calculateEV(1 - market.modelProbability, data.no, fee);
const noAction = noEV > marketConfig.minEdge ? '✅ BUY NO' : 'PASS';
console.log(` ${'NO'.padEnd(11)} | ${platform.padEnd(12)} | $${data.no.toFixed(2).padStart(5)} | ${((1 - market.modelProbability) * 100).toFixed(0).padStart(6)}% | ${formatEV(noEV).padStart(8)} | ${noAction}`);
// Track opportunities
if (yesEV > marketConfig.minEdge) {
opportunities.push({
market: market.question,
platform,
position: 'YES',
price: data.yes,
ev: yesEV,
modelProb: market.modelProbability
});
}
if (noEV > marketConfig.minEdge) {
opportunities.push({
market: market.question,
platform,
position: 'NO',
price: data.no,
ev: noEV,
modelProb: 1 - market.modelProbability
});
}
}
console.log();
// Cross-platform arbitrage check
if (Object.keys(market.platforms).length > 1) {
const arbResult = checkCrossArbitrage(market);
if (arbResult.hasArbitrage) {
console.log(` 🎯 ARBITRAGE: Buy YES on ${arbResult.yesPlatform} ($${arbResult.yesPrice.toFixed(2)})`);
console.log(` Buy NO on ${arbResult.noPlatform} ($${arbResult.noPrice.toFixed(2)})`);
console.log(` Guaranteed profit: ${(arbResult.profit * 100).toFixed(2)}%`);
}
}
}
// 4. Portfolio recommendations
console.log();
console.log('4. Portfolio Recommendations:');
console.log('='.repeat(70));
if (opportunities.length === 0) {
console.log(' No positions currently meet the minimum edge criteria.');
} else {
// Sort by EV
opportunities.sort((a, b) => b.ev - a.ev);
console.log(' Rank | Market | Position | Platform | EV | Size');
console.log('-'.repeat(70));
let totalAllocation = 0;
opportunities.slice(0, 5).forEach((opp, i) => {
const kelly = calculateKelly(opp.modelProb, opp.price);
const size = Math.min(kelly * 0.25, marketConfig.maxPositionSize) * marketConfig.initialCapital;
totalAllocation += size;
console.log(` ${(i + 1).toString().padStart(4)} | ${opp.market.substring(0, 38).padEnd(38)} | ${opp.position.padEnd(8)} | ${opp.platform.padEnd(12)} | ${formatEV(opp.ev).padStart(7)} | $${size.toFixed(0)}`);
});
console.log('-'.repeat(70));
console.log(` Total Allocation: $${totalAllocation.toFixed(0)} (${(totalAllocation / marketConfig.initialCapital * 100).toFixed(1)}% of capital)`);
}
console.log();
// 5. Market making opportunities
console.log('5. Market Making Opportunities:');
console.log('-'.repeat(70));
console.log(' Markets with high spread (>5%):');
predictionMarkets.forEach(market => {
for (const [platform, data] of Object.entries(market.platforms)) {
const spread = Math.abs(data.yes + data.no - 1);
if (spread > 0.05) {
console.log(` - ${market.question.substring(0, 45)} (${platform}): ${(spread * 100).toFixed(1)}% spread`);
}
}
});
console.log();
// 6. Risk analysis
console.log('6. Risk Analysis:');
console.log('-'.repeat(70));
const categoryExposure = {};
opportunities.forEach(opp => {
const market = predictionMarkets.find(m => m.question === opp.market);
if (market) {
categoryExposure[market.category] = (categoryExposure[market.category] || 0) + 1;
}
});
console.log(' Category concentration:');
Object.entries(categoryExposure).forEach(([cat, count]) => {
console.log(` - ${cat}: ${count} positions`);
});
console.log();
console.log(' Correlation warnings:');
console.log(' - BTC $100K and S&P 6000 may be correlated (risk-on assets)');
console.log(' - Consider hedging or reducing combined exposure');
console.log();
console.log('='.repeat(70));
console.log('Prediction markets analysis completed!');
console.log('='.repeat(70));
}
// Calculate Expected Value
function calculateEV(trueProb, price, fee) {
const netProfit = (1 - fee) / price - 1;
const ev = trueProb * netProfit - (1 - trueProb);
return ev;
}
// Format EV for display
function formatEV(ev) {
const pct = ev * 100;
return pct >= 0 ? `+${pct.toFixed(1)}%` : `${pct.toFixed(1)}%`;
}
// Calculate Kelly Criterion for prediction markets
function calculateKelly(prob, price) {
const b = 1 / price - 1; // Potential profit per dollar
const p = prob;
const q = 1 - prob;
const kelly = (b * p - q) / b;
return Math.max(0, kelly);
}
// Check for cross-platform arbitrage
function checkCrossArbitrage(market) {
const platforms = Object.entries(market.platforms);
if (platforms.length < 2) return { hasArbitrage: false };
let bestYes = { price: 1, platform: '' };
let bestNo = { price: 1, platform: '' };
platforms.forEach(([platform, data]) => {
if (data.yes < bestYes.price) {
bestYes = { price: data.yes, platform };
}
if (data.no < bestNo.price) {
bestNo = { price: data.no, platform };
}
});
const totalCost = bestYes.price + bestNo.price;
if (totalCost < 1) {
return {
hasArbitrage: true,
yesPlatform: bestYes.platform,
yesPrice: bestYes.price,
noPlatform: bestNo.platform,
noPrice: bestNo.price,
profit: 1 / totalCost - 1
};
}
return { hasArbitrage: false };
}
// Run the example
main().catch(console.error);

View File

@@ -0,0 +1,335 @@
/**
* Sports Betting with Neural Trader
*
* Demonstrates using @neural-trader/sports-betting for:
* - Arbitrage detection across sportsbooks
* - Kelly Criterion position sizing
* - Expected Value (EV) calculations
* - Odds comparison and analysis
* - Bankroll management
*/
// Sports betting configuration
const bettingConfig = {
// Bankroll settings
initialBankroll: 10000,
maxBetPercent: 0.05, // 5% max per bet (conservative Kelly)
minEdge: 0.02, // 2% minimum edge to bet
fractionKelly: 0.25, // Quarter Kelly for safety
// Sportsbooks
sportsbooks: ['DraftKings', 'FanDuel', 'BetMGM', 'Caesars', 'PointsBet'],
// Sports to analyze
sports: ['NFL', 'NBA', 'MLB', 'NHL', 'Soccer', 'UFC']
};
// Sample odds data (American format)
const sampleOdds = {
'NFL_Week17_Chiefs_Raiders': {
event: 'Kansas City Chiefs vs Las Vegas Raiders',
sport: 'NFL',
date: '2024-12-29',
time: '16:25 ET',
odds: {
'DraftKings': { moneyline: { home: -280, away: +230 }, spread: { home: -6.5, homeOdds: -110, away: +6.5, awayOdds: -110 }, total: { over: 44.5, overOdds: -110, under: 44.5, underOdds: -110 } },
'FanDuel': { moneyline: { home: -285, away: +235 }, spread: { home: -6.5, homeOdds: -112, away: +6.5, awayOdds: -108 }, total: { over: 44.5, overOdds: -108, under: 44.5, underOdds: -112 } },
'BetMGM': { moneyline: { home: -275, away: +225 }, spread: { home: -6.5, homeOdds: -108, away: +6.5, awayOdds: -112 }, total: { over: 45.0, overOdds: -110, under: 45.0, underOdds: -110 } },
'Caesars': { moneyline: { home: -290, away: +240 }, spread: { home: -7.0, homeOdds: -110, away: +7.0, awayOdds: -110 }, total: { over: 44.5, overOdds: -105, under: 44.5, underOdds: -115 } },
'PointsBet': { moneyline: { home: -270, away: +220 }, spread: { home: -6.5, homeOdds: -115, away: +6.5, awayOdds: -105 }, total: { over: 44.5, overOdds: -112, under: 44.5, underOdds: -108 } }
},
trueProbability: { home: 0.72, away: 0.28 } // Model estimate
},
'NBA_Lakers_Warriors': {
event: 'Los Angeles Lakers vs Golden State Warriors',
sport: 'NBA',
date: '2024-12-30',
time: '19:30 ET',
odds: {
'DraftKings': { moneyline: { home: +145, away: -170 }, spread: { home: +4.5, homeOdds: -110, away: -4.5, awayOdds: -110 }, total: { over: 225.5, overOdds: -110, under: 225.5, underOdds: -110 } },
'FanDuel': { moneyline: { home: +150, away: -175 }, spread: { home: +4.5, homeOdds: -108, away: -4.5, awayOdds: -112 }, total: { over: 226.0, overOdds: -110, under: 226.0, underOdds: -110 } },
'BetMGM': { moneyline: { home: +140, away: -165 }, spread: { home: +4.0, homeOdds: -110, away: -4.0, awayOdds: -110 }, total: { over: 225.5, overOdds: -108, under: 225.5, underOdds: -112 } },
'Caesars': { moneyline: { home: +155, away: -180 }, spread: { home: +5.0, homeOdds: -110, away: -5.0, awayOdds: -110 }, total: { over: 225.0, overOdds: -115, under: 225.0, underOdds: -105 } },
'PointsBet': { moneyline: { home: +160, away: -185 }, spread: { home: +5.0, homeOdds: -105, away: -5.0, awayOdds: -115 }, total: { over: 226.5, overOdds: -110, under: 226.5, underOdds: -110 } }
},
trueProbability: { home: 0.42, away: 0.58 }
}
};
async function main() {
console.log('='.repeat(70));
console.log('Sports Betting Analysis - Neural Trader');
console.log('='.repeat(70));
console.log();
// 1. Display configuration
console.log('1. Betting Configuration:');
console.log('-'.repeat(70));
console.log(` Initial Bankroll: $${bettingConfig.initialBankroll.toLocaleString()}`);
console.log(` Max Bet Size: ${bettingConfig.maxBetPercent * 100}% ($${bettingConfig.initialBankroll * bettingConfig.maxBetPercent})`);
console.log(` Kelly Fraction: ${bettingConfig.fractionKelly * 100}%`);
console.log(` Minimum Edge: ${bettingConfig.minEdge * 100}%`);
console.log(` Sportsbooks: ${bettingConfig.sportsbooks.join(', ')}`);
console.log();
// 2. Analyze each event
for (const [eventId, eventData] of Object.entries(sampleOdds)) {
console.log(`2. Event Analysis: ${eventData.event}`);
console.log('-'.repeat(70));
console.log(` Sport: ${eventData.sport} | Date: ${eventData.date} ${eventData.time}`);
console.log();
// Display odds comparison
console.log(' Moneyline Odds Comparison:');
console.log(' Sportsbook | Home | Away | Home Prob | Away Prob | Vig');
console.log(' ' + '-'.repeat(60));
for (const [book, odds] of Object.entries(eventData.odds)) {
const homeProb = americanToImpliedProb(odds.moneyline.home);
const awayProb = americanToImpliedProb(odds.moneyline.away);
const vig = (homeProb + awayProb - 1) * 100;
console.log(` ${book.padEnd(13)} | ${formatOdds(odds.moneyline.home).padStart(9)} | ${formatOdds(odds.moneyline.away).padStart(9)} | ${(homeProb * 100).toFixed(1).padStart(8)}% | ${(awayProb * 100).toFixed(1).padStart(8)}% | ${vig.toFixed(1)}%`);
}
console.log();
// Find best odds
const bestHomeOdds = findBestOdds(eventData.odds, 'moneyline', 'home');
const bestAwayOdds = findBestOdds(eventData.odds, 'moneyline', 'away');
console.log(` Best Home Odds: ${formatOdds(bestHomeOdds.odds)} at ${bestHomeOdds.book}`);
console.log(` Best Away Odds: ${formatOdds(bestAwayOdds.odds)} at ${bestAwayOdds.book}`);
console.log();
// Check for arbitrage
console.log(' Arbitrage Analysis:');
const arbResult = checkArbitrage(eventData.odds);
if (arbResult.hasArbitrage) {
console.log(` 🎯 ARBITRAGE OPPORTUNITY FOUND!`);
console.log(` Guaranteed profit: ${(arbResult.profit * 100).toFixed(2)}%`);
console.log(` Bet ${arbResult.homeBook} Home: $${arbResult.homeBet.toFixed(2)}`);
console.log(` Bet ${arbResult.awayBook} Away: $${arbResult.awayBet.toFixed(2)}`);
} else {
console.log(` No pure arbitrage available (combined implied: ${(arbResult.combinedImplied * 100).toFixed(1)}%)`);
}
console.log();
// EV calculations
console.log(' Expected Value Analysis (using model probabilities):');
console.log(` Model: Home ${(eventData.trueProbability.home * 100).toFixed(0)}% | Away ${(eventData.trueProbability.away * 100).toFixed(0)}%`);
console.log();
console.log(' Bet | Book | Odds | EV | Kelly | Recommended');
console.log(' ' + '-'.repeat(65));
const evAnalysis = calculateEVForAllBets(eventData);
evAnalysis.forEach(bet => {
const evStr = bet.ev >= 0 ? `+${(bet.ev * 100).toFixed(2)}%` : `${(bet.ev * 100).toFixed(2)}%`;
const kellyStr = bet.kelly > 0 ? `${(bet.kelly * 100).toFixed(2)}%` : '-';
const recBet = bet.recommendedBet > 0 ? `$${bet.recommendedBet.toFixed(0)}` : 'PASS';
console.log(` ${bet.type.padEnd(16)} | ${bet.book.padEnd(13)} | ${formatOdds(bet.odds).padStart(9)} | ${evStr.padStart(8)} | ${kellyStr.padStart(7)} | ${recBet.padStart(11)}`);
});
console.log();
// Top recommended bets
const topBets = evAnalysis.filter(b => b.recommendedBet > 0).sort((a, b) => b.ev - a.ev);
if (topBets.length > 0) {
console.log(` 📊 Top Recommended Bet:`);
const best = topBets[0];
console.log(` ${best.type} at ${best.book}`);
console.log(` Odds: ${formatOdds(best.odds)} | EV: +${(best.ev * 100).toFixed(2)}% | Bet Size: $${best.recommendedBet.toFixed(0)}`);
}
console.log();
}
// 3. Bankroll simulation
console.log('3. Bankroll Growth Simulation:');
console.log('-'.repeat(70));
const simulation = simulateBankrollGrowth(1000, 0.03, 0.55, bettingConfig);
console.log(` Starting Bankroll: $${bettingConfig.initialBankroll.toLocaleString()}`);
console.log(` Bets Placed: ${simulation.totalBets}`);
console.log(` Win Rate: ${(simulation.winRate * 100).toFixed(1)}%`);
console.log(` Final Bankroll: $${simulation.finalBankroll.toLocaleString()}`);
console.log(` ROI: ${((simulation.finalBankroll / bettingConfig.initialBankroll - 1) * 100).toFixed(1)}%`);
console.log(` Max Drawdown: ${(simulation.maxDrawdown * 100).toFixed(1)}%`);
console.log();
// 4. Syndicate management (advanced)
console.log('4. Syndicate Management:');
console.log('-'.repeat(70));
console.log(' Account Diversification Strategy:');
console.log(' - Spread bets across multiple sportsbooks');
console.log(' - Maximum 20% of action per book');
console.log(' - Rotate accounts to avoid limits');
console.log(' - Track CLV (Closing Line Value) per book');
console.log();
console.log('='.repeat(70));
console.log('Sports betting analysis completed!');
console.log('='.repeat(70));
}
// Convert American odds to implied probability
function americanToImpliedProb(odds) {
if (odds > 0) {
return 100 / (odds + 100);
} else {
return Math.abs(odds) / (Math.abs(odds) + 100);
}
}
// Convert implied probability to American odds
function probToAmerican(prob) {
if (prob >= 0.5) {
return Math.round(-100 * prob / (1 - prob));
} else {
return Math.round(100 * (1 - prob) / prob);
}
}
// Format American odds
function formatOdds(odds) {
return odds > 0 ? `+${odds}` : `${odds}`;
}
// Find best odds across sportsbooks
function findBestOdds(odds, market, side) {
let best = { odds: -Infinity, book: '' };
for (const [book, bookOdds] of Object.entries(odds)) {
const odd = bookOdds[market][side];
if (odd > best.odds) {
best = { odds: odd, book };
}
}
return best;
}
// Check for arbitrage opportunity
function checkArbitrage(odds) {
const bestHome = findBestOdds(odds, 'moneyline', 'home');
const bestAway = findBestOdds(odds, 'moneyline', 'away');
const homeProb = americanToImpliedProb(bestHome.odds);
const awayProb = americanToImpliedProb(bestAway.odds);
const combinedImplied = homeProb + awayProb;
if (combinedImplied < 1) {
// Arbitrage exists!
const profit = 1 / combinedImplied - 1;
const totalStake = 1000;
const homeBet = totalStake * (homeProb / combinedImplied);
const awayBet = totalStake * (awayProb / combinedImplied);
return {
hasArbitrage: true,
profit,
combinedImplied,
homeBook: bestHome.book,
awayBook: bestAway.book,
homeBet,
awayBet
};
}
return { hasArbitrage: false, combinedImplied };
}
// Calculate EV for all betting options
function calculateEVForAllBets(eventData) {
const results = [];
const bankroll = bettingConfig.initialBankroll;
for (const [book, odds] of Object.entries(eventData.odds)) {
// Home moneyline
const homeOdds = odds.moneyline.home;
const homeEV = calculateEV(eventData.trueProbability.home, homeOdds);
const homeKelly = calculateKelly(eventData.trueProbability.home, homeOdds);
const homeRec = homeEV >= bettingConfig.minEdge
? Math.min(homeKelly * bettingConfig.fractionKelly, bettingConfig.maxBetPercent) * bankroll
: 0;
results.push({
type: 'Home Moneyline',
book,
odds: homeOdds,
ev: homeEV,
kelly: homeKelly,
recommendedBet: homeRec
});
// Away moneyline
const awayOdds = odds.moneyline.away;
const awayEV = calculateEV(eventData.trueProbability.away, awayOdds);
const awayKelly = calculateKelly(eventData.trueProbability.away, awayOdds);
const awayRec = awayEV >= bettingConfig.minEdge
? Math.min(awayKelly * bettingConfig.fractionKelly, bettingConfig.maxBetPercent) * bankroll
: 0;
results.push({
type: 'Away Moneyline',
book,
odds: awayOdds,
ev: awayEV,
kelly: awayKelly,
recommendedBet: awayRec
});
}
return results.sort((a, b) => b.ev - a.ev);
}
// Calculate Expected Value
function calculateEV(trueProb, americanOdds) {
const impliedProb = americanToImpliedProb(americanOdds);
const decimalOdds = americanOdds > 0 ? (americanOdds / 100) + 1 : (100 / Math.abs(americanOdds)) + 1;
return (trueProb * decimalOdds) - 1;
}
// Calculate Kelly Criterion
function calculateKelly(trueProb, americanOdds) {
const decimalOdds = americanOdds > 0 ? (americanOdds / 100) + 1 : (100 / Math.abs(americanOdds)) + 1;
const b = decimalOdds - 1;
const p = trueProb;
const q = 1 - p;
const kelly = (b * p - q) / b;
return Math.max(0, kelly);
}
// Simulate bankroll growth
function simulateBankrollGrowth(numBets, avgEdge, winRate, config) {
let bankroll = config.initialBankroll;
let peak = bankroll;
let maxDrawdown = 0;
let wins = 0;
for (let i = 0; i < numBets; i++) {
const betSize = bankroll * config.maxBetPercent * config.fractionKelly;
const isWin = Math.random() < winRate;
if (isWin) {
bankroll += betSize * (1 + avgEdge);
wins++;
} else {
bankroll -= betSize;
}
peak = Math.max(peak, bankroll);
maxDrawdown = Math.max(maxDrawdown, (peak - bankroll) / peak);
}
return {
totalBets: numBets,
winRate: wins / numBets,
finalBankroll: Math.round(bankroll),
maxDrawdown
};
}
// Run the example
main().catch(console.error);