오시레이터 촛불 모멘텀 거래 전략

저자:차오장, 날짜: 2023-09-26 20:05:55
태그:

전반적인 설명

이 전략은 RSI, Stoch, MACD와 같은 오시레이터 지표를 사용하여 거래 신호를 생성하는 모멘텀 기반 전략입니다. 주요 아이디어는 지표를 사용하여 가격이 오시레이션 할 때 트렌드 방향을 파악하고 지표 신호를 기반으로 거래를 수행하는 것입니다. 이 전략은 또한 지연 슈퍼 트렌드를 중지 손실에 사용합니다.

전략 논리

전략은 먼저 사용자 정의 함수 f_getOscilatorValues를 호출하여 RSI, Stoch, MACD 등을 포함한 다른 오시레이터 지표의 값을 얻습니다. 그 다음 f_getSupertrend로 지연된 슈퍼 트렌드 값을 계산하여 스톱 로스를 추적합니다.

지표를 계산한 후, 전략은 f_getBuySellStops를 호출하여 지표 값에 기초하여 엔트리 스톱과 수익 목표를 계산합니다. 구체적으로 ATR을 계산하고 엔트리 스톱으로 스톱 손실 계수와 ATR을 인수하고 수익 목표로 수익 계수와 인수합니다. 트렌드가 역전되면 스톱과 목표가 조정됩니다.

다음으로, 전략은 촛불 방향을 결정한다. 상승 트렌드 촛불은 녹색, 하락 트렌드 촛불은 빨간색이다. 촛불과 지표를 그래프화 한 후, 전략은 입시 조건이 충족되는지 확인한다. 입시 조건은 지표가 과소매를 표시하고 가격이 상단보다 상위를 깨는 경우를 구매하고 지표가 과소매를 표시하고 가격이 하단보다 하위를 깨는 경우를 판매한다. 또한 가격이 더 높은 시간 프레임 이동 평균을 깨는 것을 요구하는 필터링 조건이 있다.

진입 후, 스톱 로스는 상위/하위 대역에 따라 가장 가깝다. 스톱 로스가 트리거되면 포지션은 닫힌다. 가격이 이익 목표에 도달하면 부분적인 이익이 취득된다.

이점 분석

이 전략의 장점은 다음과 같습니다.

  1. 트렌드 방향을 파악하기 위해 오시레이터를 사용하면 단기적 역전 기회를 적시에 파악할 수 있습니다.

  2. 지연된 슈퍼 트렌드 스톱 로스를 적용하면 손실이 증가하기 전에 중단 될 수 있으며 단일 거래 손실을 제한합니다.

  3. 동적 ATR를 기반으로 스톱 로스 및 수익 타겟을 계산하면 포지션 크기를 조정하는 데 도움이 됩니다.

  4. 더 높은 시간 프레임 이동 평균을 필터링하면 통합에 갇히지 않습니다.

  5. 부분적인 수익을 취하면 수익이 계속되면서 약간의 수익을 얻을 수 있습니다.

  6. 논리는 단순하고 양자 거래 초보자도 쉽게 이해할 수 있습니다.

위험 분석

이 전략의 일부 위험은 다음과 같습니다.

  1. 오시레이터는 지연된 문제를 가질 수 있으며, 지연된 진입 및 조기 출구 신호를 유발할 수 있습니다. 이는 매개 변수를 최적화하거나 트렌드 다음 지표를 추가함으로써 개선 될 수 있습니다.

  2. 긴 스톱 손실이 발생할 수 있습니다. 스톱 손실 범위는 확장되거나 들리어와 같은 동적 스톱이 사용될 수 있습니다.

  3. 부분적 이익 취득 후 남은 지위는 중단 될 수 있습니다. 부분적 이익 비율은 낮출 수 있습니다.

  4. 백테스트 과도한 적합성 위험. 전략은 다른 시장에서 검증되어야합니다.

  5. 더 높은 시간 프레임 이동 평균 필터의 장애. 트렌드 분류 방법은 함께 사용해야합니다.

개선 방향

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

  1. 오시일레이터 매개 변수들의 다양한 조합을 테스트하고 양질의 신호를 제공하는 것을 찾으십시오.

  2. ATR 또는 이동 평균에 기반한 후속 수익 정지로 부분 수익을 대체하려고 시도하십시오.

  3. 추세 분석을 위한 이동평균을 대체하고 정확도를 향상시키기 위해 기계 학습 알고리즘을 추가합니다.

  4. 부득이한 반전을 피하기 위해 필터링 조건으로 부피 지표를 추가합니다.

  5. 자산에 대한 최적의 조합을 찾기 위해 지표를 집합하고 중량합니다.

  6. 기계 학습 위험 제어 모듈을 추가하여 정지, 목표 및 위치 크기를 동적으로 최적화합니다.

  7. 피처스와 스팟 사이의 가격 스프레드를 사용하여 삼각형 중재 또는 기본 거래 신호를 포함합니다.

결론

전체적으로 이것은 지표와 리스크 관리에 초점을 맞춘 명확한 논리로 양 거래 초보자를위한 훌륭한 전략입니다. 그러나 매개 변수 최적화 및 리스크 감축은 여전히 라이브 거래에 필요합니다. 또한 견고성을 향상시키기 위해 트렌드 분석, 스톱 로스 최적화, 앙상블 모델 등과 같은 측면에서도 향상 될 수 있습니다. 거래 전략 템플릿으로서 귀중한 참조를 제공합니다.


/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 00:00:00
period: 1h
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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)

showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier  = input(4)
targetMultiplier  = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)

useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true

f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
    oOpen = rsi(open, length)
    oClose = rsi(close, length)
    oHigh = rsi(high, length)
    oLow = rsi(low, length)
    if(oscilatorType == "tsi")
        oOpen := tsi(open, shortlength, longlength)
        oClose := tsi(close, shortlength, longlength)
        oHigh := tsi(high, shortlength, longlength)
        oLow := tsi(low, shortlength, longlength)
    if(oscilatorType == "stoch")
        oOpen := stoch(open, longlength, shortlength, length)
        oClose := stoch(close, longlength, shortlength, length)
        oHigh := stoch(high, longlength, shortlength, length)
        oLow := stoch(low, longlength, shortlength, length)
    if(oscilatorType == "cci")
        oOpen := cci(open, length)
        oClose := cci(close, length)
        oHigh := cci(high, length)
        oLow := cci(low, length)
    if(oscilatorType == "cog")
        oOpen := cog(open, length)
        oClose := cog(close, length)
        oHigh := cog(high, length)
        oLow := cog(low, length)
    if(oscilatorType == "cmo")
        oOpen := cmo(open, length)
        oClose := cmo(close, length)
        oHigh := cmo(high, length)
        oLow := cmo(low, length)
    if(oscilatorType == "mfi")
        oOpen := mfi(open, length)
        oClose := mfi(close, length)
        oHigh := mfi(high, length)
        oLow := mfi(low, length)
    if(oscilatorType == "macd")
        [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
        [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
        [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
        [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
        oOpen := macdLineOpen
        oClose := macdLineClose
        oHigh := macdLineHigh
        oLow := macdLineLow
    [oOpen, oClose, oHigh, oLow]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
    atr = averagetruerange * stopMultiplier

    longStop = oClose - atr
    longStopPrev = nz(longStop[1], longStop)
    longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
    
    shortStop = oClose + atr
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
    
    dir = 1
    dir := nz(dir[1], dir)
    dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
    
    trailingStop = dir == 1? longStop : shortStop
    
    [dir, trailingStop]


f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
    barState = 0
    source = oClose
    
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)

    buyStop = source - atr * stopMultiplier
    sellStop = source + atr * stopMultiplier
    buyStopDerived = buyStop
    sellStopDerived = sellStop
    highTarget = considerWicks ? oHigh : source
    lowTarget = considerWicks ? oLow : source
    
    highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
    lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
    
    barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
    
    buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
    sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
    buyStop := source - atr * buyMultiplier
    sellStop := source + atr * sellMultiplier
    buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
    sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
    
    buyStopDerived := buyStop
    sellStopDerived := sellStop
    
    buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
    sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived

    [buyStopDerived, sellStopDerived, barState]


f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
    
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
    derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
    HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
    HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
    CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
    pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
    pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
    pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
    pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
    [pivothi, pivotlo]
    
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)

candleColor = colorByPreviousClose ?
                 (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : 
                 (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)

[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)

trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived

plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)

[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)

buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)

// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)

더 많은