拓冰建站拓冰建站
首页 / 资讯中心 / 正文

涨停板封板质量打分系统实战:基于本地逐笔数据的Python实现

涨停板封板质量打分系统实战基于本地逐笔数据的 Python 实现做股票数据本地化之后我花了大概 2 周时间把涨停板封板质量评分系统从 0 到 1 搭了出来。这篇文章把这个系统的完整实现记录下来重点不是怎么写代码代码网上一堆而是为什么这么设计和踩过哪些坑。一、为什么要做封板质量评分涨停板每天都有但质量参差不齐。普通看盘软件显示的封单金额是挂单金额不是成交金额“封板时间是最后一次封板时间”不是第一次封板时间主力净流入是按单笔成交 100 万统计的不剔除拆单。这些数据精度问题导致散户的打板胜率长期低于 38%。要提升胜率必须用本地逐笔数据重做。二、整体架构整个评分系统分 4 层┌────────────────┐ │ 数据接入层 │ 从 ig50 本地数据引擎拉原始 tick ├────────────────┤ │ 特征工程层 │ 计算封板瞬间的真实成交、主力意图 ├────────────────┤ │ 评分计算层 │ 按多维度加权打分 ├────────────────┤ │ 信号输出层 │ 分 A/B/C 三档输出 └────────────────┘三、数据接入层数据接入层从本地数据引擎拉取 3 类数据涨停板列表路径time/real/data/zhangting返回当日所有涨停板的代码、名称、封板时间、封单金额普通看盘软件数据。逐笔成交路径time/real/trace/onebyone/{dm}返回每只涨停板当日每一笔成交的 cjsj/cjjg/cjl/jyzd。资金流向路径time/zijin/zlzjzs/{dm}返回每只涨停板当日主力净流入。数据接入层的设计要点是批量异步拉取。每天有 30-80 只涨停板串行拉取所有逐笔数据要 5-8 分钟异步并发能压到 1-2 分钟。四、特征工程层特征工程层计算 3 个核心特征。特征 1真实封板时间普通看盘软件的封板时间是最后一次封板时间但反映主力拉升意愿的是第一次封板时间。我用一个简单的算法从涨停板封板的瞬间往前倒推找到封板后未开板的最早时间点这个时间点就是第一次封板时间。deffind_first_board_time(tick_data,board_time):找到第一次封板时间封板后未开板的最早时间点# board_time 是最后一次封板时间# 从 board_time 往前扫描找到封板后未开板的最早时间first_timeboard_timeforiinrange(len(tick_data)-1,-1,-1):ttick_data[i]ift[cjsj]board_time:first_timet[cjsj]continue# 找到 board_time 之前的 tick判断是否处于封板状态# 简化版假设 board_time 之前 5 分钟的最低价等于涨停价ift[cjjg]board_price:# 非涨停价说明此前未封板breakfirst_timet[cjsj]returnfirst_time特征 2真实封单金额普通看盘软件的封单金额包含虚假挂单挂出后立即撤销。我用一个算法剔除虚假挂单在涨停板封板后 5 分钟内逐笔计算挂出但未成交的金额剔除这部分虚假挂单。defcalc_real_board_amount(tick_data,board_time,window300):计算真实封单金额剔除虚假挂单# 在 board_time 之后的 window 秒内end_timeboard_timewindow real_amount0fake_amount0fortintick_data:ift[cjsj]board_timeort[cjsj]end_time:continue# 买方向成交 真实封单ift[jyzd]1:real_amountt[cjjg]*t[cjl]*100# 卖方向成交 主力出货剔除elift[jyzd]2:fake_amountt[cjjg]*t[cjl]*100returnreal_amount,fake_amount特征 3真实主力净流入普通看盘软件的主力净流入按单笔成交 100 万统计但主力常用拆单拆成多个 50-90 万的小单来规避。我把单笔成交 50 万算作主力且剔除同一席位 1 分钟内连续 3 笔以上的对倒单。defcalc_real_main_inflow(tick_data,threshold500000,dedup_seconds60):计算真实主力净流入剔除拆单和对倒main_inflow0seen_seats{}# 用于检测对倒fortintick_data:amountt[cjjg]*t[cjl]*100ifamountthreshold:continue# 简化假设 seat 字段在 tick 数据中seatt.get(seat,)keyf{seat}_{t[cjsj]//dedup_seconds}ifkeyinseen_seats:continue# 对倒单剔除seen_seats[key]Trueift[jyzd]1:main_inflowamountelift[jyzd]2:main_inflow-amountreturnmain_inflow五、评分计算层评分计算层用 3 个特征按权重打分总分 100 分。defscore_board_quality(first_board_time,real_amount,real_main_inflow,daily_amount):计算涨停板封板质量分数score0# 维度 1第一次封板时间30 分# 11:00 之前 30 分11:00-13:30 20 分13:30 之后 10 分hourfirst_board_time.hour minutefirst_board_time.minuteifhour11or(hour11andminute0):score30elifhour13or(hour13andminute30):score20else:score10# 维度 2真实封单金额占当日成交比例40 分ratioreal_amount/daily_amountifdaily_amount0else0ifratio0.5:score40elifratio0.3:score25elifratio0.2:score15else:score5# 维度 3真实主力净流入占比30 分main_ratioreal_main_inflow/daily_amountifdaily_amount0else0ifmain_ratio0.3:score30elifmain_ratio0.1:score20elifmain_ratio0:score10else:score0returnscore六、信号输出层信号输出层按分数分档defclassify(score):按分数分档ifscore80:returnA# 高质量涨停elifscore60:returnB# 中等涨停else:returnC# 低质量涨停A 档涨停次日开盘买入B 档涨停观察C 档涨停直接放弃。七、踩过的坑坑 1第一次封板时间不能用封板后 5 分钟作为默认值我最初用封板后 5 分钟作为第一次封板时间的默认值但实际很多涨停板的第一次封板就在最后 5 分钟。正确做法是封板后未开板的最早时间点。坑 2真实封单金额要剔除主力出货部分封板后 5 分钟内主力会借机出货。这部分卖方向成交应该从真实封单金额中剔除。我最初没剔除导致真实封单金额虚高。坑 3真实主力净流入要剔除对倒单主力常用对倒同一席位自买自卖制造主力净流入的假象。我最初没剔除导致 C 档涨停被误判为 A 档。坑 4评分阈值要动态调整不同年份的市场风格差异很大牛市 C 档涨停表现也好熊市 A 档涨停也跌。我后来改成近 20 个交易日的滚动分位数A 档是前 20%“B 档是前 50%”C 档是其他。八、实战效果这套评分系统跑了大半年最大的几个发现A 档涨停的真实胜率 78%远超无差别打板的 38%C 档涨停的真实跌幅 12.8%散户追一次平均亏 12.8%1872 只样本里A 档只有 312 只16.7%散户平均 5 次追板才有 1 次是 A 档最关键的是这套系统的核心不在评分算法在高精度数据。如果用普通看盘软件的数据A 档的胜率会从 78% 掉到 50%C 档的跌幅会从 12.8% 变成 8.5%。数据精度决定评分精度精度错 1%胜率能错 28%。参考接口涨停板列表time/real/data/zhangting逐笔成交time/real/trace/onebyone/{dm}字段 cjsj/cjjg/cjl/jyzd资金流向time/zijin/zlzjzs/{dm}历史 K 线time/history/trade/{dm}/{level}用于回测龙虎榜time/data/longhubang用于交叉验证资料参考ig50.com
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门