返回列表 发布新帖

QMT动量策略回测全流程拆解,看完就能跑

11 0

昨天仔细的介绍了动量策略1的原理,计算公式,运用等,今天看怎么样利用QMT实现动量策略的回测,做策略的研究,给一个简单的学习代码

昨天写的原理介绍动量研究-1斜率动量策略为什么涨得稳比涨得快更重要?

第一步打开qmt,先补充完整历史数据,点击界面的操作,下面有一个数据管理

8f57e30232c1aae7674beff54daa9c98.png

点击自己需要的数据补充就可以,也可以自定义标的补充,自定义时间等

4a90e69868825f8a777da6148512023c.png

点击建立策略,编辑进入策略就可以,简单的回测框架的认识,账户在回测模块中不需要输入都可以

f326838174bfaf1b89cba54946f7444c.png

回测的开始时间,结束时间

16e6bbf1f9ad979e191c16130676a768.png

回测的参数设置

9eda13338745319ba9bf480b48735f63.png

自定义股票池回测

2621fd76e4bbfcf4a937e4560793c31e.png

计算个股的动量趋势

b11f303f2fcc1d2bb5d6a8fabdec0c00.png

主要注意数据的调用周期需要和右边设置周期一样,默认周期

21eea55f216733591e03aff6a1a1fdd3.png

驱动回测框架,和排序选股算法

09ec588d93cba6a16dc79f63daab5b64.png

动量的买卖轮动交易算法,不在排名的卖出,在的继续持有

fe34a062e2057d6b7be7dd7ca371aabb.png

其它就是检查函数,比如读取持股,账户等数据

8012061df305459035d06f666e14427b.png

点击回测按钮就可以,注意区分回测按钮和运行按钮,运行按钮是实盘调试当前数据,回测按钮是驱动历史回测的

6bcf9a519cd89d082e6f3b8e6fdd2aaa.png

点击回测就会开始回测算法

0f520bfd6dac9d5e9f28e51ab8c2a4ff.png

点击返回界面就可以看见回测的详细数据

e092a9516f10a2cf92599beafe98d54a.png

标的主要是宽基,波动相对小一点

e512d35e1886badc4bc7341b2e3b01a8.png

在黄金、纳指、创业板三个低相关资产中,用"加权对数回归的斜率×R²"选出趋势最强且最稳定的一个满仓持有;同时用N日均线做个股和A股指数双重止损,跌破即空仓——本质是一个"趋势跟踪+风险平价+全天候"的轮动策略。

不懂的问我就可以,需要详细的学习代码,加我就可以

4e185ed57dd39ce1be2490a14d9729dc.jpg

开户专业的支持

f14499eb542a3b27e484e90ea5fbce7f.png

动量回测计算代码参考研究

def MOM(c,date,df,index_df,etf):
    y = np.log(df['close'].values)
    df['line']=df['close'].rolling(c.line).mean()
    n = len(y)  
    x = np.arange(n)
    weights = np.linspace(1,2, n)  # 线性增加权重
    slope, intercept = np.polyfit(x, y, 1, w=weights)
    annualized_returns = math.pow(math.exp(slope), 250) - 1
    residuals = y - (slope * x + intercept)
    weighted_residuals = weights * residuals**2
    r_squared = 1 - (np.sum(weighted_residuals) / np.sum(weights * (y - np.mean(y))**2))
    last_price=df['close'].tolist()[-1]
    last_line=df['line'].tolist()[-1]
    #计算指数风控
    index_df['line']=index_df['close'].rolling(c.index_line).mean()
    last_index=index_df['close'].tolist()[-1]
    last_index_line=index_df['line'].tolist()[-1]
    
    score = annualized_returns * r_squared
    if c.is_index=='是':
        #先检查是否触发指数风险
        if last_index<last_index_line and etf in c.index_trader_stock:
            score=-100
            print(date,etf,'触发指数风险控制卖出*****************')
        else:
            print(date,etf,'没有触发指数风险控制*****************')
            score=score
    else:
        score=score
        print(date,etf,'没有开启指数风险控制*****************')
    if c.is_stock=='是':
        if last_price<last_line:
            score=-100
            print(date,etf,'触发个股风控卖出************')
        else:
            print(date,etf,'没有触发个股风控卖出************')
            score=score
    else:
        print(date,etf,'没有开启个股风控************')
        score=score
    return score
def get_rank(c,etf_pool,score_list):
    df = pd.DataFrame(index=etf_pool, data={'score':score_list})
    df = df.sort_values(by='score', ascending=False)
    #total_score = df['score'].sum() 不告诉你这个怎么用
    df = df[(df['score'] > c.min_value) & (df['score'] <= c.max_value)] #安全区间,动量过高过低都不好
    rank_list = list(df.index)
    if len(rank_list) == 0:
        rank_list=[] #如果全部都小于0,那么空仓或者买《国债、银华日历、黄金》避险
    return rank_list

[#动量]() [#策略]() [#qmt]() [#量化]() [#交易]() [#金融]()

原理图

e877f8cba3a0b15326e7142c8725820c.png

回复

您需要登录后才可以回帖 登录 | 立即注册

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2026 迅投QMT社区 版权所有 All Rights Reserved. 京ICP备2025122616号-3
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表