MACD震荡器与EMA均线交叉策略


创建日期: 2023-09-23 15:24:12 最后修改: 2023-09-23 15:24:12
复制: 0 点击次数: 516
avatar of ChaoZhang ChaoZhang
1
关注
1247
关注者

概述

该策略是一种简单高效的交易策略,它将震荡器指标MACD与移动平均线EMA相结合。目前设置为4小时K线,可根据需要调整至其他时间周期。它在比特币和以太坊过去3年的数据上表现优异,胜过单纯持有策略。通过优化和修改,可将其调整至期货、股指、外汇、股票等市场。

策略原理

该策略主要由以下组成部分构成:

  1. MACD指标:判断价格动能变化。

  2. EMA均线:判断价格趋势方向。

  3. 时间条件:限定策略有效时间段。

  4. 多空选择:选择做多或做空方向。

具体交易规则如下:

  1. 做多/平空:当收盘价高于EMA,MACD柱状线为正,并且当前K线高于前一日时做多/平空。

  2. 做空/平多:当收盘价低于EMA,MACD柱状线为负,并且当前K线低于前一日时做空/平多。

该策略简洁明了,融合趋势和短期两大交易思想,形成高效的量化决策系统。

优势分析

相比单一指标,该策略主要有以下优点:

  1. MACD判定短期动能,EMA判断趋势方向,指标配合紧密。

  2. 规则简单清晰,容易理解实现,实施难度不大。

  3. 可灵活调整参数,适用于不同品种和时间周期。

  4. 可仅选择单向做多或做空,也可双向交易。

  5. 可设置策略有效时间段,避免不必要交易。

  6. 表现稳定优越,多年来持续盈利。

  7. 资金管理可控,可避免单笔损失过大。

  8. 可引入机器学习技术进行优化提升。

风险分析

尽管该策略具备多项优势,以下风险还需关注:

  1. 参数优化范围较广,存在过优化风险。

  2. 未设置止损止盈,存在亏损扩大的风险。

  3. 未考虑成交量,可能出现假突破。

  4. 滞后识别趋势转折点,无法完全避免损失。

  5. 效果可能因市场环境变化而减弱。

  6. 仅基于历史数据,需关注模型稳健性。

  7. 交易频次较高,交易成本可能较重。

  8. 需关注收益回撤比,避免曲线过于锯齿。

优化方向

根据以上分析,该策略可从以下方面进行优化:

  1. 加入成交量指标,避免假突破。

  2. 增加止损止盈设定,控制单笔损益。

  3. 评估不同时间段参数效果。

  4. 引入机器学习技术,实现动态优化。

  5. 多市场验证,提高稳健性。

  6. 调整仓位大小,降低交易频次。

  7. 优化资金管理策略。

  8. 测试价差合约,提高频率。

  9. 持续回测检验,防止过拟合。

总结

该策略整体来说,在MACD和EMA指标配合下形成了一个简洁高效的量化策略。但任何策略都需要不断优化和验证,使之能够对市场环境变化保持适应性和稳健性。交易策略需要不断进化与更新。

策略源码
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © SoftKill21

//@version=4
strategy("My Script", overlay=true)

//heiking ashi calculation
UseHAcandles    = input(false, title="Use Heikin Ashi Candles in Algo Calculations")
//
// === /INPUTS ===

// === BASE FUNCTIONS ===

haClose = UseHAcandles ? security(heikinashi(syminfo.tickerid), timeframe.period, close) : close
haOpen  = UseHAcandles ? security(heikinashi(syminfo.tickerid), timeframe.period, open) : open
haHigh  = UseHAcandles ? security(heikinashi(syminfo.tickerid), timeframe.period, high) : high
haLow   = UseHAcandles ? security(heikinashi(syminfo.tickerid), timeframe.period, low) : low

//timecondition
fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear = input(defval = 2020, title = "From Year", minval = 1970)
 //monday and session 
 
// To Date Inputs
toDay = input(defval = 31, title = "To Day", minval = 1, maxval = 31)
toMonth = input(defval = 12, title = "To Month", minval = 1, maxval = 12)
toYear = input(defval = 2021, title = "To Year", minval = 1970)

startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
time_cond = true

//ema data  -- moving average
len = input(9, minval=1, title="Length")
src = input(hl2, title="Source")
out = ema(src, len)
//plot(out, title="EMA", color=color.blue)

//histogram
fast_length = input(title="Fast Length", type=input.integer, defval=12)
slow_length = input(title="Slow Length", type=input.integer, defval=26)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
sma_source = input(title="Simple MA (Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA (Signal Line)", type=input.bool, defval=false)

// Calculating
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal


//main variables to apply conditions are going to be out(moving avg) and hist(macd)

long = haClose > out and haClose > haClose[1] and out > out[1] and hist> 0 and hist[1] < 0 and time_cond
short = haClose < out and haClose < haClose[1] and out < out[1] and hist < 0 and hist[1] > 0 and time_cond

//limit to 1 entry
var longOpeneda = false
var shortOpeneda = false
var int timeOfBuya = na



longCondition= long and not longOpeneda 

if longCondition
    longOpeneda := true
    timeOfBuya := time


longExitSignala = short
exitLongCondition = longOpeneda[1] and longExitSignala

if exitLongCondition
    longOpeneda := false
    timeOfBuya := na


plotshape(longCondition, style=shape.labelup, location=location.belowbar, color=color.green, size=size.tiny, title="BUY", text="BUY", textcolor=color.white)
plotshape(exitLongCondition, style=shape.labeldown, location=location.abovebar, color=color.red, size=size.tiny, title="SELL", text="SELL", textcolor=color.white)

//automatization

longEntry= input(true)
shortEntry=input(false)

if(longEntry)
    strategy.entry("long",strategy.long,when=longCondition)
    strategy.close("long",when=exitLongCondition)

if(shortEntry)
    strategy.entry("short",strategy.short,when=exitLongCondition)
    strategy.close("short",when=longCondition)