QMT Python API
代码示例
常见过滤场景
排除 ST / 退市股票
提示
通过 get_instrument_detail 返回的 InstrumentName 字段判断股票名称是否包含 ST、*ST 或退字样。
name = detail.get('InstrumentName', '')if 'ST' in name or '*ST' in name or '退' in name: continue排除上市不足 120 日的股票
提示
通过 get_instrument_detail 返回的 OpenDate 字段获取 IPO 日期,结合交易日历判断上市天数是否 >= 120。
open_date = str(detail.get('OpenDate', ''))# 结合交易日历判断上市天数是否 >= 120流通市值 / 总市值过滤
提示
通过 get_instrument_detail 返回的 FloatVolume(流通股本,单位:股)和 TotalVolume(总股本,单位:股),乘以 get_full_tick 返回的 lastPrice 计算市值。
float_volume = detail.get('FloatVolume', 0) # 流通股本(股)total_volume = detail.get('TotalVolume', 0) # 总股本(股) # 流通市值 = 流通股本 × lastPrice# 总市值 = 总股本 × lastPrice涨跌停价格判断(盘中不买不卖)
提示
通过 get_instrument_detail 返回的 UpStopPrice(涨停价)和 DownStopPrice(跌停价),与 get_full_tick 返回的 lastPrice 比较判断。
up_price = detail.get('UpStopPrice', 0)dwn_price = detail.get('DownStopPrice', 0) if lastPrice == up_price: # 涨停 → 不买 returnif lastPrice == dwn_price: # 跌停 → 不卖 return停牌检测 / 复牌标记
提示
通过 get_instrument_detail 返回的 InstrumentStatus(停牌天数,第1天=0,第2天=1…正常交易也为0)和 IsTrading(合约是否可交易)判断停牌状态。
status = detail.get('InstrumentStatus', 0)is_trading = detail.get('IsTrading', True)if not is_trading: loger.info(f'{s} 当前不可交易(停牌中)')elif status > 0 and is_trading: loger.info(f'{s} 今日复牌! 停牌天数={status}')批量获取涨跌停价模板
批量获取沪深A股涨跌停价 - get_today_up_down
原型
up_to_down_dict = {} # {股票代码: [涨停价, 跌停价]}stock_name_dict = {} # {股票代码: 股票名称} def get_today_up_down(C): up_to_down_dict.clear() for s in C.get_stock_list_in_sector('沪深A股'): info = C.get_instrument_detail(s) if not info: continue up_price = info.get('UpStopPrice') down_price = info.get('DownStopPrice') if not up_price or not down_price: continue up_to_down_dict[s] = [round(up_price, 2), round(down_price, 2)] stock_name_dict[s] = info.get('InstrumentName', '') loger.info(f'涨跌停价初始化完成, 共{len(up_to_down_dict)}只')释义
遍历沪深A股全部股票,通过 get_instrument_detail 获取每只股票的涨停价和跌停价,存入全局字典供盘中查询。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
返回值
无返回值,结果存入全局变量 up_to_down_dict({股票代码: [涨停价, 跌停价]})和 stock_name_dict({股票代码: 股票名称})。
示例
def init(C): get_today_up_down(C) # 查询某只股票的涨跌停价 if '600000.SH' in up_to_down_dict: up, down = up_to_down_dict['600000.SH'] loger.info(f'600000.SH 涨停价:{up} 跌停价:{down}')历史 K 线计算场景
提示
以下场景基于 get_market_data_ex 返回的历史 DataFrame 实现。所有场景依赖以下公共代码获取日 K 线数据:
stock = '600000.SH'daily_data = C.get_market_data_ex( fields=['open', 'high', 'low', 'close', 'volume'], stock_code=[stock], period='1d', start_time='', end_time='', count=11, dividend_type='none', fill_data=False)df = daily_data[stock]detail = C.get_instrument_detail(stock)换手率计算(昨日 / 历史序列)
提示
volume 单位是手,FloatVolume 单位是股,计算时需 ×100 换算。
stock = '600000.SH'daily_data = C.get_market_data_ex( fields=['open', 'high', 'low', 'close', 'volume'], stock_code=[stock], period='1d', start_time='', end_time='', count=11, dividend_type='none', fill_data=False) df = daily_data[stock]float_volume = detail.get('FloatVolume', 0) # 流通股本(股) # 昨日换手率yesterday_volume = df['volume'].iloc[-2] # 昨日成交量(手)yesterday_turnover = (yesterday_volume * 100) / float_volume * 100 # 最近10日换手率序列turnover_series = (df['volume'] * 100) / float_volume * 100avg_turnover_10 = round(turnover_series[-10:].mean(), 2) # 10日平均换手率昨天市值 / 昨天流通市值
提示
用昨日收盘价 × 股本,计算昨天的总市值和流通市值。
df = daily_data[stock]yesterday_close = df['close'].iloc[-2] # 昨日收盘价 float_vol = detail.get('FloatVolume', 0) # 流通股本(股)total_vol = detail.get('TotalVolume', 0) # 总股本(股) # 昨日流通市值(亿)yesterday_float_cap = yesterday_close * float_vol / 1e8# 昨日总市值(亿)yesterday_total_cap = yesterday_close * total_vol / 1e8 # 历史某日市值(如 5 天前)hist_close = df['close'].iloc[-5]hist_float_cap = hist_close * float_vol / 1e8最近 N 天涨幅
提示
计算最近 3 日、5 日、10 日、30 日涨幅,用于动量排序和筛选。
df = daily_data[stock]closes = df['close'] # 最近 N 日涨幅 = (今日收盘 / N日前收盘 - 1) × 100gain_3 = round((closes.iloc[-1] / closes.iloc[-4] - 1) * 100, 2) # 3日涨幅gain_5 = round((closes.iloc[-1] / closes.iloc[-6] - 1) * 100, 2) # 5日涨幅gain_10 = round((closes.iloc[-1] / closes.iloc[-11] - 1) * 100, 2) # 10日涨幅gain_30 = round((closes.iloc[-1] / closes.iloc[-31] - 1) * 100, 2) # 30日涨幅 # N 日内最大涨幅(峰值)max_gain_10 = round((closes.iloc[-10:].max() / closes.iloc[-11] - 1) * 100, 2)# N 日内最大回撤(谷值)max_dd_10 = round((closes.iloc[-10:].min() / closes.iloc[-11] - 1) * 100, 2)均线计算(MA / EMA / MACD)
提示
基于 K 线收盘价计算移动平均线和指数均线,用于趋势判断。
df = daily_data[stock]closes = df['close'] # 简单移动平均ma5 = round(closes.iloc[-5:].mean(), 2) # 5日均线ma10 = round(closes.iloc[-10:].mean(), 2) # 10日均线ma20 = round(closes.iloc[-20:].mean(), 2) # 20日均线ma60 = round(closes.iloc[-60:].mean(), 2) # 60日均线 # 指数移动平均(EMA)ema12 = round(closes.ewm(span=12, adjust=False).mean().iloc[-1], 2)ema26 = round(closes.ewm(span=26, adjust=False).mean().iloc[-1], 2) # MACDdif = round(ema12 - ema26, 4)dea = round(closes.ewm(span=9, adjust=False).mean().iloc[-1], 4)macd = round(2 * (dif - dea), 4) # 金叉/死叉if ma5 > ma10 and closes.iloc[-2] < closes.ewm(span=10, adjust=False).mean().iloc[-2]: loger.info(f'{stock} MA5上穿MA10 金叉')成交量分析(放量 / 缩量)
提示
对比今日与近期平均成交量,判断放缩量。
df = daily_data[stock]volumes = df['volume'] today_vol = volumes.iloc[-1] # 今日成交量(手)avg_vol_5 = volumes.iloc[-6:-1].mean() # 最近5日平均量(不含今日)avg_vol_10 = volumes.iloc[-11:-1].mean() # 最近10日平均量 # 量比vol_ratio = round(today_vol / avg_vol_5, 2) if avg_vol_5 > 0 else 0 if vol_ratio > 2: loger.info(f'{stock} 放量 量比:{vol_ratio}')elif vol_ratio < 0.5: loger.info(f'{stock} 缩量 量比:{vol_ratio}')历史停牌检测
提示
利用 suspendFlag 字段检测历史停牌日,避免计算时引入噪声。
df = daily_data[stock] # 历史停牌天数suspend_days = (df['suspendFlag'] == 1).sum() # 最近 10 日是否有停牌recent_suspend = (df['suspendFlag'].iloc[-10:] == 1).any() # 过滤停牌日后的有效交易日序列valid_df = df[df['suspendFlag'] == 0]valid_closes = valid_df['close']振幅 / 波动率计算
提示
计算日内振幅和 N 日年化波动率,用于风险评估和仓位调整。
df = daily_data[stock] # 日内振幅 = (最高 - 最低) / 前收盘 × 100daily_amplitude = ((df['high'] - df['low']) / df['preClose'] * 100).round(2) # 最近 20 日年化波动率daily_returns = df['close'].pct_change().iloc[-20:]annualized_vol = round(daily_returns.std() * (252 ** 0.5) * 100, 2)分钟级盘中数据获取
提示
获取当日分钟 K 线,用于盘中策略。
min_data = C.get_market_data_ex( fields=['open', 'high', 'low', 'close', 'volume'], stock_code=[stock], period='1m', start_time=time.strftime('%Y%m%d') + '093000', end_time='', count=-1, dividend_type='none', fill_data=False, subscribe=True)min_df = min_data[stock]# 第一根分钟K线(9:31)first_min = min_df.iloc[0]# 当前分钟收盘价cur_min_close = min_df['close'].iloc[-1]字段功能速查表
get_full_tick 字段能做什么
| 字段 | 能做的事 |
|---|---|
lastPrice | 当日涨幅、涨停封板强度、市值计算、保证金计算(贯穿全文) |
lastClose | 前收盘参考、涨跌幅计算(与 PreClose 互补) |
volume | 换手率计算、成交量分析(单位:手) |
amount | 成交额过滤、活跃度排序 |
askPrice / bidPrice | 盘口分析、委买卖压 |
askVol / bidVol | 委买卖量、买卖力道对比 |
stockStatus | 实时证券状态判断 |
get_market_data_ex 字段能做什么
| 字段 | 能做的事 |
|---|---|
close | 昨天市值、N日涨幅、均线、波动率、动量排序 |
open / high / low | 振幅计算、K线形态识别 |
volume | 换手率序列、放缩量判断、量比计算 |
amount | 成交额过滤、活跃度排序 |
preClose | 日内振幅计算、涨跌幅基准 |
suspendFlag | 历史停牌检测、有效交易日过滤 |
settelementPrice | 期货结算价参考 |
openInterest | 期货持仓量变化分析 |
get_instrument_detail 字段能做什么
| 字段 | 能做的事 |
|---|---|
UpStopPrice | 涨停封板强度、一字板检测、涨停不撤单、距涨停幅度 |
DownStopPrice | 跌停不撤单、跌停封死检测 |
PreClose | 当日涨幅计算、跳空缺口检测、涨跌幅排序 |
FloatVolume | 换手率计算、流通市值过滤、自由流通市值分级 |
TotalVolume | 总市值过滤、大中小盘分级 |
OpenDate | 次新股筛选、上市天数过滤、IPO 日期标记 |
InstrumentName | ST/退市过滤、关键词筛选 |
InstrumentStatus | 停牌检测、复牌首日标记 |
PriceTick | 下单价格精度对齐、废单防范 |
VolumeMultiple | 期货保证金计算、每手价值 |
LongMarginRatio | 期货保证金、杠杆倍数 |
MainContract | 主力合约切换检测、移仓换月 |
SettlementPrice | 期货结算价参考 |
ExpireDate | 退市/到期日过滤 |
一键初始化全市场基础信息
盘前初始化全市场基础信息 - init_market_info
提示
将以上功能整合,盘前一次性构建全市场基础信息字典 + 实时 Tick 缓存。全局缓存变量包括:stock_info_dict({股票代码: detail字典})、up_to_down_dict({股票代码: [涨停价, 跌停价]})、float_vol_dict({股票代码: 流通股本})、tick_dict({股票代码: get_full_tick返回的实时数据})。
原型
# 全局缓存stock_info_dict = {} # {股票代码: detail字典}up_to_down_dict = {} # {股票代码: [涨停价, 跌停价]}float_vol_dict = {} # {股票代码: 流通股本}tick_dict = {} # {股票代码: get_full_tick返回的实时数据} def init_market_info(C): """盘前初始化: 获取沪深A股全部基础信息""" all_stocks = C.get_stock_list_in_sector('沪深A股') for s in all_stocks: info = C.get_instrument_detail(s) if not info: continue name = info.get('InstrumentName', '') if 'ST' in name or '*ST' in name or '退' in name: continue up = info.get('UpStopPrice') dwn = info.get('DownStopPrice') if up and dwn: up_to_down_dict[s] = [round(up, 2), round(dwn, 2)] stock_info_dict[s] = info float_vol_dict[s] = info.get('FloatVolume', 0) loger.info(f'全市场基础信息初始化完成: 有效股票{len(stock_info_dict)}只')释义
盘前初始化,获取沪深A股全部基础信息,排除 ST/退市股票,将涨跌停价、合约详情、流通股本缓存到全局字典。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
返回值
无返回值,结果存入全局变量 stock_info_dict、up_to_down_dict、float_vol_dict。
盘中刷新实时 Tick - refresh_tick
原型
def refresh_tick(C): """盘中定时刷新实时Tick数据""" valid_stocks = list(stock_info_dict.keys()) tick_dict = C.get_full_tick(valid_stocks) loger.info(f'实时Tick刷新完成: {len(tick_dict)}只')释义
盘中定时调用,刷新 stock_info_dict 中所有有效股票的实时 Tick 数据。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
返回值
无返回值,结果存入全局变量 tick_dict。
获取历史 K 线(按需) - get_hist_data
原型
def get_hist_data(C, stock, count=30): """获取最近N日日K线""" data = C.get_market_data_ex( fields=['open', 'high', 'low', 'close', 'volume', 'preClose', 'suspendFlag'], stock_code=[stock], period='1d', start_time='', end_time='', count=count, dividend_type='none', fill_data=False ) return data.get(stock)释义
按需获取单只股票最近 N 日日 K 线数据,包含 preClose 和 suspendFlag 字段。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
stock | str | 股票代码,如 '600000.SH' |
count | int | 获取的 K 线条数,默认 30 |
返回值
DataFrame — 指定股票的历史日 K 线数据。
盘中调用示例
# 查涨停价up_price = up_to_down_dict.get(s, [0, 0])[0] # 查流通股本float_vol = float_vol_dict.get(s, 0) # 查前收盘pre_close = stock_info_dict.get(s, {}).get('PreClose', 0) # 查实时最新价(来自 get_full_tick)lastPrice = tick_dict.get(s, {}).get('lastPrice', 0) # 当日涨幅if pre_close > 0 and lastPrice: pct = round((lastPrice - pre_close) / pre_close * 100, 2) # 最近5日涨幅(来自 get_market_data_ex)df = get_hist_data(C, s, count=6)if df is not None and len(df) >= 6: gain_5 = round((df['close'].iloc[-1] / df['close'].iloc[-6] - 1) * 100, 2)盘中实时量比计算
提示
量比 = 当日累计成交量 / 已过分钟数 / 历史5日每分钟平均成交量
同时用到 get_full_tick(实时 volume + time)和 get_market_data_ex(历史5日 volume),是跨接口组合的典型场景。
第一步:盘前预计算历史5日每分钟平均量
原型
import timefrom datetime import datetime his_dict = {} # {股票代码: 历史5日每分钟平均成交量} def his_lb_func(C, all_stock_list): """盘前调用: 批量预计算所有股票历史5日每分钟平均量 Args: C: 策略上下文 all_stock_list: 成分股列表,如 C.get_stock_list_in_sector('沪深A股') """ # 获取最近10个交易日(取倒数第2个=昨天,排除今天) trading_dates = C.get_trading_dates('000001.SH', '', '', 10, '1d') end_tm = trading_dates[-1] if time.strftime('%Y%m%d') == trading_dates[-1]: end_tm = trading_dates[-2] # 排除今天,只要历史5日 # 批量获取所有股票历史5日日成交量 price = C.get_market_data_ex( ['volume'], all_stock_list, period='1d', start_time='', end_time=end_tm, count=5, dividend_type='front', fill_data=False ) for s in price: his_dict[s] = price[s]['volume'].sum() / (240 * 5) # 5日总量 / (240分钟×5天) loger.info(f'{s} 历史5日每分钟均量: {his_dict[s]}')释义
盘前批量预计算所有股票的历史5日每分钟平均成交量,公式为:5日总量 / (240分钟 × 5天)。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
all_stock_list | list[str] | 成分股列表,如 C.get_stock_list_in_sector('沪深A股') |
返回值
无返回值,结果存入全局变量 his_dict({股票代码: 历史5日每分钟平均成交量})。
第二步:盘中实时量比
原型
def calculate_qrr(C, s): """盘中实时计算量比 (全推 get_full_tick 模式)""" full_kline = C.get_full_tick([s]) # 当前 tick 时间 t0 = datetime.now().replace(hour=9, minute=30, second=0, microsecond=0) t = full_kline[s]['time'] tick_time = datetime.fromtimestamp(t / 1000) r = tick_time - t0 # 当日已过分钟数(9:30 起算) market_open_knums = int(r.seconds / 60 + 1) if tick_time.hour >= 13: # 午休 90 分钟扣除 market_open_knums -= 90 market_open_knums = min(market_open_knums + 1, 240) # 上限 240 vol = full_kline[s]['volume'] # 当日累计成交量(手) pased_volumes = his_dict.get(s) # 历史5日每分钟平均量 if not pased_volumes: return 0 return vol / market_open_knums / pased_volumes释义
盘中实时计算量比,从 get_full_tick 获取当日累计成交量和当前 tick 时间,计算已过分钟数,再除以历史5日每分钟平均量。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
s | str | 股票代码,如 '600000.SH' |
返回值
float — 实时量比值。>1 为放量,<1 为缩量。
第三步:init 串联调用
原型
def init(C): # 1. 获取成分股 all_stock_list = C.get_stock_list_in_sector('沪深A股') # 2. 盘前预计算历史5日每分钟平均量 his_lb_func(C, all_stock_list) # 3. 盘中逐只计算实时量比 for s in all_stock_list: qrr = calculate_qrr(C, s) loger.info(f'{s} 量比: {qrr:.2f}')释义
在 init 中串联调用三步:获取成分股 → 盘前预计算历史均量 → 盘中逐只计算实时量比。
参数
| 字段名 | 数据类型 | 解释 |
|---|---|---|
C | object | 策略上下文对象 |
返回值
无返回值。
量比逻辑说明
| 参数 | 来源 | 说明 |
|---|---|---|
vol | get_full_tick → volume | 当日累计成交量(实时,单位:手) |
market_open_knums | get_full_tick → time | 当日已过分钟数(9:30 起算,午休扣 90 分钟,上限 240) |
pased_volumes | get_market_data_ex → volume | 历史5日每分钟平均成交量 = 5日总量 / (240×5) |
trading_dates | C.get_trading_dates | 最近10个交易日时间戳,取倒数第2个排除今天 |
| 量比 | — | vol / market_open_knums / pased_volumes,>1 放量,<1 缩量 |
策略选股完整模板
提示
以下是一个完整的 init(C) 选股模板,串联了文档涉及的四个核心接口,实现 8 重过滤,可直接复制使用或按需裁剪。相关接口参考 行情函数。
过滤流程一览
| 步骤 | 过滤条件 | 依赖接口 | 依赖字段 |
|---|---|---|---|
| 1 | 排除 ST / 退市股票 | get_instrument_detail | InstrumentName |
| 2 | 排除创业板(300 开头) | get_stock_list_in_sector | 代码前缀 |
| 3 | 排除科创板(688 开头) | get_stock_list_in_sector | 代码前缀 |
| 4 | 排除上市不足 120 日 | get_instrument_detail | OpenDate |
| 5 | 排除股价 < 20 元 | get_market_data_ex | close |
| 6 | 排除流通市值 < 100 亿 | get_instrument_detail + get_market_data_ex | FloatVolume + close |
| 7 | 排除昨日换手率 < 0.05% | get_market_data_ex + get_instrument_detail | volume + FloatVolume |
| 8 | 排除 10 日涨跌幅 > 10% | get_market_data_ex | close 序列 |
提示
换手率公式:换手率(%) = 昨日成交量(手) × 100 / 流通股本(股) × 100,其中 ×100 是手→股换算。
完整代码
# encoding:gbk"""策略选股模板:获取成分股(带多重过滤条件)过滤条件: 1. 排除ST股票和退市股票 2. 排除创业板(300开头) 3. 排除科创板(688开头) 4. 排除上市时间小于120日的股票 5. 排除股价<20元的股票 6. 排除流通市值<100亿的股票 7. 排除昨日换手率<0.05%的股票(换手率 = 成交量×100/流通股本) 8. 排除10日涨跌幅>10%的股票"""import timeimport numpy as np # 全局变量:过滤后的成分股列表hs300_stocks = []# 全局变量:15分钟K线数据hs300_data = {} def init(C): """策略初始化""" global hs300_stocks, hs300_data # ── 1. 获取成分股列表 ── all_stocks = C.get_stock_list_in_sector('中证500') loger.info(f'【初始】原始成分股数量: {len(all_stocks)}') current_date = time.strftime('%Y%m%d') valid_stocks = [] for stock in all_stocks: detail = C.get_instrument_detail(stock) if not detail: continue name = detail.get('InstrumentName', '') # --- 过滤1: 排除ST / 退市 --- if 'ST' in name or '*ST' in name or '退' in name: continue code_raw = stock.split('.')[0] # --- 过滤2: 排除创业板(300开头)--- if code_raw.startswith('300'): continue # --- 过滤3: 排除科创板(688开头)--- if code_raw.startswith('688'): continue # --- 过滤4: 排除上市不足120日 --- open_date = str(detail.get('OpenDate', '')) if len(open_date) >= 8: days_diff = int(current_date) - int(open_date[:8]) if days_diff < 120: continue valid_stocks.append(stock) loger.info(f'【过滤1-4】ST/创业板/科创板/次新股后剩余: {len(valid_stocks)} 只') if not valid_stocks: hs300_stocks = [] return # ── 2. 获取日线数据(用于股价、流通市值、换手率、涨跌幅过滤)── daily_data = C.get_market_data_ex( fields=['open', 'high', 'low', 'close', 'volume'], stock_code=valid_stocks, period='1d', start_time='', end_time='', count=11, dividend_type='none', fill_data=False ) # ── 3. 过滤5: 股价 < 20元 ── price_filtered = [] for stock in valid_stocks: if stock in daily_data and len(daily_data[stock]) >= 1: close_price = daily_data[stock]['close'].iloc[-1] if close_price and close_price >= 20: price_filtered.append(stock) loger.info(f'【过滤5】股价<20元后剩余: {len(price_filtered)} 只') # ── 4. 过滤6: 流通市值 < 100亿 ── mktcap_filtered = [] for stock in price_filtered: detail = C.get_instrument_detail(stock) if not detail: continue float_volume = detail.get('FloatVolume', 0) if not float_volume or float_volume <= 0: continue close_price = daily_data[stock]['close'].iloc[-1] circulating_mktcap = (float_volume * close_price) / 1e8 # 亿 if circulating_mktcap >= 100: mktcap_filtered.append(stock) loger.info(f'【过滤6】流通市值<100亿后剩余: {len(mktcap_filtered)} 只') # ── 5. 过滤7: 昨日换手率 < 0.05% ── turnover_filtered = [] low_turnover_stocks = [] for stock in mktcap_filtered: detail = C.get_instrument_detail(stock) if not detail: continue float_volume = detail.get('FloatVolume', 0) if not float_volume or float_volume <= 0: continue if stock in daily_data and len(daily_data[stock]) >= 2: yesterday_volume = daily_data[stock]['volume'].iloc[-2] yesterday_turnover = (yesterday_volume * 100) / float_volume * 100 name = detail.get('InstrumentName', stock) if yesterday_turnover < 0.05: low_turnover_stocks.append(stock) continue turnover_filtered.append(stock) loger.info(f'【过滤7】换手率<0.05%后剩余: {len(turnover_filtered)} 只') # ── 6. 过滤8: 10日涨跌幅 > 10% ── final_stocks = [] for stock in turnover_filtered: if stock in daily_data and len(daily_data[stock]) >= 11: close_series = daily_data[stock]['close'] pct_change = (close_series.iloc[-1] / close_series.iloc[0] - 1) * 100 if abs(pct_change) > 10: continue final_stocks.append(stock) loger.info(f'【过滤8】10日涨跌>10%后剩余: {len(final_stocks)} 只') # ── 7. 过滤结果汇总 ── loger.info('========== 过滤结果汇总 ==========') loger.info(f'原始数量: {len(all_stocks)}') loger.info(f'最终数量: {len(final_stocks)}') loger.info(f'因换手率不足被排除: {len(low_turnover_stocks)} 只') if low_turnover_stocks: loger.info('因换手率不足被排除的股票列表:') for stock in low_turnover_stocks[:20]: detail = C.get_instrument_detail(stock) name = detail.get('InstrumentName', '') if detail else '' loger.info(f' - {stock} {name}') if len(low_turnover_stocks) > 20: loger.info(f' ... 还有 {len(low_turnover_stocks) - 20} 只') hs300_stocks = final_stocks # ── 8. 获取15分钟K线数据 ── if hs300_stocks: hs300_data = C.get_market_data_ex( fields=['open', 'high', 'low', 'close', 'volume'], stock_code=hs300_stocks, period='15m', start_time='20250101', end_time='', count=100, dividend_type='none', fill_data=False ) loger.info(f'15分钟K线数据获取完成,股票数量: {len(hs300_data)}') else: loger.info('没有符合条件的股票,最终列表为空!') def handlebar(C): """每根K线执行""" pass def get_hs300_stocks(): """获取过滤后的成分股列表""" return hs300_stocks def get_hs300_data(): """获取成分股15分钟K线数据""" return hs300_data模板要点说明
| 要点 | 说明 |
|---|---|
| 接口串联 | get_stock_list_in_sector → get_instrument_detail → get_market_data_ex,覆盖文档一/三/四章 |
| 分步过滤 | 先用 get_instrument_detail 做静态过滤(ST/创业板/科创板/次新),再用 get_market_data_ex 做动态过滤(股价/市值/换手率/涨跌幅) |
| 换手率公式 | 昨日成交量(手) × 100 / 流通股本(股) × 100,注意 ×100 是手→股换算 |
| count 参数 | 日线 count=11(10日涨跌幅需 11 根),15分钟线 count=100 |
| 按需裁剪 | 可注释掉任意过滤步骤,或调整阈值(如股价阈值 20→10,市值阈值 100→50) |
| 日志输出 | 每步过滤后打印剩余数量,便于排查;被排除的换手率不足个股单独列出 |