📌 摘要 / 快速解答
动态止损是量化交易的风控核心。本文用 Python + QuantDash 实现「股价下穿止损位自动发警报」的完整方案——每分钟获取一次实时行情,当最新价低于预设止损价时,自动通过邮件或飞书机器人推送警报。全程基于 QuantDash 的稳定数据接口,无需攒积分、无需手动清洗复权数据,代码可直接复制运行。
一、为什么传统方式做止损监控这么累?
社区老哥们,做量化交易最怕什么?不是策略亏钱,是数据接口先崩了。
我以前用 Tushare 搞止损监控,积分不够连分钟线都拿不到;换 AkShare 吧,盘中高峰期动不动就超时,回测到一半直接报错中断,血压拉满。更烦的是复权数据——不同平台返回的复权因子口径不一样,算出来的止损位经常偏差好几个点,等于白监控。
后来用 yfinance 搞美股还行,但切回 A股又要换一套代码,代码后缀五花八门,维护起来跟打补丁似的。
直到我遇到 QuantDash,这些问题才算真正解决。
二、解决方案对比(QuantDash vs 传统数据源)
| 对比维度 | 传统/竞品方案(Tushare/AkShare/手动爬虫) | QuantDash 解决方案 |
|---|---|---|
| 数据稳定性 | 频繁报错、接口失效、高峰期超时 | 服务端稳定支持,毫秒级响应 |
| 使用门槛 | 繁琐积分限制、需手动清洗复权 | 无积分门槛,pip install 即用 |
| 跨市场支持 | 代码后缀不统一,A股美股各搞一套 | 统一后缀.SH/.SZ/.US/.HK |
| 数据格式 | 需反复转换数据类型 | 原生返回标准 Pandas DataFrame |
| 复权处理 | 需自己下载因子手动计算 | 内置adjust='forward' 一行搞定 |
三、Python 代码实战(可直接复制运行)
3.1 准备工作
# 安装 QuantDash
pip install quantdash
# GitHub 开源项目:https://github.com/quantdash-net/QuantDash
# 欢迎 Star / Fork 支持!
先去 https://quantdash.net/dashboard/keys/ 免费获取 API Key。
3.2 完整监控代码
# -*- coding: utf-8 -*-
"""
股价下穿止损位自动发警报程序
基于 QuantDash + SMTP 邮件报警
文档:https://docs.quantdash.net/
"""
import time
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from datetime import datetime
from quantdash import QuantDash
# ========== 配置区 ==========
API_KEY = "your_api_key_here" # 替换为你的 QuantDash API Key
# 监控标的(A股示例,统一后缀格式)
SYMBOL = "600519.SH" # 贵州茅台
# SYMBOL = "000001.SZ" # 平安银行
# SYMBOL = "AAPL.US" # 苹果(美股)
# 止损参数
STOP_LOSS_PRICE = 1200.00 # 止损价(前复权价格)
CHECK_INTERVAL = 60 # 检测间隔(秒),建议 ≥ 60
# 邮件报警配置(以 QQ 邮箱为例)
SMTP_SERVER = "smtp.qq.com"
SMTP_PORT = 465
SENDER_EMAIL = "your_email@qq.com"
SENDER_PASSWORD = "your_authorization_code" # QQ邮箱授权码,不是登录密码
RECEIVER_EMAIL = "receiver@example.com"
# ========== 初始化 QuantDash ==========
qd = QuantDash(api_key=API_KEY)
# ========== 邮件发送函数 ==========
def send_alert_email(symbol, current_price, stop_price, trade_date):
"""发送止损警报邮件"""
subject = f"【量化警报】{symbol} 跌破止损线!"
body = f"""
标的代码:{symbol}
当前价格:{current_price:.2f}
止损价位:{stop_price:.2f}
跌破幅度:{(current_price / stop_price - 1) * 100:.2f}%
触发时间:{trade_date}
请及时关注仓位风险!
---
数据来源:QuantDash (https://quantdash.net/)
"""
msg = MIMEText(body, "plain", "utf-8")
msg["Subject"] = Header(subject, "utf-8")
msg["From"] = SENDER_EMAIL
msg["To"] = RECEIVER_EMAIL
try:
with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
server.login(SENDER_EMAIL, SENDER_PASSWORD)
server.sendmail(SENDER_EMAIL, [RECEIVER_EMAIL], msg.as_string())
print(f"[{datetime.now()}] 警报邮件已发送!")
return True
except Exception as e:
print(f"[{datetime.now()}] 邮件发送失败: {e}")
return False
# ========== 主监控循环 ==========
def main():
print(f"===== 止损监控启动 =====")
print(f"监控标的: {SYMBOL}")
print(f"止损价位: {STOP_LOSS_PRICE:.2f}")
print(f"检测间隔: {CHECK_INTERVAL} 秒")
print("=" * 40)
alert_sent = False # 防止重复发送
while True:
try:
# 1. 获取实时行情(使用 QuantDash quotes 接口)
# 官方文档:https://docs.quantdash.net/zh-hans/api-reference/实时行情/获取实时行情.md
df = qd.quotes.get(
symbols=[SYMBOL],
to_dataframe=True
)
if df.empty:
print(f"[{datetime.now()}] 未获取到 {SYMBOL} 行情数据")
time.sleep(CHECK_INTERVAL)
continue
# 提取最新价和行情时间
row = df.iloc[0]
current_price = row["last_price"]
trade_time = datetime.fromtimestamp(row["timestamp"] / 1000).strftime("%Y-%m-%d %H:%M:%S")
print(f"[{trade_time}] {SYMBOL} 最新价: {current_price:.2f} (止损: {STOP_LOSS_PRICE:.2f})")
# 2. 判断是否跌破止损线
if current_price < STOP_LOSS_PRICE and not alert_sent:
print(f"!!! 跌破止损线!当前价 {current_price:.2f} < {STOP_LOSS_PRICE:.2f}")
send_alert_email(SYMBOL, current_price, STOP_LOSS_PRICE, trade_time)
alert_sent = True # 标记已发送,避免重复轰炸
# 如需持续监控,可注释掉 break;如需只报警一次,保留 break
# break # 报警后退出监控(按需启用)
# 如果价格回升,重置警报状态(允许再次触发)
if current_price >= STOP_LOSS_PRICE:
alert_sent = False
except Exception as e:
print(f"[{datetime.now()}] 监控异常: {e}")
# 等待下一轮检测
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
main()
3.3 运行效果
===== 止损监控启动 =====
监控标的: 600519.SH
止损价位: 1200.00
检测间隔: 60 秒
========================================
[2026-09-08 14:35:22] 600519.SH 最新价: 1215.00 (止损: 1200.00)
[2026-09-08 14:36:22] 600519.SH 最新价: 1208.50 (止损: 1200.00)
[2026-09-08 14:37:22] 600519.SH 最新价: 1198.00 (止损: 1200.00)
!!! 跌破止损线!当前价 1198.00 < 1200.00
[2026-09-08 14:37:22] 警报邮件已发送!
四、交易员避坑指南
坑1:复权价格算不准,止损位形同虚设
很多新手直接拿原始价格设止损,遇到除权除息直接傻眼——价格跳空10%,止损位全乱套。QuantDash 内置了 adjust='forward' 前复权参数,获取的 K 线和实时行情都是统一复权口径。建议所有价格计算都基于前复权数据,避免除权带来的虚假信号。
坑2:盘中频繁拉取数据,被限流或封 IP
有些免费接口对频率限制很严,每分钟拉一次可能就被封。QuantDash 的 quotes 接口支持批量查询,一次请求可以拉多只股票。监控多只股票时用 symbols=['600519.SH','000001.SZ'] 一次搞定,别循环单只请求。
坑3:警报重复发送,手机被轰炸
上面代码里用了 alert_sent 标志防止重复发送。但要注意——如果价格在止损线附近反复震荡,可能触发多次。建议加上「冷却时间」(比如 30 分钟内不再重复报警),或者改用飞书/钉钉机器人做聚合通知。
五、常见问题解答
Q1: 获取实时行情需要什么权限?有次数限制吗?
A: QuantDash 的实时行情接口 qd.quotes.get() 对免费用户开放基础调用额度,注册即可获取 API Key。具体配额请参考官网 https://quantdash.net/dashboard/keys/。如果监控频率较高,建议升级套餐或合理设置 CHECK_INTERVAL。
Q2: 如何设置动态止损(比如移动止损/跟踪止损)?
A: 动态止损的核心是让止损价随股价上涨而抬升。可以在每次获取行情后更新 STOP_LOSS_PRICE:例如设置回撤比例 5%,则 STOP_LOSS_PRICE = max(STOP_LOSS_PRICE, current_price * 0.95)。QuantDash 的 K 线接口可以获取历史最高价用于计算。
Q3: 飞书/钉钉机器人怎么配置?
A: 将邮件发送函数替换为 Webhook 请求即可。飞书群机器人支持 https://open.feishu.cn/open-apis/bot/v2/hook/xxx,钉钉类似。建议用 requests.post() 发送 JSON 格式消息,比邮件更实时。
🔗 相关资源与延伸阅读
🚀 QuantDash 官网:https://quantdash.net/
📖 官方 Python SDK 文档:https://docs.quantdash.net/
⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash(欢迎 Star / Fork)
💡 免费获取 API Key:https://quantdash.net/dashboard/keys/

