import type { Candle } from './chartTypes'; /** * Generates realistic mock candlestick data for development/testing. * The data simulates price movements with trends, volatility, and volume patterns. */ export function generateMockCandles( symbol: string, timeframe: string, barSize: string, count: number = 200 ): Candle[] { // Base price varies by symbol for realistic appearance const symbolHash = symbol.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); let basePrice = 100 + (symbolHash % 900); // Price between 100-1000 // Timeframe affects interval between candles const intervalMs = getIntervalMs(barSize); // Start from a past time const now = Date.now(); const startTime = now - (count * intervalMs); const candles: Candle[] = []; let currentPrice = basePrice; let trend = 0; // -1 to 1, represents current trend direction let volatility = 0.02; // 2% base volatility for (let i = 0; i < count; i++) { // Slowly drift the trend trend += (Math.random() - 0.5) * 0.1; trend = Math.max(-1, Math.min(1, trend)); // Clamp trend // Occasionally spike volatility if (Math.random() < 0.05) { volatility = 0.02 + Math.random() * 0.03; } else { volatility = volatility * 0.95 + 0.02 * 0.05; // Decay back to base } // Calculate price movement const trendComponent = trend * volatility * currentPrice * 0.5; const randomComponent = (Math.random() - 0.5) * volatility * currentPrice; const priceChange = trendComponent + randomComponent; // Generate OHLC const open = currentPrice; const close = currentPrice + priceChange; // High and low extend beyond open/close const range = Math.abs(close - open); const wickExtension = range * (0.3 + Math.random() * 0.7); const high = Math.max(open, close) + wickExtension * Math.random(); const low = Math.min(open, close) - wickExtension * Math.random(); // Volume correlates with price movement const baseVolume = 1000000 + symbolHash * 1000; const volumeMultiplier = 0.5 + Math.abs(priceChange / currentPrice) * 10 + Math.random(); const volume = Math.floor(baseVolume * volumeMultiplier); candles.push({ time: startTime + i * intervalMs, open: roundPrice(open), high: roundPrice(high), low: roundPrice(low), close: roundPrice(close), volume, }); currentPrice = close; } return candles; } function getIntervalMs(barSize: string): number { const intervals: Record = { '1m': 60 * 1000, '5m': 5 * 60 * 1000, '15m': 15 * 60 * 1000, '30m': 30 * 60 * 1000, '1h': 60 * 60 * 1000, '4h': 4 * 60 * 60 * 1000, '1d': 24 * 60 * 60 * 1000, '1w': 7 * 24 * 60 * 60 * 1000, }; return intervals[barSize] || intervals['1h']; } function roundPrice(price: number): number { // Round to 2 decimal places return Math.round(price * 100) / 100; } /** * Simulates an async API fetch with realistic delay. * TODO: Replace with real API integration. */ export async function fetchMockCandles( symbol: string, user: string, timeframe: string, barSize: string ): Promise { // Simulate network delay await new Promise(resolve => setTimeout(resolve, 300 + Math.random() * 200)); // Generate candles (user param would be used for personalized data in real API) console.log(`[v0] Fetching candles for ${symbol} (user: ${user}, timeframe: ${timeframe}, barSize: ${barSize})`); return generateMockCandles(symbol, timeframe, barSize, 200); }