【量化交易策略专题一】之-----双均线结合通道突破择时策略

前言

最近因为个人需要考取专业证书原因,没有时间进行更新,深感抱歉。现在考完了试,终于有了一些时间更新。废话不多说,本文章给大家介绍目前一个比较主流常见的量化交易策略。均线择时策略和通道突破择时策略。这两种择时方法都有广泛的运用,但同时这两种方法也都有一些局限性,比如:滞后性、假信号、在震荡市场中表现不佳等。能不能将均线择时和通道突破相结合,并通过动态止损来过滤假信号,从而提高策略的整体表现和稳定性呢?答案是肯定的。

        该策略是一种综合运用均线交叉、通道突破、动态止损和再进场机制的择时策略,旨在通过结合不同的技术指标来提高择时交易的准确性和效率。该策略通过快速均线和慢速均线的交叉来识别潜在趋势,结合价格对预设通道的突破来确认趋势的有效性,使用动态止损来管理持仓风险,并在趋势持续时通过再进场机制重新参与市场,以捕捉更多的利润机会。

介绍

本文以深证个股北方铜业(000737)为例,介绍如何用Python实现这个这个策略。由于文章介绍的策略涉及比较多的参数,而过多的参数一来增加了策略调优的难度,二来也容易过拟合。因此本文对策略参数进行了精简,并使用 Pandas TA 库来计算相关指标,以减少代码量。

一、获取基础数据

1. 导入需要的库

# 导入需要使用的库
import akshare as ak
import pandas as pd
import numpy as np
import pandas_ta as ta
# 在matplotlib绘图中显示中文和负号
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = 'STKAITI' # 中文字体'STKAITI'
plt.rcParams['axes.unicode_minus'] = False   # 解决坐标轴负数的负号显示问题
# 关闭警告信息
import warnings
warnings.filterwarnings('ignore')

2. 从AKShare数据源获取深证个股北方铜业(000737)的数据

# 获取个股数据
index_code = 'sz000737'
start_date = '20140101'
end_date = '20231231'
price_df = stock_zh_a_daily_qfq_df = ak.stock_zh_a_daily(symbol=index_code, start_date=start_date, end_date=end_date, adjust="qfq")
kline = price_df.sort_values('date').set_index('date')

关于AKShare的使用,可以参看akshare官方api文档。网址:AKShare 项目概览 — AKShare 1.13.79 文档 (akfamily.xyz)  AKShare的接口有时会有变动,如果获取数据出错请参考AKShare的官网解决。

3. 计算每日的收益率

# 计算每日的收益率
kline['returns'] = kline['close'].pct_change().shift(-1).fillna(0)

这段Python代码的含义是计算股票的Return率(即收益率),并将其存储在名为returns的列中。实现原理是通过pct_change()函数计算收盘价的变化率,然后通过shift(-1)函数将变化率向前移一位(即当前收盘价的变化率),最后使用fillna(0)函数填充缺失值(即第一天收盘价的变化率为0)。数据格式如下:

二、构建双均线结合通道突破择时并动态止损的策略

先给大家介绍该策略的一些概念

一、均线交叉

均线交叉使用快速均线(短期移动平均线)和慢速均线(长期移动平均线)的交叉作为趋势的指示。具体内容包括:

1. 快速均线(Fast MA)

这是短期的移动平均线,它反映了价格近期的走势,对价格变动反应较快。

2. 慢速均线(Slow MA)

这是长期的移动平均线,慢速均线变化较慢,通常用来识别长期趋势。

3. 均线交叉信号

当快速均线从下方穿越慢速均线时,产生“金叉”信号,这通常是市场上升趋势的信号;反之,当快速均线从上方穿越慢速均线时,产生“死叉”信号,表明市场可能进入下降趋势。

4. 均线的种类

均线的种类有很多,不同类型的均线都可以运用到该策略中。我们在以前的文章中对均线的种类有过详细的介绍,具体可以参看后附文章《均线解密:如何有效利用移动平均线》。

5. 均线涉及的相关参数

1)FastWindow(快速均线窗口长度)

这是计算快速均线的时间周期,如5日、10日等。它决定了快速均线的敏感度和反应速度。

2)SlowWindow(慢速均线窗口长度)

这是计算慢速均线的时间周期,通常比FastWindow的时间长,如20日、50日等。它决定了慢速均线的稳定性。

1. 计算双均线

我们设置长(慢)短(快)两条均线。当快均线位于慢均线上方时,说明可能处于上升趋势;当快均线位于慢均线下方时,说明可能处于下降趋势。

# 计算长短双均线值
FastWindow = 9  # 快速均线窗口长度
SlowWindow = 2 * FastWindow  # 慢速均线窗口长度
kline['ma_s'] = ta.sma(kline['close'], length=FastWindow)
kline['ma_l'] = ta.sma(kline['close'], length=SlowWindow)

上述代码将快均线的计算窗口设为9个交易日,为了减少参数的个数,将慢均线的计算窗口设为快均线的2倍。接着调用 Pandas TA 来计算简单移动平均线(SMA)。关于 Pandas TA 库的使用,可以参看技术指标库 Pandas TA 教程。Pandas TA 支持二十余种移动平均线,详细介绍可以自行查找相关资料。

二、通道突破

均线交叉策略可能会产生一些假信号,特别是在市场波动较大且没有明显趋势时。短期均线可能会在短时间内反复穿越长期均线,导致频繁的买卖信号,这会增加交易成本并可能带来不必要的损失。通过引入通道突破确认,可以在一定程度上过滤这些假信号。

另外,均线交叉可以指示潜在的趋势变化,但并不总是能反映趋势的强度。通道突破提供了额外的确认,表明价格不仅已经穿越了均线,而且还有足够的动力突破了一个定义明确的价格区间,这通常意味着趋势更为强劲和可靠。

1. 通道的构建

通道通常由上轨、中轨、下轨3条线构成,其中上轨为阻力位,下轨为支撑位。构建通道的方法很多,常见的有布林带、肯特纳通道、唐奇安通道、霍尔特-温特通道和加速带等。这些通道的具体构建方法可以常见后附的文章《通道突破择时交易策略详解》。

2. 通道突破信号

当价格向上突破阻力位(通道上轨)时,发出买入信号;当价格向下突破支撑位(通道下轨)时,发出卖出信号。

3. 通道突破的相关参数

1)ChLen(通道突破周期)

这是在均线交叉后用于确定通道突破的K线数量周期。只有当价格在ChLen个交易周期内突破了通道的上轨或下轨,才被认为是有效的趋势确认。

2)通道上轨和下轨的幅度

这个参数决定了通道的宽度,从而影响策略对市场波动的敏感度。例如在布林带中,通道的上/下轨等于中轨加/减n倍的标准差,这个n就决定通道上下轨的幅度。

在申万宏源的研报研报中设置了一个参数 ExtraPct(通道突破幅度),这是一个百分比参数。通道的上轨设置为出现金叉信号时的价格乘以(1 + ExtraPct),而通道的下轨则为出现死叉信号时的价格乘以(1 - ExtraPct)。

通道参数设置需要平衡策略的敏感度和鲁棒性。过窄的通道可能导致过多的假信号,而过宽的通道可能错过市场机会。通道参数的选择通常基于历史数据的回测结果,以找到最佳的参数组合,这有助于最大化策略的表现并减少误报。

2. 计算通道

通道是价格的波动范围,通常包括上轨、中轨和下轨。通道有多种,本文以布林带为例。

# 计算布林带
std = 2.0  # 上下轨的标准差倍数
channel = ta.bbands(kline['close'], length=SlowWindow, std=std)
up = f'BBU_{SlowWindow}_{std}'  # 通道上轨
down = f'BBL_{SlowWindow}_{std}'  # 通道下轨
middle = f'BBM_{SlowWindow}_{std}'  # 通道中轨

kline[['up_channel','down_channel']] = channel[[up, down]]

上述代码调用 Pandas TA 库的bbands()函数计算布林带,参数 length 为计算中轨的均线周期,本例中跟慢均线的窗口SlowWindow一致;参数 std 为通道宽度,本例取值2.0,表示通道的上轨和下轨距离中轨都是2个标准差。

除了布林带外,常见的通道还有肯特纳通道、唐奇安通道、霍尔特-温特通道和加速带等,具体计算方法可以自行探索。

三、计算均线和通道结合的择时信号

均线择时和通道择时都可能遇到假信号,本策略将均线信号和通道突破信号相结合,增加信号的可靠性。策略的择时信号为:当短均线位于长均线上方,且价格突破通道上轨时开仓;当短均线位于长均线下方,且价格跌破通道下轨时清仓。需要注意的时,双重确认虽然能增加信号的可靠性,但也牺牲了部分交易机会。

# 计算择时信号
# 开仓信号:当短均线位于长均线上方,并且价格突破了通道上轨时开仓
# 清仓信号:当短均线位于长均线下方,并且价格突破了通道下轨时清仓
timing_df = pd.DataFrame()
timing_df['择时'] = ((kline['ma_s'] > kline['ma_l']) & (kline['close'] > kline['up_channel'])) * 1 + \
                    ((kline['ma_s'] < kline['ma_l']) & (kline['close'] < kline['down_channel'])) * - 1
timing_df = timing_df.replace(0, np.nan)  # 先将0替换为NA
timing_df = timing_df.fillna(method='ffill').fillna(0)  # 使用前值填充NA
timing_df[timing_df <= 0] = 0
timing_df['不择时'] = 1

这段代码,用于计算择时(Timing)交易策略的每日收益率(Return)和不择时的每日收益率。同时,还计算了两种交易策略的累计收益率(Cumulative Return)。

1. 首先,代码计算了择时交易策略的每日收益率。这里使用了`timing_df.mul()`函数,该函数执行一个或多个数的乘法操作。`timing_df`是一个包含择时交易策略的DataFrame,`kline['returns']`表示的是K线图上的每日收益率。`axis=0`表示在列(axis=1)上进行乘法操作。

2. 接下来,代码计算了不择时的每日收益率。这里使用了`timing_ret.fillna(0)`函数,该函数用0填充NaN值。然后,对结果进行加1操作,表示不择时的累计收益率。

3. 最后,代码计算了两种交易策略的累计收益率。这里使用了`(1 + timing_ret.fillna(0)).cumprod()`函数,该函数计算序列元素的累积乘积。`-1`表示计算的是累计收益率,而不是累计乘积。

总之,这段代码的主要目的是计算择时交易策略的收益情况和不择时的收益情况,并计算两种交易策略的累计收益率。

四、动态止损

动态止损指开仓后如果发现趋势判断错误,则进行止损。止损后如果趋势恢复,则重新进场。

# 设定止损触发价为通道中轨
kline['stop_price'] = channel[middle]
# 如果收盘价低于止损触发价,则清仓止损
timing_df['择时'] = ((timing_df['择时'] == 1) & (kline['close'] > kline['stop_price'])) * 1

上述代码将通道的中轨设置为止损触发价,如果开仓后(即'择时'列的值为1)价格跌破中轨,则止损清仓(将择时信号设为0),如果价格恢复到通道中轨之上,则重新开仓。

五、计算策略的择时收益

# 计算择时和不择时的每日收益率
timing_ret = timing_df.mul(kline['returns'], axis=0)
# 计算累计收益率
cumul_ret = (1 + timing_ret.fillna(0)).cumprod() - 1

上述代码先将日收益和择时信号相乘,如果择时信号为1,则保留该日收益;如果择时信号为0,则该日收益为0。然后计算累计收益。关于各种收益的计算,可以查找相关文章进行自定义探索。

六、可视化输出择时效果

# 可视化输出
import matplotlib
matplotlib.use('TkAgg')
cumul_ret.plot(figsize=(10, 6), title='双均线结合通道突破择时配合止盈止损策略')

结果如下:

从上图可以看出,该择时策略取得了一定的效果,在提高收益的同时降低了回撤。

三、策略调优

我们可以从以下几个方面对策略进行调优:

1. 调整均线的类型和参数

本例中用了简单移动平均来计算均线,我们还可以使用其他的均线类型;此外还可以调整均线的长周期和短周期,来观察策略效果。

2. 调整通道的类型和参数

我们可以尝试更换其他类型的通道,或调整通道的参数。

3. 调整止损触发价

本例中使用通道中轨作为止损触发价,我们还可以设定其他的止损触发价,比如用均线作为止损触发价。

通过调优,我们可能会获得更好的择时效果。借助 Pandas TA 库,很容易就能修改相关的代码。

  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是一个简单的均线策略的实现: 1. 策略思路: 均线策略是一种常见的趋势跟踪策略,它的核心思想是通过计算不同时间段的移动平均线来判断市场的趋势,并根据移动平均线之间的交叉信号进行买入或卖出操作。 2. 策略参数: 选择两条不同的移动平均线,一条是较短期的,一条是较长期的。例如,可以选择5日移动平均线和20日移动平均线。 3. 交易信号: 当短期移动平均线上穿长期移动平均线时,产生买入信号;当短期移动平均线下穿长期移动平均线时,产生卖出信号。 4. 代码实现: ```python import pandas as pd import yfinance as yf import matplotlib.pyplot as plt # 下载数据 data = yf.download('AAPL', start='2010-01-01', end='2021-01-01') # 计算5日移动平均线和20日移动平均线 data['MA5'] = data['Close'].rolling(window=5).mean() data['MA20'] = data['Close'].rolling(window=20).mean() # 计算交易信号 data['Signal'] = 0 data['Signal'][5:] = np.where(data['MA5'][5:] > data['MA20'][5:], 1, 0) data['Signal'][5:] = np.where(data['MA5'][5:] < data['MA20'][5:], -1, data['Signal'][5:]) # 计算每日收益率 data['Return'] = np.log(data['Close']/data['Close'].shift(1)) # 计算策略收益率 data['Strategy'] = data['Signal'].shift(1) * data['Return'] # 计算累计收益率 data['Cumulative_Return'] = np.cumsum(data['Strategy']) # 绘制图形 plt.plot(data['Cumulative_Return']) plt.xlabel('Date') plt.ylabel('Cumulative Return') plt.title('Dual Moving Average Strategy') plt.show() ``` 这里以苹果公司的股票价格为例,下载了2010年至2021年的日线数据,计算出了5日移动平均线和20日移动平均线,并根据交叉信号计算出了交易信号。最后计算出了策略的收益率,并绘制了累计收益率曲线。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达板森家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值