import { tickerMetrics } from './tickerMetrics'; // Helper to generate a realistic random walk for a stock price const generateRandomWalk = (startPrice, days, volatility) => { const data = []; let currentPrice = startPrice; const now = new Date(); for (let i = days; i >= 0; i--) { const date = new Date(now); date.setDate(date.getDate() - i); // Random daily return based on volatility (standard deviation) const dailyReturn = (Math.random() - 0.5) * volatility; currentPrice = currentPrice * (1 + dailyReturn); data.push({ time: date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }), date: date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }), price: Number(currentPrice.toFixed(2)) }); } return data; }; // Base starting prices for realism const basePrices = { 'SPY': 510.50, 'VOO': 468.20, 'BND': 72.15, 'BNDX': 48.90, 'AAPL': 175.40, 'MSFT': 420.10, 'GOOGL': 155.30, 'AMZN': 180.25, 'JNJ': 155.60, 'BRK-B': 410.80, 'JPM': 195.40, 'VXUS': 58.70, 'TSLA': 175.20, 'QQQ': 440.50, 'VTI': 255.60, 'CASH': 1.00 }; const mockDataCache = {}; export const fetchRealData = async (ticker) => { if (ticker === 'CASH') return getHistoricalData('CASH'); try { const proxy = 'https://corsproxy.io/?'; const url = `${proxy}https://query1.finance.yahoo.com/v8/finance/chart/${ticker}?interval=1d&range=1y`; const response = await fetch(url); const data = await response.json(); if (!data.chart?.result?.[0]) throw new Error('Invalid ticker'); const result = data.chart.result[0]; const timestamps = result.timestamp; const quotes = result.indicators.quote[0].close; const history = timestamps.map((ts, i) => { const date = new Date(ts * 1000); return { time: date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }), date: date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }), price: Number(quotes[i]?.toFixed(2)) || 0 }; }).filter(d => d.price > 0); const currentPrice = history[history.length - 1].price; const oldPrice = history[0].price; const change = currentPrice - oldPrice; const percentChange = (change / oldPrice) * 100; const finalData = { ticker, currentPrice: Number(currentPrice.toFixed(2)), change: Number(change.toFixed(2)), percentChange: Number(percentChange.toFixed(2)), isPositive: change >= 0, history }; mockDataCache[ticker] = finalData; return finalData; } catch (error) { console.error("Yahoo Finance Error:", error); return getHistoricalData(ticker); // Fallback to mock } }; export const getHistoricalData = (ticker) => { if (mockDataCache[ticker]) { return mockDataCache[ticker]; } const startPrice = basePrices[ticker] || 100; const metrics = tickerMetrics[ticker] || { beta: 1 }; const volatility = (metrics.beta * 0.015); const history = generateRandomWalk(startPrice, 365, volatility); const currentPrice = history[history.length - 1].price; const oldPrice = history[0].price; const change = currentPrice - oldPrice; const percentChange = (change / oldPrice) * 100; const result = { ticker, currentPrice: Number(currentPrice.toFixed(2)), change: Number(change.toFixed(2)), percentChange: Number(percentChange.toFixed(2)), isPositive: change >= 0, history }; mockDataCache[ticker] = result; return result; };