mirror of
https://github.com/caty21/forex-dashboard.git
synced 2026-08-25 02:18:07 +00:00
auto: sync 2026-06-02 09:40
This commit is contained in:
+33
-18
@@ -27,9 +27,10 @@ export interface CoreCPIEntry {
|
|||||||
export type CoreCPIMap = Partial<Record<Currency, CoreCPIEntry>>;
|
export type CoreCPIMap = Partial<Record<Currency, CoreCPIEntry>>;
|
||||||
|
|
||||||
export interface MoMCPIEntry {
|
export interface MoMCPIEntry {
|
||||||
value: number; // MoM %
|
value: number; // MoM % (ou QoQ pour AUD/NZD)
|
||||||
prev: number;
|
prev: number | null; // période précédente (null si calculé depuis index)
|
||||||
refMonth: string;
|
refMonth: string;
|
||||||
|
isQoQ?: boolean; // true pour AUD et NZD (données trimestrielles)
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MoMCPIMap = Partial<Record<Currency, MoMCPIEntry>>;
|
export type MoMCPIMap = Partial<Record<Currency, MoMCPIEntry>>;
|
||||||
@@ -174,17 +175,22 @@ function parseCPIIndexHTML(html: string, countryMap: Record<Currency, string>):
|
|||||||
// Format meta : "...increased to 0.40 percent in April from 0.20 percent..."
|
// Format meta : "...increased to 0.40 percent in April from 0.20 percent..."
|
||||||
// Pour CHF on utilise /switzerland/core-consumer-prices (pas de page -mom)
|
// Pour CHF on utilise /switzerland/core-consumer-prices (pas de page -mom)
|
||||||
|
|
||||||
|
// Pages existantes avec % direct : USD, EUR, GBP, CAD
|
||||||
|
// Pages index seulement (calcul delta) : JPY, CHF, AUD (QoQ), NZD (QoQ)
|
||||||
const TE_CORE_MOM_SLUG: Record<Currency, string> = {
|
const TE_CORE_MOM_SLUG: Record<Currency, string> = {
|
||||||
USD: "united-states/core-inflation-rate-mom",
|
USD: "united-states/core-inflation-rate-mom",
|
||||||
EUR: "euro-area/core-inflation-rate-mom",
|
EUR: "euro-area/core-inflation-rate-mom",
|
||||||
GBP: "united-kingdom/core-inflation-rate-mom",
|
GBP: "united-kingdom/core-inflation-rate-mom",
|
||||||
JPY: "japan/core-inflation-rate-mom",
|
JPY: "japan/core-consumer-prices", // pas de page -mom directe
|
||||||
CAD: "canada/core-inflation-rate-mom",
|
CAD: "canada/core-inflation-rate-mom",
|
||||||
AUD: "australia/core-inflation-rate-mom",
|
AUD: "australia/core-consumer-prices", // QoQ (données trimestrielles)
|
||||||
NZD: "new-zealand/core-inflation-rate-mom",
|
NZD: "new-zealand/core-consumer-prices", // QoQ (données trimestrielles)
|
||||||
CHF: "switzerland/core-consumer-prices", // index → MoM calculé
|
CHF: "switzerland/core-consumer-prices", // index → delta calculé
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Devises publiées en QoQ (trimestriel) plutôt que MoM
|
||||||
|
export const CORE_CPI_QOQ: Set<Currency> = new Set<Currency>(["AUD", "NZD"]);
|
||||||
|
|
||||||
async function fetchOneTEMeta(url: string): Promise<string> {
|
async function fetchOneTEMeta(url: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
@@ -203,22 +209,31 @@ async function fetchOneTEMeta(url: string): Promise<string> {
|
|||||||
} catch { return ""; }
|
} catch { return ""; }
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseMetaForMoM(desc: string): { value: number; prev: number } | null {
|
function parseMetaForMoM(desc: string): { value: number; prev: number; isIndex?: boolean } | null {
|
||||||
// Pattern : "increased to X percent ... from Y percent"
|
// Pattern 1 : "increased/decreased to X percent from Y percent"
|
||||||
const m = desc.match(
|
const p1 = desc.match(
|
||||||
/(?:increased|decreased|declined|rose|fell|remained|eased|changed)\s+to\s*([\d.]+)\s+percent[^.]*from\s+([\d.]+)\s+percent/i
|
/(?:increased|decreased|declined|rose|fell|eased|changed)\s+to\s*([\d.]+)\s+percent[^.]*?from\s+([\d.]+)\s+percent/i
|
||||||
);
|
);
|
||||||
if (m) return { value: parseFloat(m[1]), prev: parseFloat(m[2]) };
|
if (p1) return { value: parseFloat(p1[1]), prev: parseFloat(p1[2]) };
|
||||||
|
|
||||||
// Pattern alternatif pour les index : "increased to X from Y points"
|
// Pattern 2 : "remained unchanged at X percent" → current = prev = X, delta = 0
|
||||||
const m2 = desc.match(
|
const p2 = desc.match(/(?:remained unchanged at|is unchanged at)\s*([\d.]+)\s+percent/i);
|
||||||
/(?:increased|decreased|declined|rose|fell|remained|eased|changed)\s+to\s*([\d.]+)\s+(?:points?|index)[^.]*from\s+([\d.]+)/i
|
if (p2) { const v = parseFloat(p2[1]); return { value: v, prev: v }; }
|
||||||
|
|
||||||
|
// Pattern 3 : "increased to X points from Y points" → calcul MoM% = (X-Y)/Y*100
|
||||||
|
const p3 = desc.match(
|
||||||
|
/(?:increased|decreased|declined|rose|fell|eased|changed)\s+to\s*([\d.]+)\s+points?[^.]*?from\s+([\d.]+)\s+points?/i
|
||||||
);
|
);
|
||||||
if (m2) {
|
if (p3) {
|
||||||
const last = parseFloat(m2[1]);
|
const last = parseFloat(p3[1]);
|
||||||
const prev = parseFloat(m2[2]);
|
const prev = parseFloat(p3[2]);
|
||||||
if (prev !== 0) return { value: parseFloat(((last - prev) / prev * 100).toFixed(3)), prev: prev };
|
if (prev !== 0) return { value: parseFloat(((last - prev) / prev * 100).toFixed(3)), prev, isIndex: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pattern 4 : "remained unchanged at X points" → delta = 0, on retourne 0
|
||||||
|
const p4 = desc.match(/(?:remained unchanged at|is unchanged at)\s*([\d.]+)\s+points?/i);
|
||||||
|
if (p4) return { value: 0, prev: parseFloat(p4[1]), isIndex: true };
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user