트렌드 트레이딩 전략, 이중 이동 평균의 가격 채널을 기반으로

저자:차오장, 날짜: 2024-01-31 10:37:13
태그:

img

전반적인 설명

이것은 이중 이동 평균으로 만들어진 가격 채널에 기반한 트렌드 다음 전략입니다. 그것은 가격 트렌드 방향을 결정하기 위해 채널 범위를 사용하여 수익을 잠금하기 위해 트레일링 스톱 로스를 설정합니다.

전략 논리

이중 이동 평균 가격 채널 전략은 가격 채널을 구축하기 위해 빠른 EMA와 느린 EMA를 사용합니다. 빠른 EMA는 89 기간의 매개 변수를 가지고 있으며 느린 EMA는 200 기간의 매개 변수를 가지고 있습니다. 동시에 높은 가격, 낮은 가격 및 가까운 가격에 기반한 세 개의 EMA가 채널 범위를 구축하기 위해 사용됩니다. 채널의 상부 레일 및 하부 레일은 각각 34 기간의 높은 가격 EMA 및 낮은 가격 EMA입니다.

빠른 EMA가 느린 EMA보다 높고 가격이 하부 레일 아래에 있을 때, 그것은 상승 추세로 결정됩니다. 빠른 EMA가 느린 EMA보다 낮고 가격이 상부 레일보다 높을 때, 그것은 하향 추세로 결정됩니다.

상승 트렌드 중, 트렌드 반전이 확인되면 전략은 짧은 포지션을 개척합니다. 하락 트렌드 중, 트렌드 반전이 확인되면 전략은 긴 포지션을 개척합니다.

또한, 전략은 트레일링 스톱 로스 기능을 가지고 있습니다. 포지션을 열면, 트레일링 스톱 로스 가격이 실시간으로 업데이트되어 이익을 잠금합니다.

이점 분석

이 전략의 가장 큰 장점은 가격 트렌드를 결정하기 위해 이중 이동 평균 가격 채널을 사용하고, 최고치를 추격하고 최저치를 판매하는 것을 피하기 위해 역전 거래와 결합한다는 것입니다. 동시에 수익을 잠금하고 손실 위험을 줄이기 위해 후속 스톱 손실 기능을 가지고 있습니다.

다른 장점은: 다양한 제품과 주기에 맞게 조정할 수 있는 큰 매개 변수 최적화 공간; 낮은 운영 위험과 함께 정지 손실 가격의 실시간 업데이트.

위험 분석

이 전략의 주요 위험은 역전 신호를 식별하는 효과가 이상적이지 않을 수 있으며 잘못된 판단이 발생할 수 있다는 것입니다. 이 경우 트렌드 역전 결정의 효과를 보장하기 위해 매개 변수를 최적화해야합니다.

또한 스톱 로스 포인트 설정도 매우 중요합니다. 스톱 로스 포인트가 너무 높으면 스톱 로스는 충분히 결정적이지 않을 수 있습니다. 스톱 로스 포인트가 너무 낮으면 과도한 스톱 로스 상황이 발생할 수 있습니다. 특정 제품에 따라 조정해야합니다.

마지막으로 데이터 문제도 전략 실패로 이어질 수 있습니다. 전략의 백테스트 및 실시간 거래 검증에 신뢰할 수 있고 지속적인 충분한 역사적 데이터가 사용되도록 보장해야합니다.

최적화 방향

이 전략을 최적화하는 주요 분야는 다음과 같습니다.

  1. 빠른 EMA와 느린 EMA의 기간은 효과를 결정하기 위해 다른 매개 변수 조합을 테스트하여 최적화 할 수 있습니다.

  2. 또한 가격 채널의 상부 및 하부 레일의 매개 변수는 더 적합한 사이클 매개 변수를 찾기 위해 조정 할 수 있습니다.

  3. 중지 손실 포인트 설정은 중요하고 다른 매개 변수를 테스트하여 최적화 될 수 있습니다

  4. 트렌드 반전을 결정하기 위해 다른 지표를 도입하면 거래 성과를 향상시킬 수 있는지 테스트합니다.

결론

이 전략의 전반적인 운영 과정은 합리적이고 원활하다. 이 전략은 트레이딩의 트렌드 방향을 결정하기 위해 이중 이동 평균 채널을 사용하고, 수익을 잠금하기 위해 후속 스톱 로스를 가지고 있다. 매개 변수 최적화와 위험 관리 최적화를 통해 이 전략은 효율적인 양적 거래 전략이 될 수 있다.


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

//@version=4
strategy("Trend trader Strategy", overlay=true)

//f you want to trade shallower Pullbacks for quicker scalps, try reducing the 
//    PAC and EMA combination lengths for example:
//      * 21 PAC and 55, 144, 377 for fast, medium, slow EMAs
//      * 13 PAC and 34, 89, 233 for fast, medium, slow EMAs
//  - Each alert should be evaluated on it's own merits, the alerts are designed to highlight possible
//    scalping trades from Pullback recoveries around the PAC.

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

isMon() => dayofweek(time('D')) == dayofweek.monday
isTue() => dayofweek(time('D')) == dayofweek.tuesday
isWed() => dayofweek(time('D')) == dayofweek.wednesday
isThu() => dayofweek(time('D')) == dayofweek.thursday
isFri() => dayofweek(time('D')) == dayofweek.friday
 
// Calculate start/end date and time condition
DST = 1 //day light saving for usa
//--- Europe
London = iff(DST==0,"0000-0900","0100-1000")
//--- America
NewYork = iff(DST==0,"0400-1400","0500-1500")
//--- Pacific
Sydney = iff(DST==0,"1300-2200","1400-2300")
//--- Asia
Tokyo = iff(DST==0,"1500-2400","1600-0100")

customTime =iff(DST==0,"2300-1500","2400-1600")
customTime2 =iff(DST==0,"0800-1500","0900-1600")

//-- Time In Range
timeinrange(res, sess) => time(res, sess) != 0

london = timeinrange(timeframe.period, London)
newyork = timeinrange(timeframe.period, NewYork)
c_time = timeinrange(timeframe.period,customTime)
c_time2 = timeinrange(timeframe.period,customTime2)

startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
time_cond = time >= startDate and time <= finishDate and (london or newyork)


    // === INPUTS ===
HiLoLen         = input(34, minval=2, title="High Low PAC channel Length")
fastEMAlength   = input(89, minval=2)
mediumEMAlength = input(200, minval=2)
slowEMAlength   = input(600, minval=2)
ShowFastEMA     = input(false)
ShowMediumEMA   = input(false)
ShowSlowEMA     = input(false)
ShowHHLL        = input(false)
ShowFractals    = input(false)
filterBW        = input(false, title="Show Ideal Fractals Only")
ShowBarColor    = input(true, title="Show coloured Bars around PAC")
ShowBuySell     = input(false, title="Show Buy/Sell Alert Arrows")
Lookback        = input(3, minval=1, title="Pullback Lookback for PAC Cross Check")
DelayArrow      = input(false, title="Show Alert Arrows Only on Closed Candles")
Delay           = DelayArrow ? 1 : 0
ShowTrendBGcolor= input(true)
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


//  ||---   Fractal Recognition Functions:  ---------------------------------------------------------------||
isRegularFractal(mode) =>
    ret = mode == 1 ? high[4] < high[3] and high[3] < high[2] and high[2] > high[1] and 
       high[1] > high[0] : mode == -1 ? 
       low[4] > low[3] and low[3] > low[2] and low[2] < low[1] and low[1] < low[0] : 
       false
    ret

isBWFractal(mode) =>
    ret = mode == 1 ? high[4] < high[2] and high[3] <= high[2] and high[2] >= high[1] and 
       high[2] > high[0] : mode == -1 ? 
       low[4] > low[2] and low[3] >= low[2] and low[2] <= low[1] and low[2] < low[0] : 
       false
    ret
//  ||-----------------------------------------------------------------------------------------------------||

//
// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
//

//  ||---   Setup Moving Averages and PAC channel:
//  ||-----------------------------------------------------------------------------------------------------||
fastEMA     = ema(haClose, fastEMAlength)
mediumEMA   = ema(haClose, mediumEMAlength)
slowEMA     = ema(haClose, slowEMAlength)
pacC        = ema(haClose, HiLoLen)
pacL        = ema(haLow, HiLoLen)
pacU        = ema(haHigh, HiLoLen)
TrendDirection = fastEMA > mediumEMA and pacL > mediumEMA ? 1 : 
   fastEMA < mediumEMA and pacU < mediumEMA ? -1 : 0

//  ||---   Fractal Recognition:
//  ||-----------------------------------------------------------------------------------------------------||
filteredtopf = filterBW ? isRegularFractal(1) : isBWFractal(1)
filteredbotf = filterBW ? isRegularFractal(-1) : isBWFractal(-1)
//  ||-----------------------------------------------------------------------------------------------------||
//  ||---   Higher Highs, Lower Highs, Higher Lows, Lower Lows  -------------------------------------------||
valuewhen_H0 = valuewhen(filteredtopf == true, high[2], 0)
valuewhen_H1 = valuewhen(filteredtopf == true, high[2], 1)
valuewhen_H2 = valuewhen(filteredtopf == true, high[2], 2)
//
higherhigh = filteredtopf == false ? false : 
   valuewhen_H1 < valuewhen_H0 and valuewhen_H2 < valuewhen_H0
lowerhigh = filteredtopf == false ? false : 
   valuewhen_H1 > valuewhen_H0 and valuewhen_H2 > valuewhen_H0
valuewhen_L0 = valuewhen(filteredbotf == true, low[2], 0)
valuewhen_L1 = valuewhen(filteredbotf == true, low[2], 1)
valuewhen_L2 = valuewhen(filteredbotf == true, low[2], 2)
//
higherlow = filteredbotf == false ? false : 
   valuewhen_L1 < valuewhen_L0 and valuewhen_L2 < valuewhen_L0
lowerlow = filteredbotf == false ? false : 
   valuewhen_L1 > valuewhen_L0 and valuewhen_L2 > valuewhen_L0

//
// === /SERIES ===

//
// === PLOTTING ===
// 
// Plot the Price Action Channel (PAC) base on EMA high,low and close
L = plot(pacL, color=color.gray, linewidth=1, title="High PAC EMA", transp=50)
U = plot(pacU, color=color.gray, linewidth=1, title="Low PAC EMA", transp=50)
C = plot(pacC, color=color.red, linewidth=2, title="Close PAC EMA", transp=0)
fill(L, U, color=color.gray, transp=90, title="Fill HiLo PAC")

// Colour bars according to the close position relative to the PAC selected.
BARcolor = haClose > pacU ? color.blue : haClose < pacL ? color.red : color.gray
barcolor(ShowBarColor ? BARcolor : na, title="Bar Colours")
//
BGcolor = TrendDirection == 1 ? color.green : 
   TrendDirection == -1 ? color.red : color.yellow
bgcolor(ShowTrendBGcolor ? BGcolor : na, transp=90, title="Trend BG Color")


// STEP 1:
// Configure trail stop level with input options (optional)
longTrailPerc = input(title="Trail Long Loss (%)",
     type=input.float, minval=0.0, step=0.05, defval=0.1) * 0.01

shortTrailPerc = input(title="Trail Short Loss (%)",
     type=input.float, minval=0.0, step=0.05, defval=0.1) * 0.01


atrRange = input(14, title="ATR Range", type=input.integer)
buyStop = input(2, title="* ATR Buy SL", type=input.float)
sellStop = input(1, title="* ATR Sell SL", type=input.float)
targetATR = input(1, title="* ATR TP1", type=input.float)
moveToEntryFigure = input(0.5, title=" move to entry in % towards target", type=input.float)

showMove = input(true, title="Show Move to Entry points")

showMoveBuycol = showMove ? color.lime : na
showMoveSellcol = showMove ? color.lime : na

// Plots

buyStopp = plot(close - atr(atrRange) * buyStop, title="Buy SL", style=plot.style_stepline, color=color.red, transp=75, linewidth=3)
sellStopp = plot(close + atr(atrRange) * sellStop, title="Sell SL", style=plot.style_stepline, color=color.red, transp=75, linewidth=3)

buyTP1 = plot(close + atr(atrRange) * targetATR, title="Buy TP", style=plot.style_cross, color=color.lime, transp=75, linewidth=3)
sellTP1 = plot(close - atr(atrRange) * targetATR, title="Sell TP", style=plot.style_cross, color=color.lime, transp=75, linewidth=3)

buyMove = plot(close + atr(atrRange) * targetATR * moveToEntryFigure, title="Buy Move to Entry", style=plot.style_cross, color=showMoveBuycol, transp=75, linewidth=3)
sellMove = plot(close - atr(atrRange) * targetATR * moveToEntryFigure, title="Sell Move to Entry", style=plot.style_cross, color=showMoveSellcol, transp=75, linewidth=3)


if barstate.isconfirmed
    if(BGcolor==color.red and BGcolor[1]==color.yellow and c_time )
        strategy.entry("short", strategy.short, comment="short", alert_message='short')
        strategy.cancel("long")
    if(BGcolor==color.green and BGcolor[1]==color.yellow and c_time )
        strategy.entry("long", strategy.long, comment="long", alert_message = 'long')
        strategy.cancel("short")


// STEP 2:
// Determine trail stop loss prices
longStopPrice = 0.0, shortStopPrice = 0.0

longStopPrice := if (strategy.position_size > 0)
    stopValue = close * (1 - longTrailPerc)
    max(stopValue, longStopPrice[1])
else
    0

shortStopPrice := if (strategy.position_size < 0)
    stopValue = close * (1 + shortTrailPerc)
    min(stopValue, shortStopPrice[1])
else
    999999

// Plot stop loss values for confirmation
plot(series=(strategy.position_size > 0) ? longStopPrice : na,
     color=color.fuchsia, style=plot.style_cross,
     linewidth=2, title="Long Trail Stop")
plot(series=(strategy.position_size < 0) ? shortStopPrice : na,
     color=color.fuchsia, style=plot.style_cross,
     linewidth=2, title="Short Trail Stop")


// STEP 3:
// Submit exit orders for trail stop loss price
//if (strategy.position_size > 0)
//    strategy.exit("XL TRL STP","long", stop=longStopPrice)

//if (strategy.position_size < 0)
//    strategy.exit("XS TRL STP","short", stop=shortStopPrice)


tp=input(0.0032,type=input.float, title="tp")
sl=input(0.001,type=input.float, title="sl")

//strategy.close("long", when= tp/2,qty_percent = 50)

//strategy.exit("longtp/sl","long",profit=tp, loss=sl, stop=longStopPrice, alert_message='closelong')
//strategy.exit("shorttp/sl","short",profit=tp, loss=sl, stop=shortStopPrice, alert_message='closeshort')

//tpatrlong= close + atr(atrRange) * targetATR
//slatrlong= close - atr(atrRange) * buyStop

//strategy.exit("longtp/sl","long",profit=tp, loss=sl, alert_message='closelong')
//strategy.exit("shorttp/sl","short",profit=tp, loss=sl, alert_message='closeshort')

strategy.exit("closelong", "long" , profit = close * tp / syminfo.mintick, loss = close * sl / syminfo.mintick, alert_message = "closelong")
strategy.exit("closeshort", "short" , profit = close * tp / syminfo.mintick, loss = close * sl / syminfo.mintick, alert_message = "closeshort")

if(BGcolor==color.yellow or not c_time)
    strategy.close("short", comment="time or yellow", alert_message='closeshort')
    strategy.close("long", comment="time or yellow", alert_message='closelong')


    




더 많은