量化策略揭秘,首板低开实战分享与解析
首板低开是指股票在首个交易日的开盘价低于前一个交易日的收盘价,这种情况在量化交易策略中具有一定的研究价值。以下是一种基于首板低开的量化交易策略分享:
1. 筛选条件:
a. 股票在近一年内首次上市;
b. 首日开盘价低于前一个交易日的收盘价;
c. 首日开盘价低于过去5个交易日的平均开盘价;
d. 首日开盘价低于过去10个交易日的平均开盘价。
2. 策略逻辑:
a. 筛选出的股票具有较低的首日开盘价,可能存在低估或错杀的情况;
b. 股票在首日低开可能受到市场情绪、消息面等因素的影响,但长期来看,市场可能会纠正这种错误定价;
c. 通过长期跟踪这些股票,寻找潜在的反弹机会。
3. 交易策略:
a. 在满足筛选条件后,对符合条件的股票进行买入;
b. 设置止损位,例如首日收盘价低于买入价的3%;
c. 设定止盈位,例如首日收盘价高于买入价的5%;
d. 当股票达到止盈位或止损位时,及时卖出。
4. 风险控制:
a. 由于首板低开可能存在风险,因此需严格控制仓位;
相关内容:
策略的核心是选择在低位、首次涨停后次日低开的股票,开盘时买入,上午有盈利就卖出,没有就拿到尾盘在卖出;策略优点在于选择的股票在低位,风险较低,并且刚启动首板,有大资金介入,第二天能快速跑路。
回测数据如下:

*回测数据只作测试用,不代表未来实际收益
1、策略初始化配置
上午开盘买入,上午有盈利就卖出,尾盘全部卖出
run_daily(buy, '09:30') # 开盘买入
run_daily(sell, '11:28') # 上午止盈
run_daily(sell, '14:50') # 下午止损
2、买入逻辑
买入过滤条件有三个,一是排除10天内连续涨停的股票,二是股票在60天内要在相对低位,三是要低开3%-4%
(1)基础过滤股票池,过滤科创北交、上市不超过250、停牌、ST股票
def prepare_stock_list(date):
initial_list = get_all_securities('stock', date).index.tolist()
initial_list = filter_kcbj_stock(initial_list)
initial_list = filter_new_stock(initial_list, date)
initial_list = filter_st_stock(initial_list, date)
initial_list = filter_paused_stock(initial_list, date)
return initial_list
(2)排除10天内连续涨停的股票
# 获取非连板涨停的股票
ccd = get_continue_count_df(hl_list, date, 10)
lb_list = list(ccd.index)
stock_list =
(2.1)计算连板数
# 计算连板数
def get_continue_count_df(hl_list, date, watch_days):
df = pd.DataFrame()
for d in range(2, watch_days+1): # 从2天开始,一直到观察周期结束
HLC = get_hl_count_df(hl_list, date, d) # 计算连板数
CHLC = HLC == d] # 筛选出连续d天涨停的股票
df = df.append(CHLC) # 记录连续d天涨停的股票
stock_list = list(set(df.index))
ccd = pd.DataFrame()
for s in stock_list:
tmp = df.loc]
if len(tmp) > 1:
M = tmp.max() # 计算最大连板数
tmp = tmp == M]
ccd = ccd.append(tmp)
if len(ccd) != 0:
ccd = ccd.sort_values(by='count', ascending=False) # 按照连板数降序排列
return ccd
(2.2)计算涨停数
# 计算涨停数
def get_hl_count_df(hl_list, date, watch_days):
# 获取watch_days长度(观察周期)的行情数据
# 包含low(最低价)、close(收盘价)、high_limit(涨停价)三个字段
df = get_price(hl_list, end_date=date, frequency='daily', fields=, count=watch_days, panel=False, fill_paused=False, skip_paused=False)
df.index = df.code # 将股票代码设为索引
hl_count_list = # 普通涨停天数
extreme_hl_count_list = # 一字涨停天数
for stock in hl_list:
df_sub = df.loc # 获取单只股票数据
hl_days = df_sub.high_limit.count() # 计算普通涨停天数(收盘价=涨停价)
extreme_hl_days = df_sub.high_limit.count() # 计算一字涨停天数(最低价=涨停价)
hl_count_list.append(hl_days) # 记录普通涨停天数
extreme_hl_count_list.append(extreme_hl_days) # 记录一字涨停天数
#创建df记录
df = pd.DataFrame(index=hl_list, data={'count':hl_count_list, 'extreme_count':extreme_hl_count_list})
return df
(3)选取60天内在相对低位的股票
rpd = get_relative_position_df(stock_list, date, 60)
rpd = rpd <= 0.5]
stock_list = list(rpd.index)
(3.1)计算相对位置
# 计算股票处于一段时间内相对位置
def get_relative_position_df(stock_list, date, watch_days):
if len(stock_list) != 0:
df = get_price(stock_list, end_date=date, fields=, count=watch_days, fill_paused=False, skip_paused=False, panel=False).dropna()
close = df.groupby('code').apply(lambda df: df.iloc) # 计算最后一天的收盘价
high = df.groupby('code').apply(lambda df: df.max()) # 计算一段时间内的最高价
low = df.groupby('code').apply(lambda df: df.min()) # 计算一段时间内的最低价
result = pd.DataFrame()
result = (close-low) / (high-low) # 计算相对位置
return result
else:
return pd.DataFrame(columns=)
(4)选取低开3%-4%的股票
df = get_price(stock_list, end_date=date, frequency='daily', fields=, count=1, panel=False, fill_paused=False, skip_paused=True).set_index('code') if len(stock_list) != 0 else pd.DataFrame()
df = .day_open/df.loc for s in stock_list]
df = df) & (df <= 0.97)]
3、卖出逻辑
卖出时段有两个,一是上午止盈卖出,二是下午只要是不涨停就全卖出
(1)上午不涨停,并且大于我的持仓成本就止盈卖出
if ((context.portfolio.positions.closeable_amount != 0) and (current_data.last_price < current_data.high_limit) and (current_data.last_price > context.portfolio.positions.avg_cost)):
order_target_value(s, 0)
print( '止盈卖出')
(2)不涨停就全卖出
if ((context.portfolio.positions.closeable_amount != 0) and (current_data.last_price < current_data.high_limit)):
order_target_value(s, 0)
print( '全部卖出')
这篇文章主要分享首版低开策略的思路,主要的逻辑在计算连板数和涨停数上面,量化交易的回测和实盘,可以在量化交易软件中进行,券商的量化交易软件免费并且申请也基本没有门槛,大家可以去体验下量化交易的魅力
如果有不懂的,欢迎找我一起交流,加入量化交易大家庭,会定期分享量化交易学习资料包和答疑解惑