추세 반전 트레일링 스톱 전략


생성 날짜: 2023-11-14 11:33:50 마지막으로 수정됨: 2023-11-14 11:33:50
복사: 0 클릭수: 613
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

추세 반전 트레일링 스톱 전략

개요

이 전략은 트렌드 반전 지표에 기반하여, 트렌드 추적 스톱 손실 메커니즘과 결합하여, 트렌드 시장에서 트렌드를 추적하여, 정리 시장에서 손실을 줄이는 효과를 달성한다.

전략 원칙

이 전략은 헐 이동 평균을 주요 트렌드 판단 지표로 사용합니다. 가격이 헐 평균을 넘어서면 더 많은 것을하고, 가격이 헐 평균을 넘어서면 더 많은 것을하고, 가격이 헐 평균을 넘어서면 더 많은 것을하지 않습니다. 동시에, 맥기닐리 평균과 결합하여 추세를 확인합니다.

포지션 개시 후, 가격이 반전되면, 즉 헐 평균이 포크 헤드가 발생했을 때, 트렌드 변경 논리를 실행하여 현재 포지션을 닫습니다.

이 전략은 또한 트렌드 추적 스톱스 메커니즘을 도입했다. 포지션을 열고 나서 ATR에 따라 동적 스톱스 가격을 계산한다. 가격 움직임에 따라 스톱스 라인도 동적으로 조정되어 수익을 창출하는 추적 스톱스이다.

전략적 이점

  • Hull 평균을 사용하여 트렌드 반전점을 판단합니다. Hull 평균은 돌파 신호에 민감합니다.
  • 맥킨리 평균과 함께 트렌드 확인을 통해 일부 가짜 돌파구를 필터링 할 수 있습니다.
  • 동적 추적 스톱 메커니즘을 적용하여 시장의 변동성에 따라 스톱 규모를 조정하여 손실을 효과적으로 제어합니다.
  • Hull Average를 확인하고, Hull Average가 트렌드 반향에 대응하고, 손실이 더 커지는 것을 방지합니다.
  • 최적의 변수를 찾기 위해 다양한 변수 조합을 편리하게 전환하여 테스트할 수 있습니다.

위험과 해결책

  • 진동상태에서 트리거되는 정지상태

    • 적절히 확장할 수 있는 중지폭, 증가하는 중지 완충 구역
  • 급격한 상황에서는 스톱로드를 추적하는 것이 가격 변화를 따라 잡을 수 없습니다.

    • 평준화 주기를 단축하여 스톱로스를 가격에 더 빨리 따라 잡을 수 있습니다.
  • 가짜 침입은 불필요한 손실을 초래할 수 있습니다.

    • 가짜 돌파를 방지하기 위해 확인을 위해 다른 지표를 추가합니다.
  • 잘못된 매개 변수로 인해 정책이 제대로 작동하지 않을 수 있습니다.

    • 다른 시장주기를 거슬러 올라가 최적의 변수를 찾아낼 수 있습니다.

더 나은 생각

  • K선 형태, 브린 밴드, RSI 등과 같은 다른 지표와 결합된 확인이 추가되어 신호 품질이 향상됩니다.

  • 다양한 품종, 주기적 변수를 최적화하여 최적의 변수 조합을 찾습니다.

  • 매개 변수 적응 최적화를 위해 기계 학습과 같은 방법을 시도할 수 있습니다.

  • 절감 알고리즘을 최적화하여, 절감을 보장하면서 불필요한 절감을 최소화합니다.

  • 자금 관리와 결합하여 포지션 관리 전략을 최적화

  • 자동 정지장치를 추가하는 것을 고려

요약하다

이 전략은 전체적으로 보다 안정적인 트렌드 추적 전략이다. 고정된 스톱에 비해, 이 전략은 동적 스톱 메커니즘을 사용하며, 시장의 변동성에 따라 스톱 손실을 조정할 수 있으며, 스톱 손실이 커버되는 확률을 효과적으로 줄일 수 있다. 동시에, 헐 평균과 트렌드 변화 논리의 도입은 트렌드 반향에 대해 더 빠른 반응을 할 수 있다. 그러나 이 전략은 또한 특정 위험이 있습니다.

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

// © Milleman
//@version=4
strategy("MilleMachine", overlay=true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.06)


// Additional settings
Mode = input(title="Mode", defval="LongShort", options=["LongShort", "OnlyLong", "OnlyShort","Indicator Mode"])
UseTP = false                               //input(false, title="Use Take Profit?")
QuickSwitch = true                          //input(true, title="Quickswitch")
UseTC = true                                //input(true, title="Use Trendchange?")

// Risk management settings
//Spacer2 = input(false, title="======= Risk management settings =======")
Risk = input(1.0, title="% Risk",minval=0)/100
RRR = 2                                     //input(2,title="Risk Reward Ratio",step=0.1,minval=0,maxval=20)
SL_Mode = false                             // input(true, title="ON = Fixed SL / OFF = Dynamic SL (ATR)")
SL_Fix = 3                                  //input(3,title="StopLoss %",step=0.25, minval=0)/100
ATR = atr(14)                               //input(14,title="Periode ATR"))
Mul = input(2,title="ATR Multiplier",step=0.1)
xATR = ATR * Mul
SL = SL_Mode ? SL_Fix : (1 - close/(close+xATR))

// INDICATORS  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ind(type, src, len) =>
    float result = 0
    if type=="McGinley"
        result := na(result[1]) ? ema(src, len) : result[1] + (src - result[1]) / (len * pow(src/result[1], 4))
    if type=="HMA"
        result := wma(2*wma(src, len/2)-wma(src, len), round(sqrt(len)))
    if type=="EHMA"
        result := ema(2*ema(src, len/2)-ema(src, len), round(sqrt(len)))
    if type=="THMA"
        lend = len/2
        result := wma(wma(src, lend/3)*3-wma(src, lend/2)-wma(src,lend), lend)
    if type=="SMA" // Simple
        result := sma(src, len)
    if type=="EMA" // Exponential
        result := ema(src, len)
    if type=="DEMA" // Double Exponential
        e = ema(src, len)
        result := 2 * e - ema(e, len)
    if type=="TEMA" // Triple Exponential
        e = ema(src, len)
        result := 3 * (e - ema(e, len)) + ema(ema(e, len), len)
    if type=="WMA" // Weighted
        result := wma(src, len)
    if type=="VWMA" // Volume Weighted
        result := vwma(src, len) 
    if type=="SMMA" // Smoothed
        w = wma(src, len)
        result := (w[1] * (len - 1) + src) / len
    if type == "RMA"
        result := rma(src, len)
    if type=="LSMA" // Least Squares
        result := linreg(src, len, 0)
    if type=="ALMA" // Arnaud Legoux
        result := alma(src, len, 0.85, 6)
    if type=="Kijun" //Kijun-sen
        kijun = avg(lowest(len), highest(len))
        result :=kijun
    if type=="WWSA" // Welles Wilder Smoothed Moving Average
        result := nz(result[1]) + (close -nz(result[1]))/len
    result

// Baseline : Switch from Long to Short and vice versa
BL_Act = input(true, title="====== Activate Baseline - Switch L/S ======")
BL_type = input(title="Baseline Type", defval="McGinley", options=["McGinley","HMA","EHMA","THMA","SMA","EMA","DEMA","TEMA","WMA","VWMA","SMMA","RMA","LSMA","ALMA","Kijun","WWSA"])
BL_src = input(close, title="BL source")
BL_len = input(50, title="BL length", minval=1)
BL = Ind(BL_type,BL_src, BL_len)

// Confirmation indicator
C1_Act = input(false, title="===== Activate Confirmation indicator =====")
C1_type = input(title="C1 Entry indicator", defval="SMA", options=["McGinley","HMA","EHMA","THMA","SMA","EMA","DEMA","TEMA","WMA","VWMA","SMMA","RMA","LSMA","ALMA","Kijun","WWSA"])
C1_src = input(close, title="Source")
C1_len = input(5,title="Length", minval=1)
C1 = Ind(C1_type,C1_src,C1_len)

// Entry indicator : Hull Moving Average
Spacer5 = input(true, title="====== ENTRY indicator =======")
EI_type = input(title="EI Entry indicator", defval="HMA", options=["McGinley","HMA","EHMA","THMA","SMA","EMA","DEMA","TEMA","WMA","VWMA","SMMA","RMA","LSMA","ALMA","Kijun","WWSA"])
EI_src = input(close, title="Source")
EI_Len = input(46,title="Length", minval=1)
EI = Ind(EI_type,EI_src,EI_Len)

// Trail stop settings
TrailActivation = input(true, title="===== Activate Trailing Stop =====")
TS_type = input(title="TS Traling Stop Type", defval="EMA", options=["McGinley","HMA","EHMA","THMA","SMA","EMA","DEMA","TEMA","WMA","VWMA","SMMA","RMA","LSMA","ALMA","Kijun","WWSA"])
TrailSLScaling = 1 //input(100, title="SL Scaling", minval=0, step=5)/100
TrailingSourceLong = Ind(TS_type,low,input(5,"Smoothing Trail Long EMA", minval=1))
TrailingSourceShort = Ind(TS_type,high,input(2,"Smoothing Trail Short EMA", minval=1))

//VARIABLES MANAGEMENT
TriggerPrice = 0.0, TriggerPrice := TriggerPrice[1]
TriggerSL = 0.0, TriggerSL := TriggerSL[1]
SLPrice = 0.0, SLPrice := SLPrice[1], TPPrice = 0.0, TPPrice := TPPrice[1]
isLong = false, isLong := isLong[1], isShort = false, isShort := isShort[1]

//LOGIC
GoLong = crossover(EI,EI[1]) and (strategy.position_size == 0.0 and QuickSwitch) and (not BL_Act or BL/BL[1] > 1) and (not C1_Act or C1>C1[1]) and (Mode == "LongShort" or Mode == "OnlyLong")
GoShort = crossunder(EI,EI[1]) and (strategy.position_size == 0.0 and QuickSwitch) and (not BL_Act or BL/BL[1] < 1) and (not C1_Act or C1<C1[1]) and (Mode == "LongShort" or Mode == "OnlyShort")
ExitLong = isLong and crossunder(EI,EI[1]) and UseTC
ExitShort = isShort and crossover(EI,EI[1]) and UseTC

//FRAMEWORK
//Reset Long-Short memory
if isLong and strategy.position_size == 0.0
    isLong := false
if isShort and strategy.position_size == 0.0
    isShort := false
//Long
if GoLong
    isLong := true, TriggerPrice := close, TriggerSL := SL
    TPPrice := UseTP? TriggerPrice * (1 + (TriggerSL * RRR)) : na
    SLPrice := TriggerPrice * (1-TriggerSL)
    Entry_Contracts = strategy.equity * Risk / ((TriggerPrice-SLPrice)/TriggerPrice) / TriggerPrice
    strategy.entry("Long", strategy.long, comment=tostring(round((TriggerSL/TriggerPrice)*1000)), qty=Entry_Contracts)
    strategy.exit("TPSL","Long", limit=TPPrice, stop=SLPrice)
if isLong
    NewValSL = TrailingSourceLong * (1 - (SL*TrailSLScaling))
    if TrailActivation and NewValSL > SLPrice
        SLPrice := NewValSL
    strategy.exit("TPSL","Long", limit=TPPrice, stop=SLPrice)
if ExitLong
    strategy.close_all(comment="TrendChange")
    isLong := false

//Short
if GoShort
    isShort := true, TriggerPrice := close, TriggerSL := SL
    TPPrice := UseTP? TriggerPrice * (1 - (TriggerSL * RRR)) : na
    SLPrice := TriggerPrice * (1 + TriggerSL)
    Entry_Contracts = strategy.equity * Risk / ((SLPrice-TriggerPrice)/TriggerPrice) / TriggerPrice
    strategy.entry("Short", strategy.short, comment=tostring(round((TriggerSL/TriggerPrice)*1000)), qty=Entry_Contracts)
    strategy.exit("TPSL","Short", limit=TPPrice, stop=SLPrice)
if isShort
    NewValSL = TrailingSourceShort * (1 + (SL*TrailSLScaling))
    if TrailActivation and NewValSL < SLPrice
        SLPrice := NewValSL
    strategy.exit("TPSL","Short", limit=TPPrice, stop=SLPrice)
if ExitShort
    strategy.close_all(comment="TrendChange")
    isShort := false

//VISUALISATION
plot(BL_Act?BL:na, color=color.blue,title="Baseline")
plot(C1_Act?C1:na, color=color.yellow,title="confirmation Indicator")
EIColor = EI>EI[1] ? color.green : color.red
Fill_EI = plot(EI, color=EIColor, linewidth=1, transp=40, title="Entry Indicator EI")
Fill_EID = plot(EI[1], color=EIColor, linewidth=1, transp=40, title="Entry Indicator EID")
fill(Fill_EI,Fill_EID, title="EI_Fill", color=EIColor,transp=50)

plot(strategy.position_size != 0.0 and (isLong or isShort) ? TriggerPrice : na, title="TriggerPrice", color=color.yellow, style=plot.style_linebr)
plot(strategy.position_size != 0.0 and (isLong or isShort) ? TPPrice : na, title="TakeProfit", color=color.green, style=plot.style_linebr)
plot(strategy.position_size != 0.0 and (isLong or isShort) ? SLPrice : na, title="StopLoss", color=color.red, style=plot.style_linebr)
bgcolor(isLong[1] and cross(low,SLPrice) and low[1] > SLPrice and TriggerPrice>SLPrice ? color.yellow : na, transp=75, title="SL Long")
bgcolor(isShort[1] and cross(high,SLPrice) and high[1] < SLPrice and TriggerPrice<SLPrice ? color.yellow : na, transp=75, title="SL Short")