今天给大家展示一下集合竞价选股策略,大家可以直接拿来用,我目前用的是QMT量化交易软件,在券商开户就能免费使用,同时还能享受券商的VIP费率。
# coding:gbk
'''
=======================================================================================================
本策略通过获取沪深300的成份股数据并统计其30天内开盘价大于前收盘价的天数,并在该天数大于阈值10的时候加入股票池,随后对不在股票池的股票卖出,并买入在股票池不在持仓里的股票,本策略在日级别下运行,持仓周期为30天。
回测基础股票池:沪深300
回测时间:
=======================================================================================================
'''
import numpy as np
# ===========================================策略初始化部分===========================================
def init(ContextInfo):
# context.count_bench累计天数阙值
ContextInfo.count_bench = 10
# 用于对比的天数
ContextInfo.count = 30
# 策略运行时间
ContextInfo.t = 0
# 调仓时间
ContextInfo.tc = 30
# 获取沪深300成分股
s = ContextInfo.get_stock_list_in_sector('沪深300')
# 设置基础股票池
ContextInfo.set_universe(s)
# 设置交易账户
ContextInfo.accountid = "testS"
# ============================================策略初始化部分==========================================
# =============================================策略周期循环部分=======================================
def handlebar(ContextInfo):
# 判断是否进入调仓周期
if ContextInfo.t % ContextInfo.tc == 0:
# 买入
buy_sum = 0
# 卖出
sell_sum = 0
# 当前bar线索引
index = ContextInfo.barpos
# 当前bar线时间戳
realtimetag = ContextInfo.get_bar_timetag(index)
# 打印当前bar线时间
print(timetag_to_datetime(realtimetag, '%Y%m%d %H:%M:%S'))
# 获取当前持仓信息
ContextInfo.holdings = get_holdings(
ContextInfo.accountid, "STOCK")
# 获取当前股票池
universe = ContextInfo.get_universe()
# 获取股票池30天收盘价数据
dict_close = ContextInfo.get_history_data(
ContextInfo.count, '1d', 'close', 3)
# 获取股票池30天开盘价数据
dict_open = ContextInfo.get_history_data(ContextInfo.count, '1d', 'open', 3)
# ===============================================生成买入标的=========================================
# 待买入股票池{code:开盘价大于前一天收盘价的累计次数}
excel_num = {}
for stock in universe:
if stock in list(dict_close.keys()):
open = dict_open[stock]
pre_close = dict_close[stock]
try:
# 开盘价-前一天收盘价
diff = np.array(open[1:]) - np.array(pre_close[:-1])
except ValueError:
print('value error:', stock)
# print('diff',diff)
# 获取开盘价大于前一天收盘价的累计次数超过阙值的标的池.并剔除当天没有交易的股票
if len(diff[diff > 0]) >= ContextInfo.count_bench:
# trade_symbols.append(stock)
excel_num[stock] = len(diff[diff > 0])
# print('本次股票池有股票数目: ', len(trade_symbols))
# 按excel_num的值升序排序,返回的结果类型list形如:[('code1',value1),('code2',value2)...]
exnum_sort = sorted(excel_num.items(), key=lambda x: x[1])
# 买入备选股票列表
buylist = [i[0] for i in exnum_sort]
# 如果买入备选股票列表股票数量小于10,则全买入
if len(buylist) < 10:
trade_symbols = buylist
# 不然选取10只累计天数最小的买入
else:
trade_symbols = buylist[0:10]
# =============================================生成买入标的===========================================
# =========================================根据标的股票池交易==========================================
for stock_hold in list(ContextInfo.holdings.keys()):
# 卖出不在买入标的中的股票
if stock_hold not in trade_symbols:
order_shares(
stock_hold, float(-ContextInfo.holdings[stock_hold]), 'latest', ContextInfo, ContextInfo.accountid)
# 卖出总和+1
sell_sum += 1
# print('卖出:',stock_hold)
# 买入标的股票
for symbol in trade_symbols:
if symbol not in ContextInfo.holdings:
order_shares(symbol, 10000, 'latest', ContextInfo, ContextInfo.accountid)
# 买入总和+1
buy_sum += 1
# print('买入:',symbol)
# ============================================根据标的股票池交易======================================
# 回测画图
if not ContextInfo.do_back_test:
ContextInfo.paint('buy_num', buy_sum, -1, 0)
ContextInfo.paint('sell_num', sell_sum, -1, 0)
# 策略运行天数加1
ContextInfo.t+=1
# ==========================================策略周期循环部分==========================================
# 获取持仓信息{code.market:股票数}
def get_holdings(accountid,datatype):
holdinglist={}
resultlist=get_trade_detail_data(accountid,datatype,"POSITION")
for obj in resultlist:
holdinglist[obj.m_strInstrumentID+"."+obj.m_strExchangeID]=obj.m_nVolume
return holdinglist
回测参数设置(回测频率、周期、手续费等可视化设置):
回测结果展示:
回测收益:
回测净值曲线:
联系客服