gs-port / src /data /historicalData.js
Scribbler310's picture
feat: enhance dashboard
c2b7eb3 verified
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;
};