该策略是一种简单高效的交易策略,它将震荡器指标MACD与移动平均线EMA相结合。目前设置为4小时K线,可根据需要调整至其他时间周期。它在比特币和以太坊过去3年的数据上表现优异,胜过单纯持有策略。通过优化和修改,可将其调整至期货、股指、外汇、股票等市场。
该策略主要由以下组成部分构成:
MACD指标:判断价格动能变化。
EMA均线:判断价格趋势方向。
时间条件:限定策略有效时间段。
多空选择:选择做多或做空方向。
具体交易规则如下:
做多/平空:当收盘价高于EMA,MACD柱状线为正,并且当前K线高于前一日时做多/平空。
做空/平多:当收盘价低于EMA,MACD柱状线为负,并且当前K线低于前一日时做空/平多。
该策略简洁明了,融合趋势和短期两大交易思想,形成高效的量化决策系统。
相比单一指标,该策略主要有以下优点:
MACD判定短期动能,EMA判断趋势方向,指标配合紧密。
规则简单清晰,容易理解实现,实施难度不大。
可灵活调整参数,适用于不同品种和时间周期。
可仅选择单向做多或做空,也可双向交易。
可设置策略有效时间段,避免不必要交易。
表现稳定优越,多年来持续盈利。
资金管理可控,可避免单笔损失过大。
可引入机器学习技术进行优化提升。
尽管该策略具备多项优势,以下风险还需关注:
参数优化范围较广,存在过优化风险。
未设置止损止盈,存在亏损扩大的风险。
未考虑成交量,可能出现假突破。
滞后识别趋势转折点,无法完全避免损失。
效果可能因市场环境变化而减弱。
仅基于历史数据,需关注模型稳健性。
交易频次较高,交易成本可能较重。
需关注收益回撤比,避免曲线过于锯齿。
根据以上分析,该策略可从以下方面进行优化:
加入成交量指标,避免假突破。
增加止损止盈设定,控制单笔损益。
评估不同时间段参数效果。
引入机器学习技术,实现动态优化。
多市场验证,提高稳健性。
调整仓位大小,降低交易频次。
优化资金管理策略。
测试价差合约,提高频率。
持续回测检验,防止过拟合。
该策略整体来说,在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)