布林带均线配对交易策略


创建日期: 2023-11-24 15:32:57 最后修改: 2023-11-24 15:32:57
复制: 0 点击次数: 453
avatar of ChaoZhang ChaoZhang
1
关注
1243
关注者

布林带均线配对交易策略

概述

布林带均线配对交易策略是一种随市量价运行的趋势追踪策略。它利用布林带和移动均线的交叉作为交易信号,实现了一种可以自动识别市场趋势,并配合止盈止损规则进行交易的量化策略。

策略原理

该策略主要基于布林带指标和移动均线指标的交叉信号进行交易。具体来说,它同时使用了布林带中轨、布林带上轨、以及长度为5到200天的7条移动平均线。当价格从下向上突破布林带中轨和下轨时产生买入信号;当价格从上向下跌破布林带上轨时产生卖出信号,实现了趋势追踪。

此外,策略还引入了moveToFract的多空判断指标。该指标通过计算短期和长期移动平均线顺序排列的情况,判断目前市场走势是向上还是向下,从而避免在震荡行情中产生错误信号。最后,结合可配置的止盈止损规则,形成了一个较为完整的趋势追踪交易策略。

优势分析

  1. 配置灵活,可以自定义参数组合,适应不同市场环境
  2. 结合两种不同指标作为过滤,可以减少错误信号
  3. 趋势判断指标可避免震荡市做反向操作
  4. 跟踪止损设定让利润最大化

风险分析

  1. 须适当调整参数,以符合不同周期以避免过度交易
  2. 追踪止损在快速下跌中可能扩大损失
  3. 须确保资金充足,否则无法承受连续亏损的风险

优化方向

  1. 加入黄金交叉、死叉的判断,可进一步优化
  2. 不同品种参数不一,可考虑机器学习训练最佳参数
  3. 结合波动率指数,判断趋势震荡加强风控

总结

本策略总体来说是一个非常实用的趋势追踪策略。它利用指标交叉进行决策,又加入了趋势判断模块,可以有效滤除错误信号。配置止盈止损后,可以充分跟踪趋势进行交易,获得较好收益。通过调整参数组合和加入更多滤波器,该策略可以进一步优化,适应更多市场环境,具有很大的改进空间和应用前景。

策略源码
/*backtest
start: 2023-10-24 00:00:00
end: 2023-11-23 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HeWhoMustNotBeNamed

//@version=4
strategy("BuyTheDip", overlay=true, initial_capital = 100000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

MAType = input(title="Moving Average Type", defval="sma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
exitType = input(title="Exit Strategy", defval="Signal", options=["Signal", "TrailingStop", "Both"])
LookbackPeriod = input(30, minval=10,step=10)

BBStdDev = input(2, minval=1, maxval=10, step=0.5)
BBLength = input(60, minval=5, step=5)

atrLength = input(22)
atrMult = input(6)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
backtestYears = input(10, minval=1, step=1)
includePartiallyAligned = true
f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

f_getTrailingStop(atr, atrMult)=>
    stop = close - atrMult*atr
    stop := strategy.position_size > 0 ? max(stop, stop[1]) : stop
    stop

f_getMaAlignment(MAType, includePartiallyAligned)=>
    ma5 = f_getMovingAverage(close,MAType,5)
    ma10 = f_getMovingAverage(close,MAType,10)
    ma20 = f_getMovingAverage(close,MAType,20)
    ma30 = f_getMovingAverage(close,MAType,30)
    ma50 = f_getMovingAverage(close,MAType,50)
    ma100 = f_getMovingAverage(close,MAType,100)
    ma200 = f_getMovingAverage(close,MAType,200)

    upwardScore = 0
    upwardScore := close > ma5? upwardScore+1:upwardScore
    upwardScore := ma5 > ma10? upwardScore+1:upwardScore
    upwardScore := ma10 > ma20? upwardScore+1:upwardScore
    upwardScore := ma20 > ma30? upwardScore+1:upwardScore
    upwardScore := ma30 > ma50? upwardScore+1:upwardScore
    upwardScore := ma50 > ma100? upwardScore+1:upwardScore
    upwardScore := ma100 > ma200? upwardScore+1:upwardScore
    
    upwards = close > ma5 and ma5 > ma10 and ma10 > ma20 and ma20 > ma30 and ma30 > ma50 and ma50 > ma100 and ma100 > ma200
    downwards = close < ma5 and ma5 < ma10 and ma10 < ma20 and ma20 < ma30 and ma30 < ma50 and ma50 < ma100 and ma100 < ma200
    upwards?1:downwards?-1:includePartiallyAligned ? (upwardScore > 5? 0.5: upwardScore < 2?-0.5:upwardScore>3?0.25:-0.25) : 0
    
inDateRange = time >= timestamp(syminfo.timezone, year(timenow) - backtestYears, 01, 01, 0, 0)

exitBySignal = exitType == "Signal" or exitType == "Both"
exitByTrailingStop = exitType == "TrailingStop" or exitType == "Both"
maAlignment = f_getMaAlignment(MAType,includePartiallyAligned)
atr = atr(atrLength)

trailingStop = f_getTrailingStop(atr, atrMult)
maAligned = highest(maAlignment,LookbackPeriod)
[middle, upper, lower] = bb(close, BBLength, BBStdDev)

buyCondition = maAligned == 1 and (crossover(close, lower) or crossover(close, middle))
buyExitCondition = crossunder(close, upper)

strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=buyExitCondition and exitBySignal)
strategy.exit("ExitBuy", "Buy", stop = trailingStop, when=exitByTrailingStop )