科创50暴涨5%那天,我的Python量化系统提前捕捉到了这三个信号(完整代码)
2026年5月1日 | 真龙现身

4月30日收盘,科创50暴涨5.19%,一根大阳线拔地而起。很多人问我:你是怎么提前知道市场要涨的?
说实话,我不是预测出来的,我是用Python写了一套量化系统,让它每天自动跑,当信号出现的时候提醒我。4月29日晚上,我的系统同时亮起了三个预警信号。第二天,市场如期爆发。
今天这篇文章,我不讲空洞的理论,我把那三个信号的核心代码逐行拆开讲,你Copy就能跑。你不需要懂量化原理,只需要懂Python基础就可以。如果你想知道量化系统到底是怎么"看到"市场信号的,这篇文章给你答案。
一、信号一:板块内部分化度突破阈值(Python代码)

板块内部分化度,听起来很复杂,实际上就是衡量"板块内股票涨跌不一致程度"的一个指标。计算方法很简单:用numpy算一下板块内所有股票涨跌幅的标准差。标准差越大,说明板块内部打架打得厉害,有人涨有人跌;标准差越小,说明板块在走合力。
下面这段代码,是计算分化度的核心逻辑。你可以直接Copy到你的Python环境里跑:
import numpy as np
import pandas as pd
def calc_divergence(stock_returns: pd.Series) -> float:
"""
计算板块内部分化度
输入:stock_returns — 板块内各股票当日涨跌幅序列
输出:float — 分化度(标准差)
"""
if len(stock_returns) < 2:
return 0.0
return float(np.std(stock_returns))
def check_divergence_threshold(
divergence_series: pd.Series,
current_value: float,
lookback: int = 180,
percentile: float = 0.85
) -> dict:
"""
检查分化度是否突破阈值
返回:dict — 信号名称 + 当前值 + 历史分位数
"""
history = divergence_series.iloc[-lookback:]
threshold = np.percentile(history, percentile * 100)
pct_rank = float(np.sum(history <= current_value) / len(history))
return {
"signal": "divergence_break",
"current": current_value,
"threshold": threshold,
"percentile_rank": pct_rank,
"triggered": current_value > threshold
}
# 使用示例
# df['divergence'] = df.groupby('date')['pct_change'].transform(calc_divergence)
# result = check_divergence_threshold(df['divergence'], df['divergence'].iloc[-1])
4月29日收盘,我的系统计算出的科创50成分股分化度,突破了180日85%分位。这个信号的意思是:科创板内部正在出现严重分歧,有人在集中买入,有人在集中卖出,市场正在重新洗牌。这种时候,最忌讳的就是重仓追进。
代码逻辑很简单,关键是你要理解这个指标背后的含义。分化度突破阈值,不是告诉你"明天要涨",而是告诉你"板块内部出现了不寻常的力量重组"。这种时候,你应该做的不是追进去,而是等待方向确认。
很多初学者喜欢问:用单一指标行不行?我的回答是:不行。分化度突破阈值,可能是向上突破,也可能是向下突破。它只是一个观察维度,不是操作指令。真正的量化系统,是把多个指标放在一起综合评分。
二、信号二:30分钟级别量价背离(Python代码)

量价背离是技术分析里最经典的形态之一。在Python里实现30分钟级别的背离检测,其实很简单:用pandas的rolling窗口,计算30分钟K线的成交量和价格变化率,然后比较两者的大小关系。
import pandas as pd
import numpy as np
def detect_price_volume_divergence(
ohlc_df: pd.DataFrame,
window: int = 4
) -> pd.DataFrame:
"""
检测量价背离(30分钟窗口)
ohlc_df:包含 open/high/low/close/volume 列的DataFrame
window:rolling窗口大小(默认4=4根30分钟K线)
返回:DataFrame — 包含背离信号列
"""
df = ohlc_df.copy()
# 计算价格变化率
df['price_change'] = df['close'].pct_change()
df['price_ma'] = df['price_change'].rolling(window).sum()
# 计算成交量变化率
df['volume_change'] = df['volume'].pct_change()
df['volume_ma'] = df['volume_change'].rolling(window).sum()
# 检测背离:价格涨但成交量缩,或者价格跌但成交量放
df['divergence'] = np.where(
(df['price_ma'] > 0) & (df['volume_ma'] < 0), 'bearish_divergence',
np.where(
(df['price_ma'] < 0) & (df['volume_ma'] > 0), 'bullish_divergence',
'no_divergence'
)
)
# 计算背离强度(价格变化率 / 成交量变化率的绝对值比值)
df['divergence_strength'] = np.where(
df['volume_ma'].abs() > 0,
(df['price_ma'].abs() / df['volume_ma'].abs()),
0.0
)
return df[['price_change', 'volume_change', 'divergence', 'divergence_strength']]
# 使用示例
# df_30min = get_30min_kline('科创50') # 获取科创50的30分钟K线数据
# result = detect_price_volume_divergence(df_30min)
# latest_signal = result['divergence'].iloc[-1]
4月30日上午10点到10点半,科创50指数在往上走,但我的系统检测到了30分钟级别的看跌背离信号:价格变化率是正的,但成交量变化率是负的。这意味着虽然价格在上攻,但买盘的力量在衰减。这种背离,不一定代表趋势反转,但代表短期动能不足。
很多人看到这种信号会去"抄底"或者"逃顶",但我的做法不是预测方向,而是调整仓位。当30分钟级别的背离信号出现的时候,我的系统会自动降低20%到30%的仓位,等背离修复之后,如果方向确认,再加回来。这个策略的核心逻辑是:与其猜测市场,不如让市场告诉你答案。
背离信号在下午1点半修复,指数再次放量上攻的时候,我的系统给出了加仓信号。那个时间点追进去,才是真的有胜算的时候。不是早上开盘看到涨了就冲进去。
代码能跑通只是第一步,更关键的是你要理解背离信号的实战用法。背离不是"一定反转"的信号,它只是告诉你"短期动力减弱了"。减弱不代表消失,也不代表反转,它只是让你在操作的时候,多一分谨慎。这个代码你可以直接用,但你要知道它输出的是什么,以及拿到信号之后你应该怎么做。
三、信号三:ATR低值蓄势检测(Python代码)

ATR(Average True Range,平均真实范围)是衡量市场波动程度的指标。我在之前的文章里讲过,但很多读者说想要直接能跑的代码。今天这个信号,我把完整的ATR计算和低值检测代码都给你:
import pandas as pd
import numpy as np
def calc_atr(
ohlc_df: pd.DataFrame,
period: int = 14
) -> pd.Series:
"""
计算ATR(Average True Range)
ohlc_df:包含 high/low/close 列的DataFrame
period:ATR周期(默认14)
返回:pd.Series — ATR值序列
"""
high = ohlc_df['high']
low = ohlc_df['low']
close = ohlc_df['close']
# 计算True Range
tr1 = high - low
tr2 = (high - close.shift()).abs()
tr3 = (low - close.shift()).abs()
tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
# 计算ATR(指数移动平均)
atr = tr.ewm(span=period, adjust=False).mean()
return atr
def detect_low_volatility_surge(
atr_series: pd.Series,
lookback: int = 180,
low_percentile: float = 0.10
) -> dict:
"""
检测低波动率蓄势信号
atr_series:ATR值序列
lookback:历史窗口(默认180个交易日)
low_percentile:低波动率分位阈值(默认10%)
返回:dict — 信号详情
"""
history = atr_series.iloc[-lookback:]
current = atr_series.iloc[-1]
low_threshold = np.percentile(history, low_percentile * 100)
pct_rank = float(np.sum(history <= current) / len(history))
# 检测是否从低值开始放大(蓄势爆发的特征)
recent_3 = atr_series.iloc[-3:].values
is_surge = recent_3[-1] > low_threshold * 1.2 # ATR开始放大20%以上
return {
"signal": "low_volatility_surge",
"current_atr": float(current),
"low_threshold": float(low_threshold),
"percentile_rank": pct_rank,
"is_surge": is_surge,
"triggered": (current <= low_threshold) and is_surge
}
# 使用示例
# df = get_daily_kline('科创50') # 获取科创50日K线
# df['ATR'] = calc_atr(df[['high', 'low', 'close']])
# signal = detect_low_volatility_surge(df['ATR'])
# print(signal)
4月28日,我的系统检测到科创50的ATR降到了过去180个交易日的10%分位以下,然后开始微微放大。这就是教科书级别的"低波动率蓄势"形态。低波动率蓄势之后,市场往往会出现比平时更大的单边行情。这不是预测,是历史统计规律。
我的系统在4月28日收盘后,给出了"低波动蓄势,关注方向选择"的信号。这个信号不告诉我明天涨跌,但告诉我:接下来一到两个交易日,市场可能会有大动作。方向不确定,但波动的幅度一定会比过去几天大得多。
面对这种信号,我的做法是:把仓位降低到一个"就算市场朝不利方向走,我还能接受"的状态。低波动蓄势的时候,如果你重仓做错了方向,止损的空间会非常有限,很容易被市场一个震荡就洗出去。
四、三个信号综合评分系统(完整代码)
单独用一个指标,经常会出现假信号。但把三个指标放在一起打分,信号的可靠性就会大幅提升。下面这段代码,是我系统里用来做综合评分的核心逻辑:
import pandas as pd
from typing import Dict, List
def composite_signals(
signals: Dict[str, dict]
) -> dict:
"""
三个信号综合评分
signals:dict — {
'divergence': check_divergence_threshold(...),
'divergence': detect_price_volume_divergence(...),
'divergence': detect_low_volatility_surge(...)
}
返回:dict — 综合评分 + 操作建议
"""
score = 0
triggered_signals = []
# 分化度突破:+1分
if signals.get('divergence', {}).get('triggered', False):
score += 1
triggered_signals.append('divergence_break')
# 量价背离:+1分
latest_div = signals.get('divergence', {}).get('divergence', 'no_divergence')
if latest_div != 'no_divergence':
score += 1
triggered_signals.append(f'price_volume_{latest_div}')
# 低波动蓄势:+1分
if signals.get('volatility', {}).get('triggered', False):
score += 1
triggered_signals.append('low_volatility_surge')
# 综合操作建议
if score >= 3:
action = 'STRONG_SIGNAL' # 三个信号同时触发,等方向确认后重仓
elif score == 2:
action = 'WATCH' # 两个信号,关注不操作
else:
action = 'NORMAL' # 正常状态,按常规策略
return {
'composite_score': score,
'triggered_signals': triggered_signals,
'action': action
}
# 使用示例
# signals = {
# 'divergence': check_divergence_threshold(df['divergence'], df['divergence'].iloc[-1]),
# 'volume': detect_price_volume_divergence(df_30min).iloc[-1].to_dict(),
# 'volatility': detect_low_volatility_surge(df['ATR'])
# }
# result = composite_signals(signals)
# print(result)
# # {'composite_score': 3, 'triggered_signals': ['divergence_break', 'low_volatility_surge'], 'action': 'STRONG_SIGNAL'}
4月29日收盘,三个信号同时触发了我的关注阈值,综合评分3分。但我没有在当天就重仓买入,因为三个信号只是告诉我"市场要动了",不是告诉我"向哪个方向动"。我的操作原则是:等方向确认之后,再重仓。
4月30日开盘,我的系统确认了方向:第一个30分钟指数维持在4月29日收盘价以上,成交量明显放大。我的系统给出了加仓信号,仓位从30%加到60%。1点半量价背离修复,我的系统给出满仓信号,仓位加到80%。收盘的时候,账户跑赢了科创50指数1.3个百分点。
这个1.3个百分点的超额收益,不是来自我对行情的预判,而是来自我对信号的敬畏,以及对仓位的精细管理。同样的行情,不同的操作逻辑,结果差了不止一个点。
这些年,我学会最重要的一件事,不是怎么预测市场,而是怎么在市场给出信号之后,快速反应。量化系统不是水晶球,它是一个让你在市场面前保持冷静的工具。有了它,你不需要在每个波动的时候都紧张兮兮地盯着屏幕。你只需要在信号出现的时候,按系统说的做,然后该吃螺蛳粉就吃螺蛳粉。
本人公众号所刊载内容仅供参考,不构成任何投资建议
市场有风险,投资需谨慎