동적 이동 평균 크로스오버 거래 전략

저자:차오장, 날짜: 2023-11-13 10:27:54
태그:

img

전반적인 설명

이 전략의 핵심 아이디어는 서로 다른 시간 프레임의 비율 OCHL 평균 지표를 기반으로 여러 이동 평균을 구축하고 크로스오버를 기반으로 거래 신호를 생성하는 것입니다. 가격 추세를 동적으로 캡처 할 수 있으며 중장기 거래에 적합합니다.

전략 논리

이 전략은 빠른 라인과 느린 라인으로 다른 시간 프레임으로 두 개의 비율 OCHL 평균 지표를 사용합니다. 비율 OCHL 평균은 다음과 같이 계산됩니다.

b = abs(close-open)/(high - low)
c = min(max(b, 0), 1)  
Ratio OCHL Averager = c*close + (1-c)*previous Ratio OCHL Averager

여기 b는 내일 가격 이동 비율을 나타내고 c는 정상화 된 b입니다. 비율 OCHL 평균은 이동 평균을 만들기 위해 개방, 폐쇄, 높은 및 낮은 가격을 통합합니다.

이 전략은 빠른 라인을 위해 더 짧은 기간과 느린 라인을 위해 더 긴 기간을 설정합니다. 빠른 라인이 느린 라인을 넘을 때 구매 신호가 생성되며 빠른 라인이 아래를 넘을 때 판매 신호가 생성됩니다. 이동 평균 크로스오버 논리로 트렌드를 캡처합니다.

장점

  1. OCHL 평균자책점은 가격 데이터를 부드럽게 하고 시장 소음을 필터링하여 거래 신호를 더 신뢰할 수 있게 합니다.

  2. 이중 이동 평균 크로스오버가 다른 시간 프레임과 결합되면 새로운 트렌드의 시작을 더 잘 감지 할 수 있습니다.

  3. 빠른 라인과 느린 라인의 기간은 다른 시장 조건에 맞게 조정 될 수 있습니다.

  4. 전략 논리는 간단하고 직관적입니다. 이해하기 쉽고 구현하기 쉽습니다.

  5. 스톱 로즈와 영업이익은 위험을 통제하기 위해 유연하게 설정할 수 있습니다.

위험성

  1. 이동 평균 크로스오버는 과도한 잘못된 신호를 생성 할 수 있습니다. 필터링에 다른 기술적 지표가 필요할 수 있습니다.

  2. 빠른 라인과 느린 라인의 기간은 합리적으로 선택되어야합니다. 그렇지 않으면 전략 성과에 영향을 줄 수 있습니다.

  3. 그것은 범위에 묶인 시장에 적합하지 않은 트렌드를 따르는 전략입니다. 트렌드 조건에서 사용해야합니다.

  4. 스톱 로즈와 영업이익은 손실을 줄이고 수익 수준을 최적화하기 위해 적절하게 조정되어야 합니다.

최적화 방향

  1. 신호 필터링과 품질 향상을 위해 MACD, KDJ와 같은 모멘텀 지표를 결합하는 것을 고려하십시오.

  2. 최적의 매개 변수를 찾기 위해 서로 다른 빠르고 느린 라인 기간 조합을 테스트합니다.

  3. 스톱 로스를 최적화하고 백테스트 결과를 기반으로 수익을 취합니다.

  4. 특정 시장 조건에서 매개 변수를 동적으로 조정하는 것을 고려하십시오. 예를 들어 범위 제한 시장에서 기간을 늘리십시오.

결론

이 전략은 트렌드 방향을 결정하기 위해 빠르고 느린 이동 평균 크로스오버를 사용하는 명확한 논리를 가지고 있습니다. 중장기 거래에 적합한 동적 트렌드 다음 전략입니다. 매개 변수 조정, 신호 필터링 등으로 최적화 할 수있는 공간이 여전히 많습니다. 전반적으로 유연하고 실용적인 트렌드 거래 전략입니다.


/*backtest
start: 2023-11-05 00:00:00
end: 2023-11-12 00:00:00
period: 3m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="[XC] Adaptive Strategy V3 - Ratio OCHL Averager no repaint",shorttitle="R_OHCL", overlay=true, currency=currency.EUR,initial_capital=10000,
     default_qty_value=100, default_qty_type=strategy.percent_of_equity , calc_on_every_tick=false, calc_on_order_fills=true)


//                  ╔═ SETTINGS                  ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

strategy_1     = input ( defval=true   , type=input.bool    , title="STRATEGY 1? —>"      )
Recursive      = input(false)
RES201         = "Min",RES202= "D",RES203 = "W",RES204 = "M"

//++ Resolution 1 ++
inp_resolution1 = input(600, minval=1, title="Resolution Line 1")
restype1        = input ( defval="Min"  , type=input.string , title= "Resolution Line 1" , options=[ "Min","D","W","M"])
multiplier1     = restype1 == "Min" ? "" : restype1 == "D" ? "D" : restype1 == "W" ? "W" : "M"
resolution1     = tostring(inp_resolution1)+ multiplier1

//++ Resolution 2 ++
inp_resolution2 = input(1440, minval=1, title="Resolution Line 2")
restype2        = input ( defval="Min"  , type=input.string , title= "Resolution Line 2" , options=["Min","D","W","M"])
multiplier2     = restype2 == "Min" ? "" : restype2 == "D" ? "D" : restype2 == "W" ? "W" : "M"
resolution2     = tostring(inp_resolution2)+ multiplier2

StopLoss        = input(defval = 500 , title = "Stop Loss", minval = 0)
TakeProfit      = input(defval = 2500 , title = "Take Profit", 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   = TakeProfit  >= 1 ? TakeProfit  : na
useStopLoss     = StopLoss    >= 1 ? StopLoss    : na


//                  ╔═ BACKTEST RANGE            ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░
line_breakBTR  = input ( defval = true   , type=input.bool   , title="BACKTEST RANGE —"      ) 
FromYear       = input ( defval = 2019, title = "From Year", minval = 2017)
FromMonth      = input ( defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay        = input ( defval = 2, title = "From Day", minval = 1, maxval = 31)
//FromHour     = input ( defval = 1, title = "From Hour", minval = 1, maxval = 24)
ToYear         = input ( defval = 9999, title = "To Year", minval = 2017)
//ToHour       = input ( defval = 0, title = "From Hour", minval = 0, maxval = 24)
ToMonth        = input ( defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay          = input ( defval = 1, title = "To Day", minval = 1, maxval = 31)

// === FUNCTION EXAMPLE ===
start     = timestamp(syminfo.timezone, FromYear, FromMonth, FromDay, 0, 00)  // backtest start window
finish    = timestamp(syminfo.timezone, ToYear  , ToMonth  , ToDay  , 0, 59)  // backtest finish window
window()  => time >= start and time <= finish ? true : false // create function "within window of time"

//                  ╔═ INDICATOR                 ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

// "Ratio OCHL Averager" -> alexgrover / tradingview.com/script/RGAtOI6h-Ratio-OCHL-Averager-An-Alternative-to-VWAP/

rochla( res,Recursive)=>
    //Recursive = false
    H =  security(syminfo.tickerid,res,high[1],gaps = barmerge.gaps_off,  lookahead = barmerge.lookahead_on)
    L =  security(syminfo.tickerid,res,low[1] ,gaps = barmerge.gaps_off,  lookahead = barmerge.lookahead_on)
    d = 0.
    //----
    a = Recursive ? nz(d[1],open) : open
    b = abs(close-a)/(H - L)
    c = b > 1 ? 1 : b
    d := c*close+(1-c)*nz(d[1],close)



strat1_line1=rochla(resolution1,Recursive)
strat1_line2=rochla(resolution2,Recursive)

plot(strat1_line1, title="Ratio OCHL Averager 1", color=#DAA520,linewidth=2,transp=0)
plot(strat1_line2, title="Ratio OCHL Averager 2", color=#B22222,linewidth=2,transp=0)



//                  ╔═ STRATEGY 1                ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

trading_strat1_line1 = strategy_1 == 1    ? strat1_line1   : na
trading_strat1_line2 = strategy_1 == 1    ? strat1_line2   : na

longCross  = crossunder (trading_strat1_line2, trading_strat1_line1) ? true : false
shortCross = crossover  (trading_strat1_line2, trading_strat1_line1) ? true : false

plot( longCross  ? trading_strat1_line1 : na , title = "Long"  , color=color.aqua, style=plot.style_circles, linewidth=5, offset= 0)
plot( shortCross ? trading_strat1_line2 : na , title = "Short" , color=color.red , style=plot.style_circles, linewidth=5, offset= 0)



//                  ╔═ Backtest 1                ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░


strategy.exit("close",loss = useStopLoss, profit = useTakeProfit)

if longCross  and window() and strategy_1 == 1 
    strategy.entry("Go Long", strategy.long)
if shortCross and window() and strategy_1 == 1 
    strategy.entry("Go Short", strategy.short)

//end

더 많은