QMT多因子选股源代码
今天给大家分享一个简单的策略—— QMT 多因子选股策略 代码是基于 QMT 平台开发的量化选股策略,主要针对沪深 300 成分股进行多因子选股和定期调仓。策略结合了 (ATR 和 ADTM) 进行选股评分,并通过因子加权方式确定买入标的。
coding:gbk
"""
回测模型示例(非实盘交易策略)
#HS300日线下运行,20个交易日进行 一次调仓,每次买入在买入备选中因子评分前10的股票,每支股票各分配当前可用资金的10%(权重可调整)
#扩展数据需要在补完HS300成分股数据之后生成,本模型中扩展数据暂时使用VBA指标ATR和ADTM生成,命名为atr和adtm
"""
import pandas as pd
import numpy as np
import time
import datetime
def init(ContextInfo):
ContextInfo.s = ContextInfo.get_sector('000300.SH')
ContextInfo.set_universe(ContextInfo.s)
ContextInfo.day = 0
ContextInfo.holdings = {i:0 for i in ContextInfo.s}
ContextInfo.weight = [0.1]*10 #设置资金分配权重
ContextInfo.buypoint = {}
ContextInfo.money = ContextInfo.capital
ContextInfo.profit = 0
ContextInfo.accountID='testS'
def handlebar(ContextInfo):
rank1 = {}
rank2 = {}
rank_total = {}
tmp_stock = {}
d = ContextInfo.barpos
price = ContextInfo.get_history_data(1,'1d','open',3)
if d > 60 and d % 20 == 0: #每月一调仓
nowDate = timetag_to_datetime(ContextInfo.get_bar_timetag(d),'%Y%m%d')
print(nowDate)
buys, sells = signal(ContextInfo)
order = {}
for k in list(buys.keys()):
if buys[k] == 1:
rank1[k] = ext_data_rank('atr',k[-2:]+k[0:6],0,ContextInfo)
rank2[k] = ext_data_rank('adtm',k[-2:]+k[0:6],0,ContextInfo)
#print rank1[k], rank2[k]
rank_total[k] = 1.0 * rank1[k] #因子的权重需要人为设置,此处取了0.5和-0.5
print (1111111, rank1[k])
tmp = sorted(list(rank_total.items()), key = lambda item:item[1])
#print tmp
if len(tmp) >= 10:
tmp_stock = {i[0] for i in tmp[:10]}
else:
tmp_stock = {i[0] for i in tmp} #买入备选中若超过10只股票则选10支,不足10支则全选
for k in list(buys.keys()):
if k not in tmp_stock:
buys[k] = 0
if tmp_stock:
print('stock pool:',tmp_stock)
for k in ContextInfo.s:
if ContextInfo.holdings[k] > 0 and sells[k] == 1:
print('ready to sell')
order_shares(k,-ContextInfo.holdings[k]*100,'fix',price[k][-1],ContextInfo,ContextInfo.accountID)
ContextInfo.money += price[k][-1] * ContextInfo.holdings[k] * 100 - 0.0003*ContextInfo.holdings[k]*100*price[k][-1] #按万三设定
ContextInfo.profit += (price[k][-1]-ContextInfo.buypoint[k]) * ContextInfo.holdings[k] * 100 - 0.0003*ContextInfo.holdings[k]*100*price[k][-1]
#print price[k][-1]
print(k)
#print ContextInfo.money
ContextInfo.holdings[k] = 0
ContextInfo.money_distribution = {k:i*ContextInfo.money for (k,i) in zip(tmp_stock,ContextInfo.weight)}
for k in tmp_stock:
if ContextInfo.holdings[k] == 0 and buys[k] == 1:
print('ready to buy')
order[k] = int(ContextInfo.money_distribution[k]/(price[k][-1]))/100
order_shares(k,order[k]*100,'fix',price[k][-1],ContextInfo,ContextInfo.accountID)
ContextInfo.buypoint[k] = price[k][-1]
ContextInfo.money -= price[k][-1] * order[k] * 100 - 0.0003*order[k]*100*price[k][-1]
ContextInfo.profit -= 0.0003*order[k]*100*price[k][-1]
print(k)
ContextInfo.holdings[k] = order[k]
print(ContextInfo.money,ContextInfo.profit,ContextInfo.capital)
profit = ContextInfo.profit/ContextInfo.capital
if not ContextInfo.do_back_test:
ContextInfo.paint('profit_ratio', profit, -1, 0)
def signal(ContextInfo):
buy = {i:0 for i in ContextInfo.s}
sell = {i:0 for i in ContextInfo.s}
data_high = ContextInfo.get_history_data(22,'1d','high',3)
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 ContextInfo.s:
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日最高价,加入买入备选
elif data_high_pre[k][-2] < np.mean(data_close60[k][:-2]):
sell[k] = 1 #低于60日均线,加入卖出备选
#print buy
#print sell
return buy,sell #买入卖出备选策略总体逻辑
标的池:沪深300成分股 调仓频率:每20个交易日(约每月)调仓一次 选股规则:买入突破20日高点的股票,卖出跌破60日均线的股票 选股数量:每次买入10只股票(如果符合条件的股票≥10只) 资金分配:每只股票分配10%的可用资金(等权重分配) 因子排序:使用ATR和ADTM两个技术指标对股票进行排序 QMT核心函数逻辑
1、 init() 初始化函数
获取沪深300成分股列表
- 初始化持仓字典(全为0)
- 设置10只股票各10%的权重
- 初始化账户资金和收益
2、handlebar() 主处理函数if 调仓日(d>60且每20天):
1. 生成买卖信号(signal函数)
2. 对买入备选股票按因子排序:
rank1 = ATR指标排名
rank2 = ADTM指标排名
rank_total = 1.0 * rank1 # 实际只用了ATR排名
3. 选取排名前10的股票(或全部)
4. 执行卖出:
- 持仓股票且卖出信号=1
- 市价卖出全部持仓
- 更新可用资金和累计收益
5. 执行买入:
- 计算每只股票分配的资金
- 市价买入计算的数量
- 更新成本价和持仓
6. 计算并绘制收益率曲线
3、signal() 信号生成函数买入条件(buy[k] = 1):
前一天的最高价 > 过去20日的最高价(排除最近两天)
即:突破20日高点
卖出条件(sell[k] = 1):
前一天的最高价 < 过去60日的收盘价均值(排除最近一天)
即:跌破60日均线
总结
关注"叩富问财"公众号,回复"资深吴经理",联系专属客户经理开通量化交易权限!立即行动:打开微信,搜索"叩富问财",在对话框中输入"资深吴经理",开启你的量化交易之旅!
温馨提示:投资有风险,选择需谨慎。
其他人追问


1对1私行级陪伴








问一问

分享该文章

456


+微信
电话
公网安备:11010802032515号 ICP备案:京ICP备18019099号-3