EMAC 기하급수적 이동 평균 크로스 최적화 전략

저자:차오장, 날짜: 2023-11-07 15:16:03
태그:

img

전반적인 설명

EMAC 지수적 이동 평균 크로스 최적화 전략은 기본 EMAC 전략에 기반한 최적화된 버전이다. 중장기 트렌드를 따르는 것을 목표로 트렌드 판단, 여러 이동 평균 필터링 및 스톱 로스/익스피트 출출을 포함합니다.

전략 논리

  1. 최근 트렌드 방향을 판단: 최근 26주 동안 폐쇄 가격의 증가/감소 비율을 계산하여 상승, 하락 또는 옆으로 추세를 결정합니다.

  2. 여러 이동 평균 필터: 10 기간, 20 기간, 34 기간 EMA를 계산하고 구매 신호를 유발하기 위해 50 기간 SMA를 넘을 때까지 기다립니다.

  3. ATR 스톱 손실: 입력 신호가 표시되면 입력 바의 낮은 또는 높은 - 2.5ATR에 스톱 손실을 설정합니다.

  4. 스톱 로스 후속: 가격 상승에 따라 스톱 로스 라인을 점진적으로 이동합니다.

  5. 이윤을 취하라: 진입 신호가 나타나면, 3ATR을 더한 마감 가격에 목표를 설정한다.

  6. MA pullback exit: 가격이 10일 EMA 이하로 떨어지면 적극적으로 빠져나간다.

장점

  1. 복수 MA 필터는 신호 신뢰성을 높이고 거짓 파장을 피합니다.

  2. ATR 스톱 로스는 시장 변동성에 따라 합리적인 스톱 거리를 허용합니다.

  3. 트레일링 스톱은 상승하면서 수익을 올립니다.

  4. 합리적인 수익 목표는 너무 많은 수익을 되돌리는 것을 피합니다.

  5. MA 인하 출구는 트렌드가 역전될 때 적절한 시간에 출시를 허용합니다.

위험 과 해결책

  1. EMA 교차는 옆 시장에서 윙사브를 할 수 있으며 연속 손실을 유발할 수 있습니다. EMA 기간을 늘리거나 MA 교차 필터를 추가 할 수 있습니다.

  2. 큰 ATR 값은 너무 멀리 떨어져있는 중지로 인해 손실 위험을 증가시킬 수 있습니다. ATR 이동 평균 또는 감소 계수로 최적화 할 수 있습니다.

  3. 오버나이트 격차 위험은 고려되지 않습니다. 거래 기간 중 신호를 피하기 위해 논리를 추가 할 수 있습니다.

  4. 시장 체제는 고려되지 않습니다. 전략 전환으로 시장 트렌드 필터를 추가 할 수 있습니다.

최적화 방향

  1. 다양한 제품에 최적의 길이를 찾기 위해 EMA 조합을 테스트합니다.

  2. 정지 거리를 최적화하기 위해 ATR 이동 평균 또는 감소 계수를 테스트합니다.

  3. 거래 기간 중 신호를 피하기 위해 논리를 추가합니다.

  4. 시장 트렌드 필터를 시장이 불리할 때 전략 전환으로 추가합니다.

  5. 최적의 안정성을 찾기 위해 여러 해 동안 파라미터 조합을 테스트합니다.

요약

EMAC 기하급수적 이동 평균 크로스 최적화 전략은 중장기 트렌드를 따라 트렌드 판단, 여러 MA 필터링 및 동적 정지를 결합합니다. 원래 버전과 비교하면 실제 거래 성능을 향상시키기 위해 매개 변수 최적화를 거쳤습니다. 그러나 다른 시장 상황을 처리하고 위험을 줄이고 안정성과 수익성을 향상시키기 위해 더 많은 논리를 추가하여 추가 최적화와 향상이 필요합니다.


/*backtest
start: 2023-10-01 00:00:00
end: 2023-10-31 23:59:59
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//Author = Dustin Drummond https://www.tradingview.com/u/Dustin_D_RLT/
//Strategy based in part on original 10ema Basic Swing Trade Strategy by Matt Delong: https://www.tradingview.com/u/MattDeLong/
//Link to original 10ema Basic Swing Trade Strategy: https://www.tradingview.com/script/8yhGnGCM-10ema-Basic-Swing-Trade-Strategy/
//This is the Original EMAC - Exponential Moving Average Cross Strategy built as a class for reallifetrading dot com and so has all the default settings and has not been optimized
//I would not recomend using this strategy with the default settings and is for educational purposes only
//For the fully optimized version please come back around the same time tomorrow 6/16/21 for the EMAC - Exponential Moving Average Cross - Optimized
//EMAC - Exponential Moving Average Cross
strategy(title="EMAC - Exponential Moving Average Cross", shorttitle = "EMAC", overlay = true, calc_on_every_tick=false, default_qty_value = 100, initial_capital = 100000, default_qty_type = strategy.fixed, pyramiding = 0, process_orders_on_close=true)
//creates a time filter to prevent "too many orders error" and allows user to see Strategy results per year by changing input in settings in Stratey Tester
startYear = input(2015, title="Start Year", minval=1980, step=1)
timeFilter = true
//R Size (Risk Amount)
rStaticOrPercent = input(title="R Static or Percent", defval="Percent", options=["Static", "Percent"])
rSizeStatic = input(2000, title="R Size Static", minval=1, step=100)
rSizePercent = input(3, title="R Size Percent", minval=.01, step=.01)
rSize = rStaticOrPercent == "Static" ? rSizeStatic : rStaticOrPercent == "Percent" ? (rSizePercent * .01 * strategy.equity) : 1
//Recent Trend Indicator "See the standalone version for detailed description"
res = input(title="Trend Timeframe", type=input.resolution, defval="W")
trend = input(26, minval=1, title="# of Bars for Trend")
trendMult = input(15, minval=0, title="Trend Growth %", step=.25) / 100
currentClose = security(syminfo.tickerid, res, close)
pastClose = security(syminfo.tickerid, res, close[trend])
//Trend Indicator
upTrend = (currentClose >= (pastClose * (1 + trendMult)))
downTrend = (currentClose <= (pastClose * (1 - trendMult)))
sidewaysUpTrend = (currentClose < (pastClose * (1 + trendMult)) and (currentClose > pastClose))
sidewaysDownTrend = (currentClose > (pastClose * (1 - trendMult)) and (currentClose < pastClose))
//Plot Trend on Chart
plotshape(upTrend, "Up Trend", style=shape.square, location=location.top, color=color.green, size=size.small)
plotshape(downTrend, "Down Trend", style=shape.square, location=location.top, color=color.red, size=size.small)
plotshape(sidewaysUpTrend, "Sideways Up Trend", style=shape.square, location=location.top, color=color.yellow, size=size.small)
plotshape(sidewaysDownTrend, "Sideways Down Trend", style=shape.square, location=location.top, color=color.orange, size=size.small)
//What trend signals to use in entrySignal
trendRequired = input(title="Trend Required", defval="Red", options=["Green", "Yellow", "Orange", "Red"])
goTrend = trendRequired == "Orange" ? upTrend or sidewaysUpTrend or sidewaysDownTrend : trendRequired == "Yellow" ? upTrend or sidewaysUpTrend : trendRequired == "Green" ? upTrend : trendRequired == "Red" ? upTrend or sidewaysUpTrend or sidewaysDownTrend or downTrend : na
//MAs Inputs Defalt is 10 EMA, 20 EMA, 50 EMA, 100 SMA and 200 SMA
ma1Length = input(10, title="MA1 Period", minval=1, step=1)
ma1Type = input(title="MA1 Type", defval="EMA", options=["SMA", "EMA", "WMA"])
ma2Length = input(20, title="MA2 Period", minval=1, step=1)
ma2Type = input(title="MA2 Type", defval="EMA", options=["SMA", "EMA", "WMA"])
ma3Length = input(34, title="MA3 Period", minval=1, step=1)
ma3Type = input(title="MA3 Type", defval="EMA", options=["SMA", "EMA", "WMA"])
ma4Length = input(100, title="MA4 Period", minval=1, step=1)
ma4Type = input(title="MA4 Type", defval="SMA", options=["SMA", "EMA", "WMA"])
ma5Length = input(200, title="MA5 Period", minval=1, step=1)
ma5Type = input(title="MA5 Type", defval="SMA", options=["SMA", "EMA", "WMA"])
//MAs defined
ma1 = ma1Type == "EMA" ? ema(close, ma1Length) : ma1Type == "SMA" ? sma(close, ma1Length) : wma(close, ma1Length)
ma2 = ma2Type == "EMA" ? ema(close, ma2Length) : ma2Type == "SMA" ? sma(close, ma2Length) : wma(close, ma2Length)
ma3 = ma3Type == "EMA" ? ema(close, ma3Length) : ma3Type == "SMA" ? sma(close, ma3Length) : wma(close, ma3Length)
ma4 = ma4Type == "SMA" ? sma(close, ma4Length) : ma4Type == "EMA" ? ema(close, ma4Length) : wma(close, ma4Length)
ma5 = ma5Type == "SMA" ? sma(close, ma5Length) : ma5Type == "EMA" ? ema(close, ma5Length) : wma(close, ma5Length)
//Plot MAs
plot(ma1, title="MA1", color=color.yellow, linewidth=1, style=plot.style_line)
plot(ma2, title="MA2", color=color.purple, linewidth=1, style=plot.style_line)
plot(ma3, title="MA3", color=#00FFFF, linewidth=1, style=plot.style_line)
plot(ma4, title="MA4", color=color.blue, linewidth=2, style=plot.style_line)
plot(ma5, title="MA5", color=color.orange, linewidth=2, style=plot.style_line)
//Allows user to toggle on/off ma1 > ma2 filter
enableShortMAs = input(title="Enable Short MA Cross Filter", defval="No", options=["Yes", "No"])
shortMACross = enableShortMAs == "Yes" and ma1 > ma2 or enableShortMAs == "No"
//Allows user to toggle on/off ma4 > ma5 filter
enableLongMAs = input(title="Enable Long MA Cross Filter", defval="No", options=["Yes", "No"])
longMACross = enableLongMAs == "Yes" and ma4 >= ma5 or enableLongMAs == "No"
//Entry Signals
entrySignal = (strategy.position_size <= 0 and close[1] < ma1[1] and close > ma1 and close > ma2 and close > ma3 and shortMACross and ma1 > ma3 and longMACross and goTrend)
secondSignal = (strategy.position_size > 0 and close[1] < ma1[1] and close > ma1 and close > ma2 and close > ma3 and shortMACross and ma1 > ma3 and longMACross and goTrend)
plotshape(entrySignal, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
plotshape(secondSignal, style=shape.triangleup, location=location.belowbar, color=color.lime, size=size.small)
//ATR for Stops
atrValue = (atr(14))
//to test ATR enable next line
//plot(atrValue, linewidth=1, color=color.black, style=plot.style_line)
atrMult = input(2.5, minval=.25, step=.25, title="Stop ATR Multiple")
//Only target3Mult is used in current strategy target1 and target2 might be used in the future with pyramiding
//target1Mult = input(1.0, minval=.25, step=.25, title="Targert 1 Multiple")
//target2Mult = input(2.0, minval=.25, step=.25, title="Targert 2 Multiple")
target3Mult = input(3.0, minval=.25, step=.25, title="Target Multiple")
enableAtrStop = input(title="Enable ATR Stops", defval="No", options=["Yes", "No"])
//Intitial Recomended Stop Location
atrStop = entrySignal and ((high - (atrMult * atrValue)) < low) ? (high - (atrMult * atrValue)) : low
//oneAtrStop is used for testing only enable next 2 lines to test
//oneAtrStop = entrySignal ? (high - atrValue) : na
//plot(oneAtrStop, "One ATR Stop", linewidth=2, color=color.orange, style=plot.style_linebr)
initialStop = entrySignal and enableAtrStop == "Yes" ? atrStop : entrySignal ? low : na
//Stops changed to stoploss to hold value for orders the next line is old code "bug"
//plot(initialStop, "Initial Stop", linewidth=2, color=color.red, style=plot.style_linebr)
//Set Initial Stop and hold value "debug code"
stoploss = valuewhen(entrySignal, initialStop, 0)
plot(stoploss, title="Stop", linewidth=2, color=color.red)
enableStops = input(title="Enable Stops", defval="No", options=["Yes", "No"])
yesStops = enableStops == "Yes" ? 1 : enableStops == "No" ? 0 : na
//Calculate size of trade based on R Size
//Original buggy code: 
//positionSize = (rSize/(close - initialStop))
//Added a minimum order size of 1 "debug code"
positionSize = (rSize/(close - initialStop)) > 1 ? (rSize/(close - initialStop)) : 1
//Targets
//Enable or Disable Targets
enableTargets = input(title="Enable Targets", defval="No", options=["Yes", "No"])
yesTargets = enableTargets == "Yes" ? 1 : enableTargets == "No" ? 0 : na
//Only target3 is used in current strategy target1 and target2 might be used in the future with pyramiding
//target1 = entrySignal ? (close + ((close - initialStop) * target1Mult)) : na
//target2 = entrySignal ? (close + ((close - initialStop) * target2Mult)) : na
target3 = entrySignal ? (close + ((close - initialStop) * target3Mult)) : na
//plot(target1, "Target 1", linewidth=2, color=color.green, style=plot.style_linebr)
//plot(target2, "Target 2", linewidth=2, color=color.green, style=plot.style_linebr)
plot(target3, "Target 3", linewidth=2, color=color.green, style=plot.style_linebr)
//Set Target and hold value "debug code"
t3 = valuewhen(entrySignal, target3, 0)
//To test t3 and see plot enable next line
//plot(t3, title="Target", linewidth=2, color=color.green)
//MA1 Cross Exit
enableEarlyExit = input(title="Enable Early Exit", defval="Yes", options=["Yes", "No"])
earlyExit = enableEarlyExit == "Yes" ? 1 : enableEarlyExit == "No" ? 0 : na
ma1CrossExit = strategy.position_size > 0 and close < ma1
//Entry Order
strategy.order("Entry", long = true, qty = positionSize, when = (strategy.position_size <= 0 and entrySignal and timeFilter))
//Early Exit Order
strategy.close_all(when = ma1CrossExit and timeFilter and earlyExit, comment = "MA1 Cross Exit")
//Stop and Target Orders
//strategy.cancel orders are needed to prevent bug with Early Exit Order
strategy.order("Stop Loss", false, qty = strategy.position_size, stop=stoploss, oca_name="Exit",  when = timeFilter and yesStops, comment = "Stop Loss")
strategy.cancel("Stop Loss", when = ma1CrossExit and timeFilter and earlyExit)
strategy.order("Target", false, qty = strategy.position_size, limit=t3, oca_name="Exit",  when = timeFilter and yesTargets, comment = "Target")
strategy.cancel("Target", when = ma1CrossExit and timeFilter and earlyExit)

더 많은