Python+Streamlit+Plotly做一个金/白银近 5 年价格走势看板(代码自取)

目录
专栏导读
❤️ 欢迎各位佬关注! ❤️
文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
📕 此外还有python基础专栏:请点击——>Python基础学习专栏 求订阅
🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏 求订阅
👍 该系列文章专栏:请点击——>Python办公自动化专栏 求订阅
🏳️🌈 ZEEKLOG博客主页:请点击——> ZEEKLOG的博客主页 求关注
🏳️🌈 知乎主页:请点击——> 知乎主页 求关注
🏳️🌈 Github主页:请点击——> Github主页 求Star⭐
🏳️🌈 个人博客主页:请点击——> 个人的博客主页 求收藏
🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手
从零做一个黄金/白银近 5 年价格走势看板(自动抓取 + 可视化)
这篇文章记录一个小而完整的数据可视化项目:自动抓取黄金/白银历史价格(近 5 年),落盘缓存,并用一个网页看板展示趋势、区间涨跌、最高/最低和明细数据。
项目代码在本地目录:111-黄金白银价格趋势,核心文件:
- [app.py](file:///d:/测试/daily-code/111-黄金白银价格趋势/app.py):Streamlit 看板入口
- [prices.py](file:///d:/测试/daily-code/111-黄金白银价格趋势/prices.py):数据抓取 + 缓存 + 统计
- [requirements.txt](file:///d:/测试/daily-code/111-黄金白银价格趋势/requirements.txt):依赖
代码自取:Python+Streamlit+Plotly做一个金/白银近 5 年价格走势看板(代码自取)
1. 需求拆解
需求一句话:过去 5 年黄金/白银价格走势自动抓取,并有看板展示。
拆成 4 个可交付点:
- 数据源:能拿到黄金、白银的历史日线(或至少是按天频率的收盘价)。
- 自动抓取:启动时自动拉取数据;重复启动不应每次都全量请求。
- 缓存与复用:本地缓存避免频繁请求;支持配置刷新周期。
- 看板展示:
- 折线趋势图(可选品种、可选日期范围)
- 区间概览(最新价、区间涨跌、区间最高/最低)
- 明细表(便于对账和导出前的数据检查)
2. 技术选型
为了“做得快、跑得稳、交互友好”,选了下面这组组合:
- Python + Pandas:数据处理最省事(读 CSV、日期筛选、统计)。
- Requests:简单可靠的 HTTP 拉取。
- Streamlit:用很少的前端代码就能做交互式看板(侧边栏、滑块、表格、指标卡)。
- Plotly:图表交互体验好(hover、缩放、图例开关)。
依赖列表见 [requirements.txt](file:///d:/测试/daily-code/111-黄金白银价格趋势/requirements.txt)。
3. 数据源选择与坑:为什么不用 FRED
最开始我们尝试用 FRED(圣路易斯联储)提供的 fredgraph.csv 下载方式(很多教程都这么写),但在当前环境里:
https://fred.stlouisfed.org/graph/fredgraph.csv?id=...对部分 series 返回 404。
为了做到“开箱即用、无需申请 API Key”,最终改用 Stooq 公共历史行情 CSV:
- 黄金:
xauusd - 白银:
xagusd - 下载地址形如:
https://stooq.com/q/d/l/?s=xauusd&i=d
这个接口的优点:
- 无需登录/无需 key
- 直接给 CSV
- 历史跨度足够长(我们只取近 5 年)
4. 项目结构
项目结构保持极简(小项目最重要的是可读):
111-黄金白银价格趋势/ app.py prices.py requirements.txt run.ps1 README.md data/ cache/ xauusd.csv xagusd.csv 其中 data/cache 会被 .gitignore 忽略,避免把缓存数据提交进仓库。
5. 数据抓取与缓存设计(prices.py)
5.1 拉取逻辑
Stooq 的 CSV 格式是:
Date,Open,High,Low,Close ... 我们只关心两列:
date:日期close:收盘价(作为当天价格代表)
在 [prices.py](file:///d:/测试/daily-code/111-黄金白银价格趋势/prices.py) 里,核心步骤是:
requests.get(url)拉取 CSV 文本pd.read_csv(StringIO(text))转为 DataFrame- 规范列名为小写
- 输出统一的数据结构:
date+value
这样上层看板不需要关心“数据源具体是什么字段”。
5.2 缓存策略(TTL)
我们做了一个很轻量的 TTL 缓存:
- 缓存文件:
data/cache/{symbol}.csv - 判断是否过期:用文件
mtime(修改时间)与ttl_seconds比较
默认 TTL 12 小时(看板侧边栏可改),逻辑是:
- 缓存新鲜:直接读缓存 CSV
- 缓存过期/不存在:重新下载并覆盖缓存
这个设计适合个人看板场景:
- 简单
- 不引入数据库
- 跨平台(Windows/Mac/Linux 都能用)
6. 近 5 年筛选与统计
6.1 近 N 年截取
在 [prices.py](file:///d:/测试/daily-code/111-黄金白银价格趋势/prices.py) 里 last_n_years(df, years) 的思路:
- 以数据最后一天
end为基准 start = end - timedelta(days=365*years)- 过滤
date >= start
这样不会遇到“2 月 29 日”这种日期构造问题(相比 date(end.year - years, end.month, end.day) 更稳)。
6.2 区间概览指标
summarize(df) 输出四个指标:
- latest:最新价
- change_pct:区间首尾涨跌百分比
- min:区间最低
- max:区间最高
注意点:
- 先
dropna(value),避免空值影响统计 first == 0时避免除零错误
7. 看板实现(app.py)
看板用 Streamlit 实现,整体是“侧边栏控制 + 主区图表 + 右侧指标 + 底部表格”:
7.1 侧边栏交互
在 [app.py](file:///d:/测试/daily-code/111-黄金白银价格趋势/app.py) 侧边栏提供:
- 选择品种:黄金/白银多选
- 展示最近 N 年:默认 5
- 缓存刷新间隔(小时):默认 12
这些控件的输出会直接影响数据加载与筛选。
7.2 趋势折线图
使用 Plotly Express:
- x:日期
- y:价格
- color:品种
- hovermode:统一 x 轴提示(横向对比更直观)
并且额外提供一个“日期范围滑块”做二次筛选:
- 一次筛选:取近 N 年
- 二次筛选:用户手动拖动选择时间段
7.3 区间指标卡
右侧区域循环每个品种,输出:
- 最新价
- 区间涨跌
- 区间最低
- 区间最高
指标的视觉效果是“卡片 + 分组”,浏览速度很快。
7.4 明细表
底部用 st.dataframe 展示明细,默认显示最近 200 行,可调:
- 日期
- 品种
- 价格
明细表的作用:
- 校验异常值(例如突然跳变)
- 便于后续加入“导出 CSV”按钮
8. 运行方式
8.1 安装依赖
python -m pip install -r requirements.txt 8.2 启动
python -m streamlit run app.py 或一键启动:
.\run.ps1 启动后打开:
http://localhost:8501
9. 常见问题与排查
9.1 页面打开慢 / 首次加载慢
首次会触发:
- 安装依赖(第一次)
- 下载 CSV(首次或缓存过期)
建议:
- 保持默认缓存 12 小时,减少下载次数
- 网络波动时可稍等重试
9.2 数据看起来“不像美元金价/银价”
不同数据源对符号的定义、报价方式可能不同(点差、合约、汇率因素等)。当前项目使用 Stooq 的 xauusd/xagusd 历史行情。
如果你想换成:
- 上海黄金交易所(CNY)
- COMEX 期货主连
- 伦敦金现
可以把 prices.py 的下载函数替换为对应数据源即可(看板层不需要大改)。
10. 可以继续扩展的方向
这个版本偏“最小可用”。如果要更像“正式看板”,下一步建议:
- 币种切换:USD ↔ CNY(自动抓 USD/CNY 并换算)
- 收益曲线:基准归一化(起点=100),更直观比较两条曲线
- 均线与波动率:MA(20/60)、rolling std
- 导出按钮:一键导出当前筛选区间 CSV
- 异常值处理:对离群点做标注或过滤
11. 小结
这个项目的关键点不是“图画得多漂亮”,而是把链路打通:
- 数据源可用(无需 Key)
- 自动抓取 + TTL 缓存(可长期运行)
- 看板交互完整(筛选、指标、表格齐全)
如果你希望我把“USD→CNY 自动换算 + 导出 CSV + 基准归一化对比”这三项也做进去,我可以直接在现有代码上补齐。