当前位置: 首页 > 工具软件 > QMT > 使用案例 >

0013-量化第二天:QMT—收益统计与函数封装交易信号

百里文景
2023-12-01

目录

一、模型介绍

二、可学习部分

1.记录买点,得出当前市值

2.统计利润

3. 计算持仓股,在图中输出基本统计值

4.函数封装交易信号 

三.代码逐行注释


一、模型介绍

以价格逻辑进行交易,并生成基本的收益统计,其中,交易信号 :

价格超过20天最高价,买入

价格跌破60日均线,卖出

				if data_high_pre[k][-2] > max(data_high[k][:-2]):
					buy[k] = 1     #昨天价格超过20日最高价,给买入字典赋值1(加入买入备选)
				elif data_high_pre[k][-2] < np.mean(data_close60[k][:-2]):
					sell[k] = 1              #低于60日均线,加入卖出备选

二、可学习部分

1.记录买点,得出当前市值

order_shares(k,order[k]*100,'fix',tmp[k][-1],ContextInfo,ContextInfo.accountID)  #开盘价下单
				ContextInfo.buypoint[k] = tmp[k][-1] #把最近开盘价给买点字典
				ContextInfo.money_distribution[k] -= 0.0003*order[k]*100*tmp[k][-1]
                #计算市值,要买的初始资金-手续费

2.统计利润

		profit = sum(ContextInfo.money_distribution.values())/ContextInfo.capital - 1
        #所有市值加起来/初始市值就是现在净值了

3. 计算持仓股,在图中输出基本统计值

		ttt = 0
		for v in list(ContextInfo.holdings.values()):
			if v > 0:  #持有股数不为零
				ttt += 1
		ContextInfo.paint('收益',profit,-1,0)
		ContextInfo.paint('对冲收益',profit-net_hs300-1,-1,0)
		ContextInfo.paint('对冲收益净值',profit+1-net_hs300,-1,0)
		ContextInfo.paint('个股',ttt,-1,0)

4.函数封装交易信号 

def signal(ContextInfo):
	buy = {i:0 for i in s} #生成初始股票的字典,格式:{股票:0}
	sell = {i:0 for i in s}
	data_high = ContextInfo.get_history_data(22,'1d','high',3) #获得22天的最高价字典
	data_high_pre = ContextInfo.get_history_data(2,'1d','high',3)
	data_close60 = ContextInfo.get_history_data(62,'1d','close',3)
	#print data_high
	#print data_close
	#print data_close60
	for k in list(data_high_pre.keys()): #遍历字典data_high_pre的键
		if k in data_close60: 
			if len(data_high_pre[k]) == 2 and len(data_high[k]) == 22 and len(data_close60[k]) == 62:  #股票的三个值都在
				if data_high_pre[k][-2] > max(data_high[k][:-2]):
					buy[k] = 1     #昨天价格超过20日最高价,给买入字典赋值1(加入买入备选)
				elif data_high_pre[k][-2] < np.mean(data_close60[k][:-2]):
					sell[k] = 1              #低于60日均线,加入卖出备选
	#print buy
	#print sell
	return buy,sell             #买入卖出备选

三.代码逐行注释

#coding:gbk
#HS300日线下运行
#股票池暂设为包含4只股票,每只分配可用资金的25%
import pandas as pd
import numpy as np
import time
import datetime

s = ['600000.SH','600004.SH','000001.SZ','000002.SZ']            #股票池
def init(ContextInfo):
	ContextInfo.set_universe(s) #设定基础股票池s,才能获取历史数据
	ContextInfo.day = 0 
	ContextInfo.weight = [0.25,0.25,0.25,0.25]         #设置初始权重列表
	ContextInfo.money_distribution_original = {k:i*ContextInfo.capital for (k,i) in zip(s,ContextInfo.weight)}
    #设定回测模式下的初始资金用ContextInfo.capital,生成股票:初始资金字典
    #zip函数返回一个以元组为元素的列表,其中第i个元组包含每个参数序列的第i个元素
    #也就是用zip做了,代码+权重的元组(元组不可更改)

	ContextInfo.money_distribution = ContextInfo.money_distribution_original
	ContextInfo.buypoint = {}  #创建一个买点字典
	ContextInfo.accountID='testS'

def handlebar(ContextInfo):
	d = ContextInfo.barpos 
	timetag = ContextInfo.get_bar_timetag(d)
	ContextInfo.holdings = get_holdings(ContextInfo.accountID,"STOCK")
	if ContextInfo.day == 0:  #取主图最近一天收盘价作为基准价
		ContextInfo.benchmark_start = ContextInfo.get_market_data(['close'],period='1d')
	benchmark = ContextInfo.get_market_data(['close'],period='1d')
	#print benchmark
	net_hs300 = benchmark/ContextInfo.benchmark_start  #基准价净值
	ContextInfo.paint('沪深300指数净值',net_hs300,-1,0)  #净值就是最新收盘价/基准
	ContextInfo.paint('沪深300指数收益',net_hs300-1,-1,0) #收益=净值-1
	tmp = ContextInfo.get_history_data(1,'1d','open',3) #最新一天开盘价,等比前复权
	if d > 60: 
		nowDate = timetag_to_datetime(ContextInfo.get_bar_timetag(d),'%Y%m%d')
		print(nowDate)  #获取当前时间
		buys, sells = signal(ContextInfo) #引用函数获得两个字典-确定谁买谁卖
		order = {}
		for k in s:
			if k not in ContextInfo.holdings and buys[k] == 1:   #在买入备选中且无持仓
				print('ready to buy',k)
				order[k] = int(ContextInfo.money_distribution[k]/(tmp[k][-1]))/100
                #确定下单手数:初始分配资金/最近开盘价/100
				order_shares(k,order[k]*100,'fix',tmp[k][-1],ContextInfo,ContextInfo.accountID)  #开盘价下单
				ContextInfo.buypoint[k] = tmp[k][-1] #把最近开盘价给买点字典
				ContextInfo.money_distribution[k] -= 0.0003*order[k]*100*tmp[k][-1]
                #计算市值,要买的初始资金-手续费
				#print ContextInfo.money_distribution[k]
			elif k in ContextInfo.holdings and sells[k] == 1:     #在卖出备选中且有持仓
				print('ready to sell',k)
				order_shares(k,-ContextInfo.holdings[k]*100,'fix',tmp[k][-1],ContextInfo,ContextInfo.accountID)
				ContextInfo.money_distribution[k] += (tmp[k][-1]-ContextInfo.buypoint[k]) * ContextInfo.holdings[k] * 100 - 0.0003*ContextInfo.holdings[k]*100*tmp[k][-1]
                #计算盈亏,最新开盘价-买点的开盘价,乘持仓减去手续费
				#print tmp[k][-1]
				#print ContextInfo.buypoint[k]
				#print ContextInfo.money_distribution[k]
		profit = sum(ContextInfo.money_distribution.values())/ContextInfo.capital - 1
        #所有市值加起来/初始市值就是现在净值了
		ttt = 0
		for v in list(ContextInfo.holdings.values()):
			if v > 0:  #持有股数不为零
				ttt += 1
		ContextInfo.paint('收益',profit,-1,0)
		ContextInfo.paint('对冲收益',profit-net_hs300-1,-1,0)
		ContextInfo.paint('对冲收益净值',profit+1-net_hs300,-1,0)
		ContextInfo.paint('个股',ttt,-1,0)
		ContextInfo.day += 1
		
def signal(ContextInfo):
	buy = {i:0 for i in s} #生成初始股票的字典,格式:{股票:0}
	sell = {i:0 for i in s}
	data_high = ContextInfo.get_history_data(22,'1d','high',3) #获得22天的最高价字典
	data_high_pre = ContextInfo.get_history_data(2,'1d','high',3)
	data_close60 = ContextInfo.get_history_data(62,'1d','close',3)
	#print data_high
	#print data_close
	#print data_close60
	for k in list(data_high_pre.keys()): #遍历字典data_high_pre的键
		if k in data_close60: 
			if len(data_high_pre[k]) == 2 and len(data_high[k]) == 22 and len(data_close60[k]) == 62:  #股票的三个值都在
				if data_high_pre[k][-2] > max(data_high[k][:-2]):
					buy[k] = 1     #昨天价格超过20日最高价,给买入字典赋值1(加入买入备选)
				elif data_high_pre[k][-2] < np.mean(data_close60[k][:-2]):
					sell[k] = 1              #低于60日均线,加入卖出备选
	#print buy
	#print sell
	return buy,sell             #买入卖出备选

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/100
	return holdinglist

 类似资料: