
集合竞价数据挖掘实战用Python构建开盘信号识别系统集合竞价是每个交易日开盘前的15分钟很多人觉得这段时间没什么信息量开盘价出来再操作也不迟。但我实际测试下来集合竞价阶段的数据包含了大量有价值的信号特别是对日内短线交易来说。这篇文章分享我用Python构建的集合竞价信号识别系统。集合竞价分两个时间段9:15-9:20可以申报也可以撤单9:20-9:25只能申报不能撤单9:25产生开盘价。还有一个尾盘集合竞价是14:57-15:00。我主要分析的是早盘集合竞价。数据用的是集合竞价接口time/real/trace/jhjj/{dm}这个接口在集合竞价时间段每1分钟更新一次返回的字段包括申报时间、匹配量、未匹配量、标志1表示买单-1表示卖单、成交价。数据按时间升序排列。importjsonimportosimportpandasaspdimportnumpyasnpfromcollectionsimportdefaultdict data_dirD:/stock_datadefread_jhjj(dm):file_pathos.path.join(data_dir,time,real,trace,jhjj,dm)ifnotos.path.exists(file_path):returnNonewithopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[sbsj,ppl,wppl,bz,cjj]returndf字段名继续用简写sbsj是申报时间ppl是匹配量wppl是未匹配量bz是标志1买单-1卖单cjj是成交价。第一个信号集合竞价放量。集合竞价的成交量如果远超平时说明市场对这只股票的关注度突然提高。我会把当天的集合竞价量和前5个交易日的平均集合竞价量做对比如果超过2倍就标记为放量。defcalc_volume_ratio(df_today,history_volumes):today_voldf_today[ppl].sum()avg_volnp.mean(history_volumes)ifhistory_volumeselse0ratiotoday_vol/avg_volifavg_vol0else0returnratio,today_voldefsignal_volume(df_today,history_volumes,threshold2.0):ratio,volcalc_volume_ratio(df_today,history_volumes)ifratiothreshold:return{signal:集合竞价放量,ratio:ratio,volume:vol,score:65}returnNone第二个信号集合竞价价格走势。9:20到9:25之间的成交价变化最有参考价值因为这段时间不能撤单申报都是真实的。如果这段期间成交价持续上升说明买盘在加强如果持续下降说明卖盘占优。defsignal_price_trend(df_today):df_latedf_today[df_today[sbsj]09:20:00].copy()iflen(df_late)2:returnNonepricesdf_late[cjj].values first_priceprices[0]last_priceprices[-1]iffirst_price0:returnNonechange(last_price-first_price)/first_priceifchange0.02:return{signal:集合竞价尾段拉升,change:change,score:70}elifchange-0.02:return{signal:集合竞价尾段下挫,change:change,score:30}else:returnNone第三个信号未匹配量堆积。9:25时的未匹配量能反映买卖力量的失衡。如果未匹配买单远大于匹配量说明买盘很强但没成交完开盘后可能继续涨。反过来如果未匹配卖单堆积开盘后可能跌。defsignal_unmatched(df_today):df_lastdf_today.tail(1)iflen(df_last)0:returnNonewppldf_last[wppl].values[0]bzdf_last[bz].values[0]ppldf_last[ppl].values[0]ifppl0:returnNoneratioabs(wppl)/pplifbz1andratio3:return{signal:未匹配买单堆积,ratio:ratio,score:68}elifbz-1andratio3:return{signal:未匹配卖单堆积,ratio:ratio,score:32}returnNone第四个信号高开幅度。集合竞价形成开盘价如果开盘价高于前日收盘价3%以上属于大幅高开。大幅高开有两种情况一种是利好消息驱动的后续可能继续涨另一种是主力拉高出货的开盘后冲高回落。区分这两种情况需要结合成交量和未匹配量。defsignal_open_premium(df_today,prev_close):ifprev_close0:returnNoneopen_pricedf_today[cjj].iloc[-1]premium(open_price-prev_close)/prev_close vol_ratio,_calc_volume_ratio(df_today,[])unmatcheddf_today.tail(1)[wppl].values[0]unmatched_bzdf_today.tail(1)[bz].values[0]ifpremium0.03:ifunmatched_bz1andunmatched0:return{signal:放量高开买盘堆积,premium:premium,score:72}else:return{signal:高开但买盘不足,premium:premium,score:45}elifpremium-0.03:return{signal:低开,premium:premium,score:40}returnNone把这些信号汇总起来就是一个完整的集合竞价分析系统。defanalyze_jhjj(dm,prev_close,history_volumes):dfread_jhjj(dm)ifdfisNoneorlen(df)0:returnNonesignals[]s1signal_volume(df,history_volumes)ifs1:signals.append(s1)s2signal_price_trend(df)ifs2:signals.append(s2)s3signal_unmatched(df)ifs3:signals.append(s3)s4signal_open_premium(df,prev_close)ifs4:signals.append(s4)ifnotsignals:return{dm:dm,score:50,signals:[无明显信号]}total_scorenp.mean([s[score]forsinsignals])return{dm:dm,score:round(total_score,1),signals:[s[signal]forsinsignals]}实际使用的时候我会在每天9:25运行这个系统遍历全市场的股票筛选出综合得分超过65分的股票作为当日观察池。然后配合开盘后的实时行情做最终决策。几个使用经验。第一集合竞价信号对次新股和小盘股效果更好因为这类股票的集合竞价参与者少几个大单就能改变走势。大盘股的集合竞价信号不太准。第二集合竞价信号要配合前一日收盘状态来看如果前一天涨停且今天集合竞价放量高开信号更强。第三9:20到9:25的信号比9:15到9:20的信号可靠因为9:20之后不能撤单。我用的数据来源是ig50的集合竞价接口数据每分钟更新一次做实时分析完全够用。接口说明time/real/trace/jhjj/{股票代码} - 集合竞价本地路径数据存放目录/time/real/trace/jhjj/{股票代码}更新频率集合竞价时间段9:159:3014:4715:30每1分钟数据格式[{},…]主要字段申报时间(sbsj)、匹配量(ppl)、未匹配量(wppl)、标志(bz, 1买单/-1卖单)、成交价(cjj)gitee开源地址github开源地址