Spaces:
Running
Running
File size: 4,911 Bytes
dcc4f27 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | // 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);
});
|