不仅是看板:用 Streamlit + QuantDash 20分钟拼装一个跨市场(A/H/US)技术异动扫描雷达

📅 2026/7/16 13:26:18
不仅是看板:用 Streamlit + QuantDash 20分钟拼装一个跨市场(A/H/US)技术异动扫描雷达
对于频繁交易的独立开发者来说“盯盘”是一件极其消耗心神的事。想盯着 A 股核心资产的均线粘合度又想扫一扫港股和美股有没有超跌反弹RSI 30的机会[9]。为此同时开着同花顺、富途和盈透在各大客户端之间反复切换、频繁刷新效率低下。其实利用 Python 的极简 Web 框架Streamlit配合QuantDash统一的多市场数据接口你完全可以用不超过 80 行代码在本地搭建一个轻量、好看、自动化刷新的跨市场多空技术雷达大屏。1. 为什么不用传统盯盘软件个性化差传统盯盘大屏无法让你在后台插入自定义的 Python 逻辑如计算特定周期的波动率或成交量异动倍数。多市场割裂想在一个页面无缝比对 600519.SH、00700.HK 和 AAPL.US市面上的免费客户端通常需要多次跳转。开发太重用 Vue/React 写前端再用 FastAPI 写后端对于只想抓信号的交易员来说技术栈太重、工程量太大[1]。2. 技术雷达大屏的实战代码我们通过编写一个简单的单文件 app.py实现一个能够实时扫描指定多市场自选股并标记出布林带收敛波动率极低预示将选择方向以及 RSI 超买超卖信号的监控面板[9]。首先确保本地已安装依赖库pip install streamlit quantdash pandas numpy然后创建 app.pyimport streamlit as st import pandas as pd import numpy as np from quantdash import QuantDash # 页面配置 st.set_page_config(layoutwide, page_title跨市场技术异动监控雷达) st.title(⚡ 跨市场A股/港股/美股技术异动监控雷达) # 在侧边栏配置 API 凭证和扫描标的 st.sidebar.header( 系统配置) api_key st.sidebar.text_input(QuantDash API Key, typepassword, value) refresh_btn st.sidebar.button(立即扫描市场) # 默认监控标的支持跨市场统一后缀 DEFAULT_WATCHLIST [600519.SH, 300750.SZ, 00700.HK, AAPL.US, NVDA.US, MSFT.US] symbols_input st.sidebar.text_area(自选股列表 (逗号分隔), value,.join(DEFAULT_WATCHLIST)) def calculate_indicators(df: pd.DataFrame) - dict: 接收日 K 线计算 RSI 和布林带判断异常值 if df is None or df.empty or len(df) 21: return {rsi: np.nan, bb_width: np.nan, status: 数据不足} # 1. 计算 14 日 RSI delta df[close].diff() gain delta.clip(lower0) loss -delta.clip(upper0) avg_gain gain.rolling(14).mean() avg_loss loss.rolling(14).mean() # 避免分母为0 avg_loss avg_loss.replace(0, 1e-5) rs avg_gain / avg_loss df[rsi] 100 - 100 / (1 rs) # 2. 计算布林带宽度 (Bollinger Band Width) 衡量波动率挤压 df[ma20] df[close].rolling(20).mean() df[std20] df[close].rolling(20).std() df[upper] df[ma20] 2 * df[std20] df[lower] df[ma20] - 2 * df[std20] df[bb_width] (df[upper] - df[lower]) / df[ma20] latest df.iloc[-1] # 判断异动状态 status 正常 if latest[rsi] 30: status 严重超卖 (RSI 30) elif latest[rsi] 70: status 严重超买 (RSI 70) elif latest[bb_width] 0.05: status ⚠️ 波动率极度收敛 (变盘在即) return { price: round(latest[close], 2), rsi: round(latest[rsi], 2) if not pd.isna(latest[rsi]) else N/A, bb_width: f{latest[bb_width] * 100:.2f}% if not pd.isna(latest[bb_width]) else N/A, status: status } if not api_key: st.warning(⚠️ 请在侧边栏中输入您的 QuantDash API Key 启动扫描器。) else: # 启动扫描 qd QuantDash(api_keyapi_key) symbols_list [s.strip() for s in symbols_input.split(,) if s.strip()] st.subheader( 实时异动检测表) # 动态表格容器 results [] progress_bar st.progress(0) for idx, symbol in enumerate(symbols_list): try: # 统一数据抓取拉取近60天数据足够计算指标 df qd.klines.get( symbolsymbol, period1d, count60, adjustqfq, to_dataframeTrue ) metrics calculate_indicators(df) results.append({ 标的代码: symbol, 最新收盘价: metrics[price], 14日 RSI: metrics[rsi], 布林带宽度: metrics[bb_width], 异动雷达信号: metrics[status] }) except Exception as e: results.append({ 标的代码: symbol, 最新收盘价: Error, 14日 RSI: N/A, 布林带宽度: N/A, 异动雷达信号: f⚠️ 抓取失败: {str(e)[:30]} }) progress_bar.progress((idx 1) / len(symbols_list)) # 转换为 DataFrame 并在 Streamlit 完美渲染 res_df pd.DataFrame(results) # 针对状态列着色 def highlight_status(val): if 超卖 in val: return background-color: #2ecc71; color: white elif 超买 in val: return background-color: #e74c3c; color: white elif 变盘 in val: return background-color: #f1c40f; color: black return styled_df res_df.style.applymap(highlight_status, subset[异动雷达信号]) st.dataframe(styled_df, use_container_widthTrue, height400) st.success(✨ 扫描完成)在终端运行以下命令streamlit run app.py一个精美、直观、跨 A/H/US 市场的专业量化技术扫描雷达就已经跑在你的浏览器里了。3. 为什么这个方案能够如此简单这得益于底层QuantDash接口干净、统一的接口[2][3]零拼装噪音你不用考虑获取 A 股要调用哪个网页接口、获取美股又要去哪个 Yahoo Finance 的镜像抓取[2]。一个统一的 qd.klines.get()入参格式、出参 DataFrame 的列名close, open, volume完全雷同甚至连 AI 编程助手如 GitHub Copilot、Cursor读取后都可以做到 100% 正确生成无任何幻觉干扰[6]。免除性能担忧云端服务端完成了缓存和数据清洗逻辑[1]保证了极速的响应。如果你希望让你的量化投研从“繁杂的 API 对接和 Bug 调试泥潭”中解脱出来专注于策略层面的信号挖掘去 pip install quantdash 体验一下这种“不制造噪音”的生产级行情服务。在 QuantDash你可以在 5 秒内免费创建属于你的 API 密钥[8]。相关链接 QuantDash 官方QuantDashPython SDK 快速开始快速开始 - QuantDash