2828 lines
147 KiB
HTML
2828 lines
147 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="archive/index.html">归档</a>
|
||
<a href="feed.xml" style="color:var(--dimmed)">RSS</a>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- NAV -->
|
||
<nav class="jump-nav" id="jump-nav">
|
||
<a href="#sec-summary">📊 大势</a>
|
||
<a href="#sec-ai-trading">🤖 AI操盘</a>
|
||
<a href="#sec-news">📰 要闻</a>
|
||
<a href="#sec-watchlist">🎯 AI分析</a>
|
||
<a href="#sec-macro">📈 宏观</a>
|
||
<a href="#sec-earnings">💼 财报</a>
|
||
<a href="#sec-sectors">🏭 行业</a>
|
||
<a href="#sec-debate">⚔️ 辩论</a>
|
||
<a href="#sec-calendar">📅 日历</a>
|
||
<a href="#sec-my">⭐ 我的</a>
|
||
</nav>
|
||
|
||
<!-- INDICES TICKER -->
|
||
<section class="indices-section">
|
||
<div class="indices-scroll-wrapper">
|
||
<div class="indices-track">
|
||
<!-- INDICES:START -->
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">标普500</div>
|
||
<div class="ticker-value">7,444.25</div>
|
||
<div class="ticker-change up">▲ +0.58%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">纳斯达克</div>
|
||
<div class="ticker-value">26,402.34</div>
|
||
<div class="ticker-change up">▲ +1.20%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">道琼斯</div>
|
||
<div class="ticker-value">49,693.19</div>
|
||
<div class="ticker-change down">▼ -0.14%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">上证综指</div>
|
||
<div class="ticker-value">4,242.57</div>
|
||
<div class="ticker-change up">▲ +0.16%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">恒生指数</div>
|
||
<div class="ticker-value">26,304.50</div>
|
||
<div class="ticker-change down">▼ -0.27%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">日经225</div>
|
||
<div class="ticker-value">63,272.11</div>
|
||
<div class="ticker-change up">▲ +0.84%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">德国DAX</div>
|
||
<div class="ticker-value">24,162.53</div>
|
||
<div class="ticker-change up">▲ +0.87%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">黄金现货</div>
|
||
<div class="ticker-value">$4,700</div>
|
||
<div class="ticker-change down">▼ -0.28%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">WTI原油</div>
|
||
<div class="ticker-value">$102.18</div>
|
||
<div class="ticker-change up">▲ +4.37%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">比特币</div>
|
||
<div class="ticker-value">$80,304</div>
|
||
<div class="ticker-change down">▼ -0.87%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">美元指数</div>
|
||
<div class="ticker-value">98.28</div>
|
||
<div class="ticker-change up">▲ +0.39%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">离岸人民币</div>
|
||
<div class="ticker-value">6.79</div>
|
||
<div class="ticker-change down">▼ -0.15%</div>
|
||
</div>
|
||
<!-- INDICES:END -->
|
||
<!-- INDICES:END -->
|
||
<!-- duplicate for seamless loop -->
|
||
<!-- INDICES:START -->
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">标普500</div>
|
||
<div class="ticker-value">7,444.25</div>
|
||
<div class="ticker-change up">▲ +0.58%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">纳斯达克</div>
|
||
<div class="ticker-value">26,402.34</div>
|
||
<div class="ticker-change up">▲ +1.20%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">道琼斯</div>
|
||
<div class="ticker-value">49,693.19</div>
|
||
<div class="ticker-change down">▼ -0.14%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">上证综指</div>
|
||
<div class="ticker-value">4,242.57</div>
|
||
<div class="ticker-change up">▲ +0.16%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">恒生指数</div>
|
||
<div class="ticker-value">26,304.50</div>
|
||
<div class="ticker-change down">▼ -0.27%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">日经225</div>
|
||
<div class="ticker-value">63,272.11</div>
|
||
<div class="ticker-change up">▲ +0.84%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">德国DAX</div>
|
||
<div class="ticker-value">24,162.53</div>
|
||
<div class="ticker-change up">▲ +0.87%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">黄金现货</div>
|
||
<div class="ticker-value">$4,700</div>
|
||
<div class="ticker-change down">▼ -0.28%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">WTI原油</div>
|
||
<div class="ticker-value">$102.18</div>
|
||
<div class="ticker-change up">▲ +4.37%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">比特币</div>
|
||
<div class="ticker-value">$80,304</div>
|
||
<div class="ticker-change down">▼ -0.87%</div>
|
||
</div>
|
||
<div class="ticker-card up">
|
||
<div class="ticker-name">美元指数</div>
|
||
<div class="ticker-value">98.28</div>
|
||
<div class="ticker-change up">▲ +0.39%</div>
|
||
</div>
|
||
<div class="ticker-card down">
|
||
<div class="ticker-name">离岸人民币</div>
|
||
<div class="ticker-value">6.79</div>
|
||
<div class="ticker-change down">▼ -0.15%</div>
|
||
</div>
|
||
<!-- INDICES:END -->
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- SUMMARY HERO -->
|
||
<section class="summary-section sec-anchor" id="sec-summary">
|
||
<div class="container">
|
||
<!-- SUMMARY:START -->
|
||
<div class="summary-card bullish">
|
||
<div class="summary-top">
|
||
<span class="sentiment-pill bullish">🟢 看多 · Bullish</span>
|
||
<span class="vix-badge">VIX <span class="vix-num">17.99</span></span>
|
||
</div>
|
||
<div class="summary-headline">科技股无视通胀创新高,标普纳指再破纪录</div>
|
||
<ul class="key-points"><li class="kp-item"><span class="kp-arrow">▸</span>科技股无视通胀刷新纪录</li><li class="kp-item"><span class="kp-arrow">▸</span>新任美联储主席就职</li><li class="kp-item"><span class="kp-arrow">▸</span>特朗普访华聚焦贸易</li></ul>
|
||
<details class="summary-details">
|
||
<summary class="summary-details-toggle">深度解读 ▸</summary>
|
||
<div class="summary-context">尽管4月CPI同比升至3.8%、PPI飙升至6%,但科技巨头带动纳指涨1.2%、标普涨0.58%双双刷新历史纪录。AI芯片股领涨,伊朗战争推高油价至102美元/桶,VIX仅17.99显示市场仍淡定。Kevin Warsh今日获参议院确认接任鲍威尔成为新任美联储主席,特朗普抵达北京与习近平会晤聚焦贸易与伊朗。对北美华人投资者:科技股ETF持续受益,但通胀超预期令年内降息无望,持有能源及防御性资产对冲风险。</div>
|
||
</details>
|
||
</div>
|
||
<!-- SUMMARY:END -->
|
||
<!-- SUMMARY:END -->
|
||
</div>
|
||
</section>
|
||
|
||
<!-- PODCAST PLAYER -->
|
||
<div class="podcast-bar" id="podcast-bar">
|
||
<div class="container">
|
||
<div class="podcast-inner">
|
||
<div class="podcast-left">
|
||
<span class="podcast-icon">🎙️</span>
|
||
<div class="podcast-info">
|
||
<div class="podcast-title">金融日报早报 · 今日播客</div>
|
||
<div class="podcast-sub" id="podcast-date">欣欣 & 建国 · 约3分钟</div>
|
||
</div>
|
||
</div>
|
||
<div class="podcast-controls">
|
||
<audio id="podcast-audio" preload="none">
|
||
<source src="audio/latest.mp3" type="audio/mpeg">
|
||
</audio>
|
||
<button class="pod-btn" id="pod-play" onclick="togglePodcast()">▶ 播放</button>
|
||
<div class="pod-progress-wrap" onclick="seekPodcast(event)">
|
||
<div class="pod-progress-bar" id="pod-progress"></div>
|
||
</div>
|
||
<span class="pod-time" id="pod-time">0:00</span>
|
||
<button class="pod-btn pod-btn-sm" onclick="document.getElementById('podcast-audio').playbackRate=document.getElementById('podcast-audio').playbackRate===1?1.5:1;this.textContent=document.getElementById('podcast-audio').playbackRate+'x'">1x</button>
|
||
<a class="pod-btn pod-btn-sm" href="audio/latest.mp3" download="金融日报早报.mp3" title="下载">⬇</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.podcast-bar {
|
||
background: linear-gradient(90deg, rgba(0,212,170,.08), rgba(79,195,247,.05));
|
||
border-bottom: 1px solid rgba(0,212,170,.2);
|
||
padding: 10px 0;
|
||
}
|
||
.podcast-inner { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; }
|
||
.podcast-left { display:flex; align-items:center; gap:10px; }
|
||
.podcast-icon { font-size:1.4rem; animation: pulse-pod 3s ease-in-out infinite; }
|
||
@keyframes pulse-pod { 0%,100%{transform:scale(1)} 50%{transform:scale(1.1)} }
|
||
.podcast-title { font-size:.82rem; font-weight:600; color:var(--text); }
|
||
.podcast-sub { font-size:.65rem; color:var(--muted); font-family:var(--mono); margin-top:1px; }
|
||
.podcast-controls { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
|
||
.pod-btn {
|
||
background: rgba(0,212,170,.15); color:var(--accent);
|
||
border: 1px solid rgba(0,212,170,.3); border-radius:6px;
|
||
padding: 5px 14px; font-size:.75rem; cursor:pointer;
|
||
font-family:var(--sans); transition:background .15s; white-space:nowrap;
|
||
}
|
||
.pod-btn:hover { background:rgba(0,212,170,.25); }
|
||
.pod-btn.playing { background:rgba(255,82,82,.12); color:var(--down); border-color:rgba(255,82,82,.3); }
|
||
.pod-btn-sm { padding:5px 9px; font-size:.68rem; }
|
||
.pod-btn-sm[download] { color:var(--muted); background:rgba(255,255,255,.05); border-color:var(--border); text-decoration:none; }
|
||
.pod-progress-wrap { width:160px; height:4px; background:var(--border); border-radius:2px; cursor:pointer; }
|
||
@media(max-width:640px){ .pod-progress-wrap { width:80px; } }
|
||
.pod-progress-bar { height:100%; background:var(--accent); border-radius:2px; width:0%; transition:width .3s linear; }
|
||
.pod-time { font-family:var(--mono); font-size:.65rem; color:var(--muted); min-width:32px; }
|
||
</style>
|
||
|
||
<script>
|
||
(function(){
|
||
var audio = document.getElementById('podcast-audio');
|
||
var btn = document.getElementById('pod-play');
|
||
var bar = document.getElementById('pod-progress');
|
||
var time = document.getElementById('pod-time');
|
||
if (!audio) return;
|
||
|
||
// Check if audio exists
|
||
fetch('audio/latest-meta.json').then(r=>r.json()).then(m=>{
|
||
document.getElementById('podcast-date').textContent = '欣欣 & 建国 · ' + m.date + ' · 约3分钟';
|
||
}).catch(()=>{
|
||
document.getElementById('podcast-bar').style.opacity = '0.4';
|
||
btn.textContent = '暂无音频';
|
||
btn.disabled = true;
|
||
});
|
||
|
||
audio.addEventListener('timeupdate', function(){
|
||
if (!audio.duration) return;
|
||
bar.style.width = (audio.currentTime / audio.duration * 100) + '%';
|
||
var m = Math.floor(audio.currentTime/60);
|
||
var s = Math.floor(audio.currentTime%60);
|
||
time.textContent = m + ':' + (s<10?'0':'')+s;
|
||
});
|
||
audio.addEventListener('ended', function(){
|
||
btn.textContent = '▶ 播放';
|
||
btn.classList.remove('playing');
|
||
bar.style.width = '0%';
|
||
});
|
||
|
||
window.togglePodcast = function(){
|
||
if (audio.paused) {
|
||
audio.play();
|
||
btn.textContent = '⏸ 暂停';
|
||
btn.classList.add('playing');
|
||
} else {
|
||
audio.pause();
|
||
btn.textContent = '▶ 播放';
|
||
btn.classList.remove('playing');
|
||
}
|
||
};
|
||
window.seekPodcast = function(e){
|
||
if (!audio.duration) return;
|
||
var rect = e.currentTarget.getBoundingClientRect();
|
||
audio.currentTime = ((e.clientX - rect.left) / rect.width) * audio.duration;
|
||
};
|
||
})();
|
||
</script>
|
||
|
||
<!-- MAIN PAGE BODY -->
|
||
<div class="page-body">
|
||
<div class="container">
|
||
|
||
<!-- SUBSCRIBE (dismissible) -->
|
||
<div class="subscribe-strip" id="subscribe-strip">
|
||
<div class="subscribe-strip-icon">📬</div>
|
||
<div class="subscribe-strip-body">
|
||
<strong>订阅每日金融早报</strong>
|
||
<span>每个交易日自动更新,开盘前 + 收盘后各一次</span>
|
||
</div>
|
||
<div class="subscribe-strip-actions">
|
||
<form action="https://buttondown.email/api/emails/embed-subscribe/yangbai0110" method="post" target="_blank" style="display:flex;gap:6px;">
|
||
<input type="email" name="email" placeholder="your@email.com" required style="padding:6px 10px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--text);font-size:.73rem;width:148px;outline:none;" />
|
||
<button type="submit" class="btn-sub-email">📧 邮件</button>
|
||
</form>
|
||
<a href="https://t.me/GGmanm_bot?start=subscribe" target="_blank" class="btn-sub-tg">
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.894 8.221-1.97 9.28c-.145.658-.537.818-1.084.508l-3-2.21-1.447 1.394c-.16.16-.295.295-.605.295l.213-3.053 5.56-5.023c.242-.213-.054-.333-.373-.12L7.44 13.55l-2.955-.924c-.643-.204-.657-.643.136-.953l11.566-4.461c.537-.194 1.006.131.707.009z"/></svg>
|
||
Telegram
|
||
</a>
|
||
<button onclick="document.getElementById('subscribe-strip').style.display='none';localStorage.setItem('fd_sub_dismissed','1');" style="background:none;border:none;color:var(--dimmed);cursor:pointer;font-size:1rem;padding:2px 4px;" title="关闭">×</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- PRIMARY GRID: main content + sidebar -->
|
||
<div class="content-grid">
|
||
|
||
<!-- ── LEFT / MAIN COLUMN ─────────────────────────────── -->
|
||
<div class="main-col">
|
||
|
||
<!-- NEWS -->
|
||
<div class="section-block sec-anchor" id="sec-news">
|
||
<div class="card">
|
||
<div class="section-label">📰 市场要闻 · Market News</div>
|
||
<!-- NEWS:START -->
|
||
<div class="news-item breaking featured" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot breaking"></span>
|
||
<div class="news-title">特朗普抵京会晤习近平 科技巨头随行聚焦AI与贸易</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>特朗普访华谈贸易与伊朗,科技股若达成芯片出口松绑可能受益,但台湾军售悬而未决令地缘风险犹存</div>
|
||
<div class="news-body-collapse">美国总统特朗普今日抵达北京开启为期两天国事访问,随行包括苹果CEO库克、特斯拉CEO马斯克及英伟达CEO黄仁勋等16位商业领袖。会谈议题涵盖台湾军售、关税、AI管控及伊朗战争。特朗普称将与习近平'长谈'伊朗问题,但强调主要焦点仍是贸易。中国是伊朗最大贸易伙伴,霍尔木兹海峡封锁令全球能源危机加剧,华盛顿希望北京施压德黑兰重开航道。市场预期将公布大豆及波音订单协议。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge breaking">🔥 BREAKING</span>
|
||
<div class="tags"><span class="tag">#中美关系</span><span class="tag">#贸易</span><span class="tag">#科技</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="news-item breaking featured" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot breaking"></span>
|
||
<div class="news-title">通胀超预期:4月CPI飙至3.8% PPI年增6% 降息预期破灭</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>通胀失控侵蚀购买力,工薪阶层最受伤,今年别指望降息,固定收益类资产配置价值下降</div>
|
||
<div class="news-body-collapse">美国劳工部公布4月CPI同比上涨3.8%,高于预期的3.7%,创2023年5月以来最高;核心CPI月增0.4%、年增2.8%。生产者价格指数(PPI)月增1.4%、年增6%,远超预期的0.5%,创2022年以来最大涨幅。能源占CPI月增的40%,汽油价格年增28.4%至4.50美元/加仑。实际工资下降0.3%,这是三年来首次工资增长被通胀完全吞噬。CME FedWatch显示年内加息概率升至30%,降息预期彻底破灭。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge breaking">🔥 BREAKING</span>
|
||
<div class="tags"><span class="tag">#通胀</span><span class="tag">#美联储</span><span class="tag">#经济数据</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="news-item breaking featured" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot breaking"></span>
|
||
<div class="news-title">科技股无视通胀刷新纪录 纳指涨1.2%标普涨0.58%创历史新高</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>科技股'一股独大'格局延续,持有QQQ等科技ETF继续受益,但市场广度恶化暗示回调风险</div>
|
||
<div class="news-body-collapse">尽管通胀数据火热,标普500和纳斯达克周三双双创下收盘与盘中历史新高,分别收于7,444.25(+0.58%)和26,402.34(+1.20%)。芯片股领涨,英伟达涨2.5%,美光涨近5%。摩根士丹利将标普500年底目标价从7,800上调至8,000,认为伊朗战争影响已被定价。道指微跌0.14%至49,693.19,金融与通信股拖累。市场显示极端窄幅领涨:仅143只标普成分股上涨,中小盘股走势疲弱。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge breaking">🔥 BREAKING</span>
|
||
<div class="tags"><span class="tag">#美股</span><span class="tag">#科技股</span><span class="tag">#AI</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="news-item high" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot high"></span>
|
||
<div class="news-title">福特暴涨13% 推出储能子公司Ford Energy 电池业务单独上市</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>传统车企转型能源存储打开新增长曲线,关注清洁能源板块配置机会</div>
|
||
<div class="news-body-collapse">福特汽车周三收涨13.18%至13.57美元,成交量飙升265%。公司宣布成立电池储能子公司Ford Energy,摩根士丹利发布看好报告强调其盈利与合作潜力。这标志福特从传统车企向能源公司转型。相比之下,特斯拉涨1.5%,马斯克随特朗普访华,特斯拉中国推出新融资方案降低Model 3首付以对抗本土竞争对手。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge high">• HIGH</span>
|
||
<div class="tags"><span class="tag">#汽车</span><span class="tag">#清洁能源</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="news-item breaking" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot breaking"></span>
|
||
<div class="news-title">伊朗战争拖累和谈 油价飙升4.2%至102美元特朗普称停火'生命垂危'</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>油价破百美元推高生活成本,持有能源ETF(XLE)对冲通胀,但经济衰退风险上升需警惕</div>
|
||
<div class="news-body-collapse">特朗普拒绝伊朗和平提议,称霍尔木兹海峡主权等要求'完全不可接受',并形容当前停火'生命垂危'。WTI原油周二飙升4.2%至102.18美元/桶,布伦特原油涨3.4%至107.77美元。战争已持续超10周,全球20%石油贸易受阻。高盛警告供应缓冲正在耗尽,Shell CEO称全球可能因战争少产10亿桶原油。航空燃油价格年增20.7%,牛肉价格年增14.8%,供应链压力持续蔓延至食品。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge breaking">🔥 BREAKING</span>
|
||
<div class="tags"><span class="tag">#原油</span><span class="tag">#地缘政治</span><span class="tag">#通胀</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="news-item medium" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot medium"></span>
|
||
<div class="news-title">阿里巴巴Q4财报不及预期 AI投入拖累利润股价跌2%</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>中概科技股短期承压于AI投入,但长期AI变现值得关注,波动中寻找配置时机</div>
|
||
<div class="news-body-collapse">阿里巴巴第四财季营收未达华尔街预期,AI基础设施、云扩张及一小时达业务的重投入拖累盈利。云收入年增38%至61.3亿美元符合预期。公司将AI业务从云计算分拆,成立'阿里巴巴Token Hub',CEO吴泳铭亲自挂帅力图将AI投资转化为盈利。股价盘前跌近2%。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge medium">• MEDIUM</span>
|
||
<div class="tags"><span class="tag">#中概股</span><span class="tag">#财报</span><span class="tag">#AI</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="news-item medium" onclick="toggleNews(this)">
|
||
<div class="news-header">
|
||
<span class="imp-dot medium"></span>
|
||
<div class="news-title">A股缩量震荡 沪指微涨0.16% 半导体设备股强者恒强</div>
|
||
<span class="news-expand-icon">+</span>
|
||
</div>
|
||
<div class="news-tldr"><span class="tldr-label">💡 新手解读</span>A股量能萎缩显示观望情绪浓厚,建议聚焦半导体国产替代及新能源等政策支持板块</div>
|
||
<div class="news-body-collapse">周三A股震荡整理,沪指收涨0.16%报4,242.57点,深成指跌0.25%,创业板指跌0.47%。两市成交3.2万亿缩量,北向资金净流出12亿。半导体设备、电力电网设备逆势走强,中际旭创股价突破千元。全市场超4000股飘绿,市场分化明显。分析师指出在全球通胀和美联储鹰派背景下,A股外资流出压力加大。</div>
|
||
<div class="news-footer">
|
||
<span class="importance-badge medium">• MEDIUM</span>
|
||
<div class="tags"><span class="tag">#A股</span><span class="tag">#半导体</span></div>
|
||
</div>
|
||
</div>
|
||
<!-- NEWS:END -->
|
||
<!-- NEWS:END -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- AI 操盘实验 -->
|
||
<div class="section-block sec-anchor" id="sec-ai-trading">
|
||
<div class="card">
|
||
<div class="section-label">🤖 AI 操盘实验 · AI Trading Challenge</div>
|
||
<div id="ai-portfolio-loading" style="color:var(--muted);font-size:0.82rem;padding:8px 0;">加载中…</div>
|
||
<div id="ai-portfolio-content" style="display:none">
|
||
<!-- 排行榜 -->
|
||
<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:10px;">🏆 排行榜 · Leaderboard <span style="font-size:0.68rem;color:var(--dimmed);margin-left:6px;">初始资金 $10,000 · 基线 SPY买入持有</span></div>
|
||
<div id="ai-leaderboard" style="display:flex;flex-direction:column;gap:8px;margin-bottom:18px;"></div>
|
||
<!-- 各模型详情 Tab -->
|
||
<div style="display:flex;gap:6px;margin-bottom:12px;" id="ai-model-tabs"></div>
|
||
<div id="ai-model-detail"></div>
|
||
<!-- 历史对比表 -->
|
||
<div id="ai-history-wrap" style="margin-top:16px;">
|
||
<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:8px;">📈 历史表现对比</div>
|
||
<div id="ai-history-table" style="font-family:var(--mono);font-size:0.76rem;"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- AI WATCHLIST -->
|
||
<section class="section-block sec-anchor" id="sec-watchlist">
|
||
<div class="card">
|
||
<div class="section-label">🎯 AI 决策仪表盘 · AI Watchlist</div>
|
||
<!-- WATCHLIST_ANALYSIS:START -->
|
||
<div class="watchlist-grid">
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">NVDA</div><div class="wc-name">英伟达</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">890.50</div><div class="wc-price-chg up">+2.5%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge BUY">BUY</span>
|
||
<span class="wc-score">评分 <span>88</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">AI霸主地位无可撼动,Blackwell订单超5000亿</div>
|
||
<div class="wc-driver">黄仁勋随特朗普访华,对华高端芯片出口限制有望松绑,Rubin架构技术领先可维持溢价定价</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 950</span><span class="wc-target-down">↓ 820</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
|
||
<div class="wc-action">回调至850美元附近可加仓,5/21财报前注意获利了结部分仓位对冲波动风险</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#AI</span><span class="tag">#半导体</span><span class="tag">#增长</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">QQQ</div><div class="wc-name">纳斯达克100 ETF</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">520.30</div><div class="wc-price-chg up">+1.1%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>72</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">科技股集中度风险加剧,但AI周期未结束</div>
|
||
<div class="wc-driver">前10大持仓占比超50%,市场广度恶化但AI基础设施投入仍处上升期,沃什就职令政策不确定性上升</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 550</span><span class="wc-target-down">↓ 480</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
|
||
<div class="wc-action">持有为主,VIX低于18显示波动率被低估,建议配置5-10%看跌期权对冲</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#科技</span><span class="tag">#ETF</span><span class="tag">#波动</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">SPY</div><div class="wc-name">标普500 ETF</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">744.50</div><div class="wc-price-chg up">+0.6%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>68</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">估值偏高但盈利增速支撑,利率风险是最大变量</div>
|
||
<div class="wc-driver">Q1盈利增速27%创2021年来最高,但远期市盈率20.9倍高于10年均值18.9倍,10年期国债破4.5%是估值承压拐点</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 780</span><span class="wc-target-down">↓ 700</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
|
||
<div class="wc-action">标配持有,若国债收益率突破4.7%需减仓至低配,关注金融与公用事业板块轮动机会</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#大盘</span><span class="tag">#ETF</span><span class="tag">#估值</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">BTC-USD</div><div class="wc-name">比特币</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">80,304</div><div class="wc-price-chg down">-0.9%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge SELL">SELL</span>
|
||
<span class="wc-score">评分 <span>38</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">跌破关键支撑,技术面转弱宏观逆风加剧</div>
|
||
<div class="wc-driver">失守82,000美元阻力后回落,实际利率上升与美元走强双重打击,铜金比突破200日均线暗示比特币或跟随大宗商品走弱</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 85,000</span><span class="wc-target-down">↓ 72,000</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge high">风险:high</span></div>
|
||
<div class="wc-action">建议减持至5%以下仓位,若跌破75,000需止损,等待49,000-58,000区间再布局</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#加密货币</span><span class="tag">#风险</span><span class="tag">#宏观</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">510300.SS</div><div class="wc-name">沪深300 ETF</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">4.15</div><div class="wc-price-chg up">+0.3%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>58</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">政策底已现但市场底未明,量能萎缩显示信心不足</div>
|
||
<div class="wc-driver">两市成交3.2万亿缩量,北向资金持续流出,但半导体国产替代与新能源政策支持力度不减,特朗普访华结果影响外资情绪</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 4.50</span><span class="wc-target-down">↓ 3.80</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge medium">风险:medium</span></div>
|
||
<div class="wc-action">维持中性配置,聚焦半导体设备、电力电网等高景气细分赛道,等待放量突破再加仓</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#A股</span><span class="tag">#ETF</span><span class="tag">#政策</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">GC=F</div><div class="wc-name">黄金期货</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">4,700</div><div class="wc-price-chg down">-0.3%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge BUY">BUY</span>
|
||
<span class="wc-score">评分 <span>75</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">短期调整是加仓良机,地缘与通胀双重支撑</div>
|
||
<div class="wc-driver">美元走强与实际利率上升压制金价,但伊朗战争悬而未决、央行购金趋势未变,印度上调黄金关税反而暗示需求旺盛</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 5,200</span><span class="wc-target-down">↓ 4,400</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge low">风险:low</span></div>
|
||
<div class="wc-action">回调至4,600美元下方分批买入,配置5-10%作为通胀与地缘风险对冲</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#黄金</span><span class="tag">#避险</span><span class="tag">#通胀对冲</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">CL=F</div><div class="wc-name">WTI原油期货</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">102.18</div><div class="wc-price-chg up">+4.2%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>70</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">战争溢价高企但和谈传闻令波动加剧</div>
|
||
<div class="wc-driver">霍尔木兹海峡封锁令全球20%石油贸易受阻,Shell警告供应缓冲耗尽,但特朗普-习近平会谈若取得进展油价或暴跌10%</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 118</span><span class="wc-target-down">↓ 85</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge high">风险:high</span></div>
|
||
<div class="wc-action">持有能源股ETF(XLE)而非原油期货,波动率过高不适合激进追涨,和谈破裂再加仓</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#原油</span><span class="tag">#地缘</span><span class="tag">#通胀</span></div>
|
||
</div>
|
||
<div class="watchlist-card">
|
||
<div class="wc-header">
|
||
<div><div class="wc-ticker">TSLA</div><div class="wc-name">特斯拉</div></div>
|
||
<div class="wc-price"><div class="wc-price-val">225.80</div><div class="wc-price-chg up">+1.5%</div></div>
|
||
</div>
|
||
<div class="wc-signal-row">
|
||
<span class="signal-badge HOLD">HOLD</span>
|
||
<span class="wc-score">评分 <span>55</span>/100</span>
|
||
</div>
|
||
<div class="wc-conclusion">马斯克访华提振情绪,但基本面仍待改善</div>
|
||
<div class="wc-driver">随特朗普访华暗示中国政策松绑,推出低首付融资方案对抗本土竞争,但Q1交付量下滑8.6%、xAI投资引发治理担忧</div>
|
||
<div class="wc-targets"><span class="wc-target-up">↑ 280</span><span class="wc-target-down">↓ 180</span></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><span class="risk-badge high">风险:high</span></div>
|
||
<div class="wc-action">暂持有观望,若中国市场份额回升可加仓,但需警惕马斯克政治风险与FSD监管不确定性</div>
|
||
<div class="tags" style="margin-top:8px"><span class="tag">#电动车</span><span class="tag">#中国</span><span class="tag">#成长</span></div>
|
||
</div>
|
||
</div>
|
||
<!-- WATCHLIST_ANALYSIS:END -->
|
||
<!-- WATCHLIST_ANALYSIS:END -->
|
||
</div>
|
||
</section>
|
||
|
||
<!-- MACRO + DEBATE (2-up) -->
|
||
<div class="two-up">
|
||
<div class="section-block sec-anchor" id="sec-macro">
|
||
<div class="card" style="height:100%">
|
||
<div class="section-label">📈 宏观指标 · Macro</div>
|
||
<!-- MACRO:START -->
|
||
<div class="macro-grid">
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">CPI YoY (4月)</div>
|
||
<div class="macro-value macro-value-down">3.8%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 3.3%</div>
|
||
<div class="macro-desc">消费者价格指数创近三年新高,能源占月增40%,实际工资负增长</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">Core CPI YoY (4月)</div>
|
||
<div class="macro-value macro-value-down">2.8%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 2.6%</div>
|
||
<div class="macro-desc">核心通胀月增0.4%,住房租金因去年政府关门统计扭曲而跳涨0.6%</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">PPI YoY (4月)</div>
|
||
<div class="macro-value macro-value-down">6.0%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 4.0%</div>
|
||
<div class="macro-desc">生产者价格指数年增6%创2022年以来最高,批发通胀失控</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">PPI MoM (4月)</div>
|
||
<div class="macro-value macro-value-down">1.4%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 0.5%</div>
|
||
<div class="macro-desc">月增1.4%远超预期0.5%,汽油价格跳涨15.7%为主因</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">10年期美债收益率</div>
|
||
<div class="macro-value macro-value-up">4.47%</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 4.27%</div>
|
||
<div class="macro-desc">升至2025年7月以来新高,30年期破5%创2025年5月来首次</div>
|
||
</div>
|
||
<div class="macro-card dir-down">
|
||
<div class="macro-indicator">实际平均时薪 YoY</div>
|
||
<div class="macro-value macro-value-down">-0.3%</div>
|
||
<div class="macro-prev"><span class="arrow down">↓</span> 前值: +0.2%</div>
|
||
<div class="macro-desc">三年来首次工资增长被通胀完全吞噬,中低收入家庭财务压力加剧</div>
|
||
</div>
|
||
<div class="macro-card dir-down">
|
||
<div class="macro-indicator">密歇根消费者信心指数(5月初)</div>
|
||
<div class="macro-value macro-value-down">48.2</div>
|
||
<div class="macro-prev"><span class="arrow down">↓</span> 前值: 49.9</div>
|
||
<div class="macro-desc">创历史新低,油价飙升令消费者信心受重创</div>
|
||
</div>
|
||
<div class="macro-card dir-up">
|
||
<div class="macro-indicator">美元指数 DXY</div>
|
||
<div class="macro-value macro-value-up">98.28</div>
|
||
<div class="macro-prev"><span class="arrow up">↑</span> 前值: 97.84</div>
|
||
<div class="macro-desc">因通胀高企降息预期破灭而走强,但仍较3月伊朗战争高点103回落</div>
|
||
</div>
|
||
</div>
|
||
<!-- MACRO:END -->
|
||
<!-- MACRO:END -->
|
||
</div>
|
||
</div>
|
||
<div class="section-block sec-anchor" id="sec-debate">
|
||
<div class="card" style="height:100%">
|
||
<div class="section-label">⚔️ 多空辩论 · Bull vs Bear</div>
|
||
<!-- MARKET_DEBATE:START -->
|
||
<div class="debate-container">
|
||
<div class="debate-header">标普500 本周展望</div>
|
||
<div class="debate-sides">
|
||
<div class="debate-side bull">
|
||
<div class="debate-side-title">🐂 多方看涨</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>Q1盈利增速27%创三年新高,企业盈利超预期18%</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>AI资本开支7250亿美元超预期,科技股基本面扎实</div>
|
||
<div class="debate-point"><span class="conf-badge medium">medium</span>摩根士丹利上调年底目标至8000点,伊朗风险已定价</div>
|
||
</div>
|
||
<div class="debate-side bear">
|
||
<div class="debate-side-title">🐻 空方看跌</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>通胀失控令降息无望,30%概率年内加息侵蚀估值</div>
|
||
<div class="debate-point"><span class="conf-badge high">high</span>市场广度恶化仅143只成分股上涨,'一股独大'难持续</div>
|
||
<div class="debate-point"><span class="conf-badge medium">medium</span>10年期国债破4.5%临界点,实际利率上升压制股票吸引力</div>
|
||
</div>
|
||
</div>
|
||
<div class="debate-verdict">
|
||
<div class="verdict-label">裁判结论 <span class="verdict-lean bullish">BULLISH</span></div>
|
||
<div class="verdict-text">短期多头占优但需警惕6月FOMC,科技股盈利支撑估值但利率是达摩克利斯之剑。建议持有QQQ但配置5-10%看跌期权,若10年期国债破4.7%或VIX升破22需果断减仓</div>
|
||
</div>
|
||
</div>
|
||
<!-- MARKET_DEBATE:END -->
|
||
<!-- MARKET_DEBATE:END -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- EARNINGS + SECTORS (2-up) -->
|
||
<div class="two-up">
|
||
<div class="section-block sec-anchor" id="sec-earnings">
|
||
<div class="card">
|
||
<div class="section-label">💼 财报追踪 · Earnings</div>
|
||
<!-- EARNINGS:START -->
|
||
<div class="earnings-grid">
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">AAPL</div>
|
||
<div class="earnings-company">Apple</div>
|
||
<span class="earnings-beat-badge beat">BEAT ✓</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual beat">$2.01</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$1.95</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$111.2B</span></div>
|
||
<div class="earnings-highlight">Q1财报超预期,服务收入创新高,供应受限但AI iPhone需求强劲</div>
|
||
</div>
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">MSFT</div>
|
||
<div class="earnings-company">Microsoft</div>
|
||
<span class="earnings-beat-badge beat">BEAT ✓</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual beat">$4.27</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$4.06</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$82.9B</span></div>
|
||
<div class="earnings-highlight">Azure增长稳健,AI资本开支升至990亿美元,运营利润率收窄至67%</div>
|
||
</div>
|
||
<div class="earnings-card pending">
|
||
<div class="earnings-ticker">NVDA</div>
|
||
<div class="earnings-company">Nvidia</div>
|
||
<span class="earnings-beat-badge pending">UPCOMING</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$预计6.20</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">REPORT DATE</div>
|
||
<div class="eps-value est" style="font-size:0.75rem;">2026-05-28</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>预计$350B</span></div>
|
||
<div class="earnings-highlight">Blackwell与Rubin订单超5000亿美元,黄仁勋随特朗普访华暗示对华出口松绑</div>
|
||
</div>
|
||
<div class="earnings-card miss">
|
||
<div class="earnings-ticker">TSLA</div>
|
||
<div class="earnings-company">Tesla</div>
|
||
<span class="earnings-beat-badge miss">MISS ✗</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual miss">$0.42</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$0.51</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$21.3B</span></div>
|
||
<div class="earnings-highlight">Q1交付量下滑,能源业务增长但汽车业务承压,xAI投资引发利益冲突担忧</div>
|
||
</div>
|
||
<div class="earnings-card miss">
|
||
<div class="earnings-ticker">BABA</div>
|
||
<div class="earnings-company">Alibaba</div>
|
||
<span class="earnings-beat-badge miss">MISS ✗</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual miss">$1.18</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$1.25</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$30.1B</span></div>
|
||
<div class="earnings-highlight">Q4营收不及预期,AI与云扩张投入拖累,云收入增38%至61.3亿美元</div>
|
||
</div>
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">F</div>
|
||
<div class="earnings-company">Ford</div>
|
||
<span class="earnings-beat-badge beat">BEAT ✓</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual beat">$0.58</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$0.52</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$42.8B</span></div>
|
||
<div class="earnings-highlight">Q1超预期,推出Ford Energy储能子公司,摩根士丹利看好能源转型</div>
|
||
</div>
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">SNDK</div>
|
||
<div class="earnings-company">SanDisk</div>
|
||
<span class="earnings-beat-badge beat">BEAT ✓</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual beat">$23.41</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$14.62</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$5.95B</span></div>
|
||
<div class="earnings-highlight">大幅超预期,AI数据中心存储需求爆发</div>
|
||
</div>
|
||
<div class="earnings-card beat">
|
||
<div class="earnings-ticker">INTC</div>
|
||
<div class="earnings-company">Intel</div>
|
||
<span class="earnings-beat-badge beat">BEAT ✓</span>
|
||
<div class="earnings-eps">
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS ACTUAL</div>
|
||
<div class="eps-value actual beat">$0.29</div>
|
||
</div>
|
||
<div class="eps-item">
|
||
<div class="eps-label">EPS EST.</div>
|
||
<div class="eps-value est">$0.02</div>
|
||
</div>
|
||
</div>
|
||
<div class="earnings-revenue">收入: <span>$13.6B</span></div>
|
||
<div class="earnings-highlight">扭亏为盈超预期,代工业务回暖但仍落后台积电</div>
|
||
</div>
|
||
</div>
|
||
<!-- EARNINGS:END -->
|
||
<!-- EARNINGS:END -->
|
||
</div>
|
||
</div>
|
||
<div class="section-block sec-anchor" id="sec-sectors">
|
||
<div class="card">
|
||
<div class="section-label">🏭 板块表现 · Sectors</div>
|
||
<!-- SECTORS:START -->
|
||
<div class="sectors-list">
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">通信服务</div><div class="sector-name-en">Communication Services</div></div>
|
||
<div class="sector-etf">XLC</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:100%"></div></div>
|
||
<div class="sector-pct up">+2.65%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">信息技术</div><div class="sector-name-en">Information Technology</div></div>
|
||
<div class="sector-etf">XLK</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:43%"></div></div>
|
||
<div class="sector-pct up">+0.98%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">非必需消费</div><div class="sector-name-en">Consumer Discretionary</div></div>
|
||
<div class="sector-etf">XLY</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:35%"></div></div>
|
||
<div class="sector-pct up">+0.75%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">工业</div><div class="sector-name-en">Industrials</div></div>
|
||
<div class="sector-etf">XLI</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:54%"></div></div>
|
||
<div class="sector-pct up">+1.30%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">材料</div><div class="sector-name-en">Materials</div></div>
|
||
<div class="sector-etf">XLB</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:54%"></div></div>
|
||
<div class="sector-pct up">+1.30%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">能源</div><div class="sector-name-en">Energy</div></div>
|
||
<div class="sector-etf">XLE</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:98%"></div></div>
|
||
<div class="sector-pct up">+2.60%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">金融</div><div class="sector-name-en">Financials</div></div>
|
||
<div class="sector-etf">XLF</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:46%"></div></div>
|
||
<div class="sector-pct down">-1.07%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">医疗</div><div class="sector-name-en">Health Care</div></div>
|
||
<div class="sector-etf">XLV</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar up" style="width:24%"></div></div>
|
||
<div class="sector-pct up">+0.42%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">房地产</div><div class="sector-name-en">Real Estate</div></div>
|
||
<div class="sector-etf">XLRE</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:40%"></div></div>
|
||
<div class="sector-pct down">-0.90%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">公用事业</div><div class="sector-name-en">Utilities</div></div>
|
||
<div class="sector-etf">XLU</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:52%"></div></div>
|
||
<div class="sector-pct down">-1.26%</div>
|
||
</div>
|
||
<div class="sector-row">
|
||
<div><div class="sector-name">必需消费</div><div class="sector-name-en">Consumer Staples</div></div>
|
||
<div class="sector-etf">XLP</div>
|
||
<div class="sector-bar-wrap"><div class="sector-bar down" style="width:43%"></div></div>
|
||
<div class="sector-pct down">-1.00%</div>
|
||
</div>
|
||
</div>
|
||
<!-- SECTORS:END -->
|
||
<!-- SECTORS:END -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- REPLAY + CALENDAR (2-up) -->
|
||
<div class="two-up">
|
||
<div class="section-block sec-anchor" id="sec-replay">
|
||
<div class="card">
|
||
<div class="section-label">📽️ 大盘复盘 · Replay</div>
|
||
<!-- MARKET_REPLAY:START -->
|
||
<div class="replay-grid"><div class="replay-card">
|
||
<div class="replay-card-title">🇺🇸 美股</div>
|
||
<div class="replay-summary">科技股一骑绝尘但市场广度恶化,通胀数据未撼动AI信仰</div>
|
||
<div class="ad-bar-wrap">
|
||
<span class="ad-label-up">↑678</span>
|
||
<div class="ad-bar adv" style="width:36px;max-width:80px"></div>
|
||
<div class="ad-bar dec" style="width:64px;max-width:80px"></div>
|
||
<span class="ad-label-dn">↓1210</span>
|
||
</div>
|
||
<div class="replay-stats">
|
||
<div class="replay-stat"><div class="replay-stat-label">热门板块</div><div class="replay-stat-val">通信服务+2.65%</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">领涨标的</div><div class="replay-stat-val">Ford F +13.18% (储能业务)</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">创52周新高</div><div class="replay-stat-val">82</div></div>
|
||
</div>
|
||
</div><div class="replay-card">
|
||
<div class="replay-card-title">🇨🇳 A股</div>
|
||
<div class="replay-summary">缩量震荡显示观望浓厚,国产替代主线坚挺</div>
|
||
<div class="ad-bar-wrap">
|
||
<span class="ad-label-up">↑2100</span>
|
||
<div class="ad-bar adv" style="width:42px;max-width:80px"></div>
|
||
<div class="ad-bar dec" style="width:58px;max-width:80px"></div>
|
||
<span class="ad-label-dn">↓2900</span>
|
||
</div>
|
||
<div class="replay-stats">
|
||
<div class="replay-stat"><div class="replay-stat-label">热门板块</div><div class="replay-stat-val">半导体设备</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">领涨标的</div><div class="replay-stat-val">中际旭创 突破千元</div></div>
|
||
<div class="replay-stat"><div class="replay-stat-label">北向资金</div><div class="replay-stat-val">-12亿</div></div>
|
||
</div>
|
||
</div></div>
|
||
<!-- MARKET_REPLAY:END -->
|
||
<!-- MARKET_REPLAY:END -->
|
||
</div>
|
||
</div>
|
||
<div class="section-block sec-anchor" id="sec-calendar">
|
||
<div class="card">
|
||
<div class="section-label">📅 本周日程 · Calendar</div>
|
||
<!-- CALENDAR:START -->
|
||
<div class="calendar-grid">
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周四 5/14<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">零售销售月率</div>
|
||
<div class="cal-values">预期: <span>+0.3%</span> · 前值: +0.1%</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item medium">
|
||
<div class="cal-date">周四 5/14<br><span style="font-size:0.6rem;color:var(--dimmed)">8:30 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">初请失业金人数</div>
|
||
<div class="cal-values">预期: <span>225K</span> · 前值: 223K</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周五 5/15<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
|
||
<div>
|
||
<div class="cal-event">Kevin Warsh正式就职美联储主席</div>
|
||
<div class="cal-values">预期: <span>N/A</span> · 前值: N/A</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item medium">
|
||
<div class="cal-date">周五 5/15<br><span style="font-size:0.6rem;color:var(--dimmed)">9:45 AM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">5月Markit制造业PMI初值</div>
|
||
<div class="cal-values">预期: <span>51.5</span> · 前值: 51.2</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item medium">
|
||
<div class="cal-date">周六-周日 5/17-5/18<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
|
||
<div>
|
||
<div class="cal-event">G7财长会议(意大利)</div>
|
||
<div class="cal-values">预期: <span>讨论伊朗制裁与能源危机</span> · 前值: N/A</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周一 5/19<br><span style="font-size:0.6rem;color:var(--dimmed)">全天</span></div>
|
||
<div>
|
||
<div class="cal-event">特朗普-习近平会谈成果公布</div>
|
||
<div class="cal-values">预期: <span>关注贸易协议与台湾军售</span> · 前值: N/A</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周二 5/20<br><span style="font-size:0.6rem;color:var(--dimmed)">2:00 PM ET</span></div>
|
||
<div>
|
||
<div class="cal-event">4月FOMC会议纪要公布</div>
|
||
<div class="cal-values">预期: <span>解读8-4分裂投票细节</span> · 前值: N/A</div>
|
||
</div>
|
||
</div>
|
||
<div class="cal-item high">
|
||
<div class="cal-date">周三 5/21<br><span style="font-size:0.6rem;color:var(--dimmed)">盘后</span></div>
|
||
<div>
|
||
<div class="cal-event">Nvidia Q1财报</div>
|
||
<div class="cal-values">预期: <span>EPS $6.20</span> · 前值: EPS $5.16</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- CALENDAR:END -->
|
||
<!-- CALENDAR:END -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- end main-col -->
|
||
|
||
<!-- ── RIGHT / SIDEBAR ────────────────────────────────── -->
|
||
<div class="sidebar-col">
|
||
|
||
<!-- LEADERS -->
|
||
<div class="section-block sec-anchor mb16" id="sec-leaders">
|
||
<div class="card">
|
||
<div class="section-label">👔 领袖观点 · Leaders</div>
|
||
<!-- LEADERS:START -->
|
||
<div class="leader-card">
|
||
<div class="leader-header">
|
||
<div class="leader-avatar jd">JD</div>
|
||
<div class="leader-meta">
|
||
<div class="leader-name">杰米·戴蒙 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Jamie Dimon</span></div>
|
||
<div class="leader-role">摩根大通CEO</div>
|
||
</div>
|
||
<div class="leader-date">4月11日</div>
|
||
</div>
|
||
<div class="leader-quote">"利率对几乎所有资产价格都像地心引力一样"</div>
|
||
<div class="leader-body">戴蒙在2026年致股东信中重申巴菲特26年前的警告,强调通胀升温将导致利率走高,进而对资产估值施加向下压力。他警告当前经济环境可能导致利率长期维持高位,即便没有衰退,持续的通胀也会成为'派对上的臭鼬'。这番言论与伊朗战争推高能源成本的背景高度契合。</div>
|
||
<div class="tags"><span class="tag">#利率</span><span class="tag">#通胀</span></div>
|
||
</div>
|
||
<div class="leader-card">
|
||
<div class="leader-header">
|
||
<div class="leader-avatar default">KW</div>
|
||
<div class="leader-meta">
|
||
<div class="leader-name">凯文·沃什 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Kevin Warsh</span></div>
|
||
<div class="leader-role">新任美联储主席</div>
|
||
</div>
|
||
<div class="leader-date">5月13日</div>
|
||
</div>
|
||
<div class="leader-quote">"央行需要政权更迭"</div>
|
||
<div class="leader-body">沃什今日以54-45票获参议院确认,将于周五接替鲍威尔成为第17任美联储主席,这是史上最分裂的美联储主席投票。他此前曾批评QE规模过大,主张缩表并警告通胀风险。尽管特朗普期待降息,但4月CPI飙升至3.8%令沃什面临两难:降息可能加剧通胀,不降则激怒白宫。首次FOMC会议定于6月16-17日。</div>
|
||
<div class="tags"><span class="tag">#美联储</span><span class="tag">#政策</span></div>
|
||
</div>
|
||
<div class="leader-card">
|
||
<div class="leader-header">
|
||
<div class="leader-avatar wb">WB</div>
|
||
<div class="leader-meta">
|
||
<div class="leader-name">沃伦·巴菲特 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Warren Buffett</span></div>
|
||
<div class="leader-role">伯克希尔哈撒韦董事长</div>
|
||
</div>
|
||
<div class="leader-date">5月初</div>
|
||
</div>
|
||
<div class="leader-quote">"只有当潮水退去时,你才会知道谁在裸泳"</div>
|
||
<div class="leader-body">巴菲特在伯克希尔年会上重申利率是影响投资回报的最重要因素,这句26年前的名言被戴蒙引用警示当前市场。巴菲特强调在高利率环境下,投资者对回报的预期需要降低,否则只能以更低价格买入股票。他表示在5月卸任CEO后将保持低调,专注长期价值投资。</div>
|
||
<div class="tags"><span class="tag">#价值投资</span><span class="tag">#利率</span></div>
|
||
</div>
|
||
<div class="leader-card">
|
||
<div class="leader-header">
|
||
<div class="leader-avatar jp">JP</div>
|
||
<div class="leader-meta">
|
||
<div class="leader-name">杰罗姆·鲍威尔 <span style="color:var(--muted);font-weight:400;font-size:0.78rem;">Jerome Powell</span></div>
|
||
<div class="leader-role">卸任美联储主席</div>
|
||
</div>
|
||
<div class="leader-date">4月29日</div>
|
||
</div>
|
||
<div class="leader-quote">"我将留任理事直到调查彻底结束"</div>
|
||
<div class="leader-body">鲍威尔任期将于5月15日到期,但他宣布将罕见地留任理事至2028年,直到司法部对美联储总部装修的调查完全结束。他在4月FOMC会议上指出通胀预期中值升至2.7%,远高于2%目标。鲍威尔强调将保持低调,'只有一位美联储主席,当沃什确认就职后,他就是主席'。这是近80年来首次前主席留任理事。</div>
|
||
<div class="tags"><span class="tag">#美联储</span><span class="tag">#政策</span></div>
|
||
</div>
|
||
<!-- LEADERS:END -->
|
||
<!-- LEADERS:END -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CENTRAL BANKS -->
|
||
<div class="section-block sec-anchor mb16" id="sec-banks">
|
||
<div class="card">
|
||
<div class="section-label">🏦 央行动态 · Central Banks</div>
|
||
<!-- CENTRAL_BANKS:START -->
|
||
<div class="cb-grid">
|
||
<div class="cb-card">
|
||
<div class="cb-header">
|
||
<div>
|
||
<div class="cb-name">美联储</div>
|
||
<div class="cb-name-en">Federal Reserve</div>
|
||
</div>
|
||
<span class="bias-badge hawkish">Hawkish</span>
|
||
</div>
|
||
<div class="cb-rate">3.50-3.75%</div>
|
||
<div class="cb-action">维持利率3.50-3.75%不变,4月会议8-4分裂投票创1992年来最大分歧</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-16</span></div>
|
||
<div class="cb-note">Kevin Warsh今日确认就职,鲍威尔留任理事。通胀飙升令年内降息无望,30%概率加息</div>
|
||
</div>
|
||
<div class="cb-card">
|
||
<div class="cb-header">
|
||
<div>
|
||
<div class="cb-name">欧洲央行</div>
|
||
<div class="cb-name-en">European Central Bank</div>
|
||
</div>
|
||
<span class="bias-badge neutral">Neutral</span>
|
||
</div>
|
||
<div class="cb-rate">2.00%</div>
|
||
<div class="cb-action">维持存款利率2.00%不变,降息周期已结束</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-12</span></div>
|
||
<div class="cb-note">ECB认为已达'好地方':通胀接近2%且增长为正,除非出现意外否则不会进一步降息</div>
|
||
</div>
|
||
<div class="cb-card">
|
||
<div class="cb-header">
|
||
<div>
|
||
<div class="cb-name">中国人民银行</div>
|
||
<div class="cb-name-en">People's Bank of China</div>
|
||
</div>
|
||
<span class="bias-badge dovish">Dovish</span>
|
||
</div>
|
||
<div class="cb-rate">1年期LPR 3.45%</div>
|
||
<div class="cb-action">维持LPR利率不变,但通过公开市场操作注入流动性</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-20</span></div>
|
||
<div class="cb-note">预计年内降息20bp、降准100bp支持经济,特朗普访华可能影响货币政策节奏</div>
|
||
</div>
|
||
<div class="cb-card">
|
||
<div class="cb-header">
|
||
<div>
|
||
<div class="cb-name">日本央行</div>
|
||
<div class="cb-name-en">Bank of Japan</div>
|
||
</div>
|
||
<span class="bias-badge hawkish">Hawkish</span>
|
||
</div>
|
||
<div class="cb-rate">0.75%</div>
|
||
<div class="cb-action">4月维持短期政策利率0.75%不变,6-3投票3人主张加息至1.0%</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-13</span></div>
|
||
<div class="cb-note">上调2026财年核心通胀预期至2.8%,因油价上涨。多位委员支持尽快加息防通胀超调</div>
|
||
</div>
|
||
<div class="cb-card">
|
||
<div class="cb-header">
|
||
<div>
|
||
<div class="cb-name">英国央行</div>
|
||
<div class="cb-name-en">Bank of England</div>
|
||
</div>
|
||
<span class="bias-badge hawkish">Hawkish</span>
|
||
</div>
|
||
<div class="cb-rate">3.75%</div>
|
||
<div class="cb-action">4月维持利率3.75%不变,8-1投票首席经济学家主张加息</div>
|
||
<div class="cb-next">下次会议: <span class="font-mono" style="color:var(--neutral)">2026-06-19</span></div>
|
||
<div class="cb-note">市场预计年内还有两次25bp加息,将利率推至高于美联储水平以对抗通胀</div>
|
||
</div>
|
||
</div>
|
||
<!-- CENTRAL_BANKS:END -->
|
||
<!-- CENTRAL_BANKS:END -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TRADINGVIEW CHARTS -->
|
||
<div class="section-block mb16">
|
||
<div class="card" style="padding:14px 16px">
|
||
<div class="section-label">📈 行情图表 · Live Charts</div>
|
||
<div class="tradingview-widget-container">
|
||
<div class="tradingview-widget-container__widget"></div>
|
||
<script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-market-overview.js" async>
|
||
{
|
||
"colorTheme": "dark",
|
||
"dateRange": "1D",
|
||
"showChart": true,
|
||
"locale": "zh_CN",
|
||
"isTransparent": true,
|
||
"showSymbolLogo": true,
|
||
"showFloatingTooltip": false,
|
||
"width": "100%",
|
||
"height": "480",
|
||
"tabs": [
|
||
{
|
||
"title": "🇺🇸 美股",
|
||
"symbols": [
|
||
{"s":"FOREXCOM:SPXUSD","d":"S&P 500"},
|
||
{"s":"FOREXCOM:NSXUSD","d":"Nasdaq 100"},
|
||
{"s":"FOREXCOM:DJI","d":"道琼斯"},
|
||
{"s":"CBOE:VIX","d":"VIX 恐慌指数"},
|
||
{"s":"TVC:US10Y","d":"美10年债"}
|
||
],
|
||
"originalTitle": "US"
|
||
},
|
||
{
|
||
"title": "🇨🇳 中国",
|
||
"symbols": [
|
||
{"s":"SSE:000001","d":"上证指数"},
|
||
{"s":"SZSE:399006","d":"创业板指"},
|
||
{"s":"HKEX:HSI","d":"恒生指数"},
|
||
{"s":"FX:USDCNH","d":"离岸人民币"},
|
||
{"s":"HKEX:2318","d":"中国平安"}
|
||
],
|
||
"originalTitle": "China"
|
||
},
|
||
{
|
||
"title": "🛢️ 大宗",
|
||
"symbols": [
|
||
{"s":"TVC:GOLD","d":"黄金"},
|
||
{"s":"NYMEX:CL1!","d":"原油 WTI"},
|
||
{"s":"COMEX:SI1!","d":"白银"},
|
||
{"s":"TVC:DXY","d":"美元指数"}
|
||
],
|
||
"originalTitle": "Commodities"
|
||
},
|
||
{
|
||
"title": "₿ 加密",
|
||
"symbols": [
|
||
{"s":"BINANCE:BTCUSDT","d":"Bitcoin"},
|
||
{"s":"BINANCE:ETHUSDT","d":"Ethereum"},
|
||
{"s":"BINANCE:SOLUSDT","d":"Solana"}
|
||
],
|
||
"originalTitle": "Crypto"
|
||
}
|
||
]
|
||
}
|
||
</script>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- end sidebar-col -->
|
||
|
||
</div><!-- end content-grid -->
|
||
|
||
<!-- MY DASHBOARD (collapsed drawer) -->
|
||
<div class="my-drawer sec-anchor" id="sec-my">
|
||
<button class="my-drawer-toggle" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
|
||
<span>⭐ 我的工作台 · My Dashboard</span>
|
||
<span class="drawer-icon">▾</span>
|
||
</button>
|
||
<div class="my-drawer-body">
|
||
<div class="card">
|
||
<div class="profile-bar">
|
||
<span class="profile-label">👤 用户:</span>
|
||
<select id="profile-select" onchange="profileSwitch()"></select>
|
||
<button onclick="profileNew()">+ 新建</button>
|
||
<button onclick="profileDelete()">删除</button>
|
||
</div>
|
||
<div class="personal-header">
|
||
<div class="section-label">⭐ 我的工作台 · My Dashboard</div>
|
||
<span class="personal-privacy">🔒 数据存本地 · 不上传服务器</span>
|
||
</div>
|
||
<div class="ptabs">
|
||
<button class="ptab active" id="ptab-wl" onclick="switchTab(event,'wl')">📋 自选股</button>
|
||
<button class="ptab" id="ptab-pf" onclick="switchTab(event,'pf')">💼 持仓盈亏</button>
|
||
<button class="ptab" id="ptab-sim" onclick="switchTab(event,'sim')">📊 模拟器</button>
|
||
</div>
|
||
<div id="panel-wl">
|
||
<div class="add-row">
|
||
<input id="wl-sym" placeholder="代码,如 AAPL / 000001.SS / BTC-USD" />
|
||
<input id="wl-name" placeholder="备注名(可选)" />
|
||
<button onclick="wlAdd()">+ 添加</button>
|
||
</div>
|
||
<div id="wl-empty" class="p-empty">还没有自选股,输入代码开始追踪 →</div>
|
||
<div id="wl-list" class="wl-list"></div>
|
||
</div>
|
||
<div id="panel-pf" style="display:none">
|
||
<div class="add-row">
|
||
<input id="pf-sym" placeholder="代码,如 AAPL / TSLA" />
|
||
<input id="pf-shares" type="number" min="0.0001" step="0.0001" placeholder="数量" />
|
||
<input id="pf-cost" type="number" min="0" step="0.01" placeholder="买入均价 ($)" />
|
||
<button onclick="pfAdd()">+ 添加持仓</button>
|
||
</div>
|
||
<div id="pf-empty" class="p-empty">还没有持仓记录,输入持仓开始计算浮盈浮亏 →</div>
|
||
<div id="pf-summary" class="pf-summary" style="display:none">
|
||
<div class="pf-sum-item">总成本<span id="sum-cost">—</span></div>
|
||
<div class="pf-sum-item">总市值<span id="sum-value">—</span></div>
|
||
<div class="pf-sum-item">总盈亏<span id="sum-pnl">—</span></div>
|
||
<div class="pf-sum-item">盈亏率<span id="sum-pct">—</span></div>
|
||
</div>
|
||
<div id="pf-list" class="pf-list"></div>
|
||
</div>
|
||
<div id="panel-sim" style="display:none">
|
||
<div class="sim-section">
|
||
<div>
|
||
<div class="sim-label">总投资金额</div>
|
||
<div class="sim-capital-row">
|
||
<input type="number" id="sim-capital" min="0" step="100" value="10000" oninput="simUpdate()" />
|
||
<select id="sim-currency" onchange="simUpdate()">
|
||
<option value="USD">USD $</option>
|
||
<option value="CAD">CAD $</option>
|
||
<option value="CNY">CNY ¥</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div class="sim-label">资产配置</div>
|
||
<div class="sim-add-row">
|
||
<input id="sim-sym" placeholder="代码,如 AAPL" style="width:100px" />
|
||
<input id="sim-alias" placeholder="备注名" style="width:85px" />
|
||
<input type="number" id="sim-pct" placeholder="分配%" min="0" max="100" step="1" style="width:65px" />
|
||
<input type="number" id="sim-entry" placeholder="买入价(选填)" min="0" step="0.01" style="width:110px" />
|
||
<button onclick="simAddAsset()">+ 添加</button>
|
||
<span style="font-size:0.68rem;color:var(--dimmed)">不填则自动记录当前价</span>
|
||
</div>
|
||
<div id="sim-pct-total" class="sim-pct-total" style="margin-top:4px">已分配:0%</div>
|
||
</div>
|
||
<div id="sim-alloc-bar" class="sim-alloc-bar" style="display:none"></div>
|
||
<div id="sim-assets-wrap" style="display:none">
|
||
<table class="sim-assets-table">
|
||
<thead><tr><th>代码</th><th>备注</th><th>分配%</th><th>投入金额</th><th>买入价</th><th>操作</th></tr></thead>
|
||
<tbody id="sim-assets-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<div id="sim-scenario-section" style="display:none">
|
||
<div class="sim-label">收益情景(年化%)</div>
|
||
<div class="sim-scenario-row">
|
||
<label>😨 悲观 <input type="number" id="sim-bear" value="-20" step="1" oninput="simUpdate()" /></label>
|
||
<label>📊 中性 <input type="number" id="sim-base" value="8" step="1" oninput="simUpdate()" /></label>
|
||
<label>🚀 乐观 <input type="number" id="sim-bull" value="25" step="1" oninput="simUpdate()" /></label>
|
||
</div>
|
||
<div class="sim-horizon-row">
|
||
<span>时间跨度:</span>
|
||
<button class="sim-hbtn" data-h="1m" onclick="simSetHorizon(this,'1m')">1月</button>
|
||
<button class="sim-hbtn" data-h="3m" onclick="simSetHorizon(this,'3m')">3月</button>
|
||
<button class="sim-hbtn" data-h="6m" onclick="simSetHorizon(this,'6m')">6月</button>
|
||
<button class="sim-hbtn active" data-h="1y" onclick="simSetHorizon(this,'1y')">1年</button>
|
||
<button class="sim-hbtn" data-h="3y" onclick="simSetHorizon(this,'3y')">3年</button>
|
||
<button class="sim-hbtn" data-h="5y" onclick="simSetHorizon(this,'5y')">5年</button>
|
||
</div>
|
||
</div>
|
||
<div id="sim-returns-wrap" style="display:none">
|
||
<div class="sim-label">预期收益预测</div>
|
||
<table class="sim-returns-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="text-align:left">资产</th>
|
||
<th>投入</th>
|
||
<th>📈 实际</th>
|
||
<th>😨 悲观</th>
|
||
<th>📊 中性</th>
|
||
<th>🚀 乐观</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="sim-returns-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<div class="sim-actions">
|
||
<button class="sim-btn sim-btn-secondary" onclick="simReset()">🗑 重置</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- end container -->
|
||
</div><!-- end page-body -->
|
||
|
||
<!-- =========================================================
|
||
FOOTER
|
||
========================================================= -->
|
||
<footer class="site-footer">
|
||
<div class="container">
|
||
<div class="footer-inner">
|
||
<span>© 2025 金融日报 · Financial Daily | 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(() => {});
|
||
})();
|
||
|
||
// ── AI 操盘实验(多模型对比)─────────────────────────────────────────
|
||
(function loadAIPortfolio() {
|
||
const fmt$ = v => '$' + v.toLocaleString('en-US', {minimumFractionDigits:2, maximumFractionDigits:2});
|
||
const fmtPct = v => (v >= 0 ? '+' : '') + v.toFixed(2) + '%';
|
||
|
||
function renderModelDetail(modelId, pf, contest) {
|
||
const history = pf.history || [];
|
||
const latest = history[history.length - 1] || {};
|
||
const holdings = pf.holdings || [];
|
||
const startCap = contest.start_capital || 10000;
|
||
const pv = latest.portfolio_value || 0;
|
||
const bv = latest.baseline_value || 0;
|
||
const cash = latest.cash || 0;
|
||
const positions = latest.positions || {};
|
||
const trades = latest.trades || [];
|
||
|
||
let html = '';
|
||
|
||
// 持仓明细
|
||
html += `<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:8px;">📊 当前持仓</div>`;
|
||
html += `<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:14px;">`;
|
||
Object.entries(positions).forEach(([t, pos]) => {
|
||
const h = holdings.find(x => x.ticker === t);
|
||
const avg = h ? h.avg_cost : pos.price;
|
||
const pl = pos.price - avg;
|
||
const plP = avg > 0 ? pl / avg * 100 : 0;
|
||
const pct = pv > 0 ? pos.value / pv * 100 : 0;
|
||
const c = pl >= 0 ? 'var(--up)' : 'var(--down)';
|
||
html += `<div style="display:flex;align-items:center;gap:8px;padding:5px 8px;background:rgba(255,255,255,0.03);border-radius:6px;font-size:0.79rem;">
|
||
<span style="font-family:var(--mono);font-weight:600;min-width:44px;color:var(--accent);">${t}</span>
|
||
<span style="color:var(--muted);min-width:46px;">${pos.shares}股</span>
|
||
<span style="font-family:var(--mono);min-width:66px;">$${pos.price.toFixed(2)}</span>
|
||
<span style="font-family:var(--mono);min-width:72px;">${fmt$(pos.value)}</span>
|
||
<span style="color:${c};min-width:62px;">${(pl>=0?'+':'')}${fmtPct(plP)}</span>
|
||
<div style="flex:1;height:3px;background:rgba(255,255,255,0.06);border-radius:2px;"><div style="width:${Math.min(pct,100).toFixed(1)}%;height:100%;background:var(--accent);border-radius:2px;"></div></div>
|
||
<span style="color:var(--muted);min-width:34px;text-align:right;">${pct.toFixed(1)}%</span>
|
||
</div>`;
|
||
});
|
||
if (cash > 0) {
|
||
const cp = pv > 0 ? cash / pv * 100 : 0;
|
||
html += `<div style="display:flex;align-items:center;gap:8px;padding:5px 8px;background:rgba(255,255,255,0.03);border-radius:6px;font-size:0.79rem;">
|
||
<span style="font-family:var(--mono);font-weight:600;min-width:44px;color:#ffb300;">CASH</span>
|
||
<span style="color:var(--muted);min-width:46px;">—</span>
|
||
<span style="font-family:var(--mono);min-width:66px;">—</span>
|
||
<span style="font-family:var(--mono);min-width:72px;">${fmt$(cash)}</span>
|
||
<span style="color:var(--muted);min-width:62px;">现金</span>
|
||
<div style="flex:1;height:3px;background:rgba(255,255,255,0.06);border-radius:2px;"><div style="width:${Math.min(cp,100).toFixed(1)}%;height:100%;background:#ffb300;border-radius:2px;"></div></div>
|
||
<span style="color:var(--muted);min-width:34px;text-align:right;">${cp.toFixed(1)}%</span>
|
||
</div>`;
|
||
}
|
||
html += '</div>';
|
||
|
||
// 交易记录
|
||
if (trades.length) {
|
||
html += `<div style="font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--muted);margin-bottom:8px;">📋 今日交易</div>`;
|
||
html += trades.map(t => {
|
||
const ic = t.action==='BUY'?'🟢':t.action==='SELL'?'🔴':'🟡';
|
||
const c2 = t.action==='BUY'?'var(--up)':t.action==='SELL'?'var(--down)':'var(--warn)';
|
||
return `<div style="padding:5px 0;border-bottom:1px solid var(--border);font-size:0.8rem;">${ic} <strong style="color:${c2};">${t.action} ${t.ticker}</strong> ${t.shares}股 @ $${(t.price||0).toFixed(2)} <span style="color:var(--muted);">${t.reason||''}</span></div>`;
|
||
}).join('');
|
||
html += '<div style="margin-bottom:12px;"></div>';
|
||
}
|
||
|
||
// 备注
|
||
if (latest.note) {
|
||
html += `<div style="font-size:0.8rem;color:var(--muted);padding:8px 10px;background:rgba(0,212,170,0.04);border-left:2px solid var(--accent);border-radius:4px;">${latest.note}</div>`;
|
||
}
|
||
|
||
document.getElementById('ai-model-detail').innerHTML = html;
|
||
}
|
||
|
||
fetch('data/ai-portfolio.json?v=' + Date.now())
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
const contest = data.contest || {};
|
||
const portfolios = data.portfolios || {};
|
||
const startCap = contest.start_capital || 10000;
|
||
const startDate = new Date(contest.start_date || '2026-05-13');
|
||
|
||
// 计算排名
|
||
const ranked = Object.entries(portfolios).map(([id, pf]) => {
|
||
const hist = pf.history || [];
|
||
const latest = hist[hist.length - 1] || {};
|
||
const pv = latest.portfolio_value || startCap;
|
||
const bv = latest.baseline_value || startCap;
|
||
const d = new Date(latest.date || contest.start_date);
|
||
const days = Math.round((d - startDate) / 86400000) + 1;
|
||
return { id, pf, pv, bv, days, latest };
|
||
}).sort((a, b) => b.pv - a.pv);
|
||
|
||
// 排行榜
|
||
const lbEl = document.getElementById('ai-leaderboard');
|
||
lbEl.innerHTML = ranked.map((r, i) => {
|
||
const pv = r.pv;
|
||
const bv = r.bv;
|
||
const ret = (pv - startCap) / startCap * 100;
|
||
const alpha = pv - bv;
|
||
const alphaP = bv > 0 ? alpha / bv * 100 : 0;
|
||
const retC = ret >= 0 ? 'var(--up)' : 'var(--down)';
|
||
const alpC = alpha >= 0 ? 'var(--up)' : 'var(--down)';
|
||
const medal = i===0 ? '🥇' : i===1 ? '🥈' : '🥉';
|
||
const pf = r.pf;
|
||
return `<div style="display:flex;align-items:center;gap:10px;padding:10px 12px;background:rgba(255,255,255,0.04);border:1px solid var(--border);border-radius:8px;">
|
||
<span style="font-size:1.2rem;min-width:28px;">${medal}</span>
|
||
<span style="font-size:1.1rem;">${pf.emoji||'🤖'}</span>
|
||
<div style="flex:1;">
|
||
<div style="font-weight:600;font-size:0.9rem;">${pf.display_name||r.id}</div>
|
||
<div style="font-size:0.75rem;color:var(--muted);">${r.latest.note||''}</div>
|
||
</div>
|
||
<div style="text-align:right;min-width:80px;">
|
||
<div style="font-family:var(--mono);font-weight:600;font-size:0.95rem;">${fmt$(pv)}</div>
|
||
<div style="font-size:0.78rem;color:${retC};">${(ret>=0?'+':'')}${ret.toFixed(2)}%</div>
|
||
</div>
|
||
<div style="text-align:right;min-width:80px;">
|
||
<div style="font-family:var(--mono);font-size:0.85rem;color:${alpC};">${(alpha>=0?'+':'')}${fmt$(alpha)}</div>
|
||
<div style="font-size:0.75rem;color:var(--muted);">vs SPY</div>
|
||
</div>
|
||
</div>`;
|
||
}).join('');
|
||
|
||
// SPY 基线行
|
||
const anyLatest = ranked[0]?.latest || {};
|
||
const spyVal = anyLatest.baseline_value || startCap;
|
||
const spyRet = (spyVal - startCap) / startCap * 100;
|
||
const spyC = spyRet >= 0 ? 'var(--up)' : 'var(--down)';
|
||
lbEl.innerHTML += `<div style="display:flex;align-items:center;gap:10px;padding:10px 12px;background:rgba(255,255,255,0.02);border:1px solid var(--border);border-radius:8px;opacity:0.7;">
|
||
<span style="font-size:1.2rem;min-width:28px;">📊</span>
|
||
<span style="font-size:1.1rem;">—</span>
|
||
<div style="flex:1;"><div style="font-weight:600;font-size:0.9rem;">SPY 基线(买入持有)</div><div style="font-size:0.75rem;color:var(--muted);">S&P 500 ETF</div></div>
|
||
<div style="text-align:right;min-width:80px;">
|
||
<div style="font-family:var(--mono);font-weight:600;font-size:0.95rem;">${fmt$(spyVal)}</div>
|
||
<div style="font-size:0.78rem;color:${spyC};">${(spyRet>=0?'+':'')}${spyRet.toFixed(2)}%</div>
|
||
</div>
|
||
<div style="text-align:right;min-width:80px;">
|
||
<div style="font-family:var(--mono);font-size:0.85rem;color:var(--muted);">$0.00</div>
|
||
<div style="font-size:0.75rem;color:var(--muted);">展示基准</div>
|
||
</div>
|
||
</div>`;
|
||
|
||
// 模型 Tab
|
||
const tabsEl = document.getElementById('ai-model-tabs');
|
||
let activeModel = ranked[0]?.id;
|
||
function setActiveTab(id) {
|
||
activeModel = id;
|
||
tabsEl.querySelectorAll('button').forEach(b => {
|
||
b.style.background = b.dataset.id === id ? 'rgba(0,212,170,0.15)' : 'rgba(255,255,255,0.04)';
|
||
b.style.borderColor = b.dataset.id === id ? 'var(--accent)' : 'var(--border)';
|
||
b.style.color = b.dataset.id === id ? 'var(--accent)' : 'var(--text)';
|
||
});
|
||
const pf = portfolios[id];
|
||
if (pf) renderModelDetail(id, pf, contest);
|
||
}
|
||
tabsEl.innerHTML = ranked.map(r => {
|
||
const pf = r.pf;
|
||
return `<button data-id="${r.id}" onclick="(function(id){window._aiSetTab&&window._aiSetTab(id)})('${r.id}')" style="padding:6px 12px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,0.04);color:var(--text);cursor:pointer;font-size:0.8rem;">${pf.emoji||'🤖'} ${pf.display_name||r.id}</button>`;
|
||
}).join('');
|
||
window._aiSetTab = setActiveTab;
|
||
setActiveTab(activeModel);
|
||
|
||
// 历史对比表
|
||
const histEl = document.getElementById('ai-history-table');
|
||
const allDates = [...new Set(ranked.flatMap(r => (r.pf.history||[]).map(h => h.date)))].sort().reverse();
|
||
if (allDates.length > 1) {
|
||
const headers = ['<th style="text-align:left;padding:3px 6px;">日期</th>',
|
||
...ranked.map(r => `<th style="text-align:right;padding:3px 6px;">${r.pf.emoji} ${r.pf.display_name}</th>`),
|
||
'<th style="text-align:right;padding:3px 6px;">SPY基线</th>'
|
||
].join('');
|
||
const rows = allDates.map(date => {
|
||
const cells = ranked.map(r => {
|
||
const rec = (r.pf.history||[]).find(h => h.date === date);
|
||
if (!rec) return '<td style="text-align:right;padding:3px 6px;color:var(--dimmed);">—</td>';
|
||
const ret = (rec.portfolio_value - startCap) / startCap * 100;
|
||
const c = ret >= 0 ? 'var(--up)' : 'var(--down)';
|
||
return `<td style="text-align:right;padding:3px 6px;"><span style="color:${c};">${(ret>=0?'+':'')}${ret.toFixed(2)}%</span></td>`;
|
||
}).join('');
|
||
const spyRec = (ranked[0]?.pf.history||[]).find(h => h.date === date);
|
||
const spyR = spyRec ? (spyRec.baseline_value - startCap) / startCap * 100 : 0;
|
||
const sc = spyR >= 0 ? 'var(--up)' : 'var(--down)';
|
||
return `<tr style="border-top:1px solid var(--border);"><td style="padding:3px 6px;color:var(--muted);">${date}</td>${cells}<td style="text-align:right;padding:3px 6px;"><span style="color:${sc};">${(spyR>=0?'+':'')}${spyR.toFixed(2)}%</span></td></tr>`;
|
||
}).join('');
|
||
histEl.innerHTML = `<table style="width:100%;border-collapse:collapse;"><thead><tr style="color:var(--muted);">${headers}</tr></thead><tbody>${rows}</tbody></table>`;
|
||
} else {
|
||
histEl.innerHTML = '<span style="color:var(--muted);font-size:0.8rem;">天数超过1天后显示对比曲线…</span>';
|
||
}
|
||
|
||
document.getElementById('ai-portfolio-loading').style.display='none';
|
||
document.getElementById('ai-portfolio-content').style.display='';
|
||
})
|
||
.catch(()=>{ const el=document.getElementById('ai-portfolio-loading'); if(el) el.textContent='数据加载失败'; });
|
||
})();
|
||
|
||
// ── Visitor counter (Cloudflare Worker + KV) ──────────────────────────
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
const WORKER = 'https://finance-daily-counter.yangbai0110.workers.dev';
|
||
const LS_KEY = 'fd_visited';
|
||
|
||
const visEl = document.getElementById('footer-visitors');
|
||
const pvEl = document.getElementById('footer-pageviews');
|
||
|
||
function fmt(n) { return Number(n).toLocaleString('en-US'); }
|
||
|
||
function animate(el, target) {
|
||
if (!el) return;
|
||
if (target === 0) { el.textContent = '0'; return; }
|
||
const dur = 900; let t0 = null;
|
||
const step = ts => {
|
||
if (!t0) t0 = ts;
|
||
const p = Math.min((ts - t0) / dur, 1);
|
||
el.textContent = fmt(Math.round((1 - Math.pow(1 - p, 3)) * target));
|
||
if (p < 1) requestAnimationFrame(step);
|
||
};
|
||
requestAnimationFrame(step);
|
||
}
|
||
|
||
const isNew = !localStorage.getItem(LS_KEY);
|
||
fetch(WORKER + (isNew ? '?newVisitor=1' : '?newVisitor=0'))
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
localStorage.setItem(LS_KEY, '1');
|
||
animate(visEl, data.visitors || 0);
|
||
animate(pvEl, data.pageViews || 0);
|
||
})
|
||
.catch(() => {
|
||
if (visEl) visEl.textContent = '--';
|
||
if (pvEl) pvEl.textContent = '--';
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<script>
|
||
// ─── Streak counter ────────────────────────────────────────────────────────
|
||
(function() {
|
||
var today = new Date().toISOString().slice(0,10);
|
||
var last = localStorage.getItem('fd_last_visit') || '';
|
||
var streak = parseInt(localStorage.getItem('fd_streak') || '0');
|
||
if (last !== today) {
|
||
var yesterday = new Date(Date.now() - 86400000).toISOString().slice(0,10);
|
||
streak = (last === yesterday) ? streak + 1 : 1;
|
||
localStorage.setItem('fd_last_visit', today);
|
||
localStorage.setItem('fd_streak', streak);
|
||
}
|
||
if (streak >= 2) {
|
||
var meta = document.querySelector('.header-meta');
|
||
if (meta) {
|
||
var sb = document.createElement('span');
|
||
sb.className = 'streak-badge';
|
||
sb.title = '连续访问天数';
|
||
sb.innerHTML = '🔥 ' + streak + ' 天';
|
||
meta.appendChild(sb);
|
||
}
|
||
}
|
||
})();
|
||
|
||
// ─── Mark first breaking news as NEW ────────────────────────────────────────
|
||
document.querySelectorAll('.news-item.breaking, .news-item.major').forEach(function(n, i) {
|
||
if (i < 2) {
|
||
var title = n.querySelector('.news-title');
|
||
if (title) {
|
||
var badge = document.createElement('span');
|
||
badge.className = 'new-badge';
|
||
badge.textContent = '新';
|
||
badge.style.cssText = 'display:inline-block;font-size:.58rem;font-family:var(--mono);padding:1px 5px;border-radius:3px;background:rgba(0,212,170,.15);color:var(--accent);border:1px solid rgba(0,212,170,.3);margin-right:6px;vertical-align:middle;';
|
||
title.insertBefore(badge, title.firstChild);
|
||
}
|
||
}
|
||
});
|
||
|
||
// ─── News toggle ────────────────────────────────────────────────────────────
|
||
function toggleNews(el) { el.classList.toggle('expanded'); }
|
||
</script>
|
||
|
||
<!-- Floating action cluster -->
|
||
<div class="fab-cluster">
|
||
<button class="fab" id="fab-share" title="分享此页" onclick="shareOrCopy()">🔗</button>
|
||
<button class="fab" id="fab-top" title="回到顶部" onclick="window.scrollTo({top:0,behavior:'smooth'})">↑</button>
|
||
</div>
|
||
<div id="share-toast">✅ 链接已复制</div>
|
||
<div id="share-toast">✅ 链接已复制</div>
|
||
|
||
</body>
|
||
</html> |