const TIER_LABEL = {
tier1: "Point · point accuracy",
tier2: "Ranking · cross-sectional IC",
tier3: "Decision · portfolio backtest"
};
const TIER_SHORT = { tier1: "Point", tier2: "Ranking", tier3: "Decision" };
const ASPECT = { tier1: "pointwise", tier2: "ic", tier3: "portfolio" };
const METRIC_BASE_ORDER = ["hr", "hrp", "hrpp", "mase", "mase_diff", "ic", "return", "sharpe", "mdd", "vol"];
const METRIC_INFO = {
hr: ["Hit Rate", "Share of cases where the predicted direction matches the realized direction."],
hrp: ["Hit Rate (Delta)", "Share of cases where both the level direction and first-difference direction are correct."],
hrpp: ["Hit Rate (Delta2)", "Share of cases where the level, first-difference, and second-difference directions are all correct."],
mase: ["MASE (relative)", "Normalized absolute error between predicted and realized percentage changes."],
mase_diff: ["MASE (diff)", "Absolute forecast error normalized by the period-difference scale."],
ic: ["Information Coefficient", "Cross-sectional rank correlation between predicted and realized percentage changes."],
return: ["Return", "Annualized return of an equal-weight long portfolio built from top predicted assets."],
sharpe: ["Sharpe", "Annualized Sharpe ratio of the strategy returns."],
mdd: ["Max Drawdown", "Maximum peak-to-trough decline of the NAV path. Values closer to 0 are better."],
vol: ["Volatility", "Annualized standard deviation of the strategy returns."]
};
const state = {
data: null,
records: [],
models: [],
modelConfigs: new Map(),
excludedModelTypes: new Set(),
excludedMetrics: new Set(),
excludedTypes: new Set(),
excludedTargets: new Set(),
excludedDetails: new Set(),
excludedFrequencies: new Set(),
collapsedFilters: new Set(),
collapsedSubcards: new Set(),
recordsReady: false,
view: "overview",
showDetailRank: true,
showModelInfo: true,
sort: { key: "overall", asc: true },
metricsSort: { key: "rank", asc: true },
metric: { tier: "tier1", key: null, detail: "__all__", frequency: "__all__", sort: { key: "rank", asc: true } }
};
const $ = (id) => document.getElementById(id);
const isExaone = (model) => model === "exaone-forecast" || model.startsWith("exaone-");
const displayName = (model) => isExaone(model) ? "EXAONE Forecast Finance" : model;
const modelConfig = (model) => state.modelConfigs.get(model) || { model, model_type: "unknown", org: "Unknown" };
const modelType = (model) => modelConfig(model).model_type || "unknown";
const modelOrg = (model) => {
const org = modelConfig(model).org || "";
return org.toLowerCase() === "unknown" ? "" : org;
};
const modelLink = (model) => modelConfig(model).model_link || "";
const modelSize = (model) => modelConfig(model).model_size || "";
const modelSubmitTime = (model) => modelConfig(model).submit_time || "";
const orgColors = {
Alibaba: "#0891b2",
Amazon: "#2563eb",
Datadog: "#16a34a",
"Google Research": "#9333ea",
"IBM Research": "#f97316",
"LG AI Research": "#e11d48",
PriorLabs: "#be185d",
Salesforce: "#0f766e",
ServiceNow: "#7c3aed",
"Tsinghua University": "#a16207",
Unspecified: "#64748b",
"Zhejiang University": "#dc2626"
};
const fallbackOrgPalette = ["#1d4ed8", "#15803d", "#c026d3", "#0e7490", "#b45309", "#4338ca"];
const organizationName = (model) => modelOrg(model) || "Unspecified";
const organizationColor = (org) => orgColors[org] || fallbackOrgPalette[Math.abs(String(org).split("").reduce((sum, char) => sum + char.charCodeAt(0), 0)) % fallbackOrgPalette.length];
const modelTypeLabel = (type) => {
const labels = {
"zero-shot": "Pretrained",
pretrained: "Pretrained",
statistical: "Statistical",
unknown: ""
};
return labels[type] || type;
};
const includedModels = () => state.models.filter((model) => !state.excludedModelTypes.has(modelType(model)));
const displayDetailLabel = (label) => {
const map = {
"Crypto Pair Close (Top 100)": "Crypto Pair Close",
"OHLCV Close": "Close"
};
return map[label] || label;
};
const renderModelCell = (model) => {
const link = modelLink(model);
const label = displayName(model);
if (!link) return `
${label} `;
return `${label} `;
};
const renderModelTypeCell = (model) => {
const type = modelType(model);
const label = modelTypeLabel(type);
if (!label) return ' ';
return ` `;
};
const renderModelTypeFilterLabel = (type, label) => {
if (!label) return "";
return `${label} `;
};
const DETAIL_CATEGORY_EXPLANATIONS = {
"Bond Total Return Index": "A total return bond index that reflects both price changes and interest income. It evaluates the return path experienced by bond investors rather than the level of yields alone.",
Breakeven: "A market-based inflation expectation measure derived from the spread between nominal government bond yields and inflation-linked bond yields.",
"Corporate Yield": "The yield level required in corporate bond markets, reflecting both corporate funding costs and market pricing of credit risk.",
"Credit Spread": "The spread between corporate or credit bond yields and safe asset yields. It tends to widen when default risk, liquidity stress, or recession risk rises.",
"Forward Inflation": "A forward-looking market measure of expected inflation over a future period, useful for assessing shifts in the expected inflation path.",
"Inflation Expectation": "Expected future inflation from consumers, experts, or markets. It is an important macro signal for monetary policy expectations and long-term rates.",
"Money Market": "Short-term funding market indicators related to policy rates, liquidity, and financial institutions' funding conditions.",
"Mortgage Rate": "Mortgage interest rate levels, which help explain housing affordability, real estate demand, and household financial conditions.",
"Term Spread": "The difference between long-term and short-term interest rates, commonly used to assess growth expectations, policy expectations, and recession risk.",
"TIPS Yield": "Real yields on U.S. Treasury Inflation-Protected Securities, used to evaluate real rate conditions and real discount rates.",
"Treasury Yield": "U.S. Treasury yields, representing the term structure of risk-free rates and a benchmark for asset pricing and macro-financial conditions.",
Activity: "Broad measures of economic activity such as production, consumption, transport, and coincident indicators, used to detect expansion and slowdown.",
Banking: "Indicators of bank lending, deposits, reserves, and credit supply, important for evaluating financial intermediation and banking system liquidity.",
"Capacity Utilization by Industry": "Industry-level measures of how intensively production capacity is being used, useful for assessing spare capacity and supply-side pressure.",
Credit: "Credit volumes and lending flows in the private or public sector, reflecting leverage, funding supply, and financial cycle dynamics.",
"Current Account": "External transaction indicators covering goods, services, income, and transfers, used to assess external balance and medium-term currency pressure.",
"Energy Activity": "Energy-sector activity such as production, consumption, inventories, and drilling, capturing supply-demand shifts in commodity markets and industry.",
External: "Macro indicators related to exports, imports, external transactions, and the balance of payments, used for global demand and external vulnerability analysis.",
"FDI Flows": "Foreign direct investment inflows and outflows, reflecting long-term capital movement and firms' overseas production and investment activity.",
"Financial Flows": "Financial account, capital flow, and financial asset transaction indicators, used to assess global fund flows and risk appetite.",
Fiscal: "Government spending, revenue, fiscal balance, and debt indicators, describing fiscal policy stance and public-sector funding needs.",
Freight: "Freight and logistics activity indicators, which quickly reflect real demand, manufacturing activity, and supply-chain conditions.",
GDP: "Gross domestic product and related growth indicators, the broadest measure of total production and the business cycle.",
Housing: "Housing starts, permits, sales, inventories, and other housing market activity indicators, often rate-sensitive and forward-looking.",
"Housing Price": "Housing price or rent indicators, important for assessing asset prices, housing affordability, and household wealth.",
Income: "Household or personal income indicators, key variables for evaluating consumption capacity and labor income flows.",
"Industrial Production by Industry": "Industry-level production or production index measures, used to evaluate sector-specific cyclical sensitivity and manufacturing activity.",
Inflation: "Consumer prices, producer prices, and other price level indicators, directly tied to monetary policy, real income, and rate expectations.",
"International Investment Position": "A country's stock of external financial assets and liabilities, used to assess net external position and external vulnerability.",
Inventory: "Inventory levels and changes for firms or industries, used to assess demand slowdown, oversupply, and production adjustment risk.",
Labor: "Employment, unemployment, wages, labor participation, and other labor market indicators that explain both growth and inflation pressure.",
"Labor by Industry": "Industry-level employment and labor market indicators, used to evaluate labor demand by sector rather than at the aggregate level.",
Money: "Money supply, liquidity, deposits, and related indicators, describing financial conditions and macro liquidity.",
"Portfolio Flows": "Cross-border portfolio investment inflows and outflows in equities, bonds, and other financial assets.",
Productivity: "Labor productivity or total factor productivity indicators, used to assess long-term growth potential and unit labor cost pressure.",
"Regional Fed": "Manufacturing and services survey indicators from regional Federal Reserve banks, reflecting regional business conditions and sentiment.",
Saving: "Household or national saving rate indicators, describing consumption propensity, fiscal capacity, and long-term capital accumulation.",
Sentiment: "Consumer, business, or market participant sentiment and expectations, often useful as leading indicators.",
Spending: "Personal consumption expenditures, retail sales, and other spending activity indicators, used to assess domestic demand and consumer momentum.",
Stress: "Financial market or macroeconomic stress indicators, capturing market instability, liquidity strain, and downside risk.",
"TIC Flows": "International capital flow indicators from U.S. Treasury International Capital data, showing foreign transactions and holdings of U.S. securities.",
"Implied Volatility": "Forward-looking volatility inferred from option prices, reflecting uncertainty, risk aversion, and potential short-term shocks.",
"US Equity Index": "Major U.S. equity index levels, used as broad benchmarks for stock market direction and risk asset performance.",
"Equity OHLCV Close": "Close price series for listed equities, a core target for company-level price forecasting, cross-sectional ranking, and portfolio backtests.",
"ETF OHLCV Close": "Close price series for exchange-traded funds, covering tradable sector, style, asset class, and thematic exposures.",
"Balance Sheet": "Corporate balance sheet items such as assets, liabilities, and equity, used to assess financial health, leverage, and asset-base changes.",
"Cash Flow": "Cash flow statement items such as operating cash flow and capital expenditure, showing actual cash generation and investment activity.",
"EPS Basic": "Basic earnings per share, measuring profit per common share without dilution effects.",
"EPS Diluted": "Diluted earnings per share, a more conservative shareholder earnings measure that accounts for potential share dilution.",
"Net Income": "A company's final net profit after revenue, expenses, interest, taxes, and other items.",
"Operating Income": "Profit from core operations before interest, taxes, and one-off items, used to assess core business profitability.",
Revenue: "A company's top-line sales from products and services, directly reflecting growth and demand.",
"Commodity ETF Broad": "Broad commodity ETF prices that provide diversified exposure to commodity markets.",
"Commodity ETF Single": "ETF prices tracking a single commodity or narrow commodity exposure, such as gold or oil.",
"Commodity ETF Thematic": "Thematic commodity ETF prices covering areas such as batteries, uranium, or commodity-related industries.",
"Commodity Spot Bdaily": "Business-daily commodity spot or benchmark price series, used to evaluate short-term commodity price changes and price discovery.",
"Commodity Spot Monthly": "Monthly commodity spot or benchmark price series, used to evaluate lower-frequency commodity trends and supply-demand shifts.",
"Future Front": "Nearest-maturity commodity futures prices, reflecting tradable prices that include storage costs, rates, and supply-demand expectations.",
"Inventory Stock": "Commodity inventory or stock levels, used to evaluate shortage, excess inventory, and seasonal supply-demand changes.",
"Crypto Pair Close (Top 100)": "USD-denominated close price series for crypto assets, used to evaluate direction, ranking, and investment performance in volatile digital assets.",
"Crypto Pair Close": "USD-denominated close price series for crypto assets, used to evaluate direction, ranking, and investment performance in volatile digital assets.",
"FX Pair": "Exchange rate series between two currencies, reflecting rate differentials, trade conditions, capital flows, and risk appetite.",
"Country Index": "Country-level equity market index series, used for cross-country ranking and global asset allocation analysis.",
"Regional Index": "Regional equity index series covering groups of countries such as Europe, Asia, or emerging markets."
};
const strengthHeaderLabel = (label) => {
const words = String(label).split(/\s+/).filter(Boolean);
if (words.length < 3 && String(label).length <= 16) return `${label} `;
const mid = Math.ceil(words.length / 2);
const lines = [words.slice(0, mid).join(" "), words.slice(mid).join(" ")].filter(Boolean);
return `${lines.map((line) => `${line} `).join("")} `;
};
const finite = (v) => Number.isFinite(v);
const fmt = (v, digits = 2) => finite(v) ? v.toFixed(digits) : '— ';
const fmtValue = (v) => {
if (!finite(v)) return '— ';
const a = Math.abs(v);
if (a !== 0 && (a < 1e-3 || a >= 1e5)) return v.toExponential(2);
if (a >= 100) return v.toFixed(1);
if (a >= 1) return v.toFixed(3);
return v.toFixed(4);
};
const arithmeticMean = (values) => {
const valid = values.filter(finite);
return valid.length ? valid.reduce((sum, value) => sum + value, 0) / valid.length : null;
};
const escapeHtml = (value) => String(value ?? "")
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
const formatAoeDate = (value) => {
const date = new Date(value);
const aoe = new Date(date.getTime() - 12 * 60 * 60 * 1000);
return `${aoe.getUTCFullYear()}-${String(aoe.getUTCMonth() + 1).padStart(2, "0")}-${String(aoe.getUTCDate()).padStart(2, "0")} ${aoe.getUTCHours() < 12 ? "AM" : "PM"} ${aoe.getUTCHours() % 12 || 12}:${String(aoe.getUTCMinutes()).padStart(2, "0")}:${String(aoe.getUTCSeconds()).padStart(2, "0")} AoE`;
};
const rankBadge = (r) => {
if (!finite(r)) return '— ';
const whole = Number.isInteger(r);
const cls = whole && r <= 3 ? ` g${r}` : "";
return `${whole ? r : r.toFixed(1)} `;
};
const overviewRankBadge = (rank) => {
if (!finite(rank)) return '— ';
const whole = Number.isInteger(rank);
const cls = whole && rank <= 3 ? ` g${rank}` : "";
return `${whole ? rank : rank.toFixed(1)} `;
};
const overviewScoreText = (score) => {
if (!finite(score)) return '— ';
return `${fmt(score)} `;
};
const parseModelSize = (value) => {
const raw = String(value || "").trim().toLowerCase();
if (!raw) return null;
const match = raw.match(/^\s*([0-9]+(?:\.[0-9]+)?)\s*([kmb])$/);
if (!match) return null;
const amount = Number(match[1]);
const unit = match[2];
if (!finite(amount)) return null;
if (unit === "k") return amount / 1000;
if (unit === "b") return amount * 1000;
return amount;
};
const sizeTickLabel = (value) => {
if (value < 1) return `${Math.round(value * 1000)}K`;
if (value >= 1000) return `${fmt(value / 1000, value % 1000 ? 1 : 0)}B`;
return `${fmt(value, value % 1 ? 1 : 0)}M`;
};
const metricBase = (metric) => {
if (metric.startsWith("mase_diff")) return "mase_diff";
if (metric.startsWith("hrpp")) return "hrpp";
if (metric.startsWith("hrp")) return "hrp";
if (metric.startsWith("hr")) return "hr";
if (metric.startsWith("mase")) return "mase";
return metric.split("_")[0];
};
const metricName = (metric) => {
const base = metricBase(metric);
return METRIC_INFO[base]?.[0] || base;
};
const metricDirection = (metric) => metric.startsWith("mase_") || metric.startsWith("vol_") ? -1 : 1;
const metricLabel = (metric) => {
const horizon = metric.replace(/^(hrpp|hrp|hr|mase_diff|mase|ic|return|sharpe|mdd|vol)_?/, "");
return `${metricName(metric)} · ${horizon || metric}`;
};
const metricGroupKey = (metric) => metric === "mase_pct0" ? "mase_pct0" : metricBase(metric);
const metricGroupLabel = (key) => {
if (key === "hr") return "Hitrate";
if (key === "hrp") return "Hitrate △";
if (key === "hrpp") return "Hitrate △²";
if (key === "mase_pct0") return "MASE";
return METRIC_INFO[key]?.[0] || key;
};
const metricGroupDirection = (metric) => metric === "mase_pct0" || metric === "mase_diff" || metric === "mase" || metric === "vol" ? -1 : 1;
const drawerMetricName = (metric) => {
const base = metricBase(metric);
if (base === "hr") return "Hitrate";
if (base === "hrp") return "Hitrate △";
if (base === "hrpp") return "Hitrate △²";
return METRIC_INFO[base]?.[0] || base;
};
const periodLabel = (token) => {
const key = String(token || "").toLowerCase();
const map = {
pct1w: "WoW",
pct1m: "MoM",
pct1q: "QoQ",
pct1h: "HoH",
pct1y: "YoY",
h1w: "WoW",
h1m: "MoM",
h1q: "QoQ",
h1h: "HoH",
h1y: "YoY"
};
return map[key] || token || "—";
};
const targetLabel = (token) => {
const key = String(token || "").toLowerCase();
const match = key.match(/^after(\d+)([wmqhy])$/);
return match ? `${match[1]}${match[2].toUpperCase()}` : "—";
};
const optionNone = "__none__";
const predTargetLabel = (token) => token === optionNone ? "Original" : targetLabel(token);
const typeLabel = (token) => {
const key = String(token || "").toLowerCase();
const map = {
pct1w: "WoW",
pct1m: "MoM",
pct1q: "QoQ",
pct1h: "HoH",
pct1y: "YoY",
h1w: "WoW",
h1m: "MoM",
h1q: "QoQ",
h1h: "HoH",
h1y: "YoY",
[optionNone]: "All"
};
return map[key] || token || "All";
};
const optionOrder = (token) => {
const key = String(token || "").toLowerCase();
if (key === optionNone) return 999;
const pctOrder = { pct1w: 0, pct1m: 1, pct1q: 2, pct1h: 3, pct1y: 4 };
const horizonOrderMap = { h1w: 10, h1m: 11, h1q: 12, h1h: 13, h1y: 14 };
if (key in pctOrder) return pctOrder[key];
if (key in horizonOrderMap) return horizonOrderMap[key];
const match = key.match(/^after1([wmqhy])$/);
if (match) return ({ w: 0, m: 1, q: 2, h: 3, y: 4 }[match[1]] ?? 99);
return 99;
};
const targetFromType = (typeToken) => {
const match = String(typeToken || "").toLowerCase().match(/^h1([wmqhy])$/);
return match ? `after1${match[1]}` : "";
};
const metricOptionTokens = (metric) => {
const base = metricBase(metric);
if (base === "mase" && metric === "mase_pct0") return { type: optionNone, target: optionNone };
const rest = metric.replace(new RegExp(`^${base}_?`), "");
const [type, target] = rest.split("_");
return {
type: type || optionNone,
target: target || targetFromType(type) || optionNone
};
};
const freqCode = (frequency) => {
const map = {
"Annual": "Y",
"Business-daily": "BD",
"Daily": "D",
"Monthly": "M",
"Quarterly": "Q",
"Weekly": "W"
};
return map[frequency] || frequency || "";
};
const horizonOrder = (value) => {
const key = String(value || "").toLowerCase();
const match = key.match(/(?:pct|after|h)(\d+)([wmqhy])$/);
if (!match) return 99;
const unitOrder = { w: 0, m: 1, q: 2, h: 3, y: 4 };
return (Number(match[1]) * 10) + (unitOrder[match[2]] ?? 9);
};
const parseMetricParts = (metric) => {
const base = metricBase(metric);
if (base === "mase" && metric === "mase_pct0") {
return { name: drawerMetricName(metric), type: typeLabel(optionNone), target: predTargetLabel(optionNone) };
}
const rest = metric.replace(new RegExp(`^${base}_?`), "");
const [typeToken, targetToken] = rest.split("_");
const derivedTarget = targetToken || targetFromType(typeToken);
return {
name: drawerMetricName(metric),
type: periodLabel(typeToken),
target: predTargetLabel(derivedTarget || optionNone)
};
};
const rankText = (rank, total) => {
if (!finite(rank)) return "—";
return `${rankBadge(rank)}/ ${total.toLocaleString()} `;
};
const metricFilterKey = (row) => `${row.tier}|${metricGroupKey(row.metric)}`;
const includedRecords = ({ model = true, metric = true, option = true, detail = true, frequency = true } = {}) => state.records.filter((r) => {
const options = metricOptionTokens(r.metric);
return (!model || !state.excludedModelTypes.has(modelType(r.model)))
&& (!metric || !state.excludedMetrics.has(metricFilterKey(r)))
&& (!option || (!state.excludedTypes.has(options.type) && !state.excludedTargets.has(options.target)))
&& (!detail || !state.excludedDetails.has(r.detail_category))
&& (!frequency || !state.excludedFrequencies.has(r.frequency));
});
const geometricMean = (values) => {
const valid = values.filter((v) => finite(v) && v > 0);
return valid.length ? Math.exp(valid.reduce((s, v) => s + Math.log(v), 0) / valid.length) : null;
};
const rankSum = (values) => {
const valid = values.filter(finite);
return valid.length ? valid.reduce((sum, value) => sum + value, 0) : null;
};
const compareNullable = (a, b, asc = true) => {
const af = finite(a);
const bf = finite(b);
if (!af && !bf) return 0;
if (!af) return 1;
if (!bf) return -1;
return asc ? a - b : b - a;
};
function rankRows(rows, valueKey, direction = -1) {
const rankValue = (value) => Math.round(value * 10000) / 10000;
const sorted = rows.filter((r) => finite(r[valueKey])).sort((a, b) => direction > 0 ? rankValue(b[valueKey]) - rankValue(a[valueKey]) : rankValue(a[valueKey]) - rankValue(b[valueKey]));
for (let i = 0; i < sorted.length;) {
let j = i + 1;
while (j < sorted.length && rankValue(sorted[j][valueKey]) === rankValue(sorted[i][valueKey])) j += 1;
const rank = (i + 1 + j) / 2;
for (let k = i; k < j; k += 1) sorted[k].rank = rank;
i = j;
}
return sorted;
}
function tierStats(records = includedRecords()) {
const byModelTier = new Map();
for (const row of records) {
const key = `${row.model}|${row.tier}`;
if (!byModelTier.has(key)) byModelTier.set(key, []);
byModelTier.get(key).push(row.rank);
}
const models = includedModels();
const stats = new Map(models.map((model) => [model, { model, count: 0, pointwise_k: null, ic_k: null, portfolio_k: null }]));
for (const model of models) {
const count = records.filter((r) => r.model === model).length;
const target = stats.get(model);
target.count = count;
for (const tier of Object.keys(ASPECT)) target[`${ASPECT[tier]}_k`] = geometricMean(byModelTier.get(`${model}|${tier}`) || []);
}
for (const aspect of ["pointwise", "ic", "portfolio"]) {
const ranked = rankRows([...stats.values()].map((row) => ({ model: row.model, value: row[`${aspect}_k`] })), "value", -1);
for (const row of ranked) stats.get(row.model)[aspect] = row.rank;
}
return [...stats.values()].map((row) => ({ ...row, overall: rankSum([row.pointwise, row.ic, row.portfolio]) }));
}
function sortedOverview() {
const rows = (state.recordsReady ? tierStats() : [...(state.data?.overall || [])]).map((row) => ({
...row,
overall_k: geometricMean([row.pointwise_k, row.ic_k, row.portfolio_k])
}));
const s = state.sort;
const valueForSort = (row, key) => {
if (key === "pos") return row.overall;
if (key === "model_type") return modelTypeLabel(modelType(row.model));
if (key === "org") return modelOrg(row.model);
if (key === "model_size") return parseModelSize(modelSize(row.model));
if (key === "submit_time") return modelSubmitTime(row.model);
return row[key];
};
rows.sort((a, b) => {
if (s.key === "model") return s.asc ? displayName(a.model).localeCompare(displayName(b.model)) : displayName(b.model).localeCompare(displayName(a.model));
if (s.key === "model_type" || s.key === "org" || s.key === "submit_time") {
const av = valueForSort(a, s.key);
const bv = valueForSort(b, s.key);
return s.asc ? av.localeCompare(bv) : bv.localeCompare(av);
}
const av = valueForSort(a, s.key);
const bv = valueForSort(b, s.key);
return compareNullable(av, bv, s.asc);
});
return rows;
}
function detailsByScope() {
const grouped = new Map();
for (const row of state.records) {
const group = `${row.scope || "Other"} · ${row.category || "Other"}`;
if (!grouped.has(group)) grouped.set(group, new Map());
if (!grouped.get(group).has(row.detail_category)) grouped.get(group).set(row.detail_category, displayDetailLabel(row.detail_category));
}
return [...grouped.entries()].sort((a, b) => a[0].localeCompare(b[0]));
}
function allFrequencies() {
return [...new Set(state.records.map((row) => row.frequency).filter(Boolean))].sort();
}
function metricGroupsByTier() {
const order = new Map(["hr", "hrp", "hrpp", "mase", "mase_pct0", "mase_diff", "ic", "return", "sharpe", "mdd", "vol"].map((key, index) => [key, index]));
const grouped = new Map();
for (const row of state.records) {
const key = metricGroupKey(row.metric);
if (!grouped.has(row.tier)) grouped.set(row.tier, new Set());
grouped.get(row.tier).add(key);
}
return Object.keys(TIER_LABEL).map((tier) => {
const metrics = [...(grouped.get(tier) || [])].sort((a, b) => (order.get(a) ?? 99) - (order.get(b) ?? 99) || a.localeCompare(b));
return [tier, metrics];
});
}
function metricOptionGroups() {
const types = new Set();
const targets = new Set();
for (const row of state.records) {
const options = metricOptionTokens(row.metric);
types.add(options.type);
targets.add(options.target);
}
return {
types: [...types].sort((a, b) => optionOrder(a) - optionOrder(b) || typeLabel(a).localeCompare(typeLabel(b))),
targets: [...targets].sort((a, b) => optionOrder(a) - optionOrder(b) || predTargetLabel(a).localeCompare(predTargetLabel(b)))
};
}
function modelTypeGroups() {
return [...new Set(state.models.map(modelType))]
.sort((a, b) => modelTypeLabel(a).localeCompare(modelTypeLabel(b)));
}
function optionButtonGroups(values, labeler, mergeByLabel = false) {
if (!mergeByLabel) {
return values.map((value) => ({
label: labeler(value),
tokens: [value],
title: value === optionNone ? "No option" : value
}));
}
const groups = new Map();
for (const value of values) {
const label = labeler(value);
if (!groups.has(label)) groups.set(label, []);
groups.get(label).push(value);
}
return [...groups.entries()]
.map(([label, tokens]) => ({
label,
tokens,
title: tokens.map((value) => value === optionNone ? "No option" : value).join(", ")
}))
.sort((a, b) => optionOrder(a.tokens[0]) - optionOrder(b.tokens[0]) || a.label.localeCompare(b.label));
}
function buildOptionSubcard({ container, key, title, values, excluded, labeler, mergeByLabel = false }) {
const buttonGroups = optionButtonGroups(values, labeler, mergeByLabel);
const allTokens = buttonGroups.flatMap((group) => group.tokens);
const groupAllOn = allTokens.every((value) => !excluded.has(value));
const subcardKey = `option|${key}`;
const collapsed = state.collapsedSubcards.has(subcardKey);
const wrap = document.createElement("div");
wrap.className = `spec-group spec-subcard${collapsed ? " subcard-collapsed" : ""}`;
wrap.innerHTML = `
${title}
${collapsed ? "+" : "-"}
${groupAllOn ? "Deselect all" : "Select all"}
`;
wrap.querySelector(".subcard-trigger").onclick = () => {
if (state.collapsedSubcards.has(subcardKey)) state.collapsedSubcards.delete(subcardKey);
else state.collapsedSubcards.add(subcardKey);
buildSpecToggles();
};
wrap.querySelector(".group-toggle").onclick = () => {
for (const value of allTokens) {
if (groupAllOn) excluded.add(value);
else excluded.delete(value);
}
buildSpecToggles();
render();
};
const chips = wrap.querySelector(".spec-chips");
for (const option of buttonGroups) {
const allOn = option.tokens.every((value) => !excluded.has(value));
const btn = document.createElement("button");
btn.type = "button";
if (key === "model-type") btn.innerHTML = renderModelTypeFilterLabel(option.tokens[0], option.label);
else btn.textContent = option.label;
btn.title = option.title;
btn.className = `filter-chip ${allOn ? "on" : "off"}`;
btn.onclick = () => {
for (const value of option.tokens) {
if (allOn) excluded.add(value);
else excluded.delete(value);
}
buildSpecToggles();
render();
};
chips.appendChild(btn);
}
container.appendChild(wrap);
}
function buildSpecToggles() {
const modelBox = $("model-toggles");
const metricBox = $("metric-toggles");
const optionBox = $("metric-option-toggles");
const box = $("spec-toggles");
const freqBox = $("frequency-toggles");
if (!state.recordsReady) {
modelBox.innerHTML = 'Loading model configs...
';
metricBox.innerHTML = 'Loading detailed records...
';
optionBox.innerHTML = 'Loading detailed records...
';
box.innerHTML = 'Loading detailed records...
';
freqBox.innerHTML = 'Loading detailed records...
';
$("toggle-all-models").disabled = true;
$("toggle-all-metrics").disabled = true;
$("toggle-all-metric-options").disabled = true;
$("toggle-all-specs").disabled = true;
$("toggle-all-frequencies").disabled = true;
return;
}
$("toggle-all-models").disabled = false;
$("toggle-all-metrics").disabled = false;
$("toggle-all-metric-options").disabled = false;
$("toggle-all-specs").disabled = false;
$("toggle-all-frequencies").disabled = false;
modelBox.innerHTML = "";
metricBox.innerHTML = "";
optionBox.innerHTML = "";
box.innerHTML = "";
freqBox.innerHTML = "";
buildOptionSubcard({
container: modelBox,
key: "model-type",
title: "Model Type",
values: modelTypeGroups(),
excluded: state.excludedModelTypes,
labeler: modelTypeLabel
});
const modelTypes = modelTypeGroups();
const allModelTypesOn = modelTypes.every((type) => !state.excludedModelTypes.has(type));
$("toggle-all-models").textContent = allModelTypesOn ? "Deselect all" : "Select all";
$("toggle-all-models").onclick = () => {
state.excludedModelTypes = allModelTypesOn ? new Set(modelTypes) : new Set();
buildSpecToggles();
render();
};
const metricGroups = metricGroupsByTier();
const presentMetrics = metricGroups.flatMap(([tier, metrics]) => metrics.map((metric) => `${tier}|${metric}`));
for (const [tier, metrics] of metricGroups) {
const metricKeys = metrics.map((metric) => `${tier}|${metric}`);
const groupAllOn = metricKeys.every((key) => !state.excludedMetrics.has(key));
const subcardKey = `metric|${tier}`;
const collapsed = state.collapsedSubcards.has(subcardKey);
const wrap = document.createElement("div");
wrap.className = `spec-group spec-subcard${collapsed ? " subcard-collapsed" : ""}`;
wrap.innerHTML = `
${TIER_SHORT[tier]}
${collapsed ? "+" : "-"}
${groupAllOn ? "Deselect all" : "Select all"}
`;
wrap.querySelector(".subcard-trigger").onclick = () => {
if (state.collapsedSubcards.has(subcardKey)) state.collapsedSubcards.delete(subcardKey);
else state.collapsedSubcards.add(subcardKey);
buildSpecToggles();
};
wrap.querySelector(".group-toggle").onclick = () => {
for (const key of metricKeys) {
if (groupAllOn) state.excludedMetrics.add(key);
else state.excludedMetrics.delete(key);
}
buildSpecToggles();
render();
};
const chips = wrap.querySelector(".spec-chips");
for (const metric of metrics) {
const key = `${tier}|${metric}`;
const btn = document.createElement("button");
btn.type = "button";
btn.textContent = metricGroupLabel(metric);
btn.title = metric;
btn.className = `filter-chip ${state.excludedMetrics.has(key) ? "off" : "on"}`;
if (btn.textContent.length > 18) btn.classList.add("wide");
btn.onclick = () => {
if (state.excludedMetrics.has(key)) state.excludedMetrics.delete(key);
else state.excludedMetrics.add(key);
buildSpecToggles();
render();
};
chips.appendChild(btn);
}
metricBox.appendChild(wrap);
}
const allMetricsOn = presentMetrics.every((key) => !state.excludedMetrics.has(key));
$("toggle-all-metrics").textContent = allMetricsOn ? "Deselect all" : "Select all";
$("toggle-all-metrics").onclick = () => {
state.excludedMetrics = allMetricsOn ? new Set(presentMetrics) : new Set();
buildSpecToggles();
render();
};
const optionGroups = metricOptionGroups();
buildOptionSubcard({
container: optionBox,
key: "type",
title: "Target Type",
values: optionGroups.types,
excluded: state.excludedTypes,
labeler: typeLabel,
mergeByLabel: true
});
buildOptionSubcard({
container: optionBox,
key: "target",
title: "Pred. Target",
values: optionGroups.targets,
excluded: state.excludedTargets,
labeler: predTargetLabel
});
const allMetricOptionsOn = optionGroups.types.every((type) => !state.excludedTypes.has(type))
&& optionGroups.targets.every((target) => !state.excludedTargets.has(target));
$("toggle-all-metric-options").textContent = allMetricOptionsOn ? "Deselect all" : "Select all";
$("toggle-all-metric-options").onclick = () => {
state.excludedTypes = allMetricOptionsOn ? new Set(optionGroups.types) : new Set();
state.excludedTargets = allMetricOptionsOn ? new Set(optionGroups.targets) : new Set();
buildSpecToggles();
render();
};
const groups = detailsByScope();
const present = groups.flatMap(([, values]) => [...values.keys()]);
for (const [group, values] of groups) {
const groupDetails = [...values.keys()];
const groupAllOn = groupDetails.every((detail) => !state.excludedDetails.has(detail));
const subcardKey = `detail|${group}`;
const collapsed = state.collapsedSubcards.has(subcardKey);
const wrap = document.createElement("div");
wrap.className = `spec-group spec-subcard${collapsed ? " subcard-collapsed" : ""}`;
wrap.innerHTML = `
${group}
${collapsed ? "+" : "-"}
${groupAllOn ? "Deselect all" : "Select all"}
`;
wrap.querySelector(".subcard-trigger").onclick = () => {
if (state.collapsedSubcards.has(subcardKey)) state.collapsedSubcards.delete(subcardKey);
else state.collapsedSubcards.add(subcardKey);
buildSpecToggles();
};
wrap.querySelector(".group-toggle").onclick = () => {
for (const detail of groupDetails) {
if (groupAllOn) state.excludedDetails.add(detail);
else state.excludedDetails.delete(detail);
}
buildSpecToggles();
render();
};
const chips = wrap.querySelector(".spec-chips");
for (const [detail, label] of [...values.entries()].sort((a, b) => a[1].localeCompare(b[1]))) {
const btn = document.createElement("button");
btn.type = "button";
btn.textContent = label;
btn.title = detail;
btn.className = `filter-chip ${state.excludedDetails.has(detail) ? "off" : "on"}`;
if (label.length > 18) btn.classList.add("wide");
btn.onclick = () => {
if (state.excludedDetails.has(detail)) state.excludedDetails.delete(detail);
else state.excludedDetails.add(detail);
buildSpecToggles();
render();
};
chips.appendChild(btn);
}
box.appendChild(wrap);
}
const allOn = present.every((detail) => !state.excludedDetails.has(detail));
$("toggle-all-specs").textContent = allOn ? "Deselect all" : "Select all";
$("toggle-all-specs").onclick = () => {
state.excludedDetails = allOn ? new Set(present) : new Set();
buildSpecToggles();
render();
};
const frequencies = allFrequencies();
for (const frequency of frequencies) {
const btn = document.createElement("button");
btn.type = "button";
btn.textContent = frequency;
btn.className = `filter-chip ${state.excludedFrequencies.has(frequency) ? "off" : "on"}`;
btn.onclick = () => {
if (state.excludedFrequencies.has(frequency)) state.excludedFrequencies.delete(frequency);
else state.excludedFrequencies.add(frequency);
buildSpecToggles();
render();
};
freqBox.appendChild(btn);
}
const allFreqOn = frequencies.every((frequency) => !state.excludedFrequencies.has(frequency));
$("toggle-all-frequencies").textContent = allFreqOn ? "Deselect all" : "Select all";
$("toggle-all-frequencies").onclick = () => {
state.excludedFrequencies = allFreqOn ? new Set(frequencies) : new Set();
buildSpecToggles();
render();
};
}
function setupCollapsibles() {
document.querySelectorAll(".collapse-trigger").forEach((button) => {
const target = $(button.dataset.collapseTarget);
if (!target) return;
const sync = () => {
const collapsed = state.collapsedFilters.has(button.dataset.collapseTarget);
target.classList.toggle("collapsed", collapsed);
button.setAttribute("aria-expanded", String(!collapsed));
button.querySelector(".collapse-mark").textContent = collapsed ? "+" : "-";
};
button.onclick = () => {
if (state.collapsedFilters.has(button.dataset.collapseTarget)) state.collapsedFilters.delete(button.dataset.collapseTarget);
else state.collapsedFilters.add(button.dataset.collapseTarget);
sync();
};
sync();
});
}
function setupTabs() {
document.querySelectorAll("#viewtabs button").forEach((button) => {
button.onclick = () => {
state.view = button.dataset.view;
document.querySelectorAll("#viewtabs button").forEach((item) => item.classList.toggle("active", item === button));
document.querySelectorAll("main > .panel").forEach((panel) => panel.hidden = panel.id !== `panel-${state.view}`);
syncSidebarForView();
render();
};
});
}
function syncSidebarForView() {
const showSidebar = state.view === "overview" || state.view === "overview-plot" || state.view === "metrics" || state.view === "strength";
$("sidebar").hidden = !showSidebar;
$("model-filter-card").hidden = !showSidebar;
$("metric-filter-card").hidden = !showSidebar;
$("metric-option-card").hidden = !showSidebar;
}
function renderLoadingPanel(targetId) {
$(targetId).innerHTML = 'Loading detailed records. The overview is shown first. ';
}
function renderOrganizationLegend() {
const orgs = [...new Set(includedModels().map(organizationName))].sort();
$("organization-legend-body").innerHTML = orgs
.map((org) => `${escapeHtml(org)} `)
.join("");
}
function renderOverviewPlot(rows) {
const target = $("overview-plot-body");
const points = rows
.map((row) => ({
model: row.model,
label: displayName(row.model),
org: organizationName(row.model),
sizeLabel: modelSize(row.model),
size: parseModelSize(modelSize(row.model)),
pointwise: row.pointwise,
ic: row.ic,
portfolio: row.portfolio,
rank: row.overall
}))
.filter((row) => finite(row.size) && row.size > 0 && finite(row.rank));
if (!points.length) {
target.innerHTML = 'No model size metadata is available for the selected models.
';
return;
}
const width = 860;
const height = 360;
const pad = { left: 58, right: 24, top: 22, bottom: 48 };
const minX = Math.min(...points.map((p) => p.size));
const maxX = Math.max(...points.map((p) => p.size));
const minY = Math.min(...points.map((p) => p.rank));
const maxY = Math.max(...points.map((p) => p.rank));
const logMin = Math.log10(Math.max(minX * 0.8, 0.1));
const logMax = Math.log10(maxX * 1.2);
const yMin = Math.max(0, minY - 3);
const yMax = maxY + 3;
const x = (value) => pad.left + ((Math.log10(value) - logMin) / (logMax - logMin || 1)) * (width - pad.left - pad.right);
const y = (value) => pad.top + ((value - yMin) / (yMax - yMin || 1)) * (height - pad.top - pad.bottom);
const xTicks = [0.5, 1, 10, 100, 1000, 2500].filter((tick) => tick >= minX * 0.75 && tick <= maxX * 1.35);
const yTicks = Array.from({ length: 5 }, (_, index) => yMin + ((yMax - yMin) * index) / 4);
const byOrg = new Map();
for (const point of points) {
if (!byOrg.has(point.org)) byOrg.set(point.org, []);
byOrg.get(point.org).push(point);
}
const lines = [...byOrg.entries()].map(([org, group]) => {
if (org === "Unspecified") return "";
const sorted = group.slice().sort((a, b) => a.size - b.size);
if (sorted.length < 2) return "";
return ` `;
}).join("");
const tooltipRows = (p) => [
["Model", p.label],
["Org", p.org],
["Model size", p.sizeLabel],
["Point rank", fmt(p.pointwise, finite(p.pointwise) && p.pointwise % 1 ? 1 : 0)],
["Ranking rank", fmt(p.ic, finite(p.ic) && p.ic % 1 ? 1 : 0)],
["Decision rank", fmt(p.portfolio, finite(p.portfolio) && p.portfolio % 1 ? 1 : 0)],
["Rank sum", fmt(p.rank, p.rank % 1 ? 1 : 0)]
];
const bestRank = Math.min(...points.map((p) => p.rank));
const dots = points.map((p) => `
${p.rank === bestRank
? `★ ${escapeHtml(p.label)} `
: ` `}
`).join("");
target.innerHTML = `
${xTicks.map((tick) => ` `).join("")}
${yTicks.map((tick) => ` `).join("")}
${xTicks.map((tick) => `${sizeTickLabel(tick)} `).join("")}
${yTicks.map((tick) => `${fmt(tick, 0)} `).join("")}
Model size, parameters (log scale)
Rank sum
${lines}
${dots}
`;
const tooltip = target.querySelector(".plot-tooltip");
target.querySelectorAll(".plot-point").forEach((point) => {
point.addEventListener("mouseenter", () => {
const rows = JSON.parse(point.dataset.tooltip);
tooltip.innerHTML = `${rows.map(([key, value]) => `${escapeHtml(key)} ${escapeHtml(value)} `).join("")}
`;
tooltip.hidden = false;
});
point.addEventListener("mousemove", (event) => {
const rect = target.getBoundingClientRect();
const left = event.clientX - rect.left - tooltip.offsetWidth - 12;
tooltip.style.left = `${Math.max(8, left)}px`;
tooltip.style.top = `${event.clientY - rect.top + 12}px`;
});
point.addEventListener("mouseleave", () => {
tooltip.hidden = true;
});
});
}
function renderMetricProgressPlots() {
const target = $("metric-progress-body");
if (!state.recordsReady) {
target.innerHTML = 'Loading detailed records.
';
return;
}
const models = includedModels().filter((model) => /^\d{4}-\d{2}-\d{2}$/.test(modelSubmitTime(model)));
if (!models.length) {
target.innerHTML = 'No dated model tier K data matches the selected filters.
';
return;
}
const statsByModel = new Map(tierStats().map((row) => [row.model, row]));
const tiers = [
{ key: "pointwise_k", title: "Point rank", tier: "tier1" },
{ key: "ic_k", title: "Ranking rank", tier: "tier2" },
{ key: "portfolio_k", title: "Decision rank", tier: "tier3" }
];
const width = 860;
const height = 300;
const pad = { left: 74, right: 24, top: 22, bottom: 48 };
const dateValue = (model) => Date.parse(`${modelSubmitTime(model)}T00:00:00Z`);
const allDates = [...new Set(models.map((model) => dateValue(model)).filter(finite))].sort((a, b) => a - b);
if (!allDates.length) {
target.innerHTML = 'No submit date metadata is available for the selected models.
';
return;
}
const minDate = allDates[0];
const maxDate = allDates[allDates.length - 1];
const x = (date) => pad.left + ((date - minDate) / (maxDate - minDate || 1)) * (width - pad.left - pad.right);
const dateLabel = (date) => new Date(date).toISOString().slice(0, 10);
const dateTicks = allDates.length <= 3 ? allDates : [allDates[0], allDates[Math.floor(allDates.length / 2)], allDates[allDates.length - 1]];
const cards = tiers.map((tierInfo) => {
const modelValues = models.map((model) => ({
model,
date: dateValue(model),
value: statsByModel.get(model)?.[tierInfo.key]
})).filter((row) => finite(row.value)).sort((a, b) => a.date - b.date || displayName(a.model).localeCompare(displayName(b.model)));
const timeline = [];
let best = null;
for (const date of allDates) {
for (const row of modelValues.filter((item) => item.date === date)) {
if (!best || row.value < best.value) best = row;
}
if (best) timeline.push({ date, value: best.value, model: best.model, org: organizationName(best.model) });
}
if (timeline.length < 1) return "";
const values = timeline.map((p) => p.value);
const rawMin = Math.min(...values);
const rawMax = Math.max(...values);
const spread = rawMax - rawMin || Math.max(Math.abs(rawMax) * 0.1, 1);
const yMin = rawMin - spread * 0.12;
const yMax = rawMax + spread * 0.12;
const y = (value) => pad.top + ((value - yMin) / (yMax - yMin || 1)) * (height - pad.top - pad.bottom);
const yTicks = [yMin, (yMin + yMax) / 2, yMax];
const segments = timeline.slice(1).map((p, index) => {
const prev = timeline[index];
return ` `;
}).join("");
const pointTimeline = timeline.filter((p, index) => {
if (index === 0 || index === timeline.length - 1) return true;
return p.value !== timeline[index - 1].value;
});
const points = pointTimeline.map((p) => {
const rows = [
["Date", dateLabel(p.date)],
["Tier", tierInfo.title],
["Best model", displayName(p.model)],
["Org", p.org],
["K score", fmt(p.value)]
];
return ` `;
}).join("");
return `
${tierInfo.title} lower K is better
${dateTicks.map((date) => ` `).join("")}
${yTicks.map((tick) => ` `).join("")}
${dateTicks.map((date) => `${dateLabel(date).slice(2, 7)} `).join("")}
${yTicks.map((tick) => `${fmtValue(tick)} `).join("")}
Date
K score
${segments}
${points}
`;
}).filter(Boolean).join("");
if (!cards) {
target.innerHTML = 'No tier K progress data matches the selected filters.
';
return;
}
target.innerHTML = `${cards}
`;
const tooltip = target.querySelector(".plot-tooltip");
target.querySelectorAll(".metric-progress-point").forEach((point) => {
point.addEventListener("mouseenter", () => {
const rows = JSON.parse(point.dataset.tooltip);
tooltip.innerHTML = `${rows.map(([key, value]) => `${escapeHtml(key)} ${escapeHtml(value)} `).join("")}
`;
tooltip.hidden = false;
});
point.addEventListener("mousemove", (event) => {
const rect = target.getBoundingClientRect();
const left = event.clientX - rect.left - tooltip.offsetWidth - 12;
tooltip.style.left = `${Math.max(8, left)}px`;
tooltip.style.top = `${event.clientY - rect.top + 12}px`;
});
point.addEventListener("mouseleave", () => {
tooltip.hidden = true;
});
});
}
function renderOverviewPlotPage() {
renderOrganizationLegend();
renderOverviewPlot(sortedOverview());
renderMetricProgressPlots();
}
function renderOverview() {
const rows = sortedOverview();
const showModelInfo = state.showModelInfo;
const best = Math.min(...rows.map((r) => r.overall).filter(finite));
const leader = [...(state.recordsReady ? tierStats() : (state.data?.overall || []))]
.sort((a, b) => compareNullable(a.overall, b.overall) || a.model.localeCompare(b.model))[0];
const strip = $("winner-strip");
if (strip && leader) {
strip.innerHTML = `Overall #1 ${displayName(leader.model)} Rank sum ${fmt(leader.overall, finite(leader.overall) && leader.overall % 1 ? 1 : 0)} `;
}
$("detail-rank-toggle").checked = state.showDetailRank;
$("model-info-toggle").checked = state.showModelInfo;
const hint = $("overview-mode-hint");
if (hint) {
hint.innerHTML = `Overall rank is the sum of the Point·Ranking·Decision tier ranks. Each tier rank is ordered by the geometric mean K of metric ranks under the selected Detail Category and Frequency filters. Each cell is shown as A (B) . (B appears when the Detail Value toggle is on ). A is the tier rank, and B is the K score used to produce that rank. Lower Rank sum is better.`;
}
document.querySelector('#overview-table th[data-sort="pointwise"]').textContent = "Point rank";
document.querySelector('#overview-table th[data-sort="ic"]').textContent = "Ranking rank";
document.querySelector('#overview-table th[data-sort="portfolio"]').textContent = "Decision rank";
document.querySelector('#overview-table th[data-sort="overall"]').textContent = "Rank sum ↓";
document.querySelector('#overview-table th[data-sort="org"]').hidden = !showModelInfo;
document.querySelector('#overview-table th[data-sort="model_size"]').hidden = !showModelInfo;
document.querySelector('#overview-table th[data-sort="submit_time"]').hidden = !showModelInfo;
const tierCell = (row, tier) => {
const aspect = ASPECT[tier];
const rank = row[aspect];
const k = row[`${aspect}_k`];
if (!finite(k)) return `${fmt(k)} `;
const content = state.showDetailRank
? `${overviewRankBadge(rank)} (${overviewScoreText(k)}) `
: overviewRankBadge(rank);
return `${content} `;
};
const overallCell = (row) => {
const value = row.overall;
const text = fmt(value, finite(value) && value % 1 ? 1 : 0);
return `${text} `;
};
$("overview-body").innerHTML = rows.map((row, index) => `
${rankBadge(index + 1)}
${renderModelTypeCell(row.model)}
${renderModelCell(row.model)}
${showModelInfo ? `${modelOrg(row.model)} ${modelSize(row.model)} ${modelSubmitTime(row.model)} ` : ""}
${tierCell(row, "tier1")}
${tierCell(row, "tier2")}
${tierCell(row, "tier3")}
${overallCell(row)}
`).join("");
$("overview-body").querySelectorAll(".tier-rank").forEach((td) => td.onclick = () => showTierDetail(td.dataset.model, td.dataset.tier));
$("overview-body").querySelectorAll(".rank-sum").forEach((td) => td.onclick = () => showModelDetail(td.dataset.model));
document.querySelectorAll("#overview-table th[data-sort]").forEach((th) => {
th.classList.toggle("sorted", th.dataset.sort === state.sort.key);
th.classList.toggle("asc", th.dataset.sort === state.sort.key && state.sort.asc);
th.onclick = () => {
if (state.sort.key === th.dataset.sort) state.sort.asc = !state.sort.asc;
else { state.sort.key = th.dataset.sort; state.sort.asc = th.dataset.sort !== "model"; }
renderOverview();
};
});
}
function bindMetricsSortHeaders(columns) {
const metricDirections = new Map(columns.map((column) => [`metric:${column.key}`, metricGroupDirection(column.metric)]));
document.querySelectorAll("#metrics-head th[data-sort]").forEach((th) => {
th.onclick = () => {
const key = th.dataset.sort;
if (state.metricsSort.key === key) {
state.metricsSort.asc = !state.metricsSort.asc;
} else {
state.metricsSort.key = key;
state.metricsSort.asc = key.startsWith("metric:") ? metricDirections.get(key) < 0 : true;
}
renderMetrics();
};
});
}
function renderMetrics() {
$("metrics-model-info-toggle").checked = state.showModelInfo;
if (!state.recordsReady) {
renderLoadingPanel("metrics-body");
return;
}
const scopedRecords = includedRecords();
const columns = metricGroupsByTier()
.flatMap(([tier, metrics]) => metrics.map((metric) => ({ tier, metric, key: `${tier}|${metric}` })))
.filter((column) => !state.excludedMetrics.has(column.key) && scopedRecords.some((row) => metricFilterKey(row) === column.key));
const sortState = state.metricsSort;
const sortClass = (key) => `${sortState.key === key ? " sorted" : ""}${sortState.key === key && sortState.asc ? " asc" : ""}`;
const orgHead = state.showModelInfo
? `Organization Model size Submit date `
: "";
const orgColspan = state.showModelInfo ? 5 : 2;
if (!columns.length) {
$("metrics-head").innerHTML = `Model ${orgHead} `;
$("metrics-body").innerHTML = `No metric is selected. `;
bindMetricsSortHeaders(columns);
return;
}
const rows = tierStats();
const valuesByModel = new Map();
for (const model of includedModels()) {
const map = new Map();
for (const column of columns) {
map.set(column.key, arithmeticMean(scopedRecords
.filter((row) => row.model === model && metricFilterKey(row) === column.key)
.map((row) => row.value)));
}
valuesByModel.set(model, map);
}
const bestByColumn = new Map(columns.map((column) => {
const values = rows.map((row) => valuesByModel.get(row.model).get(column.key)).filter(finite);
const direction = metricGroupDirection(column.metric);
return [column.key, values.length ? (direction > 0 ? Math.max(...values) : Math.min(...values)) : null];
}));
const valueForSort = (row, key) => {
if (key === "rank") return row.overall;
if (key === "model_type") return modelTypeLabel(modelType(row.model));
if (key === "model") return displayName(row.model);
if (key === "org") return modelOrg(row.model);
if (key === "model_size") return parseModelSize(modelSize(row.model));
if (key === "submit_time") return modelSubmitTime(row.model);
if (key.startsWith("metric:")) return valuesByModel.get(row.model)?.get(key.slice(7));
return row[key];
};
rows.sort((a, b) => {
const key = sortState.key;
const av = valueForSort(a, key);
const bv = valueForSort(b, key);
if (["model_type", "model", "org", "submit_time"].includes(key)) {
const cmp = String(av || "").localeCompare(String(bv || ""));
return sortState.asc ? cmp : -cmp;
}
return compareNullable(av, bv, sortState.asc) || displayName(a.model).localeCompare(displayName(b.model));
});
$("metrics-head").innerHTML = `# Model ${orgHead}${columns.map((column) => `${TIER_SHORT[column.tier]} ${metricGroupLabel(column.metric)} `).join("")} `;
$("metrics-body").innerHTML = rows.map((row, index) => {
const modelValues = valuesByModel.get(row.model);
return `
${rankBadge(index + 1)}
${renderModelTypeCell(row.model)}
${renderModelCell(row.model)}
${state.showModelInfo ? `${modelOrg(row.model)} ${modelSize(row.model)} ${modelSubmitTime(row.model)} ` : ""}
${columns.map((column) => {
const value = modelValues.get(column.key);
return finite(value)
? `${fmtValue(value)} `
: `${fmtValue(value)} `;
}).join("")}
`;
}).join("");
$("metrics-body").querySelectorAll(".metric-score").forEach((td) => {
td.onclick = () => showMetricScoreDetail(td.dataset.model, td.dataset.tier, td.dataset.metricGroup);
});
bindMetricsSortHeaders(columns);
}
function showMetricScoreDetail(model, tier, metricGroup) {
const rows = includedRecords()
.filter((row) => row.model === model && metricFilterKey(row) === `${tier}|${metricGroup}`)
.sort((a, b) => a.category.localeCompare(b.category)
|| a.detail_category.localeCompare(b.detail_category)
|| a.frequency.localeCompare(b.frequency)
|| metricBase(a.metric).localeCompare(metricBase(b.metric))
|| a.metric.localeCompare(b.metric));
const mean = (values) => {
const valid = values.filter(finite);
return valid.length ? valid.reduce((sum, value) => sum + value, 0) / valid.length : null;
};
const overall = mean(rows.map((row) => row.value));
let html = `${TIER_SHORT[tier]} · ${metricGroupLabel(metricGroup)} average = ${fmtValue(overall)} · ${rows.length.toLocaleString()} cells
`;
html += `Description for Date Codes D DayW WeekM MonthQ QuarterH Half-yearY YearB BusinessBD Business-day
`;
html += `Detail Category Freq Metrics Target Type Pred. Target Value Rank `;
for (const row of rows) {
const parts = parseMetricParts(row.metric);
const direction = metricDirection(row.metric);
const total = state.records.filter((candidate) => {
return candidate.tier === row.tier
&& candidate.detail_category === row.detail_category
&& candidate.frequency === row.frequency
&& candidate.series_id === row.series_id
&& candidate.metric === row.metric;
}).length;
html += `${displayDetailLabel(row.detail_category)} ${freqCode(row.frequency)} ${parts.name} ${direction > 0 ? "↑" : "↓"} ${parts.type} ${parts.target} ${fmtValue(row.value)} ${rankText(row.rank, total)} `;
}
html += `
These are the raw metric values and ranks used to form this average cell under the current left-side Metric · Detail Category · Frequency filters.
`;
openDrawer(`${displayName(model)} · ${metricGroupLabel(metricGroup)}`, html);
closeDrawer2();
}
function unitK(tier, records = includedRecords()) {
const out = new Map();
for (const model of includedModels()) out.set(model, new Map());
const grouped = new Map();
for (const row of records.filter((r) => !tier || r.tier === tier)) {
const key = JSON.stringify([row.model, row.unit]);
if (!grouped.has(key)) grouped.set(key, []);
grouped.get(key).push(row.rank);
}
for (const [key, ranks] of grouped) {
const [model, unit] = JSON.parse(key);
if (out.has(model)) out.get(model).set(unit, geometricMean(ranks));
}
return out;
}
function renderStrength() {
if (!state.recordsReady) {
$("strength-body").innerHTML = 'Loading detailed records.
';
return;
}
const scopedRecords = includedRecords();
if (!scopedRecords.length) {
$("strength-body").innerHTML = 'No cells match the selected filters.
';
return;
}
const models = includedModels();
const overallScores = new Map(models.map((model) => [
model,
geometricMean(scopedRecords.filter((row) => row.model === model).map((row) => row.rank))
]));
const overallRanks = new Map(rankRows([...overallScores.entries()].map(([model, value]) => ({ model, value })), "value", -1).map((row) => [row.model, row.rank]));
const units = [...new Map(scopedRecords.map((r) => [r.unit, displayDetailLabel(r.unit_label || r.unit)])).entries()].sort((a, b) => a[1].localeCompare(b[1]));
const matrix = unitK(null, scopedRecords);
const overall = models
.filter((model) => finite(overallScores.get(model)))
.sort((a, b) => compareNullable(overallScores.get(a), overallScores.get(b)) || a.localeCompare(b));
const colRanks = new Map();
for (const [unit] of units) {
const vals = models.map((model) => ({ model, value: matrix.get(model).get(unit) }));
colRanks.set(unit, new Map(rankRows(vals, "value", -1).map((r) => [r.model, r.rank])));
}
const color = (rank, n) => {
if (!finite(rank)) return "#f3f4f6";
const t = n > 1 ? (rank - 1) / (n - 1) : 0;
return `hsl(${120 * (1 - Math.max(0, Math.min(1, t)))}, 62%, 78%)`;
};
let html = `Model (${overall.length}) Overall `;
for (const [, label] of units) html += `${strengthHeaderLabel(label)} `;
html += ``;
for (const model of overall) {
const ov = overallScores.get(model);
const ovRank = overallRanks.get(model);
html += `${displayName(model)} ${fmt(ov)} `;
for (const [unit] of units) {
const k = matrix.get(model).get(unit);
const rank = colRanks.get(unit).get(model);
html += `${finite(k) ? k.toFixed(1) : "·"} `;
}
html += ` `;
}
$("strength-body").innerHTML = html + `
`;
}
function guideTable(title, rows) {
return `
${title}
Button Meaning
${rows.map(([button, meaning]) => `${button} ${meaning} `).join("")}
`;
}
function renderLeaderboardGuide() {
if (!state.recordsReady) {
$("leaderboard-guide-body").innerHTML = 'Loading detailed records.
';
return;
}
const metricRows = metricGroupsByTier().flatMap(([tier, metrics]) => metrics.map((metric) => {
const base = metric === "mase_pct0" ? "mase" : metric;
const desc = metric === "mase_pct0" ? "Forecast error on the original target without a percentage-change option." : (METRIC_INFO[base]?.[1] || "Includes this metric group in rank calculations.");
return [`${TIER_SHORT[tier]} · ${metricGroupLabel(metric)}`, desc];
}));
const optionGroups = metricOptionGroups();
const typeRows = optionButtonGroups(optionGroups.types, typeLabel, true).map((group) => {
const descriptions = {
All: "Original-target metrics without a specific percentage-change type.",
WoW: "Week-over-week percentage change as the target type.",
MoM: "Month-over-month percentage change as the target type.",
QoQ: "Quarter-over-quarter percentage change as the target type.",
HoH: "Half-year-over-half-year percentage change as the target type.",
YoY: "Year-over-year percentage change as the target type."
};
return [group.label, descriptions[group.label] || "Includes this target type in rank calculations."];
});
const targetRows = optionButtonGroups(optionGroups.targets, predTargetLabel).map((group) => {
const descriptions = {
Original: "Original target without a forecast horizon label.",
"1W": "Forecast target one week ahead.",
"1M": "Forecast target one month ahead.",
"1Q": "Forecast target one quarter ahead.",
"1H": "Forecast target one half-year ahead.",
"1Y": "Forecast target one year ahead."
};
return [group.label, descriptions[group.label] || "Includes this prediction target horizon in rank calculations."];
});
const detailRows = detailsByScope().flatMap(([, values]) => [...values.entries()]
.sort((a, b) => a[1].localeCompare(b[1]))
.map(([detail, label]) => [label, DETAIL_CATEGORY_EXPLANATIONS[detail] || DETAIL_CATEGORY_EXPLANATIONS[label] || "Evaluation data for this Detail Category."]));
const frequencyRows = allFrequencies().map((frequency) => {
const descriptions = {
Annual: "Time series observed at an annual frequency.",
"Business-daily": "Time series observed at a business-daily frequency.",
Daily: "Time series observed at a daily frequency.",
Monthly: "Time series observed at a monthly frequency.",
Quarterly: "Time series observed at a quarterly frequency.",
Weekly: "Time series observed at a weekly frequency."
};
return [frequency, descriptions[frequency] || `Time series observed at a ${frequency} frequency.`];
});
$("leaderboard-guide-body").innerHTML = `
${guideTable("Metric", metricRows)}
${guideTable("Metric Additional Option · Target Type", typeRows)}
${guideTable("Metric Additional Option · Pred. Target", targetRows)}
${guideTable("Detail Category", detailRows)}
${guideTable("Frequency", frequencyRows)}
`;
}
function showModelDetail(model) {
if (!state.recordsReady) return;
const stats = tierStats().find((r) => r.model === model);
const units = [...new Map(includedRecords().filter((r) => r.model === model).map((r) => [r.unit, displayDetailLabel(r.unit_label || r.unit)])).entries()].sort((a, b) => a[1].localeCompare(b[1]));
const categoryByUnit = new Map(includedRecords().filter((r) => r.model === model).map((r) => [r.unit, r.category || ""]));
const matrixByTier = Object.fromEntries(Object.keys(TIER_LABEL).map((tier) => [tier, unitK(tier).get(model)]));
let html = `Rank sum = ${fmt(stats.overall, finite(stats.overall) && stats.overall % 1 ? 1 : 0)}
Category Detail Category Point Ranking Decision `;
const cell = (tier, unit) => {
const value = matrixByTier[tier].get(unit);
return finite(value)
? `${fmt(value)} `
: `${fmt(value)} `;
};
for (const [unit, label] of units) html += `${categoryByUnit.get(unit) || ""} ${label} ${cell("tier1", unit)}${cell("tier2", unit)}${cell("tier3", unit)} `;
html += `
Each cell is the geometric mean K of metric ranks for that Detail Category under the selected Frequency filters. Lower is better. Click a number to view raw metric values and ranks.
`;
openDrawer(displayName(model), html);
closeDrawer2();
$("detail-body").querySelectorAll(".cat-rank").forEach((td) => {
td.onclick = () => showMetricDetail(td.dataset.model, td.dataset.tier, td.dataset.unit);
});
}
function showTierDetail(model, tier) {
if (!state.recordsReady) return;
const matrix = unitK(tier).get(model);
const units = [...new Map(includedRecords().filter((r) => r.model === model && r.tier === tier).map((r) => [r.unit, displayDetailLabel(r.unit_label || r.unit)])).entries()].sort((a, b) => a[1].localeCompare(b[1]));
const categoryByUnit = new Map(includedRecords().filter((r) => r.model === model && r.tier === tier).map((r) => [r.unit, r.category || ""]));
let html = `${TIER_SHORT[tier]} K = ${fmt(tierStats().find((r) => r.model === model)[`${ASPECT[tier]}_k`])}
Category Detail Category K `;
for (const [unit, label] of units) {
const value = matrix.get(unit);
html += `${categoryByUnit.get(unit) || ""} ${label} ${finite(value)
? `${fmt(value)} `
: `${fmt(value)} `} `;
}
html += `
Click a K value to view the raw metric values and ranks used in the calculation.
`;
openDrawer(`${displayName(model)} · ${TIER_SHORT[tier]}`, html);
closeDrawer2();
$("detail-body").querySelectorAll(".cat-rank").forEach((td) => {
td.onclick = () => showMetricDetail(td.dataset.model, td.dataset.tier, td.dataset.unit);
});
}
function showMetricDetail(model, tier, unit) {
if (!state.recordsReady) return;
const rows = includedRecords()
.filter((r) => r.model === model && r.tier === tier && r.unit === unit)
.sort((a, b) => {
const [aType, aTarget] = a.metric.replace(new RegExp(`^${metricBase(a.metric)}_?`), "").split("_");
const [bType, bTarget] = b.metric.replace(new RegExp(`^${metricBase(b.metric)}_?`), "").split("_");
return a.frequency.localeCompare(b.frequency)
|| metricBase(a.metric).localeCompare(metricBase(b.metric))
|| horizonOrder(aType) - horizonOrder(bType)
|| horizonOrder(aTarget) - horizonOrder(bTarget)
|| a.metric.localeCompare(b.metric);
});
const label = displayDetailLabel(rows[0]?.unit_label || unit);
const k = geometricMean(rows.map((r) => r.rank));
let html = `${TIER_SHORT[tier]} · ${label} K = ${fmt(k)} · ${rows.length.toLocaleString()} cells
`;
html += `Description for Date Codes D DayW WeekM MonthQ QuarterH Half-yearY YearB BusinessBD Business-day
`;
html += `Freq Metrics Target Type Pred. Target Value Rank `;
for (const row of rows) {
const parts = parseMetricParts(row.metric);
const direction = metricDirection(row.metric);
const total = state.records.filter((candidate) => {
return candidate.tier === row.tier
&& candidate.detail_category === row.detail_category
&& candidate.frequency === row.frequency
&& candidate.series_id === row.series_id
&& candidate.metric === row.metric;
}).length;
html += `${freqCode(row.frequency)} ${parts.name} ${direction > 0 ? "↑" : "↓"} ${parts.type} ${parts.target} ${fmtValue(row.value)} ${rankText(row.rank, total)} `;
}
html += `
↑ means higher is better, and ↓ means lower is better. Rank is shown as rank/total within the same tier · Detail Category · Frequency · metric comparison unit.
`;
$("detail2-title").textContent = `${label} · ${TIER_SHORT[tier]}`;
$("detail2-body").innerHTML = html;
$("detail2").hidden = false;
$("detail").classList.add("shifted");
$("drawer-scrim").hidden = false;
}
function openDrawer(title, html) {
$("detail-title").textContent = title;
$("detail-body").innerHTML = html;
$("detail").classList.remove("shifted");
$("detail").hidden = false;
$("drawer-scrim").hidden = false;
}
function closeDrawer2() {
const drawer = $("detail2");
if (!drawer) return;
drawer.hidden = true;
$("detail").classList.remove("shifted");
}
function closeDrawer() {
closeDrawer2();
$("detail").hidden = true;
$("drawer-scrim").hidden = true;
}
function render() {
syncSidebarForView();
if (state.view === "overview") renderOverview();
if (state.view === "overview-plot") renderOverviewPlotPage();
if (state.view === "metrics") renderMetrics();
if (state.view === "strength") renderStrength();
if (state.view === "leaderboard-guide") renderLeaderboardGuide();
}
async function boot() {
state.data = await fetch("leaderboard_data.json", { cache: "no-store" }).then((response) => response.json());
state.models = (state.data.overall || []).map((row) => row.model).sort();
const configEntries = await Promise.all((state.data.result_files || []).map((item) => {
const path = item.config_path || item.path.replace(/result\.json$/, "config.json");
return fetch(path, { cache: "no-store" })
.then((response) => response.ok ? response.json() : null)
.then((config) => [item.model, config || { model: item.model, model_type: "unknown" }]);
}));
state.modelConfigs = new Map(configEntries);
$("model-count").textContent = `${state.models.length} models`;
$("updated").textContent = `updated ${formatAoeDate(state.data.generated_at)}`;
$("detail-close").onclick = closeDrawer;
$("detail2-close").onclick = closeDrawer2;
$("drawer-scrim").onclick = closeDrawer;
$("detail-rank-toggle").onchange = (event) => {
state.showDetailRank = event.target.checked;
renderOverview();
};
$("model-info-toggle").onchange = (event) => {
state.showModelInfo = event.target.checked;
render();
};
$("metrics-model-info-toggle").onchange = (event) => {
state.showModelInfo = event.target.checked;
render();
};
setupTabs();
setupCollapsibles();
buildSpecToggles();
render();
const columns = state.data.rank_record_columns || [];
let chunks = [];
if (state.data.result_files?.length) {
const results = await Promise.all(state.data.result_files.map((item) => fetch(item.path, { cache: "no-store" }).then((response) => response.json())));
chunks = results.flatMap((result) => result.records || []);
} else if (state.data.result_index) {
const index = await fetch(state.data.result_index, { cache: "no-store" }).then((response) => response.json());
const results = await Promise.all(index.models.map((item) => fetch(item.path, { cache: "no-store" }).then((response) => response.json())));
chunks = results.flatMap((result) => result.records || []);
} else {
chunks = state.data.rank_record_files
? (await Promise.all(state.data.rank_record_files.map((file) => fetch(file, { cache: "no-store" }).then((response) => response.json())))).flat()
: (state.data.rank_records || []);
}
state.records = chunks.map((row) => Array.isArray(row)
? Object.fromEntries(columns.map((column, index) => [column, row[index]]))
: row);
state.models = [...new Set(state.records.map((r) => r.model))].sort();
state.recordsReady = true;
$("model-count").textContent = `${state.models.length} models`;
buildSpecToggles();
render();
}
boot();