量化qmt之N 字涨停板技术形态解析与实操策略详解(下)---附完整 Python 源码
·
前言
书接上回,上一篇文章给大家讲解了涨停板识别基础逻辑,本篇分享一套实战可用的N 字板潜力个股筛选策略,配套完整可运行 Python 代码,基于 MySQL 日线行情数据,结合涨停、BIAS 乖离率、成交量缩量三重条件选股,适合短线博弈 N 字反包行情。
风险提示:本文仅为技术策略代码教学,不构成任何投资建议,股市有风险,入市需谨慎。
一、策略核心逻辑
专门筛选具备走出 N 字反包涨停潜力的标的,三大硬性筛选条件缺一不可:
- 涨停条件:近 5 个交易日内,有且仅有 1 次涨停;涨幅阈值设 9.8%,规避浮点四舍五入漏判标准 10% 涨停个股。
- 超卖回调条件:当日 BIAS 乖离率<-5,代表短期股价严重超卖,存在修复反弹需求。
- 缩量止跌条件:当日成交量小于 5 日均量,下跌过程持续缩量,空头抛压逐步衰竭。
策略参数说明
| 参数 | 含义 |
|---|---|
| lookback_days | 读取历史行情总天数,用于计算均线、BIAS 指标,示例默认 30 天 |
| bias_period | BIAS 乖离率对应的均线周期,示例默认 6 日 BIAS |
二、完整 Python 实现代码
依赖库:pandas、numpy、sqlalchemy、datetime,需提前安装 MySQL 并备好stock_daily日线表、stock_basic股票基础信息表。
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
import sys
from pathlib import Path
from datetime import datetime, timedelta
# 数据库连接,自行修改账号密码、库名
engine = create_engine("mysql://root:12345678@localhost/db_stock?charset=utf8")
def get_n_shape_potential_stocks(lookback_days=30, bias_period=6):
"""
筛选具备N字板潜力的股票。
策略逻辑:
1.近5个交易日内,有且仅有1个涨停板。
2.当前股价处于回调状态,且乖离率(BIAS)小于-5,表示超卖。
3.当前成交量小于5日平均成交量,表示下跌缩量,抛压减弱。
参数:
lookback_days:查询的历史数据天数,用于计算技术指标。
bias_period:计算BIAS指标所用的均线周期。
返回:
一个包含符合条件的股票信息的DataFrame
"""
# 1.获取数据库最新交易日
end_date_query = "SELECT MAX(trade_date) as max_date FROM stock_daily"
try:
end_date = pd.read_sql(end_date_query, engine).iloc[0]['max_date']
except IndexError:
print("错误:无法从数据库获取最新交易日期,请检查数据库连接和表名。")
return pd.DataFrame()
# 计算起始查询日期
start_date = (pd.to_datetime(end_date) - timedelta(days=lookback_days))
print(f"正在分析数据,时间范围:{start_date}至{end_date}")
# 联表查询股票日线+股票名称基础信息
data_query = f"""
SELECT
sd.trade_date,
sd.ts_code,
sb.name,
sd.open,
sd.high,
sd.low,
sd.close,
sd.pre_close,
sd.vol
FROM stock_daily sd
LEFT JOIN stock_basic sb ON sd.ts_code=sb.ts_code
WHERE sd.trade_date >= '{start_date}' AND sd.trade_date <= '{end_date}'
ORDER BY sd.ts_code,sd.trade_date
"""
df = pd.read_sql(data_query, engine)
if df.empty:
print("未获取到数据,请检查数据库表'stock_daily'和'stock_basic'是否存在数据")
return pd.DataFrame()
# 2.单只股票指标计算与筛选逻辑
def process_stock(group):
# 按交易日期升序排序
group = group.sort_values('trade_date').reset_index(drop=True)
# 计算当日涨跌幅
group['pct_chg'] = (group['close'] / group['pre_close'] - 1) * 100
# 计算BIAS均线与乖离率
group['ma'] = group['close'].rolling(bias_period).mean()
group['bias'] = (group['close'] / group['ma'] - 1) * 100
# 5日成交量均线
group['vol_ma5'] = group['vol'].rolling(5).mean()
# 截取最近5个交易日数据校验涨停条件
recent_data = group.tail(5)
# 条件1:近5日恰好1次涨停(涨幅≥9.8%)
limit_up_days = recent_data[recent_data['pct_chg'] >= 9.8]
if len(limit_up_days) != 1:
return None
# 提取涨停日期存入结果
limit_up_date = limit_up_days.iloc[0]['trade_date']
# 条件2:最新一日BIAS小于-5,排除空值
latest_bias = group["bias"].iloc[-1]
if pd.isna(latest_bias) or latest_bias >= -5:
return None
# 条件3:当日成交量小于5日均量,缩量回调
latest_vol = group['vol'].iloc[-1]
latest_vol_ma5 = group['vol_ma5'].iloc[-1]
if pd.isna(latest_vol_ma5) or latest_vol >= latest_vol_ma5:
return None
# 返回当日完整行情+涨停日期
latest_row = group.iloc[-1].copy()
latest_row['limit_up_date'] = limit_up_date
return latest_row
# 按股票代码分组批量处理
res_list = []
for _, group in df.groupby("ts_code"):
stock_res = process_stock(group)
if stock_res is not None:
res_list.append(stock_res)
if not res_list:
return pd.DataFrame()
result_df = pd.DataFrame(res_list)
# 精简输出字段
out_cols = ["ts_code","name","trade_date","close","pct_chg","bias","vol","vol_ma5","limit_up_date"]
result_df = result_df[out_cols].rename(columns={
"close":"close_price",
"vol":"volume"
})
return result_df
if __name__ == "__main__":
print("开始筛选具备N字板潜力的股票...")
# 传入参数:回看30天行情,6日BIAS指标
potential_stocks = get_n_shape_potential_stocks(lookback_days=30, bias_period=6)
if not potential_stocks.empty:
print(f"\n找到{len(potential_stocks)}只具备N字板潜力的股票:")
print("="*90)
# 循环打印选股结果
for _, stock in potential_stocks.iterrows():
print(f"股票代码:{stock['ts_code']}\t股票名称:{stock['name']}")
print(f"分析日期:{stock['trade_date']}\t收盘价:{stock['close_price']}")
print(f"当日涨跌幅:{stock['pct_chg']:.2f}%\t前次涨停日期:{stock['limit_up_date']}")
print(f"乖离率(BIAS):{stock['bias']:.2f}\t成交量:{stock['volume']} 5日均量:{stock['vol_ma5']}")
print("-"*90)
else:
print("当前无符合条件的N字潜力个股")
三、策略运行输出结果示例
代码运行后输出 DataFrame 表格数据,字段说明: ts_code:股票代码 | name:股票名称 | trade_date:分析日期 | close_price:当日收盘价 pct_chg:当日涨跌幅 | bias:6 日乖离率 | volume:当日成交量 | vol_ma5:5 日均量 limit_up_date:近 5 日内涨停日期
筛选结果 CSV 样
ts_code,name,trade_date,close_price,pct_chg,bias,volume,vol_ma5,limit_up_date
001336.SZ,楚环科技,20251205,24.36,-10.01,-7.19,51312.0,52058.0,20251203
002778.SZ,中晟高科,20251205,20.96,-1.27,-5.06,54710.0,69838.0,20251201
002806.SZ,华锋股份,20251205,12.7,0.16,-5.45,142114.0,283177.0,20251201
002862.SZ,实丰文化,20251205,21.32,-1.02,-5.49,143592.0,222865.0,20251201
688260.SH,昀冢科技,20251205,34.12,0.65,-14.87,128669.0,212741.0,20251201
688719.SH,爱科赛博,20251205,41.14,-5.64,-7.13,91426.0,122037.0,20251202
控制台打印输出示例
找到6只具备N字板潜力的股票:
==========================================================================================
股票代码:001336.SZ 股票名称:楚环科技
分析日期:20251205 收盘价:24.36
当日涨跌幅:-10.01% 前次涨停日期:20251203
乖离率(BIAS):-7.19 成交量:51312.0 5日均量:52058.0
------------------------------------------------------------------------------------------
股票代码:002778.SZ 股票名称:中晟高科
分析日期:20251205 收盘价:20.96
当日涨跌幅:-1.27% 前次涨停日期:20251201
乖离率(BIAS):-5.06 成交量:54710.0 5日均量:69838.0
------------------------------------------------------------------------------------------
四、策略原理拆解
1. N 字行情逻辑
N 字走势:先涨停拉升→短期回调洗盘→再度涨停反包。 本策略抓涨停后缩量超卖回调节点,博弈二次拉升机会。
2. BIAS<-5 超卖逻辑
BIAS 反映股价偏离均线幅度,数值越小代表短期下跌幅度越大,小于 - 5 说明短期超跌,技术面存在修复反弹动能。
3. 缩量过滤下跌风险
涨停后回调如果持续放量,代表资金出逃;缩量代表筹码锁定良好,抛压衰竭,反弹概率更高。
五、使用注意事项
- 数据环境:需要自行搭建 MySQL,导入 A 股日线行情、股票基础信息表,可通过 tushare 获取免费股票数据入库。
- 阈值可调:可根据市场风格修改 BIAS 阈值(如 - 6、-8)、涨停统计周期(5 日改为 7 日)。
- 市场局限:该策略仅为短线技术选股工具,大盘单边下跌行情中选股成功率会大幅下降,需结合大盘环境使用。
- 风险提醒:量化策略存在失效风险,历史回测结果不代表未来收益,请勿直接重仓交易。
结尾
以上就是涨停板识别衍生的 N 字潜力股完整筛选方案,源码可直接调试使用,感兴趣的朋友可以自行修改参数、扩充筛选条件(如叠加 MACD、筹码指标)优化策略。
更多推荐

所有评论(0)