
一、先搞清楚:什么是"异动",为什么要监控它?
交易所对异动的定义其实相当明确:连续3个交易日内,日收盘价格涨跌幅偏离值累计达到±20%、日振幅值达到15%、日换手率达到20%——这些都属于异动范畴。你可能会问,为什么要专门监控这个?答案很简单:异动背后是市场情绪的剧烈波动,对持仓者而言,这就是必须正视的风险信号。
手动盯盘?不现实。你需要的,是一个能够7×24小时替你值班的机器人。
核心需求拆解开来,大致就是下面这样:
需求 | 技术实现 |
|---|---|
实时获取行情数据 | WebSocket订阅 / 定时轮询 |
实时计算异动指标 | 滑动窗口 偏离值公式 |
触发条件立即告警 | 规则引擎 消息推送 |
历史回测验证策略 | 离线数据 回放机制 |
二、系统架构:四层设计,每层只做一件事
代码语言:ja vascript1┌─────────────────────────────────┐2│ 告警层(通知你)│钉钉/飞书/邮件/信息3├─────────────────────────────────┤4│ 规则层(判断异动) │偏离值/振幅/换手率/量比5├─────────────────────────────────┤6│ 计算层(实时处理) │滑动窗口 指标计算7├─────────────────────────────────┤8│ 数据层(获取行情) │Tushare / AKShare / 交易所API9└─────────────────────────────────┘10
结构非常清晰:四层设计,每一层只干一件事,彼此解耦,可以独立迭代。这就是工程化思维的基本功。
三、核心模块实现:代码级拆解
模块1:数据接入——稳定比快更重要
推荐用AKShare这个免费接口,覆盖A股全量数据,关键是目前没有频率限制,对于原型开发来说非常友好。
代码语言:ja vascriptpython1import akshare as ak2import pandas as pd34def get_realtime_quotes():5"""获取实时行情,每3秒刷新一次"""6df = ak.stock_zh_a_spot_em()7df = df[['代码', '名称', '最新价', '涨跌幅', '成交量', '换手率', '振幅']]8df.columns = ['code', 'name', 'price', 'pct_change', 'volume', 'turnover', 'amplitude']9return df10
如果你想用于生产环境,建议换成WebSocket直连腾讯云金融数据API的方式,延迟可以控制在50ms以内——这比轮询要快一个量级。
模块2:异动计算——核心公式就这三个
代码语言:ja vascriptpython1def calc_deviation(df, window=3):2"""计算N日涨跌幅偏离值"""3df['pct_change_1d'] = df['pct_change']4df['benchmark'] = df['pct_change_1d'].rolling(window).sum()# 同期大盘涨幅5df['deviation'] = df['pct_change_1d'] - df['benchmark']6df['cum_deviation'] = df['deviation'].rolling(window).sum()7return df89def check_abnormal(row):10"""异动判定规则"""11rules = {12'deviation': abs(row['cum_deviation']) >= 20, # 偏离值±20 13'amplitude': row['amplitude'] >= 15, # 振幅≥15 14'turnover': row['turnover'] >= 20, # 换手率≥20 15'volume_ratio': row['volume'] / row['volume_ma_5'] >= 3# 量比≥3 16}17return any(rules.values()), rules18
这四条规则基本就能覆盖交易所最常见的90%异动场景。先跑通这四条,再根据实际需要慢慢扩展。
模块3:告警推送——快一秒就多一分主动
代码语言:ja vascriptpython1import requests23def send_alert(stock, reason, value):4"""飞书机器人推送"""5webhook_url = "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"6message = {7"msg_type": "interactive",8"card": {9"config": {"wide_screen_mode": True},10"elements": [{11"tag": "markdown",12"content": f"## ? 异动告警"13 f"**{stock['name']}({stock['code']})**"14 f"原因: {reason}"15 f"数值: {value}"16 f"时间: {datetime.now().strftime('%H:%M:%S')}"17}]18}19}20requests.post(webhook_url, json=message)21
模块4:回测验证——上线前必须过这关
回测不是锦上添花,是必选项。误报率超过30%的规则,上线之后你很快就会被消息轰炸到不得不关掉机器人。
代码语言:ja vascriptpython1def backtest(df, start_date, end_date):2"""用历史数据验证规则有效性"""3df = df[(df['date'] >= start_date) & (df['date'] <= end_date)]4signals = []5for i in range(len(df)):6window = df.iloc[max(0,i-2):i 1]7if len(window) < 3: continue8abnormal, rules = check_abnormal(window.iloc[-1])9if abnormal:10signals.append({11'date': window.iloc[-1]['date'],12'code': window.iloc[-1]['code'],13'reason': [k for k,v in rules.items() if v][0]14})15return pd.DataFrame(signals)1617# 跑一遍2025年全年数据,看看误报率多少18results = backtest(hist_df, '2025-01-01', '2025-12-31')19print(f"全年触发{len(results)}次,误报率{calc_false_positive(results)}%")20
四、部署上线:三步让机器人7×24小时跑起来
步骤 | 操作 | 工具 |
|---|---|---|
① 容器化 | Docker打包,确保环境一致 | Dockerfile docker-compose |
② 定时调度 | 每3秒拉一次数据,用Cron或APScheduler | APScheduler比 Crontab 更灵活 |
③ 稳定运行 | 异常自动重启,日志持久化 | supervisor或systemd |
dockerfile1FROM python:3.11-slim2WORKDIR /app3COPY requirements.txt .4RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple5COPY . .6CMD ["python", "main.py"]7
五、三个踩坑血泪教训
坑 | 真相 | 解决方案 |
|---|---|---|
❌ 数据源单点故障 | AKShare偶尔抽风,机器人直接瞎了 | 双数据源兜底,AKShare挂了切Tushare |
❌ 告警风暴 | 一天触发200条,全部忽略 | 合并同股票连续告警,5分钟内只推一次 |
❌ 回测 overfitting | 历史数据表现完美,实盘全废 | 规则参数用滚动窗口优化,别硬编码固定值 |
写在最后
搭建异动风控机器人,本质上不是在写代码,而是把你脑海中的风控逻辑,翻译成机器能够执行的规则。
建议你先跑通一个最小版本:接入数据 → 计算偏离值 → 触发告警。三步就够了。之后就逐步加规则、叠加回测、再部署上线。别追求一步到位,先让机器人替你值第一个夜班。
风控不是等亏了才做的事,是赚钱之前就该建好的系统。
