mirror of
https://github.com/caty21/forex-dashboard.git
synced 2026-07-27 20:37:45 +00:00
auto: sync 2026-06-02 17:27
This commit is contained in:
@@ -1086,6 +1086,20 @@ export async function GET(req: NextRequest) {
|
||||
lastUpdated: yoyRef,
|
||||
...(yoyCons !== null ? { consensus: yoyCons } : {}),
|
||||
};
|
||||
// Flash vs Final : si un Final est attendu, calculer le delta Final_forecast − Flash_actual
|
||||
const finalForecastYoY = parseTeF(teCpiForecast?.cpiYoYFinal);
|
||||
if (finalForecastYoY !== null && indicators.cpiYoY) {
|
||||
const delta = parseFloat((finalForecastYoY - yoyValue).toFixed(2));
|
||||
(indicators.cpiYoY as Record<string,unknown>)["_finalForecast"] = finalForecastYoY;
|
||||
(indicators.cpiYoY as Record<string,unknown>)["_finalDelta"] = delta;
|
||||
}
|
||||
// Idem pour cpiCore
|
||||
const finalForecastCore = parseTeF(teCpiForecast?.cpiCoreFinal);
|
||||
if (finalForecastCore !== null && coreValue !== null && indicators.cpiCore) {
|
||||
const delta = parseFloat((finalForecastCore - coreValue).toFixed(2));
|
||||
(indicators.cpiCore as Record<string,unknown>)["_finalForecast"] = finalForecastCore;
|
||||
(indicators.cpiCore as Record<string,unknown>)["_finalDelta"] = delta;
|
||||
}
|
||||
}
|
||||
|
||||
// Core CPI MoM (pages individuelles, décimales précises)
|
||||
|
||||
@@ -414,8 +414,43 @@ export default function CurrencyCard({ currency, expectations, yields, sentiment
|
||||
)}
|
||||
{(inflFilter === "all" || inflFilter === "yoy") && (
|
||||
<>
|
||||
<Row label="Core CPI YoY" ind={inds?.cpiCore ?? null} unit="%" consensus={fc?.cpiCore ?? fc?.cpi ?? null} surpriseVsCons={fc?.cpiSurprise ?? null} />
|
||||
<Row label="Inflation Rate YoY" ind={inds?.cpiYoY ?? null} unit="%" consensus={fc?.cpi ?? null} />
|
||||
<Row
|
||||
label="Core CPI YoY"
|
||||
ind={inds?.cpiCore ?? null}
|
||||
unit="%"
|
||||
consensus={fc?.cpiCore ?? fc?.cpi ?? null}
|
||||
surpriseVsCons={fc?.cpiSurprise ?? null}
|
||||
tooltip={(() => {
|
||||
const fd = (inds?.cpiCore as (Ind & { _finalForecast?: number; _finalDelta?: number }) | null);
|
||||
if (fd?._finalForecast === undefined) return null;
|
||||
const d = fd._finalDelta ?? 0;
|
||||
const arrow = d > 0 ? "↑" : d < 0 ? "↓" : "=";
|
||||
return `Prel./Flash — Final prévu : ${fd._finalForecast?.toFixed(1)}% (${arrow}${d > 0 ? "+" : ""}${d.toFixed(2)})`;
|
||||
})()}
|
||||
info={(() => {
|
||||
const fd = (inds?.cpiCore as (Ind & { _finalDelta?: number }) | null);
|
||||
if (fd?._finalDelta === undefined) return null;
|
||||
return fd._finalDelta > 0 ? "↑F" : fd._finalDelta < 0 ? "↓F" : "=F";
|
||||
})()}
|
||||
/>
|
||||
<Row
|
||||
label="Inflation Rate YoY"
|
||||
ind={inds?.cpiYoY ?? null}
|
||||
unit="%"
|
||||
consensus={fc?.cpi ?? null}
|
||||
tooltip={(() => {
|
||||
const fd = (inds?.cpiYoY as (Ind & { _finalForecast?: number; _finalDelta?: number }) | null);
|
||||
if (fd?._finalForecast === undefined) return null;
|
||||
const d = fd._finalDelta ?? 0;
|
||||
const arrow = d > 0 ? "↑" : d < 0 ? "↓" : "=";
|
||||
return `Prel./Flash — Final prévu : ${fd._finalForecast?.toFixed(1)}% (${arrow}${d > 0 ? "+" : ""}${d.toFixed(2)})`;
|
||||
})()}
|
||||
info={(() => {
|
||||
const fd = (inds?.cpiYoY as (Ind & { _finalDelta?: number }) | null);
|
||||
if (fd?._finalDelta === undefined) return null;
|
||||
return fd._finalDelta > 0 ? "↑F" : fd._finalDelta < 0 ? "↓F" : "=F";
|
||||
})()}
|
||||
/>
|
||||
{inds?.commodityPricesYoY && (
|
||||
<Row label="Commodity Prices YoY" ind={inds.commodityPricesYoY} unit="%" info="AUD — RBA Commodity Price Index (TradingEconomics)" />
|
||||
)}
|
||||
|
||||
+16
-11
@@ -221,11 +221,13 @@ function parseCalendarHTML(html: string): TECalendarEvent[] {
|
||||
// Utilisé par la macro route pour remplir forecasts.cpiCore / forecasts.cpiMoM.
|
||||
|
||||
export interface TEInflationForecasts {
|
||||
cpiYoY: string | null;
|
||||
cpiCore: string | null;
|
||||
cpiMoM: string | null;
|
||||
cpiCoreMoM: string | null;
|
||||
ppiMoM: string | null;
|
||||
cpiYoY: string | null;
|
||||
cpiYoYFinal: string | null; // "Final" event specifically (vs Flash/Prel)
|
||||
cpiCore: string | null;
|
||||
cpiCoreFinal: string | null; // Core CPI YoY Final event
|
||||
cpiMoM: string | null;
|
||||
cpiCoreMoM: string | null;
|
||||
ppiMoM: string | null;
|
||||
}
|
||||
|
||||
export async function fetchTEInflationForecasts(
|
||||
@@ -243,20 +245,23 @@ export async function fetchTEInflationForecasts(
|
||||
|
||||
const ccy = ev.currency;
|
||||
const title = ev.title.toLowerCase();
|
||||
if (!result[ccy]) result[ccy] = { cpiYoY: null, cpiCore: null, cpiMoM: null, cpiCoreMoM: null, ppiMoM: null };
|
||||
if (!result[ccy]) result[ccy] = { cpiYoY: null, cpiYoYFinal: null, cpiCore: null, cpiCoreFinal: null, cpiMoM: null, cpiCoreMoM: null, ppiMoM: null };
|
||||
|
||||
const r = result[ccy]!;
|
||||
const r = result[ccy]!;
|
||||
const isFinal = /\bfinal\b/i.test(title);
|
||||
// Order matters: Core MoM before generic MoM, Core YoY before generic YoY, PPI before CPI
|
||||
if (!r.ppiMoM && /ppi.*mom|producer.*price.*mom/i.test(title)) {
|
||||
r.ppiMoM = ev.forecast;
|
||||
} else if (!r.cpiCoreMoM && /core.*mom|core.*inflation.*mom|core.*rate.*mom/i.test(title)) {
|
||||
r.cpiCoreMoM = ev.forecast;
|
||||
} else if (!r.cpiCore && /core.*inflation.*yoy|core.*cpi.*yoy|core.*rate.*yoy/i.test(title)) {
|
||||
r.cpiCore = ev.forecast;
|
||||
} else if (/core.*inflation.*yoy|core.*cpi.*yoy|core.*rate.*yoy/i.test(title)) {
|
||||
if (isFinal && !r.cpiCoreFinal) r.cpiCoreFinal = ev.forecast;
|
||||
if (!r.cpiCore) r.cpiCore = ev.forecast;
|
||||
} else if (!r.cpiMoM && /^(?!.*core).*(?:inflation.*mom|cpi.*mom|rate.*mom)/i.test(title)) {
|
||||
r.cpiMoM = ev.forecast;
|
||||
} else if (!r.cpiYoY && /^(?!.*core).*(?:inflation.*yoy|cpi.*yoy|inflation\s+rate.*yoy)/i.test(title)) {
|
||||
r.cpiYoY = ev.forecast;
|
||||
} else if (/^(?!.*core).*(?:inflation.*yoy|cpi.*yoy|inflation\s+rate.*yoy)/i.test(title)) {
|
||||
if (isFinal && !r.cpiYoYFinal) r.cpiYoYFinal = ev.forecast;
|
||||
if (!r.cpiYoY) r.cpiYoY = ev.forecast;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user