该策略基于自适应移动平均规则交易标普500指数,通过4年滚动选择期每日优化短期和长期区间,识别趋势信号进行交易。

I. 策略概述

该策略利用简单移动平均线(MA)规则交易标普500指数,动态优化短期和长期移动平均线的区间参数:

当短期移动平均线高于长期移动平均线时,视为上升趋势,进行多头交易;当短期移动平均线低于长期移动平均线时,视为下降趋势,进行空头交易。策略采用滚动4年历史数据的优化期每日选择最佳MA规则,并将其应用于次日交易周期。通过自适应规则调整,策略动态适应市场条件,可通过期货或ETF实现执行。

II. 策略合理性

趋势跟随系统是金融市场中的经典策略,利用市场中波动聚集现象进行交易。此类系统通过简单规则识别趋势,在高波动期(通常伴随低收益)时避免持有高风险资产,而在低波动期(通常伴随高收益)时积极参与市场。

引入自适应层使策略能够根据历史数据动态调整,以区分高波动低收益状态和低波动高收益状态,从而优化风险管理与收益捕捉。通过每日更新的规则选择,策略在快速变化的市场环境中具备更高的灵活性和准确性,从而提高整体表现。

III. 论文来源

Technical Analysis with a Long Term Perspective: Trading Strategies and Market Timing Ability [点击浏览原文]

<摘要>

本文从三个方向扩展了关于技术分析盈利能力的研究。首先,我们研究了基于较长时间段移动平均线计算的复杂交易规则的表现。通过对标普500指数的日价格模拟不同的交易规则,研究发现,当交易信号基于更长时间的移动平均线生成时,策略的盈利能力显著增强。

此外,研究验证了这些规则的市场时机能力,即在波动率较高或趋势反转时有效规避风险,并在趋势持续时最大化收益。这些发现表明,动态优化的技术分析方法可为投资者提供显著的风险调整后收益,特别是在长期视角下。

IV. 回测表现

年化收益率14.6%
波动率17.41%
Beta-0.247
夏普比率0.61
索提诺比率-0.14
最大回撤N/A
胜率43%

V. 完整python代码

import numpy as np
from AlgorithmImports import *
class AdaptiveMovingAveragesMarketTiming(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        self.SetCash(100000)
        
        data = self.AddEquity('SPY', Resolution.Daily)
        data.SetLeverage(5)
        self.symbol = data.Symbol
        self.period = 4 * 12 * 21
        self.SetWarmUp(self.period, Resolution.Daily)
        self.data = RollingWindow[float](self.period)
        
        self.ma = {}
        self.ma_signal = {}
        
        sma_periods = [x for x in range(1, 101, 4)]
        lma_periods = [x for x in range(5, 991, 20)]
        
        ma_combinations = [[i, j] for i in sma_periods for j in lma_periods if i<j]
        for sma, lma in ma_combinations:
            self.ma[sma,lma] = [self.SMA(self.symbol, sma, Resolution.Daily), self.SMA(self.symbol, lma, Resolution.Daily)]
            self.ma_signal[sma,lma] = RollingWindow[float](self.period)
        
    def OnData(self, data):
        # Update SPY price every day.
        symbol_obj = self.Symbol(self.symbol)
        if symbol_obj in data and data[symbol_obj]:
            self.data.Add(data[symbol_obj].Value)
        
        # Store vector value for current day and optimize from previous values.
        avg_return = {}
        for sma_lma in self.ma:
            sma = self.ma[sma_lma][0]
            lma = self.ma[sma_lma][1]
            if sma.IsReady and lma.IsReady:
                sma_value = sma.Current.Value
                lma_value = lma.Current.Value
                
                # MA SIGNAL = if short term MA is OVER long term MA == 1 else -1
                self.ma_signal[sma_lma].Add(1 if sma_value > lma_value else -1)
                
                # 4 years of SPY data is ready.
                if self.data.IsReady:
                    values = np.array([x for x in self.data])
                    daily_changes = values[:-1] / values[1:] - 1
                
                    # Find optimal sma_lma pair.
                    if self.ma_signal[sma_lma].IsReady:
                        # Multiply both vectors to get daily performance for sma_lma pair.
                        # Ignore last value from ma_signal since it's today's value. It will be used to trade decision for next day.
                        ma_signal_vector = [x for x in self.ma_signal[sma_lma]][1:]
                        return_vector = ma_signal_vector * daily_changes
                        
                        # Store avg daily performance for sma_lma pair.
                        avg_return[sma_lma] = np.average([x for x in return_vector])
                
            else:
                # MA is not ready yet.
                self.ma_signal[sma_lma].Add(0)
        if self.IsWarmingUp: return
        if len(avg_return) == 0: return
        
        # Optimalization
        optimal_sma_lma = max(avg_return, key=avg_return.get)
        
        # Trading
        last_signal = self.ma_signal[optimal_sma_lma][0]
        if last_signal == 1:
            self.SetHoldings(self.symbol, 1)
        elif last_signal == -1:
            self.SetHoldings(self.symbol, -1)




发表评论

了解 Quant Buffet 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读