
이 전략은 쌍방향 역행 MACD 양적 거래 전략이다. 이 전략은 윌리엄 블라우가 그의 저서 ?? Momentum, Direction and Divergence ?? 에서 설명한 기술 지표를 모티브로 삼고, 이를 기반으로 확장하였다. 이 전략은 동시에 회귀 기능을 가지고 있으며, 경고, 필터, 추적 스톱 등과 같은 부가 기능을 추가할 수 있다.
이 전략의 핵심 지표는 MACD이다. 그것은 빠른 이동 평균 EMA ® 와 느린 이동 평균 EMA (slowMALen) 를 계산하고, 그 다음 그들의 차수를 계산한다. xmacd의 EMA (signalLength) 를 계산한다. 또한 xmacd의 EMA (signalLength) 는 xMA_MACD를 얻는다.
또한, 이 전략은 트렌드 필터를 도입한다. 여러 신호를 발송할 때, 보이스 트렌드 필터를 구성하면 가격이 상승하고 있는지 검출할 수 있다. 유사하게, 하위 신호는 가격 하락의 경향을 검출할 수 있다. RSI 지표와 MFI 지표도 필터링 신호 구성을 위해 사용될 수 있다.
이 전략의 가장 큰 장점은 재검토 기능이 강하다는 것입니다. 다른 거래 품종을 선택하고, 재검토의 시간 범위를 설정하고, 특정 품종 데이터에 대해 전략적 최적화를 할 수 있습니다. 간단한 MACD 전략에 비해, 추세, 과매, 과매 판단을 증가시키고, 몇 가지雷同 신호를 필터링 할 수 있습니다. 쌍궤도 역 MACD는 전통적인 MACD와 달리, 전통적인 MACD가 놓칠 수있는 몇 가지 기회를 잡을 수 있습니다.
이 전략의 위험은 주로 역전 거래의 사고에서 비롯된다. 역전 신호는 몇 가지 기회를 얻을 수 있지만, 일부 전통적인 MACD 매수점을 포기하는 것을 의미하며, 이는 신중하게 평가되어야 한다. 또한, MACD 자체는 여러 개의 가짜 신호를 생성하는 데 취약하다.
위험을 줄이기 위해, 적절한 변수를 조정하여 이동 평균의 길이를 최적화 할 수 있습니다. 추세와 지표 필터를 결합하여 흔들리는 시장에서 신호를 발생하지 않도록합니다. 개별 거래의 손실을 제어하기 위해 중지 손실 거리를 적절히 높일 수 있습니다.
이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.
이중 궤도 역 MACD 양적 전략은 클래식 MACD 지표의 아이디어를 빌려 확장 및 개선이 이루어졌습니다. 이 전략은 동시에 유연한 매개 변수 구성, 풍부한 필터링 메커니즘 선택, 강력한 회수 기능 등의 장점을 가지고 있습니다. 이것은 서로 다른 거래 품종에 맞게 개인화 최적화를 할 수있게 해줍니다.
/*backtest
start: 2023-11-20 00:00:00
end: 2023-12-20 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version = 3
////////////////////////////////////////////////////////////
// Copyright by HPotter v1.0 09/12/2016
// This is one of the techniques described by William Blau in his book
// "Momentum, Direction and Divergence" (1995). If you like to learn more,
// we advise you to read this book. His book focuses on three key aspects
// of trading: momentum, direction and divergence. Blau, who was an electrical
// engineer before becoming a trader, thoroughly examines the relationship
// between price and momentum in step-by-step examples. From this grounding,
// he then looks at the deficiencies in other oscillators and introduces some
// innovative techniques, including a fresh twist on Stochastics. On directional
// issues, he analyzes the intricacies of ADX and offers a unique approach to help
// define trending and non-trending periods.
// Blau`s indicator is like usual MACD, but it plots opposite of meaningof
// stndard MACD indicator.
//
// You can change long to short in the Input Settings
// Please, use it only for learning or paper trading. Do not for real trading.
//
//
// 2018-09 forked by Khalid Salomão
// - Backtesting
// - Added filters: RSI, MFI, Price trend
// - Trailing Stop Loss
// - Other minor adjustments
//
////////////////////////////////////////////////////////////
strategy(title="Ergotic MACD Backtester [forked from HPotter]", shorttitle="Ergotic MACD Backtester", overlay=true, pyramiding=0, default_qty_type=strategy.cash, default_qty_value=25000, initial_capital=50000, commission_type=strategy.commission.percent, commission_value=0.15, slippage=3)
// === BACKTESTING: INPUT BACKTEST RANGE ===
source = input(close)
strategyType = input(defval="Long Only", options=["Long & Short", "Long Only", "Short Only"])
FromMonth = input(defval = 7, title = "From Month", minval = 1, maxval = 12)
FromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear = input(defval = 2018, title = "From Year", minval = 2017)
ToMonth = input(defval = 12, title = "To Month", minval = 1, maxval = 12)
ToDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear = input(defval = 2030, title = "To Year", minval = 2017)
start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window() => true // window of time verification
// === STRATEGY ===
r = input(144, minval=1, title="R (32,55,89,100,144,200)") // default 32
slowMALen = input(6, minval=1) // default 32
signalLength = input(6, minval=1)
reverse = input(false, title="Trade reverse (long/short switch)")
//hline(0, color=blue, linestyle=line)
fastMA = ema(source, r)
slowMA = ema(source, slowMALen)
xmacd = fastMA - slowMA
xMA_MACD = ema(xmacd, signalLength)
pos = 0
pos := iff(xmacd < xMA_MACD, 1,
iff(xmacd > xMA_MACD, -1, nz(pos[1], 0)))
possig = 0
possig := iff(reverse and pos == 1, -1,
iff(reverse and pos == -1, 1, pos))
// === FILTER: price trend ====
trending_price_long = input(true, title="Long only if price has increased" )
trending_price_short = input(false, title="Short only if price has decreased" )
trending_price_length = input( 2, minval=1 )
trending_price_with_ema = input( false )
trending_price_ema = input( 3, minval=1 )
price_trend = trending_price_with_ema ? ema(source, trending_price_ema) : source
priceLongTrend() => (trending_price_long ? rising(price_trend, trending_price_length) : true)
priceShortTrend() => (trending_price_short ? falling(price_trend, trending_price_length) : true)
// === FILTER: RSI ===
rsi_length = input( 14, minval=1 )
rsi_overSold = input( 14, minval=0, title="RSI Sell Cutoff (Sell only if >= #)" )
rsi_overBought = input( 82, minval=0, title="RSI Buy Cutoff (Buy only if <= #)" )
vrsi = rsi(source, rsi_length)
rsiOverbought() => vrsi > rsi_overBought
rsiOversold() => vrsi < rsi_overSold
trending_rsi_long = input(false, title="Long only if RSI has increased" )
trending_rsi_length = input( 2 )
rsiLongTrend() => trending_rsi_long ? rising(vrsi, trending_rsi_length) : true
// === FILTER: MFI ===
mfi_length = input(14, minval=1)
mfi_lower = input(14, minval=0, maxval=50)
mfi_upper = input(82, minval=50, maxval=100)
upper_s = sum(volume * (change(source) <= 0 ? 0 : source), mfi_length)
lower_s = sum(volume * (change(source) >= 0 ? 0 : source), mfi_length)
mf = rsi(upper_s, lower_s)
mfiOverbought() => (mf > mfi_upper)
mfiOversold() => (mf < mfi_lower)
trending_mfi_long = input(false, title="Long only if MFI has increased" )
trending_mfi_length = input( 2 )
mfiLongTrend() => trending_mfi_long ? rising(mf, trending_mfi_length) : true
// === SIGNAL CALCULATION ===
long = window() and possig == 1 and rsiLongTrend() and mfiLongTrend() and not rsiOverbought() and not mfiOverbought() and priceLongTrend()
short = window() and possig == -1 and not rsiOversold() and not mfiOversold() and priceShortTrend()
// === trailing stop
tslSource=input(hlc3,title="TSL source")
//suseCurrentRes = input(true, title="Use current chart resolution for stop trigger?")
tslResolution = input(title="Use different timeframe for stop trigger? Uncheck box above.", defval="5")
tslTrigger = input(3.0) / 100
tslStop = input(0.6) / 100
currentPrice = request.security(syminfo.tickerid, tslResolution, tslSource, barmerge.gaps_off, barmerge.lookahead_off)
isLongOpen = false
isLongOpen := nz(isLongOpen[1], false)
entryPrice=0.0
entryPrice:= nz(entryPrice[1], 0.0)
trailPrice=0.0
trailPrice:=nz(trailPrice[1], 0.0)
// update TSL high mark
if (isLongOpen )
if (not trailPrice and currentPrice >= entryPrice * (1 + tslTrigger))
trailPrice := currentPrice
else
if (trailPrice and currentPrice > trailPrice)
trailPrice := currentPrice
if (trailPrice and currentPrice <= trailPrice * (1 - tslStop))
// FIRE TSL SIGNAL
short:=true // <===
long := false
// if short clean up
if (short)
isLongOpen := false
entryPrice := 0.0
trailPrice := 0.0
if (long)
isLongOpen := true
if (not entryPrice)
entryPrice := currentPrice
// === BACKTESTING: ENTRIES ===
if long
if (strategyType == "Short Only")
strategy.close("Short")
else
strategy.entry("Long", strategy.long, comment="Long")
if short
if (strategyType == "Long Only")
strategy.close("Long")
else
strategy.entry("Short", strategy.short, comment="Short")
//barcolor(possig == -1 ? red: possig == 1 ? green : blue )
//plot(xmacd, color=green, title="Ergotic MACD")
//plot(xMA_MACD, color=red, title="SigLin")
plotshape(trailPrice ? trailPrice : na, style=shape.circle, location=location.absolute, color=blue, size=size.tiny)
plotshape(long, style=shape.triangleup, location=location.belowbar, color=green, size=size.tiny)
plotshape(short, style=shape.triangledown, location=location.abovebar, color=red, size=size.tiny)
// === Strategy Alert ===
alertcondition(long, title='BUY - Ergotic MACD Long Entry', message='Go Long!')
alertcondition(short, title='SELL - Ergotic MACD Long Entry', message='Go Short!')
// === BACKTESTING: EXIT strategy ===
sl_inp = input(7, title='Stop Loss %', type=float)/100
tp_inp = input(1.8, title='Take Profit %', type=float)/100
stop_level = strategy.position_avg_price * (1 - sl_inp)
take_level = strategy.position_avg_price * (1 + tp_inp)
strategy.exit("Stop Loss/Profit", "Long", stop=stop_level, limit=take_level)