
市场上的投资者,不管是价值投资者,还是投机者,或者短线交易者,都会根据某些因子来判断股票的涨跌。当一群交易者同时采用某个因子的时候,就会造成该因子有效。因子选股模型为什么适用?
举一个简单的例子:如果有一批人参加马拉松,想知道哪些人能获得不错的成绩,只需在跑前做一个身体测试即可。测试可以用一个或多个指标。对测试的结果进行排名,排名靠前的运动员获得好成绩的可能性就比较大。因子选股模型的原理与此类似,可以利用某些指标(因子)选择未来可能表现较好的股票。
哪些因子可能成为选择股票的依据?这主要依赖于金融经济逻辑和市场经验。总的来说,因子的来源有三方面:
(1)公司层面因子;
(2)外部环境因子;
(3)市场表现因子。
公司层面的因子,看的就是这家公司本身怎么样,与公司的生产经营息息相关,一般来自公司的财务指标,反映了公司的盈利、运营、债务和成长状况。这些因子主要有:
1)价值类因子,如PE、PB;
2)成长类因子,如ROE、净利润增长率;
3)规模类因子,如净利润、营业收入;
4)情绪类因子,如预测未来12个月的利润增长率;
5)质量类因子,如资产负债率、应收账款周转率。
政治法律、宏观经济、社会习俗和技术发展等外部环境对一个行业和企业来说都是非常重要的。比较重要并且容易量化的外部环境因子主要是
1)宏观环境因子,如经济增长率、利率等;
2)行业环境,如行业集中度等。
市场表现因子主要体现的是股票在交易过程中的价格和交易量。这些因子主要有动量和反转类因子、资金流向和各种技术类指标等。
QMT作为券商专属的专业量化交易平台,适配A股市场,支持Python编程,内置了全量行情数据、上市公司财务数据、各类因子库,无需投资者额外外接数据源、手动整理数据,彻底解决多因子实战中“数据获取难、计算繁琐”的核心痛点。平台搭配数据获取、策略编写、策略回测、实盘交易模块,实现“因子筛选—策略编写—历史回测—参数优化—一键实盘”的全流程闭环,真正把多因子模型从理论想法,快速转化为可运行、可落地的实战策略。
无论是新手入门搭建基础多因子策略,还是专业投资者优化复杂模型,QMT都能满足需求。下面为大家提供一套QMT软件自带的多因子选股实战代码,新手也能轻松上手操作:
#coding:gbk"""回测模型示例(非实盘交易策略)#HS300日线下运行,20个交易日进行 一次调仓,每次买入在买入备选中因子评分前10的股票,每支股票各分配当前可用资金的10%(权重可调整)#扩展数据需要在补完HS300成分股数据之后生成,本模型中扩展数据暂时使用VBA指标ATR和ADTM生成,命名为atr和adtm"""import pandas as pdimport numpy as npimport timeimport datetimedef 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.5print (1111111, rank1[k]) tmp = sorted(list(rank_total.items()), key = lambda item:item[1])#print tmpif 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] = 0if 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.capitalif 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_close60for 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 sellreturn buy,sell #买入卖出备选策略核心原理的是:以沪深300成分为选股范围,每20个交易日进行一次调仓;先通过信号函数筛选买入、卖出备选标的——股价超过20日最高价的纳入买入备选,低于60日均线的纳入卖出备选;再基于VBA指标生成的ATR、ADTM两类扩展因子对买入备选标的进行打分排序,选取评分前10的标的(不足10只则全选);最后按每只标的10%的资金权重等权买入,同时清仓不在标的列表且符合卖出条件的持仓,全程自动执行,还可统计账户资金、盈利情况及收益率,清晰呈现策略回测效果。
(1)开户成功后入金10万后提交QMT申请流程
(2)申请过程全程线上,预计2个工作日申请完成。
(3)等待开通过程中,可以提供测试账号、安装配置流程、量化会员资料。
(4)开通成功后,会通过邮件发送你软件下载地址,登录账号后就可以使用。

福利1:惊喜佣金
福利2:领取完整教程
福利3:添加量化讨论群
福利4:提供专业量化问题解答
福利5:量化工具安装使用教程、视频
福利6:极速柜台,量化投资者专用,速度微秒级
福利7:提供服务器托管模式:ptrade策略+ldp极速柜台+vip定向服务器(限50人)
