Files
finance-daily-site/index.html
T
2026-05-13 23:14:02 +00:00

2828 lines
147 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="金融日报 — 北美华人投资者专属每日金融简报,由 Claude AI + Web Search 自动生成,每日两次更新">
<meta property="og:title" content="金融日报 | Financial Daily">
<meta property="og:description" content="北美华人投资者专属:全球指数·市场要闻·宏观数据·财报追踪·经济日历,每日自动更新">
<meta property="og:type" content="website">
<meta name="keywords" content="金融日报,北美投资,美股,A股,港股,宏观经济,财报,经济日历">
<meta name="theme-color" content="#070b14">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="金融日报">
<link rel="manifest" href="manifest.json">
<title>金融日报 | Financial Daily — 北美华人投资者日报</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
/* =========================================================
RESET & TOKENS
========================================================= */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #070b14;
--card: #0c1525;
--card2: #0f1c30;
--border: #192840;
--border-l: #22386a;
--accent: #00d4aa;
--up: #00e676;
--down: #ff5252;
--neutral: #4fc3f7;
--warn: #ffb300;
--text: #e2e8f0;
--muted: #7a8fa8;
--dimmed: #3a4e68;
--mono: 'JetBrains Mono','Fira Code',monospace;
--sans: 'Inter',system-ui,-apple-system,sans-serif;
--r: 8px;
--rl: 14px;
}
html { font-size: 14px; scroll-behavior: smooth; }
body { font-family: var(--sans); background: var(--bg); color: var(--text); line-height: 1.6; -webkit-font-smoothing: antialiased; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: #33e0be; }
/* =========================================================
READING PROGRESS
========================================================= */
#reading-progress { position: fixed; top: 0; left: 0; height: 3px; width: 0; background: linear-gradient(90deg,var(--accent),#4fc3f7); z-index: 9999; transition: width .1s; }
/* =========================================================
HEADER
========================================================= */
.site-header {
position: sticky; top: 0; z-index: 100;
background: rgba(7,11,20,.96); backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border);
padding: 10px 0;
}
.header-inner { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.logo-block { display: flex; align-items: baseline; gap: 8px; }
.site-title { font-size: 1.1rem; font-weight: 800; color: var(--accent); letter-spacing: -.02em; }
.site-sub { font-size: .65rem; color: var(--muted); font-family: var(--mono); }
.header-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.header-date { font-family: var(--mono); font-size: .68rem; color: var(--muted); }
.header-badge { display: flex; align-items: center; gap: 5px; font-size: .62rem; color: var(--muted); background: rgba(0,212,170,.08); border: 1px solid rgba(0,212,170,.2); border-radius: 20px; padding: 2px 9px; }
.pulse-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: pulse 2s ease-in-out infinite; }
@keyframes pulse { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.4;transform:scale(.7)} }
.header-nav { display: flex; gap: 10px; }
.header-nav a { font-size: .68rem; color: var(--muted); }
.header-nav a:hover { color: var(--accent); }
.streak-badge { font-size: .62rem; font-family: var(--mono); background: rgba(255,179,0,.12); color: var(--warn); border: 1px solid rgba(255,179,0,.25); border-radius: 20px; padding: 2px 8px; }
/* =========================================================
NAV BAR
========================================================= */
.jump-nav {
position: sticky; top: 47px; z-index: 90;
background: rgba(7,11,20,.95); backdrop-filter: blur(14px);
border-bottom: 1px solid var(--border);
display: flex; overflow-x: auto; scrollbar-width: none;
}
.jump-nav::-webkit-scrollbar { display: none; }
.jump-nav a {
flex-shrink: 0; padding: 8px 14px; font-size: .72rem;
color: var(--muted); white-space: nowrap;
border-bottom: 2px solid transparent; transition: color .15s, border-color .15s;
}
.jump-nav a:hover { color: var(--text); text-decoration: none; }
.jump-nav a.active { color: var(--accent); border-bottom-color: var(--accent); }
.nav-sep { width: 1px; background: var(--border); margin: 8px 0; flex-shrink: 0; }
/* =========================================================
TICKER STRIP
========================================================= */
.indices-section { border-bottom: 1px solid var(--border); background: rgba(0,0,0,.2); }
.indices-scroll-wrapper { overflow: hidden; position: relative; }
.indices-track { display: flex; gap: 0; animation: ticker 60s linear infinite; width: max-content; }
.indices-track:hover { animation-play-state: paused; }
@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.ticker-card { padding: 8px 18px; border-right: 1px solid var(--border); white-space: nowrap; cursor: default; }
.ticker-name { font-size: .62rem; color: var(--muted); font-family: var(--mono); margin-bottom: 2px; }
.ticker-value { font-size: .9rem; font-weight: 700; font-family: var(--mono); }
.ticker-change { font-size: .68rem; font-family: var(--mono); }
.ticker-change.up,.ticker-value.up { color: var(--up); }
.ticker-change.down,.ticker-value.down { color: var(--down); }
.ticker-card.up .ticker-value { color: var(--text); }
.ticker-card.down .ticker-value { color: var(--text); }
/* =========================================================
LAYOUT
========================================================= */
.container { max-width: 1360px; margin: 0 auto; padding: 0 20px; }
.page-body { padding: 20px 0 40px; }
/* Primary grid: content + sidebar */
.content-grid {
display: grid;
grid-template-columns: 1fr 380px;
gap: 20px;
align-items: start;
}
@media (max-width: 1024px) { .content-grid { grid-template-columns: 1fr; } }
/* 2-col within a column */
.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 640px) { .two-up { grid-template-columns: 1fr; } }
/* =========================================================
CARDS & SECTIONS
========================================================= */
.card {
background: var(--card); border: 1px solid var(--border);
border-radius: var(--rl); padding: 18px 20px;
transition: border-color .2s;
}
.section-label {
font-size: .65rem; font-family: var(--mono); color: var(--accent);
letter-spacing: .1em; text-transform: uppercase;
margin-bottom: 14px; padding-bottom: 10px;
border-bottom: 1px solid var(--border);
display: flex; align-items: center; gap: 8px;
}
.section-label::before { content:''; width:3px; height:12px; background:var(--accent); border-radius:2px; flex-shrink:0; }
.section-label .sec-count { margin-left:auto; color:var(--dimmed); font-size:.6rem; }
.sec-anchor { scroll-margin-top: 100px; }
.mb16 { margin-bottom: 16px; }
/* =========================================================
SUMMARY HERO
========================================================= */
.summary-section { padding: 16px 0 0; }
.summary-card {
border-radius: var(--rl); padding: 22px 26px;
border: 1px solid var(--border); margin-bottom: 16px;
}
.summary-card.bullish { background: linear-gradient(135deg,rgba(0,230,118,.07),rgba(0,212,170,.03)); border-color:rgba(0,230,118,.28); }
.summary-card.bearish { background: linear-gradient(135deg,rgba(255,82,82,.07),rgba(255,82,82,.02)); border-color:rgba(255,82,82,.28); }
.summary-card.neutral { background: linear-gradient(135deg,rgba(79,195,247,.06),rgba(0,212,170,.03)); border-color:rgba(79,195,247,.22); }
.summary-top { display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
.sentiment-pill { font-size:.72rem; font-family:var(--mono); font-weight:700; padding:4px 14px; border-radius:20px; letter-spacing:.06em; }
.sentiment-pill.bullish { background:rgba(0,230,118,.15); color:var(--up); border:1px solid rgba(0,230,118,.3); }
.sentiment-pill.bearish { background:rgba(255,82,82,.15); color:var(--down); border:1px solid rgba(255,82,82,.3); }
.sentiment-pill.neutral { background:rgba(79,195,247,.12); color:var(--neutral);border:1px solid rgba(79,195,247,.25); }
.vix-badge { font-family:var(--mono); font-size:.72rem; color:var(--muted); }
.vix-num { color:var(--warn); font-weight:700; font-size:.9rem; }
.summary-headline { font-size:1.22rem; font-weight:800; color:var(--text); line-height:1.38; margin-bottom:14px; letter-spacing:-.02em; }
.key-points { list-style:none; display:flex; flex-direction:column; gap:7px; margin-bottom:14px; padding:0; }
.kp-item { font-size:.83rem; color:var(--text); padding:9px 14px; background:rgba(255,255,255,.04); border-radius:7px; border-left:3px solid var(--accent); display:flex; align-items:center; gap:8px; font-weight:500; line-height:1.4; }
.kp-arrow { color:var(--accent); font-size:.7rem; flex-shrink:0; }
.summary-details { margin-top:4px; }
.summary-details-toggle { font-size:.72rem; color:var(--muted); cursor:pointer; user-select:none; padding:4px 0; list-style:none; }
.summary-details-toggle:hover { color:var(--accent); }
.summary-context { font-size:.82rem; color:var(--muted); line-height:1.7; padding-top:8px; }
/* legacy hide */
.summary-icon,.summary-content,.summary-meta,.summary-label,.vix-display,.sentiment-badge { display:none !important; }
/* =========================================================
NEWS
========================================================= */
.news-item {
background: var(--card); border-radius: var(--r);
border: 1px solid var(--border); margin-bottom: 6px;
cursor: pointer; overflow: hidden; transition: border-color .18s;
}
.news-item:hover { border-color: var(--border-l); }
.news-item.expanded { border-color: var(--border-l); }
.news-header { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px 9px; }
.imp-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink:0; margin-top:5px; }
.imp-dot.breaking { background:var(--down); box-shadow:0 0 5px rgba(255,82,82,.5); }
.imp-dot.major { background:var(--warn); }
.imp-dot.normal { background:var(--neutral); opacity:.35; }
.news-title { font-size:.86rem; font-weight:600; color:var(--text); line-height:1.42; flex:1; }
.news-title a { color:var(--text); }
.news-title a:hover { color:var(--accent); }
.news-expand-icon { color:var(--dimmed); flex-shrink:0; font-size:1rem; transition:transform .2s; }
.news-item.expanded .news-expand-icon { transform:rotate(45deg); color:var(--accent); }
.news-tldr { padding:0 14px 9px 31px; font-size:.76rem; color:var(--accent); line-height:1.5; }
.tldr-label { margin-right:3px; }
.news-body-collapse { display:none; padding:9px 14px 12px 31px; font-size:.79rem; color:var(--muted); line-height:1.65; border-top:1px solid var(--border); }
.news-item.expanded .news-body-collapse { display:block; }
.news-footer { display:flex; align-items:center; gap:7px; padding:7px 14px; flex-wrap:wrap; border-top:1px solid rgba(255,255,255,.035); }
.news-item.breaking { border-left:3px solid var(--down); }
.news-item.major { border-left:3px solid var(--warn); }
.news-item.normal { border-left:3px solid transparent; }
.importance-badge { font-size:.6rem; font-family:var(--mono); padding:2px 6px; border-radius:3px; }
.importance-badge.breaking { background:rgba(255,82,82,.12); color:var(--down); }
.importance-badge.major { background:rgba(255,179,0,.12); color:var(--warn); }
.importance-badge.normal { background:rgba(79,195,247,.08); color:var(--neutral); }
.new-badge { font-size:.58rem; font-family:var(--mono); padding:1px 5px; border-radius:3px; background:rgba(0,212,170,.15); color:var(--accent); border:1px solid rgba(0,212,170,.3); }
/* =========================================================
TAGS
========================================================= */
.tag { font-size:.6rem; font-family:var(--mono); padding:2px 6px; border-radius:3px; background:rgba(255,255,255,.06); color:var(--muted); }
/* =========================================================
LEADERS
========================================================= */
.leader-card { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:14px; margin-bottom:8px; transition:border-color .2s; }
.leader-card:hover { border-color:var(--border-l); }
.leader-header { display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.leader-avatar { width:38px; height:38px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:.7rem; font-weight:700; font-family:var(--mono); flex-shrink:0; }
.leader-avatar.wb { background:linear-gradient(135deg,#4a3800,#8b6914); color:#ffd700; }
.leader-avatar.rd { background:linear-gradient(135deg,#1a3a5c,#2563a8); color:#60a5fa; }
.leader-avatar.jd { background:linear-gradient(135deg,#3a1a1a,#8b2525); color:#f87171; }
.leader-avatar.jp { background:linear-gradient(135deg,#1a3a2a,#256b40); color:#4ade80; }
.leader-avatar.default { background:rgba(0,212,170,.15); color:var(--accent); }
.leader-meta { flex:1; }
.leader-name { font-size:.83rem; font-weight:600; }
.leader-role { font-size:.68rem; color:var(--muted); }
.leader-date { font-size:.62rem; color:var(--dimmed); font-family:var(--mono); white-space:nowrap; }
.leader-quote { font-size:.82rem; color:var(--accent); font-style:italic; margin-bottom:8px; line-height:1.5; }
.leader-body { font-size:.78rem; color:var(--muted); line-height:1.6; margin-bottom:8px; }
/* =========================================================
MACRO
========================================================= */
.macro-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:10px; }
.macro-card { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:12px 14px; transition:border-color .2s; }
.macro-card:hover { border-color:var(--border-l); }
.macro-card.dir-up { border-left:3px solid var(--up); }
.macro-card.dir-down{ border-left:3px solid var(--down); }
.macro-card.dir-neutral { border-left:3px solid var(--neutral); }
.macro-indicator { font-size:.65rem; font-family:var(--mono); color:var(--muted); margin-bottom:5px; text-transform:uppercase; }
.macro-value { font-size:1.1rem; font-weight:700; font-family:var(--mono); margin-bottom:4px; }
.macro-value-up { color:var(--up); }
.macro-value-down { color:var(--down); }
.macro-prev { font-size:.66rem; color:var(--dimmed); margin-bottom:5px; }
.macro-desc { font-size:.72rem; color:var(--muted); line-height:1.5; }
.arrow.up { color:var(--up); }
.arrow.down { color:var(--down); }
/* =========================================================
EARNINGS
========================================================= */
.earnings-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:10px; }
.earnings-card { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:14px; transition:border-color .2s; }
.earnings-card:hover { border-color:var(--border-l); }
.earnings-card.beat { border-top:2px solid var(--up); }
.earnings-card.miss { border-top:2px solid var(--down); }
.earnings-card.pending{ border-top:2px solid var(--neutral); }
.e-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.e-ticker { font-family:var(--mono); font-size:.85rem; font-weight:700; }
.e-company { font-size:.7rem; color:var(--muted); }
.e-badge { font-size:.6rem; font-family:var(--mono); padding:2px 7px; border-radius:3px; }
.e-badge.beat { background:rgba(0,230,118,.15); color:var(--up); }
.e-badge.miss { background:rgba(255,82,82,.15); color:var(--down); }
.e-badge.pending{ background:rgba(79,195,247,.1); color:var(--neutral); }
.earnings-eps { display:flex; gap:10px; margin-bottom:8px; }
.eps-item { flex:1; }
.eps-label { font-size:.6rem; font-family:var(--mono); color:var(--dimmed); margin-bottom:3px; }
.eps-value { font-size:.9rem; font-weight:700; font-family:var(--mono); }
.eps-value.actual.beat { color:var(--up); }
.eps-value.actual.miss { color:var(--down); }
.eps-value.est { color:var(--muted); }
.e-revenue { font-size:.72rem; color:var(--muted); margin-bottom:5px; }
.e-highlight { font-size:.72rem; color:var(--text); line-height:1.4; }
/* =========================================================
SECTORS
========================================================= */
.sectors-list { display:flex; flex-direction:column; gap:6px; }
.sector-row { display:grid; grid-template-columns:1fr auto 120px auto; gap:8px; align-items:center; padding:8px 10px; background:var(--bg); border-radius:var(--r); border:1px solid var(--border); font-size:.78rem; }
@media(max-width:480px){ .sector-row { grid-template-columns:1fr auto; } .sector-bar-wrap,.sector-etf{ display:none; } }
.sector-name { font-weight:500; }
.sector-name-en { font-size:.65rem; color:var(--muted); }
.sector-etf { font-family:var(--mono); font-size:.65rem; color:var(--dimmed); }
.sector-bar-wrap { height:5px; background:var(--border); border-radius:3px; overflow:hidden; }
.sector-bar { height:100%; border-radius:3px; }
.sector-bar.up { background:var(--up); }
.sector-bar.down { background:var(--down); }
.sector-pct { font-family:var(--mono); font-size:.78rem; font-weight:600; text-align:right; }
.sector-pct.up { color:var(--up); }
.sector-pct.down { color:var(--down); }
/* =========================================================
CENTRAL BANKS
========================================================= */
.cb-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
@media(max-width:600px){ .cb-grid { grid-template-columns:1fr; } }
.cb-card { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:14px; transition:border-color .2s; }
.cb-card:hover { border-color:var(--border-l); }
.cb-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:8px; gap:8px; flex-wrap:wrap; }
.cb-name { font-size:.82rem; font-weight:600; }
.cb-rate { font-family:var(--mono); font-size:.78rem; color:var(--accent); }
.cb-action { font-size:.75rem; color:var(--text); margin-bottom:6px; font-weight:500; }
.cb-note { font-size:.72rem; color:var(--muted); line-height:1.5; margin-bottom:8px; }
.cb-bias { font-size:.6rem; font-family:var(--mono); padding:2px 7px; border-radius:3px; }
.cb-bias.hawkish { background:rgba(255,82,82,.12); color:var(--down); }
.cb-bias.dovish { background:rgba(0,230,118,.12); color:var(--up); }
.cb-bias.neutral { background:rgba(79,195,247,.1); color:var(--neutral); }
.cb-next { font-size:.65rem; color:var(--dimmed); font-family:var(--mono); }
/* =========================================================
CALENDAR
========================================================= */
.calendar-grid { display:flex; flex-direction:column; gap:6px; }
.cal-item { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:10px 12px; display:flex; gap:12px; align-items:flex-start; border-left-width:3px; transition:border-color .2s; }
.cal-item.high { border-left-color:var(--down); }
.cal-item.medium { border-left-color:var(--warn); }
.cal-item.low { border-left-color:var(--neutral); }
.cal-date { font-family:var(--mono); font-size:.62rem; color:var(--muted); min-width:54px; line-height:1.5; }
.cal-event { font-size:.78rem; color:var(--text); font-weight:500; margin-bottom:3px; }
.cal-values { font-family:var(--mono); font-size:.64rem; color:var(--muted); }
.cal-values span { color:var(--neutral); }
/* =========================================================
AI WATCHLIST
========================================================= */
.watchlist-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:10px; }
.watchlist-card { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:14px; transition:border-color .18s,transform .18s; }
.watchlist-card:hover { border-color:var(--border-l); transform:translateY(-2px); }
.wc-header { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:8px; }
.wc-ticker { font-family:var(--mono); font-size:.9rem; font-weight:700; color:var(--accent); }
.wc-name { font-size:.65rem; color:var(--muted); margin-top:1px; }
.wc-price { text-align:right; }
.wc-price-val { font-family:var(--mono); font-size:.85rem; font-weight:600; }
.wc-price-chg { font-size:.68rem; }
.wc-price-chg.up { color:var(--up); }
.wc-price-chg.down { color:var(--down); }
.wc-signal-row { display:flex; align-items:center; gap:8px; margin-bottom:7px; }
.signal-badge { font-family:var(--mono); font-size:.65rem; font-weight:700; padding:2px 9px; border-radius:4px; }
.signal-badge.BUY { background:rgba(0,230,118,.15); color:var(--up); border:1px solid rgba(0,230,118,.3); }
.signal-badge.SELL { background:rgba(255,82,82,.15); color:var(--down);border:1px solid rgba(255,82,82,.3); }
.signal-badge.HOLD { background:rgba(255,179,0,.15); color:var(--warn);border:1px solid rgba(255,179,0,.3); }
.wc-score { font-family:var(--mono); font-size:.68rem; color:var(--muted); }
.wc-score span { color:var(--text); font-weight:600; }
.wc-conclusion { font-size:.78rem; color:var(--text); margin-bottom:3px; font-weight:500; line-height:1.4; }
.wc-driver { font-size:.68rem; color:var(--muted); margin-bottom:8px; line-height:1.4; }
.wc-targets { display:flex; gap:6px; font-size:.66rem; margin-bottom:6px; flex-wrap:wrap; }
.wc-target-up { color:var(--up); background:rgba(0,230,118,.1); padding:2px 7px; border-radius:3px; }
.wc-target-down { color:var(--down); background:rgba(255,82,82,.1); padding:2px 7px; border-radius:3px; }
.risk-badge { font-size:.58rem; font-family:var(--mono); padding:2px 6px; border-radius:3px; text-transform:uppercase; }
.risk-badge.low { background:rgba(0,230,118,.12); color:var(--up); }
.risk-badge.medium { background:rgba(255,179,0,.12); color:var(--warn); }
.risk-badge.high { background:rgba(255,82,82,.12); color:var(--down); }
.wc-action { font-size:.68rem; color:var(--muted); line-height:1.4; margin-top:5px; }
/* =========================================================
MARKET DEBATE
========================================================= */
.debate-container { display:flex; flex-direction:column; gap:12px; }
.debate-header { font-family:var(--mono); font-size:.68rem; color:var(--muted); text-transform:uppercase; letter-spacing:.08em; }
.debate-sides { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
@media(max-width:600px){ .debate-sides { grid-template-columns:1fr; } }
.debate-side { background:var(--bg); border-radius:var(--r); padding:12px; }
.debate-side.bull { border-top:2px solid var(--up); }
.debate-side.bear { border-top:2px solid var(--down); }
.debate-side-title { font-size:.68rem; font-weight:600; text-transform:uppercase; letter-spacing:.08em; margin-bottom:8px; }
.debate-side.bull .debate-side-title { color:var(--up); }
.debate-side.bear .debate-side-title { color:var(--down); }
.debate-point { display:flex; align-items:flex-start; gap:7px; margin-bottom:7px; font-size:.76rem; line-height:1.4; }
.conf-badge { font-size:.57rem; font-family:var(--mono); padding:1px 4px; border-radius:3px; flex-shrink:0; margin-top:2px; }
.conf-badge.high { background:rgba(79,195,247,.15); color:var(--neutral); }
.conf-badge.medium { background:rgba(255,179,0,.12); color:var(--warn); }
.debate-verdict { background:var(--bg); border-radius:var(--r); padding:12px 14px; border-left:3px solid var(--accent); }
.verdict-label { font-size:.62rem; font-family:var(--mono); text-transform:uppercase; letter-spacing:.1em; color:var(--muted); margin-bottom:5px; }
.verdict-text { font-size:.81rem; line-height:1.5; }
.verdict-lean { display:inline-block; margin-left:7px; font-size:.62rem; font-family:var(--mono); padding:2px 6px; border-radius:3px; }
.verdict-lean.bullish { background:rgba(0,230,118,.15); color:var(--up); }
.verdict-lean.bearish { background:rgba(255,82,82,.15); color:var(--down); }
.verdict-lean.neutral { background:rgba(79,195,247,.12); color:var(--neutral); }
/* =========================================================
MARKET REPLAY
========================================================= */
.replay-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
@media(max-width:600px){ .replay-grid { grid-template-columns:1fr; } }
.replay-card { background:var(--bg); border:1px solid var(--border); border-radius:var(--r); padding:14px; }
.replay-card-title { font-size:.65rem; font-family:var(--mono); text-transform:uppercase; letter-spacing:.1em; color:var(--accent); margin-bottom:5px; }
.replay-summary { font-size:.82rem; font-weight:500; margin-bottom:10px; line-height:1.4; }
.ad-bar-wrap { display:flex; align-items:center; gap:6px; margin-bottom:8px; font-size:.7rem; }
.ad-bar { height:5px; border-radius:3px; }
.ad-bar.adv { background:var(--up); }
.ad-bar.dec { background:var(--down); }
.ad-label-up { color:var(--up); min-width:45px; font-family:var(--mono); font-size:.68rem; }
.ad-label-dn { color:var(--down); min-width:45px; font-family:var(--mono); font-size:.68rem; }
.replay-stats { display:grid; grid-template-columns:1fr 1fr 1fr; gap:5px; }
.replay-stat { background:rgba(255,255,255,.025); border-radius:5px; padding:6px 8px; }
.replay-stat-label { font-size:.58rem; color:var(--muted); margin-bottom:1px; }
.replay-stat-val { font-size:.76rem; font-weight:600; font-family:var(--mono); }
/* =========================================================
PERSONAL / MY DASHBOARD (collapsible drawer)
========================================================= */
.my-drawer { margin-top: 20px; }
.my-drawer-toggle {
width:100%; padding:11px 16px; background:var(--card); border:1px solid var(--border);
border-radius:var(--r); color:var(--muted); font-size:.78rem; cursor:pointer;
display:flex; align-items:center; justify-content:space-between; font-family:var(--sans);
transition:border-color .18s;
}
.my-drawer-toggle:hover { border-color:var(--border-l); color:var(--text); }
.my-drawer-toggle .drawer-icon { transition:transform .25s; }
.my-drawer-toggle.open .drawer-icon { transform:rotate(180deg); }
.my-drawer-body { display:none; margin-top:8px; }
.my-drawer-body.open { display:block; }
/* =========================================================
SUBSCRIBE STRIP (compact)
========================================================= */
.subscribe-strip {
background: rgba(0,212,170,.05); border: 1px solid rgba(0,212,170,.15);
border-radius: var(--r); padding: 12px 16px;
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
margin-bottom: 16px;
}
.subscribe-strip-icon { font-size: 1.1rem; flex-shrink: 0; }
.subscribe-strip-body { flex: 1; min-width: 160px; }
.subscribe-strip-body strong { display:block; color:var(--accent); font-size:.82rem; }
.subscribe-strip-body span { font-size:.7rem; color:var(--muted); }
.subscribe-strip-actions { display:flex; gap:7px; flex-wrap:wrap; align-items:center; }
.btn-sub-email, .btn-sub-tg {
font-size:.72rem; padding:6px 12px; border-radius:var(--r); cursor:pointer;
display:flex; align-items:center; gap:5px; white-space:nowrap;
}
.btn-sub-email { background:rgba(0,212,170,.15); color:var(--accent); border:1px solid rgba(0,212,170,.3); }
.btn-sub-tg { background:rgba(79,195,247,.12); color:var(--neutral); border:1px solid rgba(79,195,247,.25); text-decoration:none; }
/* =========================================================
SIMPLE MODE
========================================================= */
body.simple-mode .card-secondary { display: none; }
body.simple-mode .news-item:not(.featured) { display: none; }
/* =========================================================
FAB CLUSTER
========================================================= */
.fab-cluster { position:fixed; bottom:20px; right:16px; display:flex; flex-direction:column; gap:8px; z-index:500; }
.fab { width:40px; height:40px; border-radius:50%; background:var(--card); border:1px solid var(--border); color:var(--text); font-size:1rem; cursor:pointer; display:flex; align-items:center; justify-content:center; transition:border-color .18s; box-shadow:0 4px 16px rgba(0,0,0,.4); }
.fab:hover { border-color:var(--border-l); }
#share-toast { position:fixed; bottom:70px; right:16px; background:var(--card); border:1px solid var(--border); border-radius:var(--r); padding:8px 14px; font-size:.75rem; color:var(--accent); display:none; z-index:600; }
@media(max-width:640px){ .fab-cluster { bottom:70px; } }
/* =========================================================
FOOTER
========================================================= */
.site-footer { border-top:1px solid var(--border); padding:20px 0; margin-top:20px; }
.footer-inner { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; font-size:.7rem; color:var(--muted); }
/* =========================================================
ANIMATIONS
========================================================= */
.sec-anchor { animation: fadeUp .3s ease both; }
@keyframes fadeUp { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:none} }
@media (max-width: 640px) {
.jump-nav { position:fixed; bottom:0; top:auto; left:0; right:0; border-bottom:none; border-top:1px solid var(--border); justify-content:space-around; padding-bottom:env(safe-area-inset-bottom); z-index:200; }
.jump-nav a { padding:7px 3px; font-size:.58rem; flex-direction:column; gap:1px; text-align:center; }
body { padding-bottom: 60px; }
}
/* =========================================================
TRADINGVIEW OVERRIDE
========================================================= */
.tradingview-widget-container { border-radius:var(--r); overflow:hidden; }
.section-block { margin-bottom: 16px; }
</style>
</head>
<body>
<div id="reading-progress"></div>
<!-- HEADER -->
<header class="site-header">
<div class="container">
<div class="header-inner">
<div class="logo-block">
<span class="site-title">金融日报</span>
<span class="site-sub">Financial Daily</span>
</div>
<div class="header-meta">
<span class="header-date" id="current-date">Loading...</span>
<div class="header-badge"><span class="pulse-dot"></span>Claude AI</div>
<nav class="header-nav">
<a href="archive/index.html">归档</a>
<a href="feed.xml" style="color:var(--dimmed)">RSS</a>
</nav>
</div>
</div>
</div>
</header>
<!-- NAV -->
<nav class="jump-nav" id="jump-nav">
<a href="#sec-summary">📊 大势</a>
<a href="#sec-ai-trading">🤖 AI操盘</a>
<a href="#sec-news">📰 要闻</a>
<a href="#sec-watchlist">🎯 AI分析</a>
<a href="#sec-macro">📈 宏观</a>
<a href="#sec-earnings">💼 财报</a>
<a href="#sec-sectors">🏭 行业</a>
<a href="#sec-debate">⚔️ 辩论</a>
<a href="#sec-calendar">📅 日历</a>
<a href="#sec-my">⭐ 我的</a>
</nav>
<!-- INDICES TICKER -->
<section class="indices-section">
<div class="indices-scroll-wrapper">
<div class="indices-track">
<!-- INDICES:START -->
<div class="ticker-card up">
<div class="ticker-name">标普500</div>
<div class="ticker-value">7,444.25</div>
<div class="ticker-change up">▲ +0.58%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">纳斯达克</div>
<div class="ticker-value">26,402.34</div>
<div class="ticker-change up">▲ +1.20%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">道琼斯</div>
<div class="ticker-value">49,693.19</div>
<div class="ticker-change down">▼ -0.14%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">上证综指</div>
<div class="ticker-value">4,242.57</div>
<div class="ticker-change up">▲ +0.16%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">恒生指数</div>
<div class="ticker-value">26,304.50</div>
<div class="ticker-change down">▼ -0.27%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">日经225</div>
<div class="ticker-value">63,272.11</div>
<div class="ticker-change up">▲ +0.84%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">德国DAX</div>
<div class="ticker-value">24,162.53</div>
<div class="ticker-change up">▲ +0.87%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">黄金现货</div>
<div class="ticker-value">$4,700</div>
<div class="ticker-change down">▼ -0.28%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">WTI原油</div>
<div class="ticker-value">$102.18</div>
<div class="ticker-change up">▲ +4.37%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">比特币</div>
<div class="ticker-value">$80,304</div>
<div class="ticker-change down">▼ -0.87%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">美元指数</div>
<div class="ticker-value">98.28</div>
<div class="ticker-change up">▲ +0.39%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">离岸人民币</div>
<div class="ticker-value">6.79</div>
<div class="ticker-change down">▼ -0.15%</div>
</div>
<!-- INDICES:END -->
<!-- INDICES:END -->
<!-- duplicate for seamless loop -->
<!-- INDICES:START -->
<div class="ticker-card up">
<div class="ticker-name">标普500</div>
<div class="ticker-value">7,444.25</div>
<div class="ticker-change up">▲ +0.58%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">纳斯达克</div>
<div class="ticker-value">26,402.34</div>
<div class="ticker-change up">▲ +1.20%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">道琼斯</div>
<div class="ticker-value">49,693.19</div>
<div class="ticker-change down">▼ -0.14%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">上证综指</div>
<div class="ticker-value">4,242.57</div>
<div class="ticker-change up">▲ +0.16%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">恒生指数</div>
<div class="ticker-value">26,304.50</div>
<div class="ticker-change down">▼ -0.27%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">日经225</div>
<div class="ticker-value">63,272.11</div>
<div class="ticker-change up">▲ +0.84%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">德国DAX</div>
<div class="ticker-value">24,162.53</div>
<div class="ticker-change up">▲ +0.87%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">黄金现货</div>
<div class="ticker-value">$4,700</div>
<div class="ticker-change down">▼ -0.28%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">WTI原油</div>
<div class="ticker-value">$102.18</div>
<div class="ticker-change up">▲ +4.37%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">比特币</div>
<div class="ticker-value">$80,304</div>
<div class="ticker-change down">▼ -0.87%</div>
</div>
<div class="ticker-card up">
<div class="ticker-name">美元指数</div>
<div class="ticker-value">98.28</div>
<div class="ticker-change up">▲ +0.39%</div>
</div>
<div class="ticker-card down">
<div class="ticker-name">离岸人民币</div>
<div class="ticker-value">6.79</div>
<div class="ticker-change down">▼ -0.15%</div>
</div>
<!-- INDICES:END -->
</div>
</div>
</section>
<!-- SUMMARY HERO -->
<section class="summary-section sec-anchor" id="sec-summary">
<div class="container">
<!-- SUMMARY:START -->
<div class="summary-card bullish">
<div class="summary-top">
<span class="sentiment-pill bullish">🟢 看多 · Bullish</span>
<span class="vix-badge">VIX <span class="vix-num">17.99</span></span>
</div>
<div class="summary-headline">科技股无视通胀创新高,标普纳指再破纪录</div>
<ul class="key-points"><li class="kp-item"><span class="kp-arrow"></span>科技股无视通胀刷新纪录</li><li class="kp-item"><span class="kp-arrow"></span>新任美联储主席就职</li><li class="kp-item"><span class="kp-arrow"></span>特朗普访华聚焦贸易</li></ul>
<details class="summary-details">
<summary class="summary-details-toggle">深度解读 ▸</summary>
<div class="summary-context">尽管4月CPI同比升至3.8%、PPI飙升至6%,但科技巨头带动纳指涨1.2%、标普涨0.58%双双刷新历史纪录。AI芯片股领涨,伊朗战争推高油价至102美元/桶,VIX仅17.99显示市场仍淡定。Kevin Warsh今日获参议院确认接任鲍威尔成为新任美联储主席,特朗普抵达北京与习近平会晤聚焦贸易与伊朗。对北美华人投资者:科技股ETF持续受益,但通胀超预期令年内降息无望,持有能源及防御性资产对冲风险。</div>
</details>
</div>
<!-- SUMMARY:END -->
<!-- SUMMARY:END -->
</div>
</section>
<!-- PODCAST PLAYER -->
<div class="podcast-bar" id="podcast-bar">
<div class="container">
<div class="podcast-inner">
<div class="podcast-left">
<span class="podcast-icon">🎙️</span>
<div class="podcast-info">
<div class="podcast-title">金融日报早报 · 今日播客</div>
<div class="podcast-sub" id="podcast-date">欣欣 & 建国 · 约3分钟</div>
</div>
</div>
<div class="podcast-controls">
<audio id="podcast-audio" preload="none">
<source src="audio/latest.mp3" type="audio/mpeg">
</audio>
<button class="pod-btn" id="pod-play" onclick="togglePodcast()">▶ 播放</button>
<div class="pod-progress-wrap" onclick="seekPodcast(event)">
<div class="pod-progress-bar" id="pod-progress"></div>
</div>
<span class="pod-time" id="pod-time">0:00</span>
<button class="pod-btn pod-btn-sm" onclick="document.getElementById('podcast-audio').playbackRate=document.getElementById('podcast-audio').playbackRate===1?1.5:1;this.textContent=document.getElementById('podcast-audio').playbackRate+'x'">1x</button>
<a class="pod-btn pod-btn-sm" href="audio/latest.mp3" download="金融日报早报.mp3" title="下载"></a>
</div>
</div>
</div>
</div>
<style>
.podcast-bar {
background: linear-gradient(90deg, rgba(0,212,170,.08), rgba(79,195,247,.05));
border-bottom: 1px solid rgba(0,212,170,.2);
padding: 10px 0;
}
.podcast-inner { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; }
.podcast-left { display:flex; align-items:center; gap:10px; }
.podcast-icon { font-size:1.4rem; animation: pulse-pod 3s ease-in-out infinite; }
@keyframes pulse-pod { 0%,100%{transform:scale(1)} 50%{transform:scale(1.1)} }
.podcast-title { font-size:.82rem; font-weight:600; color:var(--text); }
.podcast-sub { font-size:.65rem; color:var(--muted); font-family:var(--mono); margin-top:1px; }
.podcast-controls { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.pod-btn {
background: rgba(0,212,170,.15); color:var(--accent);
border: 1px solid rgba(0,212,170,.3); border-radius:6px;
padding: 5px 14px; font-size:.75rem; cursor:pointer;
font-family:var(--sans); transition:background .15s; white-space:nowrap;
}
.pod-btn:hover { background:rgba(0,212,170,.25); }
.pod-btn.playing { background:rgba(255,82,82,.12); color:var(--down); border-color:rgba(255,82,82,.3); }
.pod-btn-sm { padding:5px 9px; font-size:.68rem; }
.pod-btn-sm[download] { color:var(--muted); background:rgba(255,255,255,.05); border-color:var(--border); text-decoration:none; }
.pod-progress-wrap { width:160px; height:4px; background:var(--border); border-radius:2px; cursor:pointer; }
@media(max-width:640px){ .pod-progress-wrap { width:80px; } }
.pod-progress-bar { height:100%; background:var(--accent); border-radius:2px; width:0%; transition:width .3s linear; }
.pod-time { font-family:var(--mono); font-size:.65rem; color:var(--muted); min-width:32px; }
</style>
<script>
(function(){
var audio = document.getElementById('podcast-audio');
var btn = document.getElementById('pod-play');
var bar = document.getElementById('pod-progress');
var time = document.getElementById('pod-time');
if (!audio) return;
// Check if audio exists
fetch('audio/latest-meta.json').then(r=>r.json()).then(m=>{
document.getElementById('podcast-date').textContent = '欣欣 & 建国 · ' + m.date + ' · 约3分钟';
}).catch(()=>{
document.getElementById('podcast-bar').style.opacity = '0.4';
btn.textContent = '暂无音频';
btn.disabled = true;
});
audio.addEventListener('timeupdate', function(){
if (!audio.duration) return;
bar.style.width = (audio.currentTime / audio.duration * 100) + '%';
var m = Math.floor(audio.currentTime/60);
var s = Math.floor(audio.currentTime%60);
time.textContent = m + ':' + (s<10?'0':'')+s;
});
audio.addEventListener('ended', function(){
btn.textContent = '▶ 播放';
btn.classList.remove('playing');
bar.style.width = '0%';
});
window.togglePodcast = function(){
if (audio.paused) {
audio.play();
btn.textContent = '⏸ 暂停';
btn.classList.add('playing');
} else {
audio.pause();
btn.textContent = '▶ 播放';
btn.classList.remove('playing');
}
};
window.seekPodcast = function(e){
if (!audio.duration) return;
var rect = e.currentTarget.getBoundingClientRect();
audio.currentTime = ((e.clientX - rect.left) / rect.width) * audio.duration;
};
})();
</script>
<!-- MAIN PAGE BODY -->
<div class="page-body">
<div class="container">
<!-- SUBSCRIBE (dismissible) -->
<div class="subscribe-strip" id="subscribe-strip">
<div class="subscribe-strip-icon">📬</div>
<div class="subscribe-strip-body">
<strong>订阅每日金融早报</strong>
<span>每个交易日自动更新,开盘前 + 收盘后各一次</span>
</div>
<div class="subscribe-strip-actions">
<form action="https://buttondown.email/api/emails/embed-subscribe/yangbai0110" method="post" target="_blank" style="display:flex;gap:6px;">
<input type="email" name="email" placeholder="your@email.com" required style="padding:6px 10px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--text);font-size:.73rem;width:148px;outline:none;" />
<button type="submit" class="btn-sub-email">📧 邮件</button>
</form>
<a href="https://t.me/GGmanm_bot?start=subscribe" target="_blank" class="btn-sub-tg">
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.894 8.221-1.97 9.28c-.145.658-.537.818-1.084.508l-3-2.21-1.447 1.394c-.16.16-.295.295-.605.295l.213-3.053 5.56-5.023c.242-.213-.054-.333-.373-.12L7.44 13.55l-2.955-.924c-.643-.204-.657-.643.136-.953l11.566-4.461c.537-.194 1.006.131.707.009z"/></svg>
Telegram
</a>
<button onclick="document.getElementById('subscribe-strip').style.display='none';localStorage.setItem('fd_sub_dismissed','1');" style="background:none;border:none;color:var(--dimmed);cursor:pointer;font-size:1rem;padding:2px 4px;" title="关闭">×</button>
</div>
</div>
<!-- PRIMARY GRID: main content + sidebar -->
<div class="content-grid">
<!-- ── LEFT / MAIN COLUMN ─────────────────────────────── -->
<div class="main-col">
<!-- NEWS -->
<div class="section-block sec-anchor" id="sec-news">
<div class="card">
<div class="section-label">📰 市场要闻 · Market News</div>
<!-- NEWS:START -->
<div class="news-item breaking featured" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot breaking"></span>
<div class="news-title">特朗普抵京会晤习近平 科技巨头随行聚焦AI与贸易</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>特朗普访华谈贸易与伊朗,科技股若达成芯片出口松绑可能受益,但台湾军售悬而未决令地缘风险犹存</div>
<div class="news-body-collapse">美国总统特朗普今日抵达北京开启为期两天国事访问,随行包括苹果CEO库克、特斯拉CEO马斯克及英伟达CEO黄仁勋等16位商业领袖。会谈议题涵盖台湾军售、关税、AI管控及伊朗战争。特朗普称将与习近平'长谈'伊朗问题,但强调主要焦点仍是贸易。中国是伊朗最大贸易伙伴,霍尔木兹海峡封锁令全球能源危机加剧,华盛顿希望北京施压德黑兰重开航道。市场预期将公布大豆及波音订单协议。</div>
<div class="news-footer">
<span class="importance-badge breaking">🔥 BREAKING</span>
<div class="tags"><span class="tag">#中美关系</span><span class="tag">#贸易</span><span class="tag">#科技</span></div>
</div>
</div>
<div class="news-item breaking featured" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot breaking"></span>
<div class="news-title">通胀超预期:4月CPI飙至3.8% PPI年增6% 降息预期破灭</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>通胀失控侵蚀购买力,工薪阶层最受伤,今年别指望降息,固定收益类资产配置价值下降</div>
<div class="news-body-collapse">美国劳工部公布4月CPI同比上涨3.8%,高于预期的3.7%,创2023年5月以来最高;核心CPI月增0.4%、年增2.8%。生产者价格指数(PPI)月增1.4%、年增6%,远超预期的0.5%,创2022年以来最大涨幅。能源占CPI月增的40%,汽油价格年增28.4%至4.50美元/加仑。实际工资下降0.3%,这是三年来首次工资增长被通胀完全吞噬。CME FedWatch显示年内加息概率升至30%,降息预期彻底破灭。</div>
<div class="news-footer">
<span class="importance-badge breaking">🔥 BREAKING</span>
<div class="tags"><span class="tag">#通胀</span><span class="tag">#美联储</span><span class="tag">#经济数据</span></div>
</div>
</div>
<div class="news-item breaking featured" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot breaking"></span>
<div class="news-title">科技股无视通胀刷新纪录 纳指涨1.2%标普涨0.58%创历史新高</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>科技股'一股独大'格局延续,持有QQQ等科技ETF继续受益,但市场广度恶化暗示回调风险</div>
<div class="news-body-collapse">尽管通胀数据火热,标普500和纳斯达克周三双双创下收盘与盘中历史新高,分别收于7,444.25(+0.58%)和26,402.34(+1.20%)。芯片股领涨,英伟达涨2.5%,美光涨近5%。摩根士丹利将标普500年底目标价从7,800上调至8,000,认为伊朗战争影响已被定价。道指微跌0.14%至49,693.19,金融与通信股拖累。市场显示极端窄幅领涨:仅143只标普成分股上涨,中小盘股走势疲弱。</div>
<div class="news-footer">
<span class="importance-badge breaking">🔥 BREAKING</span>
<div class="tags"><span class="tag">#美股</span><span class="tag">#科技股</span><span class="tag">#AI</span></div>
</div>
</div>
<div class="news-item high" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot high"></span>
<div class="news-title">福特暴涨13% 推出储能子公司Ford Energy 电池业务单独上市</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>传统车企转型能源存储打开新增长曲线,关注清洁能源板块配置机会</div>
<div class="news-body-collapse">福特汽车周三收涨13.18%至13.57美元,成交量飙升265%。公司宣布成立电池储能子公司Ford Energy,摩根士丹利发布看好报告强调其盈利与合作潜力。这标志福特从传统车企向能源公司转型。相比之下,特斯拉涨1.5%,马斯克随特朗普访华,特斯拉中国推出新融资方案降低Model 3首付以对抗本土竞争对手。</div>
<div class="news-footer">
<span class="importance-badge high">• HIGH</span>
<div class="tags"><span class="tag">#汽车</span><span class="tag">#清洁能源</span></div>
</div>
</div>
<div class="news-item breaking" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot breaking"></span>
<div class="news-title">伊朗战争拖累和谈 油价飙升4.2%至102美元特朗普称停火'生命垂危'</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>油价破百美元推高生活成本,持有能源ETF(XLE)对冲通胀,但经济衰退风险上升需警惕</div>
<div class="news-body-collapse">特朗普拒绝伊朗和平提议,称霍尔木兹海峡主权等要求'完全不可接受',并形容当前停火'生命垂危'。WTI原油周二飙升4.2%至102.18美元/桶,布伦特原油涨3.4%至107.77美元。战争已持续超10周,全球20%石油贸易受阻。高盛警告供应缓冲正在耗尽,Shell CEO称全球可能因战争少产10亿桶原油。航空燃油价格年增20.7%,牛肉价格年增14.8%,供应链压力持续蔓延至食品。</div>
<div class="news-footer">
<span class="importance-badge breaking">🔥 BREAKING</span>
<div class="tags"><span class="tag">#原油</span><span class="tag">#地缘政治</span><span class="tag">#通胀</span></div>
</div>
</div>
<div class="news-item medium" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot medium"></span>
<div class="news-title">阿里巴巴Q4财报不及预期 AI投入拖累利润股价跌2%</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>中概科技股短期承压于AI投入,但长期AI变现值得关注,波动中寻找配置时机</div>
<div class="news-body-collapse">阿里巴巴第四财季营收未达华尔街预期,AI基础设施、云扩张及一小时达业务的重投入拖累盈利。云收入年增38%至61.3亿美元符合预期。公司将AI业务从云计算分拆,成立'阿里巴巴Token Hub'CEO吴泳铭亲自挂帅力图将AI投资转化为盈利。股价盘前跌近2%。</div>
<div class="news-footer">
<span class="importance-badge medium">• MEDIUM</span>
<div class="tags"><span class="tag">#中概股</span><span class="tag">#财报</span><span class="tag">#AI</span></div>
</div>
</div>
<div class="news-item medium" onclick="toggleNews(this)">
<div class="news-header">
<span class="imp-dot medium"></span>
<div class="news-title">A股缩量震荡 沪指微涨0.16% 半导体设备股强者恒强</div>
<span class="news-expand-icon"></span>
</div>
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>A股量能萎缩显示观望情绪浓厚,建议聚焦半导体国产替代及新能源等政策支持板块</div>
<div class="news-body-collapse">周三A股震荡整理,沪指收涨0.16%报4,242.57点,深成指跌0.25%,创业板指跌0.47%。两市成交3.2万亿缩量,北向资金净流出12亿。半导体设备、电力电网设备逆势走强,中际旭创股价突破千元。全市场超4000股飘绿,市场分化明显。分析师指出在全球通胀和美联储鹰派背景下,A股外资流出压力加大。</div>
<div class="news-footer">
<span class="importance-badge medium">• MEDIUM</span>
<div class="tags"><span class="tag">#A股</span><span class="tag">#半导体</span></div>
</div>
</div>
<!-- NEWS:END -->
<!-- NEWS:END -->
</div>
</div>
<!-- AI 操盘实验 -->
<div class="section-block sec-anchor" id="sec-ai-trading">
<div class="card">
<div class="section-label">🤖 AI 操盘实验 · AI Trading Challenge</div>
<div id="ai-portfolio-loading" style="color:var(--muted);font-size:0.82rem;padding:8px 0;">加载中…</div>
<div id="ai-portfolio-content" style="display:none">
<!-- 排行榜 -->
<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:10px;">🏆 排行榜 · Leaderboard <span style="font-size:0.68rem;color:var(--dimmed);margin-left:6px;">初始资金 $10,000 · 基线 SPY买入持有</span></div>
<div id="ai-leaderboard" style="display:flex;flex-direction:column;gap:8px;margin-bottom:18px;"></div>
<!-- 各模型详情 Tab -->
<div style="display:flex;gap:6px;margin-bottom:12px;" id="ai-model-tabs"></div>
<div id="ai-model-detail"></div>
<!-- 历史对比表 -->
<div id="ai-history-wrap" style="margin-top:16px;">
<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:8px;">📈 历史表现对比</div>
<div id="ai-history-table" style="font-family:var(--mono);font-size:0.76rem;"></div>
</div>
</div>
</div>
</div>
<!-- AI WATCHLIST -->
<section class="section-block sec-anchor" id="sec-watchlist">
<div class="card">
<div class="section-label">🎯 AI 决策仪表盘 · AI Watchlist</div>
<!-- WATCHLIST_ANALYSIS:START -->
<div class="watchlist-grid">
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">NVDA</div><div class="wc-name">英伟达</div></div>
<div class="wc-price"><div class="wc-price-val">890.50</div><div class="wc-price-chg up">+2.5%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge BUY">BUY</span>
<span class="wc-score">评分 <span>88</span>/100</span>
</div>
<div class="wc-conclusion">AI霸主地位无可撼动,Blackwell订单超5000亿</div>
<div class="wc-driver">黄仁勋随特朗普访华,对华高端芯片出口限制有望松绑,Rubin架构技术领先可维持溢价定价</div>
<div class="wc-targets"><span class="wc-target-up">↑ 950</span><span class="wc-target-down">↓ 820</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
<div class="wc-action">回调至850美元附近可加仓,5/21财报前注意获利了结部分仓位对冲波动风险</div>
<div class="tags" style="margin-top:8px"><span class="tag">#AI</span><span class="tag">#半导体</span><span class="tag">#增长</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">QQQ</div><div class="wc-name">纳斯达克100 ETF</div></div>
<div class="wc-price"><div class="wc-price-val">520.30</div><div class="wc-price-chg up">+1.1%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge HOLD">HOLD</span>
<span class="wc-score">评分 <span>72</span>/100</span>
</div>
<div class="wc-conclusion">科技股集中度风险加剧,但AI周期未结束</div>
<div class="wc-driver">前10大持仓占比超50%,市场广度恶化但AI基础设施投入仍处上升期,沃什就职令政策不确定性上升</div>
<div class="wc-targets"><span class="wc-target-up">↑ 550</span><span class="wc-target-down">↓ 480</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
<div class="wc-action">持有为主,VIX低于18显示波动率被低估,建议配置5-10%看跌期权对冲</div>
<div class="tags" style="margin-top:8px"><span class="tag">#科技</span><span class="tag">#ETF</span><span class="tag">#波动</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">SPY</div><div class="wc-name">标普500 ETF</div></div>
<div class="wc-price"><div class="wc-price-val">744.50</div><div class="wc-price-chg up">+0.6%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge HOLD">HOLD</span>
<span class="wc-score">评分 <span>68</span>/100</span>
</div>
<div class="wc-conclusion">估值偏高但盈利增速支撑,利率风险是最大变量</div>
<div class="wc-driver">Q1盈利增速27%创2021年来最高,但远期市盈率20.9倍高于10年均值18.9倍,10年期国债破4.5%是估值承压拐点</div>
<div class="wc-targets"><span class="wc-target-up">↑ 780</span><span class="wc-target-down">↓ 700</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
<div class="wc-action">标配持有,若国债收益率突破4.7%需减仓至低配,关注金融与公用事业板块轮动机会</div>
<div class="tags" style="margin-top:8px"><span class="tag">#大盘</span><span class="tag">#ETF</span><span class="tag">#估值</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">BTC-USD</div><div class="wc-name">比特币</div></div>
<div class="wc-price"><div class="wc-price-val">80,304</div><div class="wc-price-chg down">-0.9%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge SELL">SELL</span>
<span class="wc-score">评分 <span>38</span>/100</span>
</div>
<div class="wc-conclusion">跌破关键支撑,技术面转弱宏观逆风加剧</div>
<div class="wc-driver">失守82,000美元阻力后回落,实际利率上升与美元走强双重打击,铜金比突破200日均线暗示比特币或跟随大宗商品走弱</div>
<div class="wc-targets"><span class="wc-target-up">↑ 85,000</span><span class="wc-target-down">↓ 72,000</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge high">风险:high</span></div>
<div class="wc-action">建议减持至5%以下仓位,若跌破75,000需止损,等待49,000-58,000区间再布局</div>
<div class="tags" style="margin-top:8px"><span class="tag">#加密货币</span><span class="tag">#风险</span><span class="tag">#宏观</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">510300.SS</div><div class="wc-name">沪深300 ETF</div></div>
<div class="wc-price"><div class="wc-price-val">4.15</div><div class="wc-price-chg up">+0.3%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge HOLD">HOLD</span>
<span class="wc-score">评分 <span>58</span>/100</span>
</div>
<div class="wc-conclusion">政策底已现但市场底未明,量能萎缩显示信心不足</div>
<div class="wc-driver">两市成交3.2万亿缩量,北向资金持续流出,但半导体国产替代与新能源政策支持力度不减,特朗普访华结果影响外资情绪</div>
<div class="wc-targets"><span class="wc-target-up">↑ 4.50</span><span class="wc-target-down">↓ 3.80</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
<div class="wc-action">维持中性配置,聚焦半导体设备、电力电网等高景气细分赛道,等待放量突破再加仓</div>
<div class="tags" style="margin-top:8px"><span class="tag">#A股</span><span class="tag">#ETF</span><span class="tag">#政策</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">GC=F</div><div class="wc-name">黄金期货</div></div>
<div class="wc-price"><div class="wc-price-val">4,700</div><div class="wc-price-chg down">-0.3%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge BUY">BUY</span>
<span class="wc-score">评分 <span>75</span>/100</span>
</div>
<div class="wc-conclusion">短期调整是加仓良机,地缘与通胀双重支撑</div>
<div class="wc-driver">美元走强与实际利率上升压制金价,但伊朗战争悬而未决、央行购金趋势未变,印度上调黄金关税反而暗示需求旺盛</div>
<div class="wc-targets"><span class="wc-target-up">↑ 5,200</span><span class="wc-target-down">↓ 4,400</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge low">风险:low</span></div>
<div class="wc-action">回调至4,600美元下方分批买入,配置5-10%作为通胀与地缘风险对冲</div>
<div class="tags" style="margin-top:8px"><span class="tag">#黄金</span><span class="tag">#避险</span><span class="tag">#通胀对冲</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">CL=F</div><div class="wc-name">WTI原油期货</div></div>
<div class="wc-price"><div class="wc-price-val">102.18</div><div class="wc-price-chg up">+4.2%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge HOLD">HOLD</span>
<span class="wc-score">评分 <span>70</span>/100</span>
</div>
<div class="wc-conclusion">战争溢价高企但和谈传闻令波动加剧</div>
<div class="wc-driver">霍尔木兹海峡封锁令全球20%石油贸易受阻,Shell警告供应缓冲耗尽,但特朗普-习近平会谈若取得进展油价或暴跌10%</div>
<div class="wc-targets"><span class="wc-target-up">↑ 118</span><span class="wc-target-down">↓ 85</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge high">风险:high</span></div>
<div class="wc-action">持有能源股ETF(XLE)而非原油期货,波动率过高不适合激进追涨,和谈破裂再加仓</div>
<div class="tags" style="margin-top:8px"><span class="tag">#原油</span><span class="tag">#地缘</span><span class="tag">#通胀</span></div>
</div>
<div class="watchlist-card">
<div class="wc-header">
<div><div class="wc-ticker">TSLA</div><div class="wc-name">特斯拉</div></div>
<div class="wc-price"><div class="wc-price-val">225.80</div><div class="wc-price-chg up">+1.5%</div></div>
</div>
<div class="wc-signal-row">
<span class="signal-badge HOLD">HOLD</span>
<span class="wc-score">评分 <span>55</span>/100</span>
</div>
<div class="wc-conclusion">马斯克访华提振情绪,但基本面仍待改善</div>
<div class="wc-driver">随特朗普访华暗示中国政策松绑,推出低首付融资方案对抗本土竞争,但Q1交付量下滑8.6%、xAI投资引发治理担忧</div>
<div class="wc-targets"><span class="wc-target-up">↑ 280</span><span class="wc-target-down">↓ 180</span></div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge high">风险:high</span></div>
<div class="wc-action">暂持有观望,若中国市场份额回升可加仓,但需警惕马斯克政治风险与FSD监管不确定性</div>
<div class="tags" style="margin-top:8px"><span class="tag">#电动车</span><span class="tag">#中国</span><span class="tag">#成长</span></div>
</div>
</div>
<!-- WATCHLIST_ANALYSIS:END -->
<!-- WATCHLIST_ANALYSIS:END -->
</div>
</section>
<!-- MACRO + DEBATE (2-up) -->
<div class="two-up">
<div class="section-block sec-anchor" id="sec-macro">
<div class="card" style="height:100%">
<div class="section-label">📈 宏观指标 · Macro</div>
<!-- MACRO:START -->
<div class="macro-grid">
<div class="macro-card dir-up">
<div class="macro-indicator">CPI YoY (4月)</div>
<div class="macro-value macro-value-down">3.8%</div>
<div class="macro-prev"><span class="arrow up"></span> 前值: 3.3%</div>
<div class="macro-desc">消费者价格指数创近三年新高,能源占月增40%,实际工资负增长</div>
</div>
<div class="macro-card dir-up">
<div class="macro-indicator">Core CPI YoY (4月)</div>
<div class="macro-value macro-value-down">2.8%</div>
<div class="macro-prev"><span class="arrow up"></span> 前值: 2.6%</div>
<div class="macro-desc">核心通胀月增0.4%,住房租金因去年政府关门统计扭曲而跳涨0.6%</div>
</div>
<div class="macro-card dir-up">
<div class="macro-indicator">PPI YoY (4月)</div>
<div class="macro-value macro-value-down">6.0%</div>
<div class="macro-prev"><span class="arrow up"></span> 前值: 4.0%</div>
<div class="macro-desc">生产者价格指数年增6%创2022年以来最高,批发通胀失控</div>
</div>
<div class="macro-card dir-up">
<div class="macro-indicator">PPI MoM (4月)</div>
<div class="macro-value macro-value-down">1.4%</div>
<div class="macro-prev"><span class="arrow up"></span> 前值: 0.5%</div>
<div class="macro-desc">月增1.4%远超预期0.5%,汽油价格跳涨15.7%为主因</div>
</div>
<div class="macro-card dir-up">
<div class="macro-indicator">10年期美债收益率</div>
<div class="macro-value macro-value-up">4.47%</div>
<div class="macro-prev"><span class="arrow up"></span> 前值: 4.27%</div>
<div class="macro-desc">升至2025年7月以来新高,30年期破5%创2025年5月来首次</div>
</div>
<div class="macro-card dir-down">
<div class="macro-indicator">实际平均时薪 YoY</div>
<div class="macro-value macro-value-down">-0.3%</div>
<div class="macro-prev"><span class="arrow down"></span> 前值: +0.2%</div>
<div class="macro-desc">三年来首次工资增长被通胀完全吞噬,中低收入家庭财务压力加剧</div>
</div>
<div class="macro-card dir-down">
<div class="macro-indicator">密歇根消费者信心指数(5月初)</div>
<div class="macro-value macro-value-down">48.2</div>
<div class="macro-prev"><span class="arrow down"></span> 前值: 49.9</div>
<div class="macro-desc">创历史新低,油价飙升令消费者信心受重创</div>
</div>
<div class="macro-card dir-up">
<div class="macro-indicator">美元指数 DXY</div>
<div class="macro-value macro-value-up">98.28</div>
<div class="macro-prev"><span class="arrow up"></span> 前值: 97.84</div>
<div class="macro-desc">因通胀高企降息预期破灭而走强,但仍较3月伊朗战争高点103回落</div>
</div>
</div>
<!-- MACRO:END -->
<!-- MACRO:END -->
</div>
</div>
<div class="section-block sec-anchor" id="sec-debate">
<div class="card" style="height:100%">
<div class="section-label">⚔️ 多空辩论 · Bull vs Bear</div>
<!-- MARKET_DEBATE:START -->
<div class="debate-container">
<div class="debate-header">标普500 本周展望</div>
<div class="debate-sides">
<div class="debate-side bull">
<div class="debate-side-title">🐂 多方看涨</div>
<div class="debate-point"><span class="conf-badge high">high</span>Q1盈利增速27%创三年新高,企业盈利超预期18%</div>
<div class="debate-point"><span class="conf-badge high">high</span>AI资本开支7250亿美元超预期,科技股基本面扎实</div>
<div class="debate-point"><span class="conf-badge medium">medium</span>摩根士丹利上调年底目标至8000点,伊朗风险已定价</div>
</div>
<div class="debate-side bear">
<div class="debate-side-title">🐻 空方看跌</div>
<div class="debate-point"><span class="conf-badge high">high</span>通胀失控令降息无望,30%概率年内加息侵蚀估值</div>
<div class="debate-point"><span class="conf-badge high">high</span>市场广度恶化仅143只成分股上涨,'一股独大'难持续</div>
<div class="debate-point"><span class="conf-badge medium">medium</span>10年期国债破4.5%临界点,实际利率上升压制股票吸引力</div>
</div>
</div>
<div class="debate-verdict">
<div class="verdict-label">裁判结论 <span class="verdict-lean bullish">BULLISH</span></div>
<div class="verdict-text">短期多头占优但需警惕6月FOMC,科技股盈利支撑估值但利率是达摩克利斯之剑。建议持有QQQ但配置5-10%看跌期权,若10年期国债破4.7%或VIX升破22需果断减仓</div>
</div>
</div>
<!-- MARKET_DEBATE:END -->
<!-- MARKET_DEBATE:END -->
</div>
</div>
</div>
<!-- EARNINGS + SECTORS (2-up) -->
<div class="two-up">
<div class="section-block sec-anchor" id="sec-earnings">
<div class="card">
<div class="section-label">💼 财报追踪 · Earnings</div>
<!-- EARNINGS:START -->
<div class="earnings-grid">
<div class="earnings-card beat">
<div class="earnings-ticker">AAPL</div>
<div class="earnings-company">Apple</div>
<span class="earnings-beat-badge beat">BEAT ✓</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual beat">$2.01</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$1.95</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$111.2B</span></div>
<div class="earnings-highlight">Q1财报超预期,服务收入创新高,供应受限但AI iPhone需求强劲</div>
</div>
<div class="earnings-card beat">
<div class="earnings-ticker">MSFT</div>
<div class="earnings-company">Microsoft</div>
<span class="earnings-beat-badge beat">BEAT ✓</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual beat">$4.27</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$4.06</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$82.9B</span></div>
<div class="earnings-highlight">Azure增长稳健,AI资本开支升至990亿美元,运营利润率收窄至67%</div>
</div>
<div class="earnings-card pending">
<div class="earnings-ticker">NVDA</div>
<div class="earnings-company">Nvidia</div>
<span class="earnings-beat-badge pending">UPCOMING</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$预计6.20</div>
</div>
<div class="eps-item">
<div class="eps-label">REPORT DATE</div>
<div class="eps-value est" style="font-size:0.75rem;">2026-05-28</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>预计$350B</span></div>
<div class="earnings-highlight">Blackwell与Rubin订单超5000亿美元,黄仁勋随特朗普访华暗示对华出口松绑</div>
</div>
<div class="earnings-card miss">
<div class="earnings-ticker">TSLA</div>
<div class="earnings-company">Tesla</div>
<span class="earnings-beat-badge miss">MISS ✗</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual miss">$0.42</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$0.51</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$21.3B</span></div>
<div class="earnings-highlight">Q1交付量下滑,能源业务增长但汽车业务承压,xAI投资引发利益冲突担忧</div>
</div>
<div class="earnings-card miss">
<div class="earnings-ticker">BABA</div>
<div class="earnings-company">Alibaba</div>
<span class="earnings-beat-badge miss">MISS ✗</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual miss">$1.18</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$1.25</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$30.1B</span></div>
<div class="earnings-highlight">Q4营收不及预期,AI与云扩张投入拖累,云收入增38%至61.3亿美元</div>
</div>
<div class="earnings-card beat">
<div class="earnings-ticker">F</div>
<div class="earnings-company">Ford</div>
<span class="earnings-beat-badge beat">BEAT ✓</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual beat">$0.58</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$0.52</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$42.8B</span></div>
<div class="earnings-highlight">Q1超预期,推出Ford Energy储能子公司,摩根士丹利看好能源转型</div>
</div>
<div class="earnings-card beat">
<div class="earnings-ticker">SNDK</div>
<div class="earnings-company">SanDisk</div>
<span class="earnings-beat-badge beat">BEAT ✓</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual beat">$23.41</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$14.62</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$5.95B</span></div>
<div class="earnings-highlight">大幅超预期,AI数据中心存储需求爆发</div>
</div>
<div class="earnings-card beat">
<div class="earnings-ticker">INTC</div>
<div class="earnings-company">Intel</div>
<span class="earnings-beat-badge beat">BEAT ✓</span>
<div class="earnings-eps">
<div class="eps-item">
<div class="eps-label">EPS ACTUAL</div>
<div class="eps-value actual beat">$0.29</div>
</div>
<div class="eps-item">
<div class="eps-label">EPS EST.</div>
<div class="eps-value est">$0.02</div>
</div>
</div>
<div class="earnings-revenue">收入: <span>$13.6B</span></div>
<div class="earnings-highlight">扭亏为盈超预期,代工业务回暖但仍落后台积电</div>
</div>
</div>
<!-- EARNINGS:END -->
<!-- EARNINGS:END -->
</div>
</div>
<div class="section-block sec-anchor" id="sec-sectors">
<div class="card">
<div class="section-label">🏭 板块表现 · Sectors</div>
<!-- SECTORS:START -->
<div class="sectors-list">
<div class="sector-row">
<div><div class="sector-name">通信服务</div><div class="sector-name-en">Communication Services</div></div>
<div class="sector-etf">XLC</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:100%"></div></div>
<div class="sector-pct up">+2.65%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">信息技术</div><div class="sector-name-en">Information Technology</div></div>
<div class="sector-etf">XLK</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:43%"></div></div>
<div class="sector-pct up">+0.98%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">非必需消费</div><div class="sector-name-en">Consumer Discretionary</div></div>
<div class="sector-etf">XLY</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:35%"></div></div>
<div class="sector-pct up">+0.75%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">工业</div><div class="sector-name-en">Industrials</div></div>
<div class="sector-etf">XLI</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:54%"></div></div>
<div class="sector-pct up">+1.30%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">材料</div><div class="sector-name-en">Materials</div></div>
<div class="sector-etf">XLB</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:54%"></div></div>
<div class="sector-pct up">+1.30%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">能源</div><div class="sector-name-en">Energy</div></div>
<div class="sector-etf">XLE</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:98%"></div></div>
<div class="sector-pct up">+2.60%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">金融</div><div class="sector-name-en">Financials</div></div>
<div class="sector-etf">XLF</div>
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:46%"></div></div>
<div class="sector-pct down">-1.07%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">医疗</div><div class="sector-name-en">Health Care</div></div>
<div class="sector-etf">XLV</div>
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:24%"></div></div>
<div class="sector-pct up">+0.42%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">房地产</div><div class="sector-name-en">Real Estate</div></div>
<div class="sector-etf">XLRE</div>
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:40%"></div></div>
<div class="sector-pct down">-0.90%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">公用事业</div><div class="sector-name-en">Utilities</div></div>
<div class="sector-etf">XLU</div>
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:52%"></div></div>
<div class="sector-pct down">-1.26%</div>
</div>
<div class="sector-row">
<div><div class="sector-name">必需消费</div><div class="sector-name-en">Consumer Staples</div></div>
<div class="sector-etf">XLP</div>
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:43%"></div></div>
<div class="sector-pct down">-1.00%</div>
</div>
</div>
<!-- SECTORS:END -->
<!-- SECTORS:END -->
</div>
</div>
</div>
<!-- REPLAY + CALENDAR (2-up) -->
<div class="two-up">
<div class="section-block sec-anchor" id="sec-replay">
<div class="card">
<div class="section-label">📽️ 大盘复盘 · Replay</div>
<!-- MARKET_REPLAY:START -->
<div class="replay-grid"><div class="replay-card">
<div class="replay-card-title">🇺🇸 美股</div>
<div class="replay-summary">科技股一骑绝尘但市场广度恶化,通胀数据未撼动AI信仰</div>
<div class="ad-bar-wrap">
<span class="ad-label-up">↑678</span>
<div class="ad-bar adv" style="width:36px;max-width:80px"></div>
<div class="ad-bar dec" style="width:64px;max-width:80px"></div>
<span class="ad-label-dn">↓1210</span>
</div>
<div class="replay-stats">
<div class="replay-stat"><div class="replay-stat-label">热门板块</div><div class="replay-stat-val">通信服务+2.65%</div></div>
<div class="replay-stat"><div class="replay-stat-label">领涨标的</div><div class="replay-stat-val">Ford F +13.18% (储能业务)</div></div>
<div class="replay-stat"><div class="replay-stat-label">创52周新高</div><div class="replay-stat-val">82</div></div>
</div>
</div><div class="replay-card">
<div class="replay-card-title">🇨🇳 A股</div>
<div class="replay-summary">缩量震荡显示观望浓厚,国产替代主线坚挺</div>
<div class="ad-bar-wrap">
<span class="ad-label-up">↑2100</span>
<div class="ad-bar adv" style="width:42px;max-width:80px"></div>
<div class="ad-bar dec" style="width:58px;max-width:80px"></div>
<span class="ad-label-dn">↓2900</span>
</div>
<div class="replay-stats">
<div class="replay-stat"><div class="replay-stat-label">热门板块</div><div class="replay-stat-val">半导体设备</div></div>
<div class="replay-stat"><div class="replay-stat-label">领涨标的</div><div class="replay-stat-val">中际旭创 突破千元</div></div>
<div class="replay-stat"><div class="replay-stat-label">北向资金</div><div class="replay-stat-val">-12亿</div></div>
</div>
</div></div>
<!-- MARKET_REPLAY:END -->
<!-- MARKET_REPLAY:END -->
</div>
</div>
<div class="section-block sec-anchor" id="sec-calendar">
<div class="card">
<div class="section-label">📅 本周日程 · Calendar</div>
<!-- CALENDAR:START -->
<div class="calendar-grid">
<div class="cal-item high">
<div class="cal-date">周四 5/14<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
<div>
<div class="cal-event">零售销售月率</div>
<div class="cal-values">预期: <span>+0.3%</span> &nbsp;&middot;&nbsp; 前值: +0.1%</div>
</div>
</div>
<div class="cal-item medium">
<div class="cal-date">周四 5/14<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
<div>
<div class="cal-event">初请失业金人数</div>
<div class="cal-values">预期: <span>225K</span> &nbsp;&middot;&nbsp; 前值: 223K</div>
</div>
</div>
<div class="cal-item high">
<div class="cal-date">周五 5/15<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
<div>
<div class="cal-event">Kevin Warsh正式就职美联储主席</div>
<div class="cal-values">预期: <span>N/A</span> &nbsp;&middot;&nbsp; 前值: N/A</div>
</div>
</div>
<div class="cal-item medium">
<div class="cal-date">周五 5/15<br><span style="font-size:0.6rem;color:var(--dimmed)">9:45 AM ET</span></div>
<div>
<div class="cal-event">5月Markit制造业PMI初值</div>
<div class="cal-values">预期: <span>51.5</span> &nbsp;&middot;&nbsp; 前值: 51.2</div>
</div>
</div>
<div class="cal-item medium">
<div class="cal-date">周六-周日 5/17-5/18<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
<div>
<div class="cal-event">G7财长会议(意大利)</div>
<div class="cal-values">预期: <span>讨论伊朗制裁与能源危机</span> &nbsp;&middot;&nbsp; 前值: N/A</div>
</div>
</div>
<div class="cal-item high">
<div class="cal-date">周一 5/19<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
<div>
<div class="cal-event">特朗普-习近平会谈成果公布</div>
<div class="cal-values">预期: <span>关注贸易协议与台湾军售</span> &nbsp;&middot;&nbsp; 前值: N/A</div>
</div>
</div>
<div class="cal-item high">
<div class="cal-date">周二 5/20<br><span style="font-size:0.6rem;color:var(--dimmed)">2:00 PM ET</span></div>
<div>
<div class="cal-event">4月FOMC会议纪要公布</div>
<div class="cal-values">预期: <span>解读8-4分裂投票细节</span> &nbsp;&middot;&nbsp; 前值: N/A</div>
</div>
</div>
<div class="cal-item high">
<div class="cal-date">周三 5/21<br><span style="font-size:0.6rem;color:var(--dimmed)">盘后</span></div>
<div>
<div class="cal-event">Nvidia Q1财报</div>
<div class="cal-values">预期: <span>EPS $6.20</span> &nbsp;&middot;&nbsp; 前值: EPS $5.16</div>
</div>
</div>
</div>
<!-- CALENDAR:END -->
<!-- CALENDAR:END -->
</div>
</div>
</div>
</div><!-- end main-col -->
<!-- ── RIGHT / SIDEBAR ────────────────────────────────── -->
<div class="sidebar-col">
<!-- LEADERS -->
<div class="section-block sec-anchor mb16" id="sec-leaders">
<div class="card">
<div class="section-label">👔 领袖观点 · Leaders</div>
<!-- LEADERS:START -->
<div class="leader-card">
<div class="leader-header">
<div class="leader-avatar jd">JD</div>
<div class="leader-meta">
<div class="leader-name">杰米·戴蒙 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Jamie Dimon</span></div>
<div class="leader-role">摩根大通CEO</div>
</div>
<div class="leader-date">4月11日</div>
</div>
<div class="leader-quote">"利率对几乎所有资产价格都像地心引力一样"</div>
<div class="leader-body">戴蒙在2026年致股东信中重申巴菲特26年前的警告,强调通胀升温将导致利率走高,进而对资产估值施加向下压力。他警告当前经济环境可能导致利率长期维持高位,即便没有衰退,持续的通胀也会成为'派对上的臭鼬'。这番言论与伊朗战争推高能源成本的背景高度契合。</div>
<div class="tags"><span class="tag">#利率</span><span class="tag">#通胀</span></div>
</div>
<div class="leader-card">
<div class="leader-header">
<div class="leader-avatar default">KW</div>
<div class="leader-meta">
<div class="leader-name">凯文·沃什 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Kevin Warsh</span></div>
<div class="leader-role">新任美联储主席</div>
</div>
<div class="leader-date">5月13日</div>
</div>
<div class="leader-quote">"央行需要政权更迭"</div>
<div class="leader-body">沃什今日以54-45票获参议院确认,将于周五接替鲍威尔成为第17任美联储主席,这是史上最分裂的美联储主席投票。他此前曾批评QE规模过大,主张缩表并警告通胀风险。尽管特朗普期待降息,但4月CPI飙升至3.8%令沃什面临两难:降息可能加剧通胀,不降则激怒白宫。首次FOMC会议定于6月16-17日。</div>
<div class="tags"><span class="tag">#美联储</span><span class="tag">#政策</span></div>
</div>
<div class="leader-card">
<div class="leader-header">
<div class="leader-avatar wb">WB</div>
<div class="leader-meta">
<div class="leader-name">沃伦·巴菲特 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Warren Buffett</span></div>
<div class="leader-role">伯克希尔哈撒韦董事长</div>
</div>
<div class="leader-date">5月初</div>
</div>
<div class="leader-quote">"只有当潮水退去时,你才会知道谁在裸泳"</div>
<div class="leader-body">巴菲特在伯克希尔年会上重申利率是影响投资回报的最重要因素,这句26年前的名言被戴蒙引用警示当前市场。巴菲特强调在高利率环境下,投资者对回报的预期需要降低,否则只能以更低价格买入股票。他表示在5月卸任CEO后将保持低调,专注长期价值投资。</div>
<div class="tags"><span class="tag">#价值投资</span><span class="tag">#利率</span></div>
</div>
<div class="leader-card">
<div class="leader-header">
<div class="leader-avatar jp">JP</div>
<div class="leader-meta">
<div class="leader-name">杰罗姆·鲍威尔 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Jerome Powell</span></div>
<div class="leader-role">卸任美联储主席</div>
</div>
<div class="leader-date">4月29日</div>
</div>
<div class="leader-quote">"我将留任理事直到调查彻底结束"</div>
<div class="leader-body">鲍威尔任期将于5月15日到期,但他宣布将罕见地留任理事至2028年,直到司法部对美联储总部装修的调查完全结束。他在4月FOMC会议上指出通胀预期中值升至2.7%,远高于2%目标。鲍威尔强调将保持低调,'只有一位美联储主席,当沃什确认就职后,他就是主席'。这是近80年来首次前主席留任理事。</div>
<div class="tags"><span class="tag">#美联储</span><span class="tag">#政策</span></div>
</div>
<!-- LEADERS:END -->
<!-- LEADERS:END -->
</div>
</div>
<!-- CENTRAL BANKS -->
<div class="section-block sec-anchor mb16" id="sec-banks">
<div class="card">
<div class="section-label">🏦 央行动态 · Central Banks</div>
<!-- CENTRAL_BANKS:START -->
<div class="cb-grid">
<div class="cb-card">
<div class="cb-header">
<div>
<div class="cb-name">美联储</div>
<div class="cb-name-en">Federal Reserve</div>
</div>
<span class="bias-badge hawkish">Hawkish</span>
</div>
<div class="cb-rate">3.50-3.75%</div>
<div class="cb-action">维持利率3.50-3.75%不变,4月会议8-4分裂投票创1992年来最大分歧</div>
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-16</span></div>
<div class="cb-note">Kevin Warsh今日确认就职,鲍威尔留任理事。通胀飙升令年内降息无望,30%概率加息</div>
</div>
<div class="cb-card">
<div class="cb-header">
<div>
<div class="cb-name">欧洲央行</div>
<div class="cb-name-en">European Central Bank</div>
</div>
<span class="bias-badge neutral">Neutral</span>
</div>
<div class="cb-rate">2.00%</div>
<div class="cb-action">维持存款利率2.00%不变,降息周期已结束</div>
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-12</span></div>
<div class="cb-note">ECB认为已达'好地方':通胀接近2%且增长为正,除非出现意外否则不会进一步降息</div>
</div>
<div class="cb-card">
<div class="cb-header">
<div>
<div class="cb-name">中国人民银行</div>
<div class="cb-name-en">People's Bank of China</div>
</div>
<span class="bias-badge dovish">Dovish</span>
</div>
<div class="cb-rate">1年期LPR 3.45%</div>
<div class="cb-action">维持LPR利率不变,但通过公开市场操作注入流动性</div>
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-20</span></div>
<div class="cb-note">预计年内降息20bp、降准100bp支持经济,特朗普访华可能影响货币政策节奏</div>
</div>
<div class="cb-card">
<div class="cb-header">
<div>
<div class="cb-name">日本央行</div>
<div class="cb-name-en">Bank of Japan</div>
</div>
<span class="bias-badge hawkish">Hawkish</span>
</div>
<div class="cb-rate">0.75%</div>
<div class="cb-action">4月维持短期政策利率0.75%不变,6-3投票3人主张加息至1.0%</div>
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-13</span></div>
<div class="cb-note">上调2026财年核心通胀预期至2.8%,因油价上涨。多位委员支持尽快加息防通胀超调</div>
</div>
<div class="cb-card">
<div class="cb-header">
<div>
<div class="cb-name">英国央行</div>
<div class="cb-name-en">Bank of England</div>
</div>
<span class="bias-badge hawkish">Hawkish</span>
</div>
<div class="cb-rate">3.75%</div>
<div class="cb-action">4月维持利率3.75%不变,8-1投票首席经济学家主张加息</div>
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-19</span></div>
<div class="cb-note">市场预计年内还有两次25bp加息,将利率推至高于美联储水平以对抗通胀</div>
</div>
</div>
<!-- CENTRAL_BANKS:END -->
<!-- CENTRAL_BANKS:END -->
</div>
</div>
<!-- TRADINGVIEW CHARTS -->
<div class="section-block mb16">
<div class="card" style="padding:14px 16px">
<div class="section-label">📈 行情图表 · Live Charts</div>
<div class="tradingview-widget-container">
<div class="tradingview-widget-container__widget"></div>
<script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-market-overview.js" async>
{
"colorTheme": "dark",
"dateRange": "1D",
"showChart": true,
"locale": "zh_CN",
"isTransparent": true,
"showSymbolLogo": true,
"showFloatingTooltip": false,
"width": "100%",
"height": "480",
"tabs": [
{
"title": "🇺🇸 美股",
"symbols": [
{"s":"FOREXCOM:SPXUSD","d":"S&P 500"},
{"s":"FOREXCOM:NSXUSD","d":"Nasdaq 100"},
{"s":"FOREXCOM:DJI","d":"道琼斯"},
{"s":"CBOE:VIX","d":"VIX 恐慌指数"},
{"s":"TVC:US10Y","d":"美10年债"}
],
"originalTitle": "US"
},
{
"title": "🇨🇳 中国",
"symbols": [
{"s":"SSE:000001","d":"上证指数"},
{"s":"SZSE:399006","d":"创业板指"},
{"s":"HKEX:HSI","d":"恒生指数"},
{"s":"FX:USDCNH","d":"离岸人民币"},
{"s":"HKEX:2318","d":"中国平安"}
],
"originalTitle": "China"
},
{
"title": "🛢️ 大宗",
"symbols": [
{"s":"TVC:GOLD","d":"黄金"},
{"s":"NYMEX:CL1!","d":"原油 WTI"},
{"s":"COMEX:SI1!","d":"白银"},
{"s":"TVC:DXY","d":"美元指数"}
],
"originalTitle": "Commodities"
},
{
"title": "₿ 加密",
"symbols": [
{"s":"BINANCE:BTCUSDT","d":"Bitcoin"},
{"s":"BINANCE:ETHUSDT","d":"Ethereum"},
{"s":"BINANCE:SOLUSDT","d":"Solana"}
],
"originalTitle": "Crypto"
}
]
}
</script>
</div>
</div>
</div>
</div><!-- end sidebar-col -->
</div><!-- end content-grid -->
<!-- MY DASHBOARD (collapsed drawer) -->
<div class="my-drawer sec-anchor" id="sec-my">
<button class="my-drawer-toggle" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
<span>⭐ 我的工作台 · My Dashboard</span>
<span class="drawer-icon"></span>
</button>
<div class="my-drawer-body">
<div class="card">
<div class="profile-bar">
<span class="profile-label">👤 用户:</span>
<select id="profile-select" onchange="profileSwitch()"></select>
<button onclick="profileNew()"> 新建</button>
<button onclick="profileDelete()">删除</button>
</div>
<div class="personal-header">
<div class="section-label">⭐ 我的工作台 · My Dashboard</div>
<span class="personal-privacy">🔒 数据存本地 · 不上传服务器</span>
</div>
<div class="ptabs">
<button class="ptab active" id="ptab-wl" onclick="switchTab(event,'wl')">📋 自选股</button>
<button class="ptab" id="ptab-pf" onclick="switchTab(event,'pf')">💼 持仓盈亏</button>
<button class="ptab" id="ptab-sim" onclick="switchTab(event,'sim')">📊 模拟器</button>
</div>
<div id="panel-wl">
<div class="add-row">
<input id="wl-sym" placeholder="代码,如 AAPL / 000001.SS / BTC-USD" />
<input id="wl-name" placeholder="备注名(可选)" />
<button onclick="wlAdd()"> 添加</button>
</div>
<div id="wl-empty" class="p-empty">还没有自选股,输入代码开始追踪 →</div>
<div id="wl-list" class="wl-list"></div>
</div>
<div id="panel-pf" style="display:none">
<div class="add-row">
<input id="pf-sym" placeholder="代码,如 AAPL / TSLA" />
<input id="pf-shares" type="number" min="0.0001" step="0.0001" placeholder="数量" />
<input id="pf-cost" type="number" min="0" step="0.01" placeholder="买入均价 ($)" />
<button onclick="pfAdd()"> 添加持仓</button>
</div>
<div id="pf-empty" class="p-empty">还没有持仓记录,输入持仓开始计算浮盈浮亏 →</div>
<div id="pf-summary" class="pf-summary" style="display:none">
<div class="pf-sum-item">总成本<span id="sum-cost"></span></div>
<div class="pf-sum-item">总市值<span id="sum-value"></span></div>
<div class="pf-sum-item">总盈亏<span id="sum-pnl"></span></div>
<div class="pf-sum-item">盈亏率<span id="sum-pct"></span></div>
</div>
<div id="pf-list" class="pf-list"></div>
</div>
<div id="panel-sim" style="display:none">
<div class="sim-section">
<div>
<div class="sim-label">总投资金额</div>
<div class="sim-capital-row">
<input type="number" id="sim-capital" min="0" step="100" value="10000" oninput="simUpdate()" />
<select id="sim-currency" onchange="simUpdate()">
<option value="USD">USD $</option>
<option value="CAD">CAD $</option>
<option value="CNY">CNY ¥</option>
</select>
</div>
</div>
<div>
<div class="sim-label">资产配置</div>
<div class="sim-add-row">
<input id="sim-sym" placeholder="代码,如 AAPL" style="width:100px" />
<input id="sim-alias" placeholder="备注名" style="width:85px" />
<input type="number" id="sim-pct" placeholder="分配%" min="0" max="100" step="1" style="width:65px" />
<input type="number" id="sim-entry" placeholder="买入价(选填)" min="0" step="0.01" style="width:110px" />
<button onclick="simAddAsset()"> 添加</button>
<span style="font-size:0.68rem;color:var(--dimmed)">不填则自动记录当前价</span>
</div>
<div id="sim-pct-total" class="sim-pct-total" style="margin-top:4px">已分配:0%</div>
</div>
<div id="sim-alloc-bar" class="sim-alloc-bar" style="display:none"></div>
<div id="sim-assets-wrap" style="display:none">
<table class="sim-assets-table">
<thead><tr><th>代码</th><th>备注</th><th>分配%</th><th>投入金额</th><th>买入价</th><th>操作</th></tr></thead>
<tbody id="sim-assets-tbody"></tbody>
</table>
</div>
<div id="sim-scenario-section" style="display:none">
<div class="sim-label">收益情景(年化%</div>
<div class="sim-scenario-row">
<label>😨 悲观 <input type="number" id="sim-bear" value="-20" step="1" oninput="simUpdate()" /></label>
<label>📊 中性 <input type="number" id="sim-base" value="8" step="1" oninput="simUpdate()" /></label>
<label>🚀 乐观 <input type="number" id="sim-bull" value="25" step="1" oninput="simUpdate()" /></label>
</div>
<div class="sim-horizon-row">
<span>时间跨度:</span>
<button class="sim-hbtn" data-h="1m" onclick="simSetHorizon(this,'1m')">1月</button>
<button class="sim-hbtn" data-h="3m" onclick="simSetHorizon(this,'3m')">3月</button>
<button class="sim-hbtn" data-h="6m" onclick="simSetHorizon(this,'6m')">6月</button>
<button class="sim-hbtn active" data-h="1y" onclick="simSetHorizon(this,'1y')">1年</button>
<button class="sim-hbtn" data-h="3y" onclick="simSetHorizon(this,'3y')">3年</button>
<button class="sim-hbtn" data-h="5y" onclick="simSetHorizon(this,'5y')">5年</button>
</div>
</div>
<div id="sim-returns-wrap" style="display:none">
<div class="sim-label">预期收益预测</div>
<table class="sim-returns-table">
<thead>
<tr>
<th style="text-align:left">资产</th>
<th>投入</th>
<th>📈 实际</th>
<th>😨 悲观</th>
<th>📊 中性</th>
<th>🚀 乐观</th>
</tr>
</thead>
<tbody id="sim-returns-tbody"></tbody>
</table>
</div>
<div class="sim-actions">
<button class="sim-btn sim-btn-secondary" onclick="simReset()">🗑 重置</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div><!-- end container -->
</div><!-- end page-body -->
<!-- =========================================================
FOOTER
========================================================= -->
<footer class="site-footer">
<div class="container">
<div class="footer-inner">
<span>© 2025 金融日报 · Financial Daily &nbsp;|&nbsp; Powered by <a href="https://www.anthropic.com" target="_blank">Claude AI</a></span>
<span>内容由AI自动生成,仅供参考,不构成投资建议</span>
<a href="feed.xml">RSS Feed</a>
</div>
<div style="display:flex;gap:24px;justify-content:center;margin-top:12px;font-size:0.75rem;color:var(--muted);">
<span>👁 访客 <strong id="footer-visitors" style="color:var(--accent)"></strong></span>
<span>📄 浏览 <strong id="footer-pageviews" style="color:var(--accent)"></strong></span>
</div>
</div>
</footer>
<script>
// Set current date
(function() {
const el = document.getElementById('current-date');
if (!el) return;
const now = new Date();
const opts = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'short' };
el.textContent = now.toLocaleDateString('zh-CN', opts);
})();
// Data age indicator
(function() {
const metaEl = document.querySelector('meta[name="last-updated"]');
if (!metaEl) return;
const updated = new Date(metaEl.content);
const ageH = (Date.now() - updated) / 3600000;
const badge = document.querySelector('.header-badge');
if (!badge) return;
const ageMin = Math.round(ageH * 60);
const ageStr = ageH < 1 ? ageMin + '分钟前更新' : Math.round(ageH) + '小时前更新';
badge.title = ageStr;
if (ageH > 14) badge.classList.add('data-stale');
})();
// Simple / Advanced mode toggle
(function() {
const btn = document.getElementById('mode-btn');
if (!btn) return;
const stored = localStorage.getItem('fd-mode') || 'advanced';
applyMode(stored);
btn.addEventListener('click', function() {
const isSimple = document.body.classList.contains('simple-mode');
const next = isSimple ? 'advanced' : 'simple';
localStorage.setItem('fd-mode', next);
applyMode(next);
});
function applyMode(mode) {
const label = btn.querySelector('.mode-label');
const icon = btn.querySelector('.mode-icon');
if (mode === 'simple') {
document.body.classList.add('simple-mode');
label.textContent = '专业模式';
icon.textContent = '📊';
} else {
document.body.classList.remove('simple-mode');
label.textContent = '新手模式';
icon.textContent = '📖';
}
}
})();
// Live quotes from data/quotes.json (populated by live-quotes workflow)
(function() {
fetch('data/quotes.json?' + Date.now())
.then(r => r.ok ? r.json() : null)
.then(data => {
if (!data || !data.quotes) return;
const track = document.querySelector('.indices-track');
if (!track) return;
data.quotes.forEach(q => {
track.querySelectorAll('.ticker-card').forEach(card => {
const nameEl = card.querySelector('.ticker-name');
if (nameEl && nameEl.textContent.trim() === q.name) {
card.className = 'ticker-card ' + q.direction;
card.querySelector('.ticker-value').textContent = q.value;
const chgEl = card.querySelector('.ticker-change');
const arrow = q.direction === 'up' ? '▲' : '▼';
chgEl.textContent = arrow + ' ' + q.change_pct;
chgEl.className = 'ticker-change ' + q.direction;
}
});
});
// Show live badge
const badge = document.querySelector('.header-badge');
if (badge) {
const updated = new Date(data.updated);
const mins = Math.round((Date.now() - updated) / 60000);
badge.title = '行情数据: ' + (mins < 60 ? mins + '分钟前' : Math.round(mins/60) + '小时前');
badge.classList.remove('data-stale');
}
})
.catch(() => {});
})();
// Auto-tooltip for financial jargon
const FIN_TERMS = {
'VIX': 'VIX = 标普期权隐含波动率,越高越恐慌',
'PCE': 'PCE = 个人消费支出物价指数,美联储首选通胀指标',
'NFP': 'NFP = 非农就业人数,衡量美国就业市场健康度',
'CPI': 'CPI = 消费者物价指数,最常见通胀衡量指标',
'PMI': 'PMI > 50 = 经济扩张;PMI < 50 = 经济收缩',
'QE': 'QE = 量化宽松,央行购买债券向市场注入流动性',
'鹰派': '鹰派 = 倾向加息/收紧货币政策,对抗通胀',
'鸽派': '鸽派 = 倾向降息/宽松货币政策,刺激经济',
'EPS': 'EPS = 每股收益,公司盈利能力的核心指标',
'DXY': 'DXY = 美元指数,衡量美元对六大货币的强弱',
};
document.addEventListener('DOMContentLoaded', function() {
const walker = document.createTreeWalker(
document.querySelector('.macro-section') || document.body,
NodeFilter.SHOW_TEXT
);
// Only apply to macro + news sections to avoid performance issues
['macro-section','news-section','cb-grid'].forEach(cls => {
const sec = document.querySelector('.' + cls);
if (!sec) return;
Object.entries(FIN_TERMS).forEach(([term, tip]) => {
sec.querySelectorAll('.macro-indicator, .cb-action, .news-body').forEach(el => {
if (el.innerHTML.includes(term) && !el.innerHTML.includes('fin-term')) {
el.innerHTML = el.innerHTML.replace(
new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g,'\\$&') + ')', 'g'),
`<span class="fin-term" data-tip="${tip}">$1</span>`
);
}
});
});
});
});
function copyRSS(e) {
e.preventDefault();
const url = 'https://yang1bai.github.io/finance-daily-site/feed.xml';
navigator.clipboard.writeText(url).then(() => {
const btn = document.getElementById('copy-rss');
btn.textContent = '✅ 已复制';
setTimeout(() => { btn.textContent = '📋 复制链接'; }, 2000);
}).catch(() => {
prompt('RSS 链接:', url);
});
}
// ═══════════════════════════════════════════════════════════
// PERSONAL DASHBOARD — Watchlist + Portfolio
// ═══════════════════════════════════════════════════════════
// ── Multi-user Profiles ──────────────────────────────────────
function profileLoad() {
return JSON.parse(localStorage.getItem('fd-profiles-v1') || 'null') || [{ id: 'default', name: '默认用户' }];
}
function profileSave(list) { localStorage.setItem('fd-profiles-v1', JSON.stringify(list)); }
function profileActive() { return localStorage.getItem('fd-active-profile-v1') || 'default'; }
function profileSetActive(id) { localStorage.setItem('fd-active-profile-v1', id); }
function profileRenderSelect() {
const list = profileLoad();
const active = profileActive();
const sel = document.getElementById('profile-select');
if (!sel) return;
sel.innerHTML = list.map(p => `<option value="${p.id}" ${p.id === active ? 'selected' : ''}>${p.name}</option>`).join('');
}
function profileSwitch() {
const sel = document.getElementById('profile-select');
if (!sel) return;
profileSetActive(sel.value);
wlRender(); pfRender(); simRender();
}
function profileNew() {
const name = prompt('输入用户名:', '用户' + (profileLoad().length + 1));
if (!name || !name.trim()) return;
const id = 'user_' + Date.now();
const list = profileLoad();
list.push({ id, name: name.trim() });
profileSave(list);
profileSetActive(id);
profileRenderSelect();
wlRender(); pfRender(); simRender();
}
function profileDelete() {
const list = profileLoad();
if (list.length <= 1) { alert('至少保留一个用户'); return; }
const active = profileActive();
const idx = list.findIndex(p => p.id === active);
if (idx === -1) return;
if (!confirm(`确认删除用户"${list[idx].name}"的所有数据?`)) return;
['watchlist-v1','portfolio-v1','sim-v1'].forEach(k => {
localStorage.removeItem(`fd-${active}-${k}`);
});
list.splice(idx, 1);
profileSave(list);
profileSetActive(list[0].id);
profileRenderSelect();
wlRender(); pfRender(); simRender();
}
// ── Dynamic localStorage keys ──────────────────────────
function lsWL() { return `fd-${profileActive()}-watchlist-v1`; }
function lsPF() { return `fd-${profileActive()}-portfolio-v1`; }
function lsSIM() { return `fd-${profileActive()}-sim-v1`; }
const priceCache = {};
function wlLoad() { return JSON.parse(localStorage.getItem(lsWL()) || '[]'); }
function wlSave(d) { localStorage.setItem(lsWL(), JSON.stringify(d)); }
function pfLoad() { return JSON.parse(localStorage.getItem(lsPF()) || '[]'); }
function pfSave(d) { localStorage.setItem(lsPF(), JSON.stringify(d)); }
function switchTab(e, tab) {
['wl','pf','sim'].forEach(t => {
document.getElementById('panel-' + t).style.display = t === tab ? 'block' : 'none';
document.getElementById('ptab-' + t).classList.toggle('active', t === tab);
});
}
// ── Price fetching (Yahoo Finance → CORS proxy fallback) ───
function toYahooSym(raw) {
if (!raw.includes(':')) return raw;
const [exch, ticker] = raw.split(':');
const map = { SSE:'', SZSE:'', HKEX:'.HK', TSX:'.TO', LSE:'.L', FWB:'.DE' };
if (exch === 'SSE') return ticker + '.SS';
if (exch === 'SZSE') return ticker + '.SZ';
return ticker + (map[exch] || '');
}
async function fetchPrice(rawSym) {
const key = rawSym;
if (priceCache[key] && Date.now() - priceCache[key].ts < 300000) return priceCache[key];
const ySym = toYahooSym(rawSym);
const yUrl = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(ySym)}?range=1d&interval=1m&includePrePost=false`;
const proxies = [
yUrl,
`https://corsproxy.io/?${encodeURIComponent(yUrl)}`,
`https://api.allorigins.win/get?url=${encodeURIComponent(yUrl)}`
];
for (const url of proxies) {
try {
const resp = await fetch(url, { signal: AbortSignal.timeout(7000) });
if (!resp.ok) continue;
let json = await resp.json();
// allorigins wraps in {contents: '...'}
if (json.contents) json = JSON.parse(json.contents);
const result = json.chart?.result?.[0];
if (!result) continue;
const meta = result.meta;
const price = meta.regularMarketPrice;
const prev = meta.chartPreviousClose || meta.previousClose || price;
const chgPct = prev ? (price - prev) / prev * 100 : 0;
const chgAbs = price - prev;
const info = { price, prev, chgPct, chgAbs, currency: meta.currency || 'USD', ts: Date.now() };
priceCache[key] = info;
return info;
} catch(e) {}
}
return null;
}
function fmtNum(n, dec=2) {
return n.toLocaleString('en-US', { minimumFractionDigits: dec, maximumFractionDigits: dec });
}
// ── Watchlist ───────────────────────────────────────────────
function wlAdd() {
const sym = (document.getElementById('wl-sym').value || '').trim().toUpperCase();
const name = (document.getElementById('wl-name').value || '').trim();
if (!sym) return;
const list = wlLoad();
if (list.find(i => i.symbol === sym)) { alert('已在自选列表'); return; }
list.push({ symbol: sym, alias: name });
wlSave(list);
document.getElementById('wl-sym').value = '';
document.getElementById('wl-name').value = '';
wlRender();
}
function wlRemove(sym) {
wlSave(wlLoad().filter(i => i.symbol !== sym));
wlRender();
}
function wlRender() {
const list = wlLoad();
const grid = document.getElementById('wl-list');
const empty = document.getElementById('wl-empty');
if (!list.length) { empty.style.display = 'block'; grid.innerHTML = ''; return; }
empty.style.display = 'none';
grid.innerHTML = list.map(item => {
const id = 'wlp-' + item.symbol.replace(/[^a-z0-9]/gi, '_');
return `<div class="wl-card">
<div class="wl-card-top">
<div>
<div class="wl-sym">${item.symbol}</div>
${item.alias ? `<div class="wl-alias">${item.alias}</div>` : ''}
</div>
<button class="wl-rm" onclick="wlRemove('${item.symbol.replace(/'/g,"\'")}')">×</button>
</div>
<div id="${id}"><span class="wl-loading">加载中…</span></div>
</div>`;
}).join('');
list.forEach(item => {
const id = 'wlp-' + item.symbol.replace(/[^a-z0-9]/gi, '_');
fetchPrice(item.symbol).then(info => {
const el = document.getElementById(id);
if (!el) return;
if (!info) { el.innerHTML = '<span class="wl-loading">获取失败</span>'; return; }
const dir = info.chgPct >= 0 ? 'up' : 'down';
const arrow = info.chgPct >= 0 ? '▲' : '▼';
el.innerHTML = `
<div class="wl-price-block">
<span class="wl-cur">${info.currency}</span>
<span class="wl-price">${fmtNum(info.price)}</span>
<span class="ticker-change ${dir}" style="font-size:0.72rem;">${arrow} ${Math.abs(info.chgPct).toFixed(2)}%</span>
</div>
<div class="wl-prev">昨收 ${fmtNum(info.prev)}</div>
`;
});
});
}
// ── Portfolio ───────────────────────────────────────────────
function pfAdd() {
const sym = (document.getElementById('pf-sym').value || '').trim().toUpperCase();
const shares = parseFloat(document.getElementById('pf-shares').value);
const cost = parseFloat(document.getElementById('pf-cost').value);
if (!sym || !shares || !cost || isNaN(shares) || isNaN(cost)) {
alert('请完整填写代码、数量和买入均价');
return;
}
const list = pfLoad();
list.push({ symbol: sym, shares, costBasis: cost, addedAt: Date.now() });
pfSave(list);
['pf-sym','pf-shares','pf-cost'].forEach(id => document.getElementById(id).value = '');
pfRender();
}
function pfRemove(idx) {
const list = pfLoad(); list.splice(idx, 1); pfSave(list); pfRender();
}
function pfRender() {
const list = pfLoad();
const grid = document.getElementById('pf-list');
const empty = document.getElementById('pf-empty');
const sumEl = document.getElementById('pf-summary');
if (!list.length) { empty.style.display='block'; grid.innerHTML=''; sumEl.style.display='none'; return; }
empty.style.display = 'none';
sumEl.style.display = 'flex';
const totalCost = list.reduce((s, i) => s + i.shares * i.costBasis, 0);
document.getElementById('sum-cost').textContent = '$' + fmtNum(totalCost);
grid.innerHTML = list.map((item, idx) => {
const id = 'pfp-' + idx;
const itemCost = item.shares * item.costBasis;
return `<div class="pf-card">
<div class="pf-card-top">
<span class="pf-sym">${item.symbol}</span>
<button class="wl-rm" onclick="pfRemove(${idx})">×</button>
</div>
<div class="pf-meta">
${fmtNum(item.shares, 4)} 股 &nbsp;×&nbsp; $${fmtNum(item.costBasis)} 成本<br>
持仓成本 <strong>$${fmtNum(itemCost)}</strong>
</div>
<div class="pf-pnl-row" id="${id}"><span class="wl-loading">计算盈亏中…</span></div>
</div>`;
}).join('');
let fetchedCount = 0, totalValue = 0;
list.forEach((item, idx) => {
fetchPrice(item.symbol).then(info => {
fetchedCount++;
const el = document.getElementById('pfp-' + idx);
if (!el) return;
if (!info) { el.innerHTML = '<span class="wl-loading">价格获取失败</span>'; return; }
const curVal = item.shares * info.price;
const pnlAbs = curVal - item.shares * item.costBasis;
const pnlPct = pnlAbs / (item.shares * item.costBasis) * 100;
const dir = pnlAbs >= 0 ? 'pos' : 'neg';
const sign = pnlAbs >= 0 ? '+' : '';
totalValue += curVal;
el.innerHTML = `
<span class="pf-cur-price">${info.currency} ${fmtNum(info.price)}</span>
<span class="pf-gain ${dir}">${sign}$${fmtNum(pnlAbs)} (${sign}${pnlPct.toFixed(2)}%)</span>
`;
if (fetchedCount === list.length) {
document.getElementById('sum-value').textContent = '$' + fmtNum(totalValue);
const totPnl = totalValue - totalCost;
const totPct = totPnl / totalCost * 100;
const sign2 = totPnl >= 0 ? '+' : '';
const cls = totPnl >= 0 ? 'pf-pnl-pos' : 'pf-pnl-neg';
document.getElementById('sum-pnl').innerHTML = `<span class="${cls}">${sign2}$${fmtNum(totPnl)}</span>`;
document.getElementById('sum-pct').innerHTML = `<span class="${cls}">${sign2}${totPct.toFixed(2)}%</span>`;
}
});
});
}
// ── Investment Simulator ─────────────────────────────────
function simLoad() {
return JSON.parse(localStorage.getItem(lsSIM()) || 'null') || {
capital: 10000, currency: 'USD',
assets: [],
scenarios: { bear: -20, base: 8, bull: 25 },
horizon: '1y'
};
}
function simSave(d) { localStorage.setItem(lsSIM(), JSON.stringify(d)); }
function simRender() {
const d = simLoad();
const capEl = document.getElementById('sim-capital');
const curEl = document.getElementById('sim-currency');
const bearEl = document.getElementById('sim-bear');
const baseEl = document.getElementById('sim-base');
const bullEl = document.getElementById('sim-bull');
if (capEl) capEl.value = d.capital;
if (curEl) curEl.value = d.currency;
if (bearEl) bearEl.value = d.scenarios.bear;
if (baseEl) baseEl.value = d.scenarios.base;
if (bullEl) bullEl.value = d.scenarios.bull;
document.querySelectorAll('.sim-hbtn').forEach(b => {
b.classList.toggle('active', b.dataset.h === d.horizon);
});
simRenderAssets(d);
simCalcReturns(d);
}
function simRenderAssets(d) {
const capital = parseFloat(d.capital) || 0;
const totalPct = d.assets.reduce((s, a) => s + (parseFloat(a.pct)||0), 0);
const pctEl = document.getElementById('sim-pct-total');
if (pctEl) {
pctEl.textContent = `已分配:${totalPct.toFixed(1)}%`;
pctEl.className = 'sim-pct-total' + (totalPct > 100 ? ' over' : '');
}
if (!d.assets.length) {
['sim-assets-wrap','sim-alloc-bar','sim-scenario-section','sim-returns-wrap'].forEach(id => {
const el = document.getElementById(id);
if (el) el.style.display = 'none';
});
return;
}
['sim-assets-wrap','sim-scenario-section','sim-returns-wrap'].forEach(id => {
const el = document.getElementById(id);
if (el) el.style.display = 'block';
});
const bar = document.getElementById('sim-alloc-bar');
if (bar) {
bar.style.display = 'flex';
bar.innerHTML = d.assets.map((a, i) => {
const w = Math.min(parseFloat(a.pct)||0, 100);
return `<div class="sim-alloc-seg" title="${a.symbol} ${a.pct}%" style="width:${w}%;background:hsl(${i*47},65%,50%);"></div>`;
}).join('');
}
const tbody = document.getElementById('sim-assets-tbody');
if (tbody) {
const cur = d.currency === 'CNY' ? '¥' : '$';
tbody.innerHTML = d.assets.map((a, idx) => {
const invest = capital * (parseFloat(a.pct)||0) / 100;
return `<tr>
<td><strong>${a.symbol}</strong></td>
<td>${a.alias || '—'}</td>
<td><input type="number" min="0" max="100" step="1" value="${a.pct}" onchange="simUpdatePct(${idx},this.value)" style="width:55px;background:transparent;border:1px solid var(--border);color:var(--text);border-radius:3px;padding:2px 5px;" /></td>
<td>${cur}${fmtNum(invest)}</td>
<td style="font-size:0.72rem;color:var(--dimmed)">${a.entryPrice ? cur + fmtNum(a.entryPrice) : '—'}</td>
<td><button class="wl-rm" onclick="simRemoveAsset(${idx})">×</button></td>
</tr>`;
}).join('');
}
}
async function simCalcReturns(d) {
const tbody = document.getElementById('sim-returns-tbody');
if (!tbody || !d.assets.length) return;
const capital = parseFloat(d.capital) || 0;
const horizonMap = { '1m': 1/12, '3m': 0.25, '6m': 0.5, '1y': 1, '3y': 3, '5y': 5 };
const years = horizonMap[d.horizon] || 1;
const bear = parseFloat(d.scenarios.bear) / 100;
const base = parseFloat(d.scenarios.base) / 100;
const bull = parseFloat(d.scenarios.bull) / 100;
const cur = d.currency === 'CNY' ? '¥' : '$';
function calcProfit(invest, rate, yrs) { return invest * Math.pow(1 + rate, yrs) - invest; }
function sCell(v, invest) {
const p = invest ? (v / invest * 100).toFixed(1) : '0.0';
const sign = v >= 0 ? '+' : '';
const cls = v >= 0 ? 'sim-ret-pos' : 'sim-ret-neg';
return `<span class="${cls}">${sign}${cur}${fmtNum(Math.abs(v))}<br><small>${sign}${p}%</small></span>`;
}
let totBear = 0, totBase = 0, totBull = 0, totInvest = 0;
// Render scenario columns immediately
tbody.innerHTML = d.assets.map(a => {
const invest = capital * (parseFloat(a.pct)||0) / 100;
const pb = calcProfit(invest, bear, years);
const pn = calcProfit(invest, base, years);
const pu = calcProfit(invest, bull, years);
totBear += pb; totBase += pn; totBull += pu; totInvest += invest;
const rid = 'simreal-' + a.symbol.replace(/[^a-z0-9]/gi,'_');
const realCell = a.entryPrice
? `<td id="${rid}"><span style="color:var(--dimmed);font-size:0.72rem">拉取中…</span></td>`
: `<td style="color:var(--dimmed);font-size:0.72rem">无买入价</td>`;
return `<tr>
<td><strong>${a.symbol}</strong>${a.alias ? `<br><small style="color:var(--muted)">${a.alias}</small>` : ''}</td>
<td>${cur}${fmtNum(invest)}</td>
${realCell}
<td>${sCell(pb, invest)}</td>
<td>${sCell(pn, invest)}</td>
<td>${sCell(pu, invest)}</td>
</tr>`;
}).join('');
tbody.innerHTML += `<tr class="total-row">
<td>合计</td>
<td>${cur}${fmtNum(totInvest)}</td>
<td id="simreal-total">—</td>
<td>${sCell(totBear, totInvest)}</td>
<td>${sCell(totBase, totInvest)}</td>
<td>${sCell(totBull, totInvest)}</td>
</tr>`;
// Async: fetch live prices for real P&L column
const realResults = new Array(d.assets.length).fill(null);
let fetched = 0;
d.assets.forEach(async (a, idx) => {
if (!a.entryPrice) { fetched++; return; }
const rid = 'simreal-' + a.symbol.replace(/[^a-z0-9]/gi,'_');
const el = document.getElementById(rid);
const info = await fetchPrice(a.symbol).catch(() => null);
fetched++;
if (!el) return;
if (!info) { el.innerHTML = '<span style="color:var(--dimmed);font-size:0.72rem">获取失败</span>'; return; }
const invest = capital * (parseFloat(a.pct)||0) / 100;
const realPnl = invest * (info.price - a.entryPrice) / a.entryPrice;
realResults[idx] = realPnl;
el.innerHTML = sCell(realPnl, invest);
// Update total row when all fetched
if (fetched === d.assets.length) {
const totEl = document.getElementById('simreal-total');
if (totEl) {
const validResults = realResults.filter(r => r !== null);
if (validResults.length) {
const totReal = validResults.reduce((s,v) => s+v, 0);
totEl.innerHTML = sCell(totReal, totInvest);
}
}
}
});
}
function simUpdate() {
const d = simLoad();
d.capital = parseFloat(document.getElementById('sim-capital').value) || 10000;
d.currency = document.getElementById('sim-currency').value;
d.scenarios.bear = parseFloat(document.getElementById('sim-bear').value) || -20;
d.scenarios.base = parseFloat(document.getElementById('sim-base').value) || 8;
d.scenarios.bull = parseFloat(document.getElementById('sim-bull').value) || 25;
simSave(d);
simRenderAssets(d);
simCalcReturns(d);
}
function simSetHorizon(btn, h) {
const d = simLoad();
d.horizon = h;
simSave(d);
document.querySelectorAll('.sim-hbtn').forEach(b => b.classList.toggle('active', b.dataset.h === h));
simCalcReturns(d);
}
async function simAddAsset() {
const sym = (document.getElementById('sim-sym').value || '').trim().toUpperCase();
const alias = (document.getElementById('sim-alias').value || '').trim();
const pct = parseFloat(document.getElementById('sim-pct').value) || 0;
const manualEntry = parseFloat(document.getElementById('sim-entry').value) || null;
if (!sym) return;
const d = simLoad();
if (d.assets.find(a => a.symbol === sym)) { alert('该资产已在列表中'); return; }
let entryPrice = manualEntry;
if (!entryPrice) {
const btn = document.querySelector('#panel-sim .sim-add-row button');
if (btn) { btn.textContent = '抓取中…'; btn.disabled = true; }
const info = await fetchPrice(sym).catch(() => null);
if (btn) { btn.textContent = ' 添加'; btn.disabled = false; }
entryPrice = info ? info.price : null;
if (!entryPrice) { alert(`无法获取 ${sym} 当前价格,请手动填入买入价`); return; }
}
d.assets.push({ symbol: sym, alias, pct, entryPrice, entryDate: new Date().toISOString().slice(0,10) });
simSave(d);
document.getElementById('sim-sym').value = '';
document.getElementById('sim-alias').value = '';
document.getElementById('sim-pct').value = '';
document.getElementById('sim-entry').value = '';
simRender();
}
function simRemoveAsset(idx) {
const d = simLoad();
d.assets.splice(idx, 1);
simSave(d);
simRender();
}
function simUpdatePct(idx, val) {
const d = simLoad();
d.assets[idx].pct = parseFloat(val) || 0;
simSave(d);
simRenderAssets(d);
simCalcReturns(d);
}
function simReset() {
if (!confirm('确认重置模拟器数据?')) return;
localStorage.removeItem(lsSIM());
simRender();
}
// Init personal dashboard on load
document.addEventListener('DOMContentLoaded', function() {
profileRenderSelect();
wlRender();
pfRender();
simRender();
// Enter key triggers add
document.getElementById('wl-name').addEventListener('keydown', e => { if(e.key==='Enter') wlAdd(); });
document.getElementById('pf-cost').addEventListener('keydown', e => { if(e.key==='Enter') pfAdd(); });
});
// ── Reading progress bar ──────────────────────────────────────────────────────────
(function() {
const bar = document.getElementById('reading-progress');
if (!bar) return;
window.addEventListener('scroll', function() {
const scrolled = window.scrollY;
const total = document.documentElement.scrollHeight - window.innerHeight;
bar.style.width = (total > 0 ? (scrolled / total * 100) : 0) + '%';
}, { passive: true });
})();
// ── Back-to-top FAB visibility ───────────────────────────────────────────────────
(function() {
const btn = document.getElementById('fab-top');
if (!btn) return;
window.addEventListener('scroll', function() {
btn.classList.toggle('visible', window.scrollY > 400);
}, { passive: true });
})();
// ── Share / copy URL ────────────────────────────────────────────────────────────
function shareOrCopy() {
const url = window.location.href;
const toast = document.getElementById('share-toast');
if (navigator.share) {
navigator.share({ title: '金融日报 | Financial Daily', url });
} else {
navigator.clipboard.writeText(url).then(function() {
toast.classList.add('show');
setTimeout(function() { toast.classList.remove('show'); }, 2000);
});
}
}
// ── Jump nav active highlight on scroll ────────────────────────────────────────
(function() {
const sections = document.querySelectorAll('.sec-anchor[id]');
const links = document.querySelectorAll('.jump-nav a');
if (!sections.length || !links.length) return;
const obs = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
links.forEach(function(l) { l.classList.remove('active'); });
const a = document.querySelector('.jump-nav a[href="#' + entry.target.id + '"]');
if (a) a.classList.add('active');
}
});
}, { rootMargin: '-20% 0px -70% 0px' });
sections.forEach(function(s) { obs.observe(s); });
})();
// ── Dismiss subscribe strip if already dismissed ────────────────────────────
(function() {
if (localStorage.getItem('fd_sub_dismissed')) {
var el = document.getElementById('subscribe-strip');
if (el) el.style.display = 'none';
}
})();
// ── Subscriber count (Telegram) ───────────────────────────────────────
(function loadSubCount() {
const el = document.getElementById('subscriber-count');
if (!el) return;
fetch('data/investment-subscribers.json')
.then(r => r.json())
.then(d => {
const count = Object.values(d.subscribers || {}).filter(s => s.active).length;
if (count > 0) el.textContent = `📱 ${count} 人已订阅Telegram早报`;
})
.catch(() => {});
})();
// ── AI 操盘实验(多模型对比)─────────────────────────────────────────
(function loadAIPortfolio() {
const fmt$ = v => '$' + v.toLocaleString('en-US', {minimumFractionDigits:2, maximumFractionDigits:2});
const fmtPct = v => (v >= 0 ? '+' : '') + v.toFixed(2) + '%';
function renderModelDetail(modelId, pf, contest) {
const history = pf.history || [];
const latest = history[history.length - 1] || {};
const holdings = pf.holdings || [];
const startCap = contest.start_capital || 10000;
const pv = latest.portfolio_value || 0;
const bv = latest.baseline_value || 0;
const cash = latest.cash || 0;
const positions = latest.positions || {};
const trades = latest.trades || [];
let html = '';
// 持仓明细
html += `<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:8px;">📊 当前持仓</div>`;
html += `<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:14px;">`;
Object.entries(positions).forEach(([t, pos]) => {
const h = holdings.find(x => x.ticker === t);
const avg = h ? h.avg_cost : pos.price;
const pl = pos.price - avg;
const plP = avg > 0 ? pl / avg * 100 : 0;
const pct = pv > 0 ? pos.value / pv * 100 : 0;
const c = pl >= 0 ? 'var(--up)' : 'var(--down)';
html += `<div style="display:flex;align-items:center;gap:8px;padding:5px 8px;background:rgba(255,255,255,0.03);border-radius:6px;font-size:0.79rem;">
<span style="font-family:var(--mono);font-weight:600;min-width:44px;color:var(--accent);">${t}</span>
<span style="color:var(--muted);min-width:46px;">${pos.shares}股</span>
<span style="font-family:var(--mono);min-width:66px;">$${pos.price.toFixed(2)}</span>
<span style="font-family:var(--mono);min-width:72px;">${fmt$(pos.value)}</span>
<span style="color:${c};min-width:62px;">${(pl>=0?'+':'')}${fmtPct(plP)}</span>
<div style="flex:1;height:3px;background:rgba(255,255,255,0.06);border-radius:2px;"><div style="width:${Math.min(pct,100).toFixed(1)}%;height:100%;background:var(--accent);border-radius:2px;"></div></div>
<span style="color:var(--muted);min-width:34px;text-align:right;">${pct.toFixed(1)}%</span>
</div>`;
});
if (cash > 0) {
const cp = pv > 0 ? cash / pv * 100 : 0;
html += `<div style="display:flex;align-items:center;gap:8px;padding:5px 8px;background:rgba(255,255,255,0.03);border-radius:6px;font-size:0.79rem;">
<span style="font-family:var(--mono);font-weight:600;min-width:44px;color:#ffb300;">CASH</span>
<span style="color:var(--muted);min-width:46px;">—</span>
<span style="font-family:var(--mono);min-width:66px;">—</span>
<span style="font-family:var(--mono);min-width:72px;">${fmt$(cash)}</span>
<span style="color:var(--muted);min-width:62px;">现金</span>
<div style="flex:1;height:3px;background:rgba(255,255,255,0.06);border-radius:2px;"><div style="width:${Math.min(cp,100).toFixed(1)}%;height:100%;background:#ffb300;border-radius:2px;"></div></div>
<span style="color:var(--muted);min-width:34px;text-align:right;">${cp.toFixed(1)}%</span>
</div>`;
}
html += '</div>';
// 交易记录
if (trades.length) {
html += `<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:8px;">📋 今日交易</div>`;
html += trades.map(t => {
const ic = t.action==='BUY'?'🟢':t.action==='SELL'?'🔴':'🟡';
const c2 = t.action==='BUY'?'var(--up)':t.action==='SELL'?'var(--down)':'var(--warn)';
return `<div style="padding:5px 0;border-bottom:1px solid var(--border);font-size:0.8rem;">${ic} <strong style="color:${c2};">${t.action} ${t.ticker}</strong> ${t.shares}股 @ $${(t.price||0).toFixed(2)} <span style="color:var(--muted);">${t.reason||''}</span></div>`;
}).join('');
html += '<div style="margin-bottom:12px;"></div>';
}
// 备注
if (latest.note) {
html += `<div style="font-size:0.8rem;color:var(--muted);padding:8px 10px;background:rgba(0,212,170,0.04);border-left:2px solid var(--accent);border-radius:4px;">${latest.note}</div>`;
}
document.getElementById('ai-model-detail').innerHTML = html;
}
fetch('data/ai-portfolio.json?v=' + Date.now())
.then(r => r.json())
.then(data => {
const contest = data.contest || {};
const portfolios = data.portfolios || {};
const startCap = contest.start_capital || 10000;
const startDate = new Date(contest.start_date || '2026-05-13');
// 计算排名
const ranked = Object.entries(portfolios).map(([id, pf]) => {
const hist = pf.history || [];
const latest = hist[hist.length - 1] || {};
const pv = latest.portfolio_value || startCap;
const bv = latest.baseline_value || startCap;
const d = new Date(latest.date || contest.start_date);
const days = Math.round((d - startDate) / 86400000) + 1;
return { id, pf, pv, bv, days, latest };
}).sort((a, b) => b.pv - a.pv);
// 排行榜
const lbEl = document.getElementById('ai-leaderboard');
lbEl.innerHTML = ranked.map((r, i) => {
const pv = r.pv;
const bv = r.bv;
const ret = (pv - startCap) / startCap * 100;
const alpha = pv - bv;
const alphaP = bv > 0 ? alpha / bv * 100 : 0;
const retC = ret >= 0 ? 'var(--up)' : 'var(--down)';
const alpC = alpha >= 0 ? 'var(--up)' : 'var(--down)';
const medal = i===0 ? '🥇' : i===1 ? '🥈' : '🥉';
const pf = r.pf;
return `<div style="display:flex;align-items:center;gap:10px;padding:10px 12px;background:rgba(255,255,255,0.04);border:1px solid var(--border);border-radius:8px;">
<span style="font-size:1.2rem;min-width:28px;">${medal}</span>
<span style="font-size:1.1rem;">${pf.emoji||'🤖'}</span>
<div style="flex:1;">
<div style="font-weight:600;font-size:0.9rem;">${pf.display_name||r.id}</div>
<div style="font-size:0.75rem;color:var(--muted);">${r.latest.note||''}</div>
</div>
<div style="text-align:right;min-width:80px;">
<div style="font-family:var(--mono);font-weight:600;font-size:0.95rem;">${fmt$(pv)}</div>
<div style="font-size:0.78rem;color:${retC};">${(ret>=0?'+':'')}${ret.toFixed(2)}%</div>
</div>
<div style="text-align:right;min-width:80px;">
<div style="font-family:var(--mono);font-size:0.85rem;color:${alpC};">${(alpha>=0?'+':'')}${fmt$(alpha)}</div>
<div style="font-size:0.75rem;color:var(--muted);">vs SPY</div>
</div>
</div>`;
}).join('');
// SPY 基线行
const anyLatest = ranked[0]?.latest || {};
const spyVal = anyLatest.baseline_value || startCap;
const spyRet = (spyVal - startCap) / startCap * 100;
const spyC = spyRet >= 0 ? 'var(--up)' : 'var(--down)';
lbEl.innerHTML += `<div style="display:flex;align-items:center;gap:10px;padding:10px 12px;background:rgba(255,255,255,0.02);border:1px solid var(--border);border-radius:8px;opacity:0.7;">
<span style="font-size:1.2rem;min-width:28px;">📊</span>
<span style="font-size:1.1rem;">—</span>
<div style="flex:1;"><div style="font-weight:600;font-size:0.9rem;">SPY 基线(买入持有)</div><div style="font-size:0.75rem;color:var(--muted);">S&amp;P 500 ETF</div></div>
<div style="text-align:right;min-width:80px;">
<div style="font-family:var(--mono);font-weight:600;font-size:0.95rem;">${fmt$(spyVal)}</div>
<div style="font-size:0.78rem;color:${spyC};">${(spyRet>=0?'+':'')}${spyRet.toFixed(2)}%</div>
</div>
<div style="text-align:right;min-width:80px;">
<div style="font-family:var(--mono);font-size:0.85rem;color:var(--muted);">$0.00</div>
<div style="font-size:0.75rem;color:var(--muted);">展示基准</div>
</div>
</div>`;
// 模型 Tab
const tabsEl = document.getElementById('ai-model-tabs');
let activeModel = ranked[0]?.id;
function setActiveTab(id) {
activeModel = id;
tabsEl.querySelectorAll('button').forEach(b => {
b.style.background = b.dataset.id === id ? 'rgba(0,212,170,0.15)' : 'rgba(255,255,255,0.04)';
b.style.borderColor = b.dataset.id === id ? 'var(--accent)' : 'var(--border)';
b.style.color = b.dataset.id === id ? 'var(--accent)' : 'var(--text)';
});
const pf = portfolios[id];
if (pf) renderModelDetail(id, pf, contest);
}
tabsEl.innerHTML = ranked.map(r => {
const pf = r.pf;
return `<button data-id="${r.id}" onclick="(function(id){window._aiSetTab&&window._aiSetTab(id)})('${r.id}')" style="padding:6px 12px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,0.04);color:var(--text);cursor:pointer;font-size:0.8rem;">${pf.emoji||'🤖'} ${pf.display_name||r.id}</button>`;
}).join('');
window._aiSetTab = setActiveTab;
setActiveTab(activeModel);
// 历史对比表
const histEl = document.getElementById('ai-history-table');
const allDates = [...new Set(ranked.flatMap(r => (r.pf.history||[]).map(h => h.date)))].sort().reverse();
if (allDates.length > 1) {
const headers = ['<th style="text-align:left;padding:3px 6px;">日期</th>',
...ranked.map(r => `<th style="text-align:right;padding:3px 6px;">${r.pf.emoji} ${r.pf.display_name}</th>`),
'<th style="text-align:right;padding:3px 6px;">SPY基线</th>'
].join('');
const rows = allDates.map(date => {
const cells = ranked.map(r => {
const rec = (r.pf.history||[]).find(h => h.date === date);
if (!rec) return '<td style="text-align:right;padding:3px 6px;color:var(--dimmed);">—</td>';
const ret = (rec.portfolio_value - startCap) / startCap * 100;
const c = ret >= 0 ? 'var(--up)' : 'var(--down)';
return `<td style="text-align:right;padding:3px 6px;"><span style="color:${c};">${(ret>=0?'+':'')}${ret.toFixed(2)}%</span></td>`;
}).join('');
const spyRec = (ranked[0]?.pf.history||[]).find(h => h.date === date);
const spyR = spyRec ? (spyRec.baseline_value - startCap) / startCap * 100 : 0;
const sc = spyR >= 0 ? 'var(--up)' : 'var(--down)';
return `<tr style="border-top:1px solid var(--border);"><td style="padding:3px 6px;color:var(--muted);">${date}</td>${cells}<td style="text-align:right;padding:3px 6px;"><span style="color:${sc};">${(spyR>=0?'+':'')}${spyR.toFixed(2)}%</span></td></tr>`;
}).join('');
histEl.innerHTML = `<table style="width:100%;border-collapse:collapse;"><thead><tr style="color:var(--muted);">${headers}</tr></thead><tbody>${rows}</tbody></table>`;
} else {
histEl.innerHTML = '<span style="color:var(--muted);font-size:0.8rem;">天数超过1天后显示对比曲线…</span>';
}
document.getElementById('ai-portfolio-loading').style.display='none';
document.getElementById('ai-portfolio-content').style.display='';
})
.catch(()=>{ const el=document.getElementById('ai-portfolio-loading'); if(el) el.textContent='数据加载失败'; });
})();
// ── Visitor counter (Cloudflare Worker + KV) ──────────────────────────
document.addEventListener('DOMContentLoaded', function () {
const WORKER = 'https://finance-daily-counter.yangbai0110.workers.dev';
const LS_KEY = 'fd_visited';
const visEl = document.getElementById('footer-visitors');
const pvEl = document.getElementById('footer-pageviews');
function fmt(n) { return Number(n).toLocaleString('en-US'); }
function animate(el, target) {
if (!el) return;
if (target === 0) { el.textContent = '0'; return; }
const dur = 900; let t0 = null;
const step = ts => {
if (!t0) t0 = ts;
const p = Math.min((ts - t0) / dur, 1);
el.textContent = fmt(Math.round((1 - Math.pow(1 - p, 3)) * target));
if (p < 1) requestAnimationFrame(step);
};
requestAnimationFrame(step);
}
const isNew = !localStorage.getItem(LS_KEY);
fetch(WORKER + (isNew ? '?newVisitor=1' : '?newVisitor=0'))
.then(r => r.json())
.then(data => {
localStorage.setItem(LS_KEY, '1');
animate(visEl, data.visitors || 0);
animate(pvEl, data.pageViews || 0);
})
.catch(() => {
if (visEl) visEl.textContent = '--';
if (pvEl) pvEl.textContent = '--';
});
});
</script>
<script>
// ─── Streak counter ────────────────────────────────────────────────────────
(function() {
var today = new Date().toISOString().slice(0,10);
var last = localStorage.getItem('fd_last_visit') || '';
var streak = parseInt(localStorage.getItem('fd_streak') || '0');
if (last !== today) {
var yesterday = new Date(Date.now() - 86400000).toISOString().slice(0,10);
streak = (last === yesterday) ? streak + 1 : 1;
localStorage.setItem('fd_last_visit', today);
localStorage.setItem('fd_streak', streak);
}
if (streak >= 2) {
var meta = document.querySelector('.header-meta');
if (meta) {
var sb = document.createElement('span');
sb.className = 'streak-badge';
sb.title = '连续访问天数';
sb.innerHTML = '🔥 ' + streak + ' 天';
meta.appendChild(sb);
}
}
})();
// ─── Mark first breaking news as NEW ────────────────────────────────────────
document.querySelectorAll('.news-item.breaking, .news-item.major').forEach(function(n, i) {
if (i < 2) {
var title = n.querySelector('.news-title');
if (title) {
var badge = document.createElement('span');
badge.className = 'new-badge';
badge.textContent = '新';
badge.style.cssText = 'display:inline-block;font-size:.58rem;font-family:var(--mono);padding:1px 5px;border-radius:3px;background:rgba(0,212,170,.15);color:var(--accent);border:1px solid rgba(0,212,170,.3);margin-right:6px;vertical-align:middle;';
title.insertBefore(badge, title.firstChild);
}
}
});
// ─── News toggle ────────────────────────────────────────────────────────────
function toggleNews(el) { el.classList.toggle('expanded'); }
</script>
<!-- Floating action cluster -->
<div class="fab-cluster">
<button class="fab" id="fab-share" title="分享此页" onclick="shareOrCopy()">🔗</button>
<button class="fab" id="fab-top" title="回到顶部" onclick="window.scrollTo({top:0,behavior:'smooth'})"></button>
</div>
<div id="share-toast">✅ 链接已复制</div>
<div id="share-toast">✅ 链接已复制</div>
</body>
</html>