0
点赞
收藏
分享

微信扫一扫

0035-量化第六天:QMT—板块收益排序后选取收益最高成分股

c一段旅程c 2022-05-01 阅读 66
python

目录

一、模型介绍

二、可学习部分

1.将指数板块股票逐一添加到初始化股票列表中

2. 取前一日的时间

3.异常处理——遍历指数列表获取收益率 

4.使用numpy库排序 

5.判断股票是否停牌

三、代码逐行解释


一、模型介绍

回测模型:该策略在股票指数日线下运行

1.每隔1个月定时触发

2.计算行业指数过去20个交易日的收益率

3.选取收益率最高的指数的成份股

4.获取了他们的市值数据

5.将仓位调整至市值最大的5只股票上

二、可学习部分

1.将指数板块股票逐一添加到初始化股票列表中

	for index in index_universe:
		for stock in ContextInfo.get_sector(index):
			index_stocks.append(stock)

2. 取前一日的时间

lastdate = timetag_to_datetime(ContextInfo.get_bar_timetag(d - 1), '%Y%m%d')

3.异常处理——遍历指数列表获取收益率 

		for index in index_list:
			ratio = 0
			try:
				ratio = (his[index][-2] - his[index][0])/his[index][0]
			except KeyError:
				print('key error:' + index)
			except IndexError:
				print('list index out of range:' + index)
			return_index.append(ratio)

4.使用numpy库排序 

best_index = index_list[np.argmax(return_index)]

5.判断股票是否停牌

		for stock in index_stock:
			if ContextInfo.is_suspended_stock(stock) == False:  #股票没停牌
				stock_available.append(stock)

三、代码逐行解释

#coding:gbk
import numpy as np
import math
def init(ContextInfo):
	MarketPosition ={}
	ContextInfo.MarketPosition = MarketPosition #初始化持仓
	index_universe = ['399971.SZ','399973.SZ','399699.SZ','399237.SZ','399236.SZ','399432.SZ'] #指数池
	index_stocks = []  #股票池
	for index in index_universe:
		for stock in ContextInfo.get_sector(index):
			index_stocks.append(stock)
	ContextInfo.set_universe(index_universe+index_stocks)   #设定股票池
	ContextInfo.day = 20             #取过去20日的收益率
	ContextInfo.ratio = 0.8
	ContextInfo.holding_amount = 5   #设置买入数量
	ContextInfo.accountID='testS'

def handlebar(ContextInfo):
	buy_condition = False  #初始化买卖条件
	sell_condition = False
	d = ContextInfo.barpos
	lastdate = timetag_to_datetime(ContextInfo.get_bar_timetag(d - 1), '%Y%m%d') #昨天日期
	date = timetag_to_datetime(ContextInfo.get_bar_timetag(d), '%Y%m%d') #今天日期
	#print(lastdate)
	index_list = ['399971.SZ','399973.SZ','399699.SZ','399237.SZ','399236.SZ','399432.SZ'] #指数表
	return_index = [] #指数收益表
	weight = ContextInfo.ratio/ContextInfo.holding_amount   #平均分配权重
	size_dict = {}
	if  (float(date[-4:-2]) != float(lastdate[-4:-2])): #换月了
		#print ('---------------------------------------------------------------------------------')
		#print ('当前交易日',date,date[-4:-2])
		his = ContextInfo.get_history_data(21,'1d','close')  #4.1(含)前的21天数据返回字典{股票:段数据}
		#print(len(his)) #89只股票
		print ("his",his,timetag_to_datetime(ContextInfo.get_bar_timetag(d),"%Y%m%d"))   #当前交易日20220401 04
		for k in list(his.keys()):
			if len(his[k]) == 0:   #没有数据就删了
				del his[k]
		for index in index_list:              #把指数表index_list的收益率逐个放到return_index表里面
			ratio = 0
			try:
				ratio = (his[index][-2] - his[index][0])/his[index][0]   #分别计算21天涨幅
			except KeyError:
				print('key error:' + index)
			except IndexError:
				print('list index out of range:' + index)
			return_index.append(ratio)
		#print("return_index",return_index)
		best_index = index_list[np.argmax(return_index)]   # 获取指定数内收益率表现最好的行业
		#print("best_index",best_index)
		# 获取当天有交易的股票
		index_stock = ContextInfo.get_sector(best_index)   #取得指数表现最好的股票
		#print(index_stock)
		stock_available = []
		for stock in index_stock:     #删选没停牌的股票
			if ContextInfo.is_suspended_stock(stock) == False:  
				stock_available.append(stock)
				
		for stock in stock_available:   #清洗过的股票池记录市值到size_dict
			if stock in list(his.keys()):
				#目前历史流通股本取不到,暂用总股本
				if len(his[stock]) >= 2:
					stocksize =his[stock][-2] * float(ContextInfo.get_financial_data(['CAPITALSTRUCTURE.total_capital'],[stock],lastdate,date).iloc[0,-1])
					size_dict[stock] = stocksize
				elif len(his[stock]) == 1:
					stocksize =his[stock][-1] * float(ContextInfo.get_financial_data(['CAPITALSTRUCTURE.total_capital'],[stock],lastdate,date).iloc[0,-1])
					size_dict[stock] = stocksize
				else:
					return
		#print("size_dict",size_dict)
		size_sorted = sorted(list(size_dict.items()), key = lambda item:item[1])   #市值排序
		pre_holding = []
		
		for tuple in size_sorted[-ContextInfo.holding_amount:]:
			pre_holding.append(tuple[0])
			print(tuple[0])
		print ('买入备选',pre_holding)
		#函数下单
		if len(pre_holding) > 0:   #有持仓但是不在买入备选里面的卖出
			sellshort_list = []
			for stock in list(ContextInfo.MarketPosition.keys()):
				if stock not in pre_holding and (stock in list(his.keys())):
					order_shares(stock,-ContextInfo.MarketPosition[stock],'lastest',his[stock][-1],ContextInfo,ContextInfo.accountID)
					print('sell',stock)
					sell_condition = True
					sellshort_list.append(stock)
			if len(sellshort_list) >0:   #从持仓表中删除卖出标的
				for stock in sellshort_list:
					del ContextInfo.MarketPosition[stock]
			for stock in pre_holding:  #在买入备选表的,但是没有持仓,买入
				if stock not in list(ContextInfo.MarketPosition.keys()):
					Lots = math.floor(ContextInfo.ratio * (1.0/len(pre_holding)) * ContextInfo.capital / (his[stock][-1] * 100))
					order_shares(stock,Lots *100,'lastest',his[stock][-1],ContextInfo,ContextInfo.accountID)
					print('buy',stock)
					buy_condition = True
					ContextInfo.MarketPosition[stock] = Lots *100
举报

相关推荐

0 条评论