이동평균선과 슈퍼트렌드를 기반으로 한 트레일링 스톱로스 전략


생성 날짜: 2023-10-20 16:50:01 마지막으로 수정됨: 2023-10-20 16:50:01
복사: 2 클릭수: 727
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

이동평균선과 슈퍼트렌드를 기반으로 한 트레일링 스톱로스 전략

개요

이 전략은 이동 평균 지표와 슈퍼 트렌드 지표를 결합하여, 트렌드 추적 기능을 갖춘 트렌드 추적 전략을 구현한다. 이 전략은 이동 평균의 트렌드 판단 능력을 최대한 활용하고 슈퍼 트렌드의 스톱 기능을 활용하여, 효과적으로 트렌드를 추적하면서 위험을 제어한다.

전략 원칙

이 전략은 두 개의 FRAMA 평행선을 사용하여 구매 및 판매 신호를 판단하고 슈퍼 트렌드 지표와 결합하여 필터링합니다.

구체적으로, 빠른 선에서 느린 선을 통과할 때 구매 신호가 발생하고 빠른 선 아래의 느린 선을 통과할 때 판매 신호가 발생한다. 가짜 파열을 피하기 위해, 전략은 슈퍼 트렌드 지표의 필터링 조건을 추가하여 슈퍼 트렌드 지표가 동방향일 때만 거래한다.

포지션 관리에서, 전략은 슈퍼 트렌드 지표의 변동을 스톱 로드 탈퇴 신호로 사용합니다. 슈퍼 트렌드 지표가 반전되면 스톱 로드 탈퇴를 합니다.

또한, 전략은 선택적으로 트래킹 스톱로스를 설정할 수 있다. 특정 수익을 달성한 후에 트래킹 스톱로스를 켜서 수익을 잠금할 수 있다.

우위 분석

  • 이동 평균을 사용하여 트렌드 방향을 판단하여 시장 소음을 효과적으로 제거하고 트렌드를 정확하게 판단 할 수 있습니다.
  • 슈퍼 트렌드 지표 필터링과 함께 가짜 돌파구를 방지하는 잘못된 거래
  • 슈퍼 트렌드 지표의 변동이 스톱포인트로, 신속한 스톱포인트 및 효과적인 위험 관리
  • 선택적 추적 중지 기능으로 수익을 극대화 할 수 있습니다.

위험 분석

  • 트렌드 추적 전략으로, 트렌드 흔들림에 따라 쉽게 잡힐 수 있으며, 위치 크기를 제어하는 데 주의가 필요합니다.
  • 이동 평균의 지연으로 인해 조기 또는 늦게 입학할 수 있습니다.
  • 슈퍼 트렌드 지표의 파라미터를 잘못 설정하면 너무 급진적이거나 보수적인 스톱 손실이 발생할 수 있습니다.
  • 트래킹 스톱을 활성화할 때 트래킹 폭을 합리적으로 설정하여 너무 급진적인 스톱을 피하십시오.

이동 평균 파라미터를 조정하고, 슈퍼 트렌드 지표 설정을 최적화하고, 추적 스톱 로스를 합리적으로 사용하여 이러한 위험을 줄일 수 있습니다.

최적화 방향

이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.

  1. 이동 평균 변수를 최적화하여 최적의 변수 조합을 찾습니다.

다양한 주기 변수의 조합을 테스트하여 부드러운 효과와 민감성의 최적의 균형을 찾을 수 있다.

  1. 슈퍼 트렌드 지표의 사용자 정의 파라미터

다양한 ATR 주기 및 곱하기 파라미터를 테스트하여 스톱로스를 최적화할 수 있다.

  1. 다른 지표 필터를 추가합니다.

상품 통로 지표, 변동률 지표 등을 추가로 필터링할 수 있다.

  1. 트래킹 중지 손실 변수를 최적화

다양한 트래킹 스톱 로드 규모를 테스트하여 수익률과 리스크 관리를 극대화하는 최적의 매개 변수를 찾을 수 있습니다.

  1. 다른 손해 방지 전략과 함께

일반적인 중단, 흔들림 중단, 운동 중단 등의 전략과 함께 테스트 할 수 있습니다.

요약하다

이 전략은 이동 평균의 트렌드 판단과 슈퍼 트렌드의 손실 관리를 통합하여, 더 완전한 트렌드 추적 스톱 기능의 트렌드 추적 전략을 형성한다. 매개 변수 최적화 및 위험 관리를 통해 전략의 안정성과 수익성을 더욱 강화할 수 있다. 전략은 기초가있는 양적 거래자의 사용에 적합하다.

전략 소스 코드
/*backtest
start: 2023-10-01 00:00:00
end: 2023-10-13 00:00:00
period: 30m
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © 03.freeman

//@version=4
// strategy("FRAMA strategy", overlay=true,precision=6, initial_capital=1000,calc_on_every_tick=true, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=10000, currency=currency.EUR)
ma_src = input(title="MA FRAMA Source", type=input.source, defval=close)
ma_frama_len = input(title="MA FRAMA Length", type=input.integer, defval=12)
res = input(title="Resolution", type=input.resolution, defval="1W")
frama_FC = input(defval=1,minval=1, title="* Fractal Adjusted (FRAMA) Only - FC")
frama_SC = input(defval=200,minval=1, title="* Fractal Adjusted (FRAMA) Only - SC")
High = security(syminfo.tickerid, res, high)
Low = security(syminfo.tickerid, res, low)
source = security(syminfo.tickerid, res, ma_src)
enterRule = input(false,title = "Use supertrend for enter")
exitRule = input(false,title = "Use supertrend for exit")

ma(src, len) =>
    float result = 0
    int len1 = len/2
    e = 2.7182818284590452353602874713527
    w = log(2/(frama_SC+1)) / log(e) // Natural logarithm (ln(2/(SC+1))) workaround
    H1 = highest(High,len1)
    L1 = lowest(Low,len1)
    N1 = (H1-L1)/len1
    H2_ = highest(High,len1)
    H2 = H2_[len1]
    L2_ = lowest(Low,len1)
    L2 = L2_[len1]
    N2 = (H2-L2)/len1
    H3 = highest(High,len)
    L3 = lowest(Low,len)
    N3 = (H3-L3)/len
    dimen1 = (log(N1+N2)-log(N3))/log(2)
    dimen = iff(N1>0 and N2>0 and N3>0,dimen1,nz(dimen1[1]))
    alpha1 = exp(w*(dimen-1))
    oldalpha = alpha1>1?1:(alpha1<0.01?0.01:alpha1)
    oldN = (2-oldalpha)/oldalpha
    N = (((frama_SC-frama_FC)*(oldN-1))/(frama_SC-1))+frama_FC
    alpha_ = 2/(N+1)
    alpha = alpha_<2/(frama_SC+1)?2/(frama_SC+1):(alpha_>1?1:alpha_)
    frama = 0.0
    frama :=(1-alpha)*nz(frama[1]) + alpha*src
    result := frama
    result

frama = ma(sma(source,1),ma_frama_len)
signal = ma(frama,ma_frama_len)
plot(frama, color=color.red)
plot(signal, color=color.green)


longCondition = crossover(frama,signal)
shortCondition = crossunder(frama,signal)

Factor=input(3, minval=1,maxval = 100)
Pd=input(7, minval=1,maxval = 100)


Up=hl2-(Factor*atr(Pd))
Dn=hl2+(Factor*atr(Pd))

TrendUp = 0.0
TrendDown = 0.0
Trend = 0.0
Tsl = 0.0
TrendUp :=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown :=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn

Trend := close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl := Trend==1? TrendUp: TrendDown

linecolor = Trend == 1 ? color.green : color.red

//plot(Tsl, color = linecolor , style =  plot.style_line , linewidth = 2,title = "SuperTrend")

plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,color.green,0,0)
plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, color.red,0,0)

plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0)


//  Strategy: (Thanks to JayRogers)
// === STRATEGY RELATED INPUTS ===
//tradeInvert     = input(defval = false, title = "Invert Trade Direction?")
// the risk management inputs
inpTakeProfit   = input(defval = 0, title = "Take Profit Points", minval = 0)
inpStopLoss     = input(defval = 0, title = "Stop Loss Points", minval = 0)
inpTrailStop    = input(defval = 0, title = "Trailing Stop Loss Points", minval = 0)
inpTrailOffset  = input(defval = 0, title = "Trailing Stop Loss Offset Points", minval = 0)

// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit   = inpTakeProfit  >= 1 ? inpTakeProfit  : na
useStopLoss     = inpStopLoss    >= 1 ? inpStopLoss    : na
useTrailStop    = inpTrailStop   >= 1 ? inpTrailStop   : na
useTrailOffset  = inpTrailOffset >= 1 ? inpTrailOffset : na

// === STRATEGY - LONG POSITION EXECUTION ===
enterLong() => enterRule? (longCondition and Trend ==1):longCondition                                             // functions can be used to wrap up and work out complex conditions
exitLong() => exitRule and Trend == -1

strategy.entry(id = "Buy", long = true, when = enterLong() )             // use function or simple condition to decide when to get in
strategy.close(id = "Buy", when = exitLong() )                         // ...and when to get out

// === STRATEGY - SHORT POSITION EXECUTION ===
enterShort() => enterRule? (shortCondition and Trend ==-1):shortCondition
exitShort() => exitRule and Trend == 1

strategy.entry(id = "Sell", long = false, when = enterShort())
strategy.close(id = "Sell", when = exitShort() )

// === STRATEGY RISK MANAGEMENT EXECUTION ===
// finally, make use of all the earlier values we got prepped
strategy.exit("Exit Buy", from_entry = "Buy", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
strategy.exit("Exit Sell", from_entry = "Sell", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)

// === Backtesting Dates === thanks to Trost

testPeriodSwitch = input(false, "Custom Backtesting Dates")
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0)
testStopYear = input(2020, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testStopHour = input(23, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0)
testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
isPeriod = true
// === /END

if not isPeriod
    strategy.cancel_all()
    strategy.close_all()