// scripts/generateDaily.js // --------------------------------------------------------------- // Generates daily Gold 24K prices (INR/gram) for the last 3 years // using FREE data sources: // 1. Monthly gold spot USD/oz → GitHub datasets // 2. Daily USD/INR rates → frankfurter.app // // Saves to src/data/history.json // --------------------------------------------------------------- require('dotenv').config(); const axios = require('axios'); const fs = require('fs'); const path = require('path'); // India duty formula function calcGold24k(goldUsdPerOz, usdInr) { const perGram = goldUsdPerOz / 31.1035; const inINR = perGram * usdInr; const withDuty = inINR * 1.15; // 15% import duty const withGST = withDuty * 1.03; // 3% GST return Math.round(withGST * 100) / 100; } async function main() { console.log('šŸŖ™ Generating 3 years of daily Gold 24K prices...\n'); // 1. Fetch monthly gold USD prices console.log('šŸ“„ Step 1: Fetching gold spot prices (USD/oz)...'); const goldRes = await axios.get('https://raw.githubusercontent.com/datasets/gold-prices/main/data/monthly.csv'); const goldLines = goldRes.data.trim().split('\n').slice(1); const monthlyGold = {}; for (const line of goldLines) { const [dateStr, priceStr] = line.split(','); if (dateStr && priceStr) { monthlyGold[dateStr.trim()] = parseFloat(priceStr.trim()); } } console.log(` āœ… Got ${Object.keys(monthlyGold).length} months of gold data\n`); // 2. Fetch daily USD/INR for last 3 years (in chunks — frankfurter limits range) console.log('šŸ“„ Step 2: Fetching daily USD/INR rates...'); const allUsdInr = {}; const today = new Date(); // Fetch year by year (frankfurter handles this better) for (let i = 3; i >= 0; i--) { const yearStart = new Date(today); yearStart.setFullYear(today.getFullYear() - i); yearStart.setMonth(0, 1); const yearEnd = new Date(yearStart); yearEnd.setFullYear(yearStart.getFullYear(), 11, 31); // Don't go past today if (yearEnd > today) { yearEnd.setTime(today.getTime() - 86400000); // yesterday } const startStr = yearStart.toISOString().split('T')[0]; const endStr = yearEnd.toISOString().split('T')[0]; if (startStr >= endStr) continue; try { console.log(` Fetching ${startStr} to ${endStr}...`); const url = `https://api.frankfurter.app/${startStr}..${endStr}?from=USD&to=INR`; const { data } = await axios.get(url, { timeout: 30000 }); for (const [date, val] of Object.entries(data.rates)) { allUsdInr[date] = val.INR; } } catch (e) { console.warn(` āš ļø Failed for ${startStr}..${endStr}: ${e.message}`); } } console.log(` āœ… Got ${Object.keys(allUsdInr).length} days of USD/INR rates\n`); // 3. Generate daily Gold 24K prices console.log('šŸ“Š Step 3: Calculating daily Gold 24K (INR/gram)...'); const sortedMonths = Object.keys(monthlyGold).sort(); const sortedDays = Object.keys(allUsdInr).sort(); // For each day with USD/INR, find the closest monthly gold price const dailyPrices = []; for (const day of sortedDays) { const usdInr = allUsdInr[day]; const dayMonth = day.substring(0, 7); // YYYY-MM // Find gold price: exact month or closest previous month let goldUsd = monthlyGold[dayMonth]; if (!goldUsd) { // Find closest previous month for (let i = sortedMonths.length - 1; i >= 0; i--) { if (sortedMonths[i] <= dayMonth) { goldUsd = monthlyGold[sortedMonths[i]]; break; } } } if (!goldUsd || !usdInr) continue; const gold24k = calcGold24k(goldUsd, usdInr); dailyPrices.push({ date: day, gold24k: gold24k }); } // Sort oldest to newest dailyPrices.sort((a, b) => a.date.localeCompare(b.date)); console.log(` āœ… Generated ${dailyPrices.length} daily prices\n`); console.log(` šŸ“… From: ${dailyPrices[0]?.date} → To: ${dailyPrices[dailyPrices.length - 1]?.date}`); console.log(` šŸ’° First price: ₹${dailyPrices[0]?.gold24k}/g`); console.log(` šŸ’° Last price: ₹${dailyPrices[dailyPrices.length - 1]?.gold24k}/g\n`); // 4. Save to file const outDir = path.join(__dirname, '..', 'src', 'data'); if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true }); const outFile = path.join(outDir, 'history.json'); fs.writeFileSync(outFile, JSON.stringify(dailyPrices, null, 0)); const sizeKB = Math.round(fs.statSync(outFile).size / 1024); console.log(`šŸ’¾ Saved to src/data/history.json (${sizeKB} KB)`); console.log(`šŸ“Š Total records: ${dailyPrices.length}`); console.log('\nāœ… Done! Your /api/history endpoint now has 3 years of daily data!'); } main().catch(err => { console.error('āŒ Failed:', err.message); process.exit(1); });