2591 lines
133 KiB
HTML
2591 lines
133 KiB
HTML
<!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="../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-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-banks">🏦 央行</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">S&P 500</div>
|
||
<div class="ticker-value">7,412.84</div>
|
||
<div class="ticker-change up">▲ +0.19%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">Nasdaq Composite</div>
|
||
<div class="ticker-value">26,274.13</div>
|
||
<div class="ticker-change up">▲ +0.10%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">Dow Jones</div>
|
||
<div class="ticker-value">49,704.47</div>
|
||
<div class="ticker-change up">▲ +0.19%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">上证综指</div>
|
||
<div class="ticker-value">4,225.02</div>
|
||
<div class="ticker-change up">▲ +1.08%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">深证成指</div>
|
||
<div class="ticker-value">15,899.30</div>
|
||
<div class="ticker-change up">▲ +2.16%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">恒生指数</div>
|
||
<div class="ticker-value">27,200.00</div>
|
||
<div class="ticker-change up">▲ +0.44%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">日经225</div>
|
||
<div class="ticker-value">62,417.88</div>
|
||
<div class="ticker-change down">▼ -0.47%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">德国DAX</div>
|
||
<div class="ticker-value">24,350.28</div>
|
||
<div class="ticker-change up">▲ +0.05%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">黄金现货</div>
|
||
<div class="ticker-value">4,745.60</div>
|
||
<div class="ticker-change up">▲ +0.31%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">WTI原油</div>
|
||
<div class="ticker-value">98.25</div>
|
||
<div class="ticker-change up">▲ +2.97%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">比特币</div>
|
||
<div class="ticker-value">81,715.06</div>
|
||
<div class="ticker-change up">▲ +1.25%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">美元指数</div>
|
||
<div class="ticker-value">102.50</div>
|
||
<div class="ticker-change up">▲ +0.24%</div>
|
||
</div>
|
||
<!-- INDICES:END -->
|
||
<!-- INDICES:END -->
|
||
<!-- duplicate for seamless loop -->
|
||
<!-- INDICES:START -->
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">S&P 500</div>
|
||
<div class="ticker-value">7,412.84</div>
|
||
<div class="ticker-change up">▲ +0.19%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">Nasdaq Composite</div>
|
||
<div class="ticker-value">26,274.13</div>
|
||
<div class="ticker-change up">▲ +0.10%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">Dow Jones</div>
|
||
<div class="ticker-value">49,704.47</div>
|
||
<div class="ticker-change up">▲ +0.19%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">上证综指</div>
|
||
<div class="ticker-value">4,225.02</div>
|
||
<div class="ticker-change up">▲ +1.08%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">深证成指</div>
|
||
<div class="ticker-value">15,899.30</div>
|
||
<div class="ticker-change up">▲ +2.16%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">恒生指数</div>
|
||
<div class="ticker-value">27,200.00</div>
|
||
<div class="ticker-change up">▲ +0.44%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">日经225</div>
|
||
<div class="ticker-value">62,417.88</div>
|
||
<div class="ticker-change down">▼ -0.47%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">德国DAX</div>
|
||
<div class="ticker-value">24,350.28</div>
|
||
<div class="ticker-change up">▲ +0.05%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">黄金现货</div>
|
||
<div class="ticker-value">4,745.60</div>
|
||
<div class="ticker-change up">▲ +0.31%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">WTI原油</div>
|
||
<div class="ticker-value">98.25</div>
|
||
<div class="ticker-change up">▲ +2.97%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">比特币</div>
|
||
<div class="ticker-value">81,715.06</div>
|
||
<div class="ticker-change up">▲ +1.25%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">美元指数</div>
|
||
<div class="ticker-value">102.50</div>
|
||
<div class="ticker-change up">▲ +0.24%</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 neutral">
|
||
<div class="summary-top">
|
||
<span class="sentiment-pill neutral">🟡 中性 · Neutral</span>
|
||
<span class="vix-badge">VIX <span class="vix-num">18.38</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>伊朗局势推升油价VIX飙升</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">标普500和纳指在AI芯片需求驱动下双双刷新历史收盘纪录,科技板块领涨。然而特朗普拒绝伊朗和平提议导致原油飙升近3%,VIX恐慌指数上涨近7%。中美元首峰会将于5月14-15日在北京举行,贸易谈判和关税政策成为焦点。对北美华人投资者而言:美股科技股仍是主线,但需警惕地缘政治风险;A股连续5周上涨,沪指站上4180点创两个月新高,中美关系改善预期提振市场信心。</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">特朗普拒绝伊朗和平提议,原油飙升地缘风险升温</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>持有能源股和通胀对冲资产(黄金、TIPS)的投资者短期受益,但通胀加剧可能推迟降息并压制股市整体估值</div>
|
||
<div class="news-body-collapse">美国总统特朗普周日拒绝伊朗关于中东战争的反提议,称其"完全不可接受"。周末美军驱逐舰在霍尔木兹海峡拦截伊朗攻击并实施防御性打击,脆弱的停火协议再次受到威胁。布伦特原油一度涨至104.80美元/桶,WTI升至近99美元。霍尔木兹海峡自2月底战争爆发以来几乎处于关闭状态,推高能源价格并加剧通胀担忧。市场预期央行可能进一步加息以遏制物价上涨,这对贵金属构成压力。</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">特朗普-习近平峰会本周举行,中美贸易谈判成焦点</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>短期内中美关系缓和预期利好两国股市,但结构性矛盾依然存在,投资者应关注峰会后的具体政策落地情况</div>
|
||
<div class="news-body-collapse">美国总统特朗普将于5月14-15日访问北京,与中国国家主席习近平举行峰会,这是他8年来首次访华。双方预计将讨论"贸易委员会"机制、关税减免、中国采购500架波音飞机及农产品、美方获取稀土矿产等议题。尽管11月达成的关税减免协议延长至今年11月,但美国正通过Section 301等手段重建"关税墙",目标是将对华有效关税率从目前的23.69%恢复至去年的27%以上。中方则希望保护科技企业免受美国监管限制,并争取中国车企进入美国市场。</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">AI芯片需求推动科技股创新高,英伟达领涨</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>持有英伟达、AMD等AI芯片股及QQQ等科技ETF的投资者继续受益,但需警惕估值过高和AI支出能否转化为盈利的风险</div>
|
||
<div class="news-body-collapse">标普500和纳指双双刷新历史收盘纪录,得益于AI芯片持续强劲需求。英伟达、AMD、博通等半导体股领涨,而Meta、微软、亚马逊等科技巨头AI基础设施投资持续增加。分析师称AI相关股票估值已降至2019年来最低水平,四大超大规模云厂商2026年资本支出预计超4700亿美元。摩根大通私人银行表示"AI超级周期可能刚刚开始",建议投资数据中心建设相关的半导体供应链、网络光学设备及电力传输资产。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge breaking">🔥 BREAKING</span>
|
||
<div class="tags"><span class="tag">#AI</span><span class="tag">#科技股</span><span class="tag">#英伟达</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">美国4月新增就业11.5万超预期,劳动力市场韧性持续</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>强劲就业数据进一步推迟降息预期,对股市是双刃剑:经济韧性是利好,但"更高更久"的利率将压制估值</div>
|
||
<div class="news-body-collapse">美国4月新增非农就业11.5万人,远超市场预期的6.2万人,3月数据上修至18.5万。就业增长主要来自医疗保健(3.7万)、运输仓储(3万)和零售业(2.2万)。失业率维持在4.3%,平均时薪环比增长0.2%,同比增速从3.5%加速至3.8%。这是近一年来首次连续两个月就业增长,显示劳动力市场在逐步降温的同时保持广泛韧性。联邦政府就业继续下降(-0.9万)。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge high">• HIGH</span>
|
||
<div class="tags"><span class="tag">#就业数据</span><span class="tag">#NFP</span><span class="tag">#美联储</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">A股连续5周上涨,沪指站上4180点创两月新高</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>持有沪深300 ETF或科技股的投资者年初至今收益丰厚,峰会前可适度获利了结,等待政策明朗后再加仓</div>
|
||
<div class="news-body-collapse">上证综指周一收于4225点上涨1.08%,深证成指暴涨2.16%至15899点,两市成交额达2.5万亿元人民币。沪指上周涨1.65%,深成指涨3.02%,均实现连续5周上涨。保险股领涨周一大盘,平均涨幅6.72%。分析师认为2025年A股形成了明显的结构性牛市,市场重新评估了中国自主科技能力、外需韧性和AI推理需求激增。尽管中美峰会前夕投资者有所谨慎,但中美关系改善预期和政策支持提振信心。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge high">• HIGH</span>
|
||
<div class="tags"><span class="tag">#A股</span><span class="tag">#上证综指</span><span class="tag">#中国市场</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">美股板块分化加剧:科技能源领涨,公用事业房地产垫底</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>投资者应适度降低板块集中度,从涨幅过大的科技股获利了结,增配估值合理的防御性板块如医疗、必需消费</div>
|
||
<div class="news-body-collapse">标普500内部出现显著分化,今年以来半导体、能源、国防和工业板块表现最佳,而公用事业和房地产板块因利率敏感性表现垫底。科技板块(XLK)今日上涨1.82%,通讯服务和非必需消费也表现强劲。相比之下,能源(XLE)、工业(XLI)、原材料(XLB)和公用事业(XLU)分别下跌1.8%、1.6%、1.9%和1.3%。78%的Q1财报公司超预期,但盈利增长集中在少数行业。分析师建议超配半导体和工业,持有能源和国防作为现金流和宏观对冲。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge high">• HIGH</span>
|
||
<div class="tags"><span class="tag">#板块轮动</span><span class="tag">#投资策略</span><span class="tag">#估值</span></div>
|
||
</div>
|
||
</div>
|
||
<!-- NEWS:END -->
|
||
<!-- NEWS:END -->
|
||
</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">875.40</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>82</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">AI芯片龙头,数据中心需求强劲</div>
|
||
<div class="wc-driver">Q4营收680亿美元超预期,Q1指引780亿美元;hyperscaler资本开支2026年超4700亿美元</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">当前估值已反映高增长预期,建议持有现有仓位,等待5/20财报后回调至850以下加仓</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">485.30</div><div class="wc-price-chg up">+0.8%</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">科技股集中度高,创历史新高后注意回调风险</div>
|
||
<div class="wc-driver">纳指连续6周上涨创2024年来最长连涨,但VIX升至18.38,市场波动性上升</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 510</span><span class="wc-target-down">↓ 465</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">科技股估值偏贵(平均远期P/E 27倍 vs 标普21倍),建议减持部分获利,保留核心仓位</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#ETF</span><span class="tag">#科技股</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">741.28</div><div class="wc-price-chg up">+0.2%</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盈利同比增长18.6%,84%公司超预期;但远期P/E 21倍高于10年均值18.9倍</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 780</span><span class="wc-target-down">↓ 710</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">#ETF</span><span class="tag">#标普500</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">81715.06</div><div class="wc-price-chg up">+1.25%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>65</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">突破10月下行趋势,但面临9.3万阻力</div>
|
||
<div class="wc-driver">机构投资者重新关注加密货币避险属性;中东紧张局势和美元走弱提供支撑</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 94000</span><span class="wc-target-down">↓ 76000</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">风险偏好较高投资者可小仓位参与,设置止损于76000;突破94000后可加仓</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.35</div><div class="wc-price-chg up">+1.5%</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">A股连续5周上涨,中美峰会预期提振</div>
|
||
<div class="wc-driver">沪指站上4180点创两月新高,政策支持和科技突破重估正在进行;外资回流迹象明显</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 4.80</span><span class="wc-target-down">↓ 4.10</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.10以下则是加仓良机;全年看好中国科技股</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#A股</span><span class="tag">#沪深300</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">4745.60</div><div class="wc-price-chg up">+0.31%</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">高盛预计2026年底金价达4900美元/盎司;但"更高更久"利率和美元走强构成逆风</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 4900</span><span class="wc-target-down">↓ 4400</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">作为投资组合5-10%的避险配置长期持有;短期若回落至4400可增持</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">98.25</div><div class="wc-price-chg up">+2.97%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>62</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">伊朗局势推升油价,但长期供应过剩风险</div>
|
||
<div class="wc-driver">特朗普拒绝伊朗和平提议,霍尔木兹海峡紧张;但OPEC+产量恢复和美国产量上升构成压力</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 105</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">短期波动剧烈不建议追高,持有能源股(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">245.80</div><div class="wc-price-chg down">-1.7%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge SELL">SELL</span>
|
||
<span class="wc-score">评分 <span>45</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">营收首次全年下滑,估值仍偏高</div>
|
||
<div class="wc-driver">2025年营收同比下降3%,交付量下滑9%;联邦税收抵免到期和竞争加剧是主因</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 275</span><span class="wc-target-down">↓ 210</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">建议减持,等待4/20财报明确机器人和自动驾驶业务进展后再考虑重新买入</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-down">
|
||
<div class="macro-indicator">非农就业人数 (NFP)</div>
|
||
<div class="macro-value macro-value-down">115K</div>
|
||
<div class="macro-prev"><span class="arrow down">↓</span> 前值: 185K</div>
|
||
<div class="macro-desc">4月新增就业11.5万人,超预期6.2万,显示劳动力市场韧性持续但增速放缓</div>
|
||
</div>
|
||
<div class="macro-card dir-neutral">
|
||
<div class="macro-indicator">失业率</div>
|
||
<div class="macro-value ">4.3%</div>
|
||
<div class="macro-prev"><span class="arrow ">→</span> 前值: 4.3%</div>
|
||
<div class="macro-desc">失业率维持不变,劳动参与率61.8%,就业人口比59.1%均小幅波动</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">平均时薪 YoY</div>
|
||
<div class="macro-value macro-value-up">3.8%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 3.5%</div>
|
||
<div class="macro-desc">时薪同比增速从3.5%加速至3.8%,环比增长0.2%,工资通胀压力上升</div>
|
||
</div>
|
||
<div class="macro-card dir-down">
|
||
<div class="macro-indicator">核心PCE (Core PCE)</div>
|
||
<div class="macro-value macro-value-up">3.0%</div>
|
||
<div class="macro-prev"><span class="arrow down">↓</span> 前值: 3.1%</div>
|
||
<div class="macro-desc">美联储首选通胀指标2月同比增长3.0%,略低于1月3.1%,但仍高于2025年水平</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">CPI YoY</div>
|
||
<div class="macro-value macro-value-down">3.3%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 3.0%</div>
|
||
<div class="macro-desc">3月CPI同比上涨3.3%,因伊朗战争推高能源价格;核心CPI维持2.6%</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">通胀预期中值</div>
|
||
<div class="macro-value macro-value-down">2.7%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 2.5%</div>
|
||
<div class="macro-desc">美联储4月FOMC会议上调2026年通胀预期至2.7%,降息前景显著恶化</div>
|
||
</div>
|
||
<div class="macro-card dir-neutral">
|
||
<div class="macro-indicator">联邦基金利率</div>
|
||
<div class="macro-value ">3.50-3.75%</div>
|
||
<div class="macro-prev"><span class="arrow ">→</span> 前值: 3.50-3.75%</div>
|
||
<div class="macro-desc">美联储连续第三次维持利率不变,4名官员投反对票创34年来最多</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">S&P 500 Q1盈利增长</div>
|
||
<div class="macro-value macro-value-up">18.6%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 15.2%</div>
|
||
<div class="macro-desc">标普500 Q1实际盈利同比增长18.6%,84%公司超预期,创Q2 2021以来最高比例</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财报季强劲,84%公司超预期创2021年来最高</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>AI投资超级周期持续,科技巨头资本开支4700亿美元</div>
|
||
<div class="debate-point"><span class="conf-badge medium">medium</span>中美峰会若达成贸易协议将提振全球风险偏好</div>
|
||
</div>
|
||
<div class="debate-side bear">
|
||
<div class="debate-side-title">🐻 空方看跌</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>美联储降息预期破灭,'更高更久'利率压制估值</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>中东局势恶化推升油价,通胀压力重燃</div>
|
||
<div class="debate-point"><span class="conf-badge medium">medium</span>VIX升至18.38,市场波动性上升,科技股估值过高</div>
|
||
</div>
|
||
</div>
|
||
<div class="debate-verdict">
|
||
<div class="verdict-label">裁判结论 <span class="verdict-lean neutral">NEUTRAL</span></div>
|
||
<div class="verdict-text">短期震荡整固概率较大。虽然财报强劲和AI主题支撑科技股,但"更高更久"利率和地缘风险升温令市场谨慎。建议减持涨幅过大板块,增配防御性板块;中美峰会若传出积极信号则是加仓良机。</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 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">$1.25</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-20</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$78B (预期)</span></div>
|
||
<div class="earnings-highlight">Q4营收680亿美元超预期,Q1指引780亿美元,AI芯片需求持续强劲</div>
|
||
</div>
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">META</div>
|
||
<div class="earnings-company">Meta Platforms</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">$待回顾</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$5.28</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$42.3B</span></div>
|
||
<div class="earnings-highlight">Q4营收同比增长24%,2026年AI相关资本支出预计1150-1350亿美元,几乎翻倍</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">$3.25</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$3.12</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$81.3B</span></div>
|
||
<div class="earnings-highlight">Q2财季营收813亿美元超预期,Azure云增长强劲,财年资本支出预计990亿美元</div>
|
||
</div>
|
||
<div class="earnings-card pending">
|
||
<div class="earnings-ticker">TSLA</div>
|
||
<div class="earnings-company">Tesla</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">$0.48</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">REPORT DATE</div>
|
||
<div class="eps-value est" style="font-size:0.75rem;">2026-04-20</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$23.5B (预期)</span></div>
|
||
<div class="earnings-highlight">2025年营收同比下降3%,首次全年下降;联邦税收抵免到期和竞争加剧是主因</div>
|
||
</div>
|
||
<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">$1.53</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$1.50</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$90.8B</span></div>
|
||
<div class="earnings-highlight">服务收入创历史新高,宣布1100亿美元回购,与谷歌达成Gemini模型集成Siri协议</div>
|
||
</div>
|
||
<div class="earnings-card pending">
|
||
<div class="earnings-ticker">AMZN</div>
|
||
<div class="earnings-company">Amazon</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">$1.18</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">REPORT DATE</div>
|
||
<div class="eps-value est" style="font-size:0.75rem;">2026-04-29</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$157B (预期)</span></div>
|
||
<div class="earnings-highlight">AWS云服务增长强劲,2026年资本支出预计超1100亿美元用于AI基础设施</div>
|
||
</div>
|
||
<div class="earnings-card pending">
|
||
<div class="earnings-ticker">GOOGL</div>
|
||
<div class="earnings-company">Alphabet</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">$1.85</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">REPORT DATE</div>
|
||
<div class="eps-value est" style="font-size:0.75rem;">2026-04-29</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$88.5B (预期)</span></div>
|
||
<div class="earnings-highlight">2025年资本支出910-930亿美元,2026年预计大幅增至1150亿美元以上</div>
|
||
</div>
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">AMD</div>
|
||
<div class="earnings-company">AMD</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">$1.12</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$1.05</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$7.2B</span></div>
|
||
<div class="earnings-highlight">Q1业绩强劲,AI芯片MI300系列需求激增,数据中心业务同比增长超80%</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">Information Technology</div></div>
|
||
<div class="sector-etf">XLK</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:96%"></div></div>
|
||
<div class="sector-pct up">+1.82%</div>
|
||
</div>
|
||
<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:78%"></div></div>
|
||
<div class="sector-pct up">+1.45%</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:50%"></div></div>
|
||
<div class="sector-pct up">+0.85%</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 up" style="width:29%"></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">Health Care</div></div>
|
||
<div class="sector-etf">XLV</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:21%"></div></div>
|
||
<div class="sector-pct down">-0.25%</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 down" style="width:85%"></div></div>
|
||
<div class="sector-pct down">-1.60%</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 down" style="width:95%"></div></div>
|
||
<div class="sector-pct down">-1.80%</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 down" style="width:100%"></div></div>
|
||
<div class="sector-pct down">-1.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:71%"></div></div>
|
||
<div class="sector-pct down">-1.30%</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:83%"></div></div>
|
||
<div class="sector-pct down">-1.55%</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:31%"></div></div>
|
||
<div class="sector-pct down">-0.45%</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">科技股推动纳指标普双创新高,但VIX飙升7%显示波动性上升</div>
|
||
<div class="ad-bar-wrap">
|
||
<span class="ad-label-up">↑3240</span>
|
||
<div class="ad-bar adv" style="width:64px;max-width:80px"></div>
|
||
<div class="ad-bar dec" style="width:36px;max-width:80px"></div>
|
||
<span class="ad-label-dn">↓1820</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">AMD (+3.8%)</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">创52周新高</div><div class="replay-stat-val">127</div></div>
|
||
</div>
|
||
</div><div class="replay-card">
|
||
<div class="replay-card-title">🇨🇳 A股</div>
|
||
<div class="replay-summary">沪深两市连续5周上涨,北向资金净流入,中美峰会预期提振信心</div>
|
||
<div class="ad-bar-wrap">
|
||
<span class="ad-label-up">↑2800</span>
|
||
<div class="ad-bar adv" style="width:65px;max-width:80px"></div>
|
||
<div class="ad-bar dec" style="width:35px;max-width:80px"></div>
|
||
<span class="ad-label-dn">↓1500</span>
|
||
</div>
|
||
<div class="replay-stats">
|
||
<div class="replay-stat"><div class="replay-stat-label">热门板块</div><div class="replay-stat-val">保险(+6.72%)</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">领涨标的</div><div class="replay-stat-val">数据电讯 (+10.04%)</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">北向资金</div><div class="replay-stat-val">+52亿</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/13<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">CPI (4月)</div>
|
||
<div class="cal-values">预期: <span>3.4%</span> · 前值: 3.3%</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周三 5/14<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
|
||
<div>
|
||
<div class="cal-event">特朗普-习近平北京峰会(第1天)</div>
|
||
<div class="cal-values">预期: <span>关税及贸易协议</span> · 前值: N/A</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">特朗普-习近平北京峰会(第2天);鲍威尔卸任</div>
|
||
<div class="cal-values">预期: <span>沃什就任美联储主席</span> · 前值: N/A</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周四 5/15<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">零售销售 (4月)</div>
|
||
<div class="cal-values">预期: <span>+0.2%</span> · 前值: -0.3%</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item medium">
|
||
<div class="cal-date">周五 5/16<br><span style="font-size:0.6rem;color:var(--dimmed)">9:15 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">工业生产 (4月)</div>
|
||
<div class="cal-values">预期: <span>+0.3%</span> · 前值: +0.5%</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周二 5/20<br><span style="font-size:0.6rem;color:var(--dimmed)">盘后</span></div>
|
||
<div>
|
||
<div class="cal-event">英伟达Q1财报</div>
|
||
<div class="cal-values">预期: <span>EPS $1.25, 营收$78B</span> · 前值: EPS $1.20</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周三 5/28<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">核心PCE (4月)</div>
|
||
<div class="cal-values">预期: <span>3.1%</span> · 前值: 3.0%</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">戴蒙在4月年度股东信中警告,通胀上升将推高利率,这会对所有资产价格形成"引力效应"。他呼应了巴菲特26年前的警告,认为当前市场估值偏高,投资者需关注利率对长期回报的影响。他还在Q1财报会议上表示,当信贷周期到来时,损失将比预期更严重,暗示AI被颠覆的软件公司可能是下一个盲点。</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">鲍威尔在4月29日最后一次FOMC会议后的新闻发布会上强调美联储独立性,表示面临司法部刑事调查威胁。他确认将于5月15日卸任主席职务,但会短暂留任理事。美联储连续第三次维持利率在3.5%-3.75%区间不变,4名官员投反对票创34年来最多。通胀预期中值升至2.7%,降息前景显著恶化,市场甚至押注小概率加息。</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">伯克希尔哈撒韦CEO</div>
|
||
</div>
|
||
<div class="leader-date">5月初</div>
|
||
</div>
|
||
<div class="leader-quote">"利率对资产价格的影响从未改变且永远不会改变"</div>
|
||
<div class="leader-body">巴菲特在近期股东信中重申其26年前的经典警告:利率是资产定价的重力。当前市场环境与互联网泡沫时期有相似之处,尽管本质不同。他强调投资者必须考虑利率上升对估值的压缩效应。值得注意的是,戴蒙在1月聘用了巴菲特的得意门生Todd Combs担任摩根大通百亿美元投资集团负责人,巴菲特对此表示虽不情愿但可以接受。</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">4月29日</div>
|
||
</div>
|
||
<div class="leader-quote">"美联储决策将基于共识,而非主席个人意愿"</div>
|
||
<div class="leader-body">特朗普提名的鲍威尔继任者沃什已通过参议院关键审批,预计很快获最终批准。分析师指出,沃什可能成为"长期以来最没有影响力的美联储主席",因为他倾向降息但难以说服其他FOMC成员。市场预期利率将在年底前维持不变,降息预期已从此前的1-2次降至零,甚至有小概率加息。沃什否认与爱泼斯坦有任何关系。</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人投反对票创34年最多</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-18</span></div>
|
||
<div class="cb-note">鲍威尔5月15日卸任主席,沃什接任;通胀预期上调至2.7%,降息预期几乎消失</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">3.00%</div>
|
||
<div class="cb-action">维持主要再融资利率3.00%</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-06</span></div>
|
||
<div class="cb-note">欧元区经济复苏疲弱,通胀回落至2.3%,央行保持政策灵活性</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-05-20</span></div>
|
||
<div class="cb-note">政策支持推动A股连续5周上涨,资金加速流入股市;中美峰会前保持政策稳定</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 neutral">Neutral</span>
|
||
</div>
|
||
<div class="cb-rate">0.25%</div>
|
||
<div class="cb-action">维持政策利率0.25%不变</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-13</span></div>
|
||
<div class="cb-note">日经225指数突破62000点创历史新高,日元兑美元约145;通胀温和上升</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>
|
||
<!-- =========================================================
|
||
MARKET CHARTS — TradingView Market Overview
|
||
========================================================= -->
|
||
<div class="section-block">
|
||
<div class="card" style="padding:16px 20px;">
|
||
<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>
|
||
</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 | 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)} 股 × $${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(() => {});
|
||
})();
|
||
|
||
// ── 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> |