feat(markets): surface gold and silver across dashboard and briefs
This commit is contained in:
@@ -571,6 +571,19 @@ export async function synthesize(data) {
|
||||
timestamp: yfData.summary?.timestamp || null,
|
||||
};
|
||||
|
||||
const yfGold = yfQuotes['GC=F'];
|
||||
const yfSilver = yfQuotes['SI=F'];
|
||||
const metals = {
|
||||
gold: yfGold?.price,
|
||||
goldChange: yfGold?.change,
|
||||
goldChangePct: yfGold?.changePct,
|
||||
goldRecent: yfGold?.history?.map(h => h.close) || [],
|
||||
silver: yfSilver?.price,
|
||||
silverChange: yfSilver?.change,
|
||||
silverChangePct: yfSilver?.changePct,
|
||||
silverRecent: yfSilver?.history?.map(h => h.close) || [],
|
||||
};
|
||||
|
||||
// Override stale EIA prices with live Yahoo Finance data if available
|
||||
const yfWti = yfQuotes['CL=F'];
|
||||
const yfBrent = yfQuotes['BZ=F'];
|
||||
@@ -595,7 +608,7 @@ export async function synthesize(data) {
|
||||
},
|
||||
sdr: { total: sdrNet.totalReceivers || 0, online: sdrNet.online || 0, zones: sdrZones },
|
||||
tg: { posts: tgData.totalPosts || 0, urgent: tgUrgent, topPosts: tgTop },
|
||||
who, fred, energy, bls, treasury, gscpi, defense, noaa, epa, acled, gdelt, space, health, news,
|
||||
who, fred, energy, metals, bls, treasury, gscpi, defense, noaa, epa, acled, gdelt, space, health, news,
|
||||
markets, // Live Yahoo Finance market data
|
||||
ideas: [], ideasSource: 'disabled',
|
||||
// newsFeed for ticker (merged RSS + GDELT + Telegram)
|
||||
|
||||
@@ -1344,6 +1344,7 @@ function renderLower(){
|
||||
const payrolls=D.bls.find(b=>b.id==='CES0000000001');
|
||||
const gscpi=D.gscpi;
|
||||
const mkt=D.markets||{};
|
||||
const metals=D.metals||{};
|
||||
|
||||
const wtiH = D.energy.wtiRecent||[];
|
||||
const wtiMax=Math.max(...wtiH),wtiMin=Math.min(...wtiH);
|
||||
@@ -1365,11 +1366,15 @@ function renderLower(){
|
||||
const vixFred = D.fred.find(f=>f.id==='VIXCLS');
|
||||
const vixVal = vixLive?.value || vixFred?.value;
|
||||
const vixChg = vixLive?.changePct != null ? `${vixLive.changePct>=0?'+':''}${vixLive.changePct}%` : '';
|
||||
const fmtMarketPrice = (price) => price != null ? `$${price.toLocaleString(undefined,{maximumFractionDigits:2})}` : '--';
|
||||
const dayMove = (pct) => pct != null ? `${pct>=0?'+':''}${pct}% today` : '';
|
||||
|
||||
const metrics=[
|
||||
{l:'WTI Crude',v:`$${D.energy.wti}`,s:'$/bbl',p:70},
|
||||
{l:'Brent',v:`$${D.energy.brent}`,s:'$/bbl',p:75},
|
||||
{l:'Nat Gas',v:`$${D.energy.natgas||'--'}`,s:'$/MMBtu',p:30},
|
||||
{l:'Gold',v:fmtMarketPrice(metals.gold),s:dayMove(metals.goldChangePct)||'COMEX proxy',p:58},
|
||||
{l:'Silver',v:fmtMarketPrice(metals.silver),s:dayMove(metals.silverChangePct)||'COMEX proxy',p:54},
|
||||
{l:'VIX',v:vixVal?vixVal.toFixed(1):'--',s:vixChg||'volatility index',p:vixVal?Math.min(vixVal*2.5,100):30},
|
||||
{l:'Fed Funds',v:ff?`${ff.value}%`:'--',s:ff?.date||'',p:36},
|
||||
{l:'GSCPI',v:gscpi?gscpi.value.toFixed(2):'--',s:gscpi?.interpretation||'',p:49},
|
||||
@@ -1383,6 +1388,8 @@ function renderLower(){
|
||||
return f?.recent?.length > 1 ? {spark: f.recent, sparkUp: up} : {};
|
||||
};
|
||||
metrics[0] = {...metrics[0], spark: D.energy.wtiRecent, sparkUp: false};
|
||||
metrics[3] = {...metrics[3], spark: metals.goldRecent, sparkUp: (metals.goldChangePct ?? 0) >= 0};
|
||||
metrics[4] = {...metrics[4], spark: metals.silverRecent, sparkUp: (metals.silverChangePct ?? 0) >= 0};
|
||||
|
||||
// Build live market cards from Yahoo Finance
|
||||
const indexCards = (mkt.indexes||[]).map(mktCard).join('');
|
||||
@@ -1456,7 +1463,7 @@ function renderLower(){
|
||||
<div class="metrics-row">${cryptoCards}</div>
|
||||
</div>`:''}
|
||||
<div style="margin-bottom:8px">
|
||||
<div style="font-family:var(--mono);font-size:9px;color:var(--dim);margin-bottom:4px;letter-spacing:1px">ENERGY + MACRO</div>
|
||||
<div style="font-family:var(--mono);font-size:9px;color:var(--dim);margin-bottom:4px;letter-spacing:1px">ENERGY + METALS + MACRO</div>
|
||||
<div class="metrics-row">${metrics.map(m=>{
|
||||
const sparkSvg = m.spark ? mkSparkSvg(m.spark, m.sparkUp) : '';
|
||||
return `<div class="mc"><div class="ml">${m.l}</div><span class="mv">${m.v}${sparkSvg}</span><span class="ms">${m.s}</span><div class="mbar"><span style="width:${m.p}%"></span></div></div>`;
|
||||
|
||||
Reference in New Issue
Block a user