量化百科|基于移动平均线交叉的量化交易策略|附回测代码

文摘   2024-08-25 06:50   英国  

量化百科|基于移动平均线交叉的量化交易策略|附回测代码

概述

本文介绍了一种基于移动平均线交叉(Moving Average Crossover)的量化交易策略,该策略通过跟踪短期和长期的指数移动平均线(EMA),识别市场趋势,并据此做出买卖决策。本文所展示的策略采用了SPY(标普500 ETF)作为交易标的,并通过QuantConnect平台进行回测。

移动平均线的应用与优劣分析

什么是移动平均线?

移动平均线(MA)是一种简单的技术分析工具,通过创建一个不断更新的平均价格来平滑价格数据。移动平均线可以根据不同的时间段来计算,例如10天、20分钟、30周等。移动平均线的主要用途是识别趋势方向和确定支撑和阻力位。

移动平均线的图例

在下图中,可以看到移动平均线如何作为支撑位和阻力位作用。当价格在上升趋势中接近50天或200天的移动平均线时,这些移动平均线往往会充当支撑位;相反,在下降趋势中,这些移动平均线则可能成为阻力位。

移动平均线示例

移动平均线的类型

移动平均线有多种类型,最常见的是简单移动平均线(SMA)指数移动平均线(EMA)。SMA是通过将选定时间段内的收盘价相加后平均得出,而EMA则对最近的价格赋予更高的权重,因此比SMA更快地反映价格变化。

简单移动平均线(SMA)与指数移动平均线(EMA)

在下图中,显示了50天的SMA与EMA的对比。可以看到,EMA由于对最近的价格赋予更高权重,所以对价格变化的反应更为敏感。

SMA与EMA对比图

常见的移动平均线长度

常用的移动平均线长度有10天、20天、50天、100天和200天。短期移动平均线对价格变化反应更快,而长期移动平均线则能更好地过滤掉短期波动的噪声。不同长度的移动平均线适用于不同的交易策略,短期交易者更倾向于使用较短的移动平均线,而长期投资者则倾向于使用较长的移动平均线。

不同长度移动平均线的效果

下图展示了20天移动平均线与100天移动平均线对价格变化的跟踪效果。20天移动平均线更贴近实际价格,而100天移动平均线则更加平滑,适合长期趋势分析。

不同长度的移动平均线对比

移动平均线交叉策略

移动平均线交叉策略是最常见的移动平均线应用之一。当短期移动平均线上穿长期移动平均线时,通常被视为买入信号,称为“金叉”;相反,当短期移动平均线下穿长期移动平均线时,则被视为卖出信号,称为“死叉”。

移动平均线交叉示意图

下图展示了经典的“金叉”和“死叉”信号。短期移动平均线(例如50天EMA)上穿长期移动平均线(例如200天EMA)时产生“金叉”,为买入信号;相反,下穿时产生“死叉”,为卖出信号。

金叉与死叉示意图

移动平均线的优缺点

优点:

  • • 趋势识别: 移动平均线通过平滑价格数据帮助交易者识别市场趋势。

  • • 信号生成: 移动平均线交叉可以产生明确的买卖信号。

  • • 支撑与阻力判断: 移动平均线可以充当动态支撑和阻力位,帮助交易者确定进出场时机。

  • • 简单易用: 移动平均线直观易懂,适合初学者,并且容易集成到自动化交易系统中。

缺点:

  • • 滞后性: 由于基于过去数据,移动平均线具有滞后性,在快速变化的市场中可能无法及时反映趋势反转。

  • • 虚假信号: 在震荡市场中,移动平均线可能会产生大量虚假信号,导致交易损失。

  • • 对时间周期敏感: 不同的时间周期对移动平均线的有效性影响很大,可能在某些市场条件下表现良好,但在其他条件下则效果不佳。

  • • 过度简化: 依赖单一的移动平均线可能忽略其他重要的市场因素,如交易量、市场情绪等。

与移动平均线相似的技术指标

除了移动平均线,还有一些类似的技术分析指标可供交易者使用,如移动平均线收敛散度(MACD)抛物线转向指标(SAR)一目均衡表(Ichimoku Cloud)。这些指标可以与移动平均线结合使用,以确认信号并优化交易策略。

策略详情

策略初始化

  • • 起始资金: $100,000 美元

  • • 回测时间范围: 2010年1月1日至2021年11月27日

  • • 交易标的: SPY(标普500 ETF)

  • • 短期EMA: 50天指数移动平均线

  • • 长期EMA: 200天指数移动平均线

技术指标

  • • 指数移动平均线(EMA):

    • • 短期EMA(Fast EMA): 50天

    • • 长期EMA(Slow EMA): 200天

通过比较短期EMA与长期EMA的值,该策略识别出市场的趋势方向。

策略逻辑

  • • 多头开仓: 当50天短期EMA上穿200天长期EMA,并且当前未持有SPY时,策略将以100%的资金买入SPY。这表明市场进入了上升趋势,适合做多。

  • • 平仓(清仓): 当50天短期EMA下穿200天长期EMA,并且当前持有SPY时,策略将卖出所有持仓。这表明市场可能进入下降趋势,适合清仓。

暖启动(Warm-Up)

策略在开始时进行暖启动(Warm-Up),通过预加载200天的历史数据来确保EMA指标的准确性和稳定性。

回测结果

在2010年到2021年的回测期间,该策略通过跟随市场趋势,在关键的趋势反转点上进行买卖操作,避免了市场的波动风险,同时也捕捉到了部分市场的上涨机会。

结语

移动平均线交叉策略虽然简单,但在实战中依然有着广泛的应用价值。本文通过代码示例展示了如何在量化平台上实现这一策略,供大家参考和学习。未来,我们可以通过调整参数和添加其他技术指标来进一步优化这一策略。同时,结合对移动平均线优劣的全面分析,可以更好地理解和应用这一技术工具,助力投资决策。



策略实现代码基于QuantConnect平台,详细完整代码和策略原文请见知识星球

from AlgorithmImports import *
### <summary>### Simple indicator demonstration algorithm of MACD### </summary>### <meta name="tag" content="indicators" />### <meta name="tag" content="indicator classes" />### <meta name="tag" content="plotting indicators" />class MovingAverageCrossAlgorithm(QCAlgorithm): def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.''' self.SetStartDate(2010, 1, 1) #Set Start Date self.SetEndDate(2021, 11, 27) #Set End Date self.SetCash(100000) #Set Strategy Cash
# add SPY to our portfolio self.AddEquity("SPY") # create a 50 day exponential moving average self.fast = self.EMA("SPY", 50, Resolution.Daily) # create a 200 day exponential moving average self.slow = self.EMA("SPY", 200, Resolution.Daily) # warm up the inidicator (i.e. give it previous data) self.SetWarmUp(200) self.previous = None
def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.''' # a couple things to notice in this method: # 1. We never need to 'update' our indicators with the data, the engine takes care of this for us # 2. We can use indicators directly in math expressions # 3. We can easily plot many indicators at the same time # Docs: https://www.quantconnect.com/docs/algorithm-reference/indicators # wait for our indicators to fully initialize if not self.slow.IsReady and not self.IsWarmingUp: return # only once per day if self.previous is not None and self.previous.date() == self.Time.date(): return # plot our indicators self.Plot("EMA", self.slow, self.fast) # define a small tolerance on our checks to avoid bouncing         # we only want to go long if we're currently short or flat
# we only want to liquidate if we're currently long # if the fast is less than the slow we'll liquidate our long
self.previous = self.Time


class MACDTrendAlgorithm(QCAlgorithm):
def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(2004, 1, 1) #Set Start Date self.SetEndDate(2023, 10, 20) #Set End Date self.SetCash(100000) #Set Strategy Cash
def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.''' # wait for our macd to fully initialize if not self.__macd.IsReady: return
# only once per day if self.__previous.date() == self.Time.date(): return
# define a small tolerance on our checks to avoid bouncing tolerance = 0.0025
holdings = self.Portfolio["SPY"].Quantity
signalDeltaPercent = (self.__macd.Current.Value - self.__macd.Signal.Current.Value)/self.__macd.Fast.Current.Value



self.__previous = self.Time

关于LLMQuant

🌟🌟 起源于剑桥大学的知识分享社区,每日更新大语言模型与量化金融的最新资讯 🌍📊 www.llmquant.com 🌟🌟

加入知识星球,你将获得:

  • 📰 每日最新资讯:人工智能与量化金融的前沿动态,附中英文原文,助你紧跟行业发展。

  • 💻 量化策略详解:获取量化策略的完整代码,支持多平台回测,提升你的实战能力。

  • ❓ 免费答疑:每日解答社区成员问题,高效提升你的知识水平。

  • 🌐 线上交流活动:与国内外量化从业者互动,参与深度知识分享,拓展你的专业网络。


欢迎加入我们的知识星球,和全球精英一起探索人工智能与量化金融的无限可能!🚀✨





搜索 LLMQuant

关注我们



LLMQuant
起源于剑桥大学的量化社区,每日分享人工智能与量化金融前沿: www.llmquant.com