상대 볼륨 백분율 모멘텀 트레이딩 전략

RVPR ATR SL/TP MA EMA SMMA WMA JMA T3
생성 날짜: 2025-07-04 11:27:18 마지막으로 수정됨: 2025-07-04 11:27:18
복사: 9 클릭수: 259
avatar of ianzeng123 ianzeng123
2
집중하다
319
수행원

상대 볼륨 백분율 모멘텀 트레이딩 전략 상대 볼륨 백분율 모멘텀 트레이딩 전략

개요

상대 거래량 비율 동력 거래 전략은 상대 거래량 동력 분석, 가격 행동 필터링, 돌파구 탐지 및 동적 스톱/스톱 논리를 결합한 통합 거래 시스템이다. 이 전략의 핵심은 상대 거래량의 윌리엄스 %R와 같은 지표 ((RVPR) 를 계산하여 쌍평등선 필터와 결합하여 거래량이 확장하거나 축소되는 순간을 식별하는 것이다. 이 전략은 추가로 조정 가능한 가격 행동 필터로 정확한 입장을 취하고, 다른 유형의 그래픽 모형을 기반으로 판단한다.

전략 원칙

이 전략의 핵심 원칙은 거래량 데이터를 비율로 변환하고, 윌리엄스 %R와 유사한 계산 방법을 사용하여 현재 거래량과 그 역사적 범위의 관계를 분석하는 것입니다. 이 전략은 다음의 몇 가지 핵심 구성 요소를 사용하여 거래 신호를 생성합니다.

  1. 상대 거래량%R 진동기: 현재 거래량과 역사 거래량의 최고 및 최저 수준을 비교하여 상대 위치를 계산한다. 이 지표는 가격 영역의 윌리엄스 %R와 비슷하지만 거래량 데이터에 적용된다.

  2. 이중 이동 평균 필터링: 전략은 두 개의 거래량 이동 평균을 사용한다 (고속 및 느린), 여러 종류의 평형 알고리즘을 선택할 수 있다 (SMA, EMA, JMA, T3, Super Smoother 등). 거래량이 빠른 평균선보다 많고 빠른 평균선이 느린 평균선보다 많을 때 거래량이 상승하는 경향을 나타낸다면, 다중 신호가 될 수 있으며, 그 반대의 경우도 마찬가지이다.

  3. 가격 행동 필터: 다른 필터 형식에 따라 거래 신호를 더 필터링합니다.

    • 간단한 모형: 기본 상승/하강
    • 필터 모드: 범위에 따라 강도 확인
    • 급진적 모드: 동력에 기반한 돌파구
    • 내부 모드: 반전형태
  4. 필터를 뚫고: 선택적으로 5개 의 고점/저점 근처의 거래를 배제하여 리스크/이익 비율이 좋지 않은 거래를 피한다.

  5. 스톱 및 스톱 시스템: ATR (평균 실제 파도) 에 기반한 동적 스톱 / 스톱 메커니즘, 스톱 및 스톱 거리를 조정하기 위해 배수를 구성할 수 있다.

  6. 탈퇴 시간: 고정된 수의 棒 후에 탈퇴하는 것을 선택할 수 있다.

다단계 입문 조건에는 거래량이 빠른 이동 평균보다 많고, 빠른 이동 평균이 느린 이동 평균보다 많고, 상대적인 거래량 %R이 가장자리보다 많고, 가격이 다단계 방향 필터를 통과하며, 최근 돌파 최고점보다 선택적으로 낮습니다. 공허 입문 조건은 반대로, 설정된 퇴출 조건에서 평점 포지션을 유발합니다.

전략적 이점

  1. 다차원 분석: 이 전략은 거래량, 가격 행동, 그리고 동적 중단/정지 등을 결합하여 포괄적인 시장 분석 프레임워크를 제공합니다.

  2. 고도 사용자 정의: 전략은 거래 방향 제어, 다른 가격 행동 필터 모드, 거래량 이동 평균 유형 선택 등 다양한 변수를 제공하여 거래자가 자신의 스타일과 시장 선호도에 따라 사용자 정의 할 수 있습니다.

  3. 스마트 입시 필터링: 거래량 동력과 가격 행동 패턴을 결합하여 전략은 더 높은 확률의 거래 기회를 식별하고 낮은 품질의 거래 신호를 피할 수 있습니다.

  4. 유연한 탈퇴 메커니즘: 전략은 시간 및 가격에 기반한 탈퇴 옵션을 제공하며, 고정된 바 수 탈퇴와 ATR 기반의 동적 스톱/스트로프를 포함하여 위험 관리를 더 유연하고 효과적으로 만듭니다.

  5. 다양한 시장 환경에 적응: 다양한 가격 행동 패턴을 통해 (단순, 필터, 급진, 내부) 전략은 추세 및 지역 시장을 포함한 다양한 시장 조건에 적응 할 수 있습니다.

  6. 고급 기술 지표 통합: 전략은 JMA (주리크 이동 평균), T3 및 Super Smoother와 같은 여러 고급 이동 평균 유형을 통합합니다. 이러한 지표는 소음을 줄이고 실제 트렌드를 포착하는 데 탁월합니다.

전략적 위험

  1. 변수 최적화 위험: 전략이 여러 개의 조정 가능한 변수를 포함하고 있기 때문에 과도하게 최적화 될 위험이 있으며, 이는 역사적 재검토 성능이 우수하지만 실장 효과는 좋지 않을 수 있습니다. 해결 방법은 전향 테스트와 거친성 분석을 사용하여 다양한 시장 조건에서 변수가 안정성을 유지할 수 있도록하는 것입니다.

  2. 가짜 돌파 위험: 거래량 돌파는 항상 지속 가능한 가격 움직임과 함께 할 필요는 없으며, 전략은 가짜 돌파에서 잘못된 신호를 일으킬 수 있습니다. 추가 확인 지표를 추가하거나 진입을 지연함으로써이 위험을 줄일 수 있습니다.

  3. 시장 환경 의존성: 이 전략은 다른 시장 환경 (예: 높은 변동성 vs 낮은 변동성) 에서 일관되게 작동하지 않을 수 있습니다. 실행하기 전에 다양한 시장 조건에서 전략을 테스트하는 것이 좋습니다.

  4. 스톱 손해 트리거 위험: ATR 기반의 스톱은 변동성이 급격히 확대될 때 트리거 될 수 있다. 변동성 조정의 스톱 손해 배수를 사용하거나 중요한 지지/저항 지점에 스톱 손해를 설정하는 것이 더 효과적일 수 있다.

  5. 탈퇴의 시간적 유연성이 없다: 고정된 바드 수 탈퇴는 수익 거래를 조기 종료하거나 손실 거래를 너무 늦게 종료할 수 있다. 트렌드 또는 동력 지표와 결합하여 탈퇴 시기를 동적으로 조정하는 것을 고려할 수 있다.

  6. 계산 복잡성: 전략은 여러 가지 복잡한 이동 평균 알고리즘과 조건 조합을 사용하여 계산 부담을 증가시키고 실행 지연을 초래할 수 있습니다. 실시간 거래에서 일부 계산 집약적인 지표를 단순화해야 할 수 있습니다.

전략 최적화 방향

  1. 역동적 인 마이너스 조정: 현재 전략은 고정된 상대 거래량% R 마이너스를 사용합니다. 최근 거래량 변동성에 따라 자동으로 조정되는 적응 마이너스를 실현하는 것을 고려 할 수 있습니다. 이것은 전략이 다른 시장 조건과 계절적 변화에 더 잘 적응하도록 할 것입니다.

  2. 다중 시간 프레임 확인: 더 높은 시간 프레임의 확인 신호를 도입하여 더 큰 트렌드 방향으로만 거래하면 전략의 승률과 위험 수익률을 높일 수 있습니다. 예를 들어, 당일 선이 상승하는 경우에만 시간 선의 다중 신호를 실행하십시오.

  3. 거래량 품질 분석: 상대적인 거래량 외에도 거래량 확산 지표 또는 거래량 분산 분석을 추가하여 거래량의 질을 평가할 수 있습니다. 이는 거래량 확인과 잠재적인 소모 신호를 구별하는 데 도움이됩니다.

  4. 스마트 스톱/스톱: 현재 ATR 기반의 스톱/스톱은 보다 지능적인 시스템으로 개량될 수 있다. 예를 들어, 중요한 지지/저항 위치에 기반한 스톱이나, 변동성 조절을 이용한 스톱으로, 낮은 변동기간에 스톱을 강화하고 높은 변동기간에 스톱을 완화한다.

  5. 시장 구조를 통합: 가격 구조 분석 (지원/저항, 트렌드 라인, 가격 채널과 같은) 을 전략에 통합하면 입구와 출구의 품질을 향상시킬 수 있습니다.

  6. 위험 관리 강화: 동적인 포지션 크기를 조정하여 현재 시장의 변동성과 최근 전략적 성과를 기반으로 포지션을 높이고, 불확실한 기간 동안 포지션을 줄입니다.

  7. 기계 학습 통합: 기계 학습 알고리즘을 사용하여 전략 매개 변수를 동적으로 최적화하거나 현재 시장 조건에서 어떤 가격 행동 필터가 가장 효과적인지 예측하여 전략 성능을 더욱 향상시킬 수 있습니다.

요약하다

상대 거래량 비율 동력 거래 전략은 거래량 분석, 다중 가격 행동 필터 및 동적 위험 관리 기술을 결합하여 거래자에게 잠재적인 시장 기회를 식별 할 수있는 강력한 도구를 제공하는 포괄적이고 유연한 거래 시스템입니다. 이 전략의 핵심 장점은 개인 선호도 및 시장 조건에 따라 거래자가 조정할 수 있는 적응성과 사용자 정의입니다.

이 전략은 특히 거래량 확인에 기반한 반전 또는 추세 연장 신호를 찾는 거래자들에게 적합합니다. Williams % R 스타일의 상대 거래량 지표를 사용하여 전략은 거래량 돌파구를 식별할 수 있습니다. 이는 종종 시장 정서의 중요한 전환이나 추세 가속화를 나타냅니다. 또한 여러 가지 가격 행동 필터 옵션은 거래자가 자신의 위험 선호도와 거래 스타일에 따라 더 보수적이거나 더 적극적인 진입 조건을 선택할 수 있습니다.

이 전략은 많은 장점을 제공하지만, 거래자는 잠재적인 과잉 최적화 위험과 시장 환경 의존성에 주의를 기울여야 합니다. 지속적인 테스트와 조정, 권장된 최적화 방향과 결합하여, 거래자는 이 전략의 안정성과 장기적인 수익성을 더욱 강화할 수 있습니다. 결국, 모든 거래 전략과 마찬가지로, 성공의 열쇠는 원칙을 깊이 이해하고, 위험을 현명하게 관리하고, 다양한 시장 조건에서 지속적으로 성능을 평가하는 것입니다.

전략 소스 코드
/*backtest
start: 2024-07-04 00:00:00
end: 2025-07-02 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © GabrielAmadeusLau

//@version=6
strategy("Relative Volume Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// === Input: Trade Direction === //
tradeDirection = input.string("Long Only", title="Trade Direction", options=["Long Only", "Short Only", "Both"], group="Strategy Settings")
dirBarModeL     = input.string("Simple", title="Long Directional Bar Mode", options=["Simple", "Filtered", "Aggressive", "Inside", "Filtered & Aggressive", "Filtered & Aggressive & Inside", "Without"], group="Strategy Settings")
dirBarModeS     = input.string("Inside", title="Short Directional Bar Mode", options=["Simple", "Filtered", "Aggressive", "Inside", "Filtered & Aggressive", "Filtered & Aggressive & Inside", "Without"], group="Strategy Settings")
useBreakout  = input.bool(true, "Use Breakout Filter", group="Strategy Settings")
useSLTP = input.bool(false, "Use Stop Loss & Take Profit", group="Strategy Settings")
atrSLMult = input.float(1, "ATR SL Multiplier", step = 0.05, group="Strategy Settings")
atrTPMult = input.float(1.75, "ATR TP Multiplier", step = 0.05, group="Strategy Settings")


// === Input: MA Function Selector === //
// — T3 Moving Average Function —
// src    = input source (e.g. rsi1, close, etc.)
// length = smoothing length (period)
// a      = T3 alpha (commonly between 0.7 and 0.9)
t3(src, length, a) =>
    e1 = ta.ema(src, length)
    e2 = ta.ema(e1, length)
    e3 = ta.ema(e2, length)
    e4 = ta.ema(e3, length)
    e5 = ta.ema(e4, length)
    e6 = ta.ema(e5, length)
    c1 = -a * a * a
    c2 = 3 * a * a + 3 * a * a * a
    c3 = -6 * a * a - 3 * a - 3 * a * a * a
    c4 = 1 + 3 * a + a * a * a + 3 * a * a
    c1 * e6 + c2 * e5 + c3 * e4 + c4 * e3

// == Jurik MA == //
jma(float src, int length, float power, float phase) => 
    phaseRatio = phase < -100 ? 0.5 : phase > 100 ? 2.5 : phase / 100 + 1.5
    beta = 0.45 * (length - 1) / (0.45 * (length - 1) + 2)
    alpha = math.pow(beta, power)
    JMA = 0.0
    e0 = 0.0
    e0 := (1 - alpha) * src + alpha * nz(e0[1])
    e1 = 0.0
    e1 := (src - e0) * (1 - beta) + beta * nz(e1[1])
    e2 = 0.0
    e2 := (e0 + phaseRatio * e1 - nz(JMA[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1])
    JMA := e2 + nz(JMA[1])

//===== 2 Pole Super Smoother Filter =====//
superSmoother(float Series, float Period) =>
    var float ALPHA =  math.pi * math.sqrt(2.0) / Period
    var float BETA  =  math.exp(-ALPHA )
    var float COEF2 = -math.pow(BETA, 2)
    var float COEF1 =  math.cos( ALPHA ) * 2.0 * BETA
    var float COEF0 =  1.0 - COEF1 - COEF2
    float sma2   = math.avg(Series, nz(Series[1], Series))
    float smooth = na, smooth := COEF0 *      sma2      +
                                 COEF1 *  nz(smooth[1]) +
                                 COEF2 *  nz(smooth[2])

// === MA Selector === //
ma(source, length, type) =>
    type == "SMA"       ? ta.sma(source, length) :
     type == "EMA"       ? ta.ema(source, length) :
     type == "SMMA (RMA)"? ta.rma(source, length) :
     type == "WMA"       ? ta.wma(source, length) :
     type == "VWMA"      ? ta.vwma(source, length) :
     type == "HMA"       ? ta.hma(source, length) : 
     type == "ALMA"      ? ta.alma(source, length, 0.85, 6) :
     type == "LSMA"      ? ta.linreg(source, length, 0) :
     type == "Optimal MA"? math.avg(ta.alma(source, length, 0.85, 6), ta.rma(source, length), ta.sma(source, length)) :
     type == "JMA"       ? jma(source, length, 2, 50) :        
     type == "Super Smoother" ? superSmoother(source, length) :
     type == "T3"        ? t3(source, length, 0.7) :
                          na

// === Input Parameters === //
rvolRLength       = input.int(112, title="Relative Volume %R Length", minval=1, group="Relative Volume", tooltip="%R used for scaling from 0 to 100, I prefer 73 or 112.")
rvolmaTypeInput   = input.string("Optimal MA" , "Type", options = ["None", "SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA", "HMA", "ALMA", "LSMA", "Optimal MA", "JMA", "Super Smoother", "T3"], group = "Relative Volume")
rvolFastLength    = input.int(7, title="Relative Volume Fast MA", minval=1, group="Relative Volume")
rvolSlowLength    = input.int(161, title="Relative Volume Slow MA", minval=1, group="Relative Volume")
exitBars          = input.int(18, title="Bars Until Exit", group="Strategy Settings", tooltip="Exit trade after N bars")
rvolThreshold = input.int(27, "Minimum Relative Volume %R Threshold", group="Relative Volume")

// === Williams %R for Volume === //
wpr(src, length) =>
    max_ = ta.highest(src, length)
    min_ = ta.lowest(src, length)
    (100 * (src - max_) / (max_ - min_)) * -1

// === Volume MAs === //
rvol      = wpr(volume, rvolRLength)
rvolFast  = ma(volume, rvolFastLength, rvolmaTypeInput)
rvolSlow  = ma(volume, rvolSlowLength, rvolmaTypeInput)

// === Price Action Filters === //
up            = close > open
upRange       = low > low[1] and close > high[1]
upRange_Aggr  = close > close[1] and close > open[1]
insideDayUp   = close < close[1] and close[1] < close[2] and close[2] < close[3] and close[3] < close[4] and close[4] < close[5] //and not (close > close[1])
down          = close < open
downRange     = high < high[1] and close < low[1]
downRange_Aggr= close < close[1] and close < open[1]
insideDayDown = close > close[1] and close[1] > close[2] and close[2] > close[3] and close[3] > close[4] and close[4] > close[5] //and not (close < close[1])
breakoutHigh = ta.highest(high, 5)
breakoutLow  = ta.lowest(low, 5)

// === Mode-Based Filter Logic === //
longBarOK =
     dirBarModeL == "Simple" ? up :
     dirBarModeL == "Filtered"  ? upRange :
     dirBarModeL == "Aggressive"? upRange_Aggr :
     dirBarModeL == "Inside"? insideDayUp : 
     dirBarModeL == "Filtered & Aggressive" ? upRange or upRange_Aggr :
     dirBarModeL == "Filtered & Aggressive & Inside" ? upRange or upRange_Aggr or insideDayUp :
     dirBarModeL == "Without"   ? true : false

shortBarOK =
     dirBarModeS == "Simple" ? down :
     dirBarModeS == "Filtered"  ? downRange :
     dirBarModeS == "Aggressive"? downRange_Aggr :
     dirBarModeS == "Inside"? insideDayDown :
     dirBarModeS == "Filtered & Aggressive"? downRange or downRange_Aggr or insideDayDown :
     dirBarModeS == "Filtered & Aggressive & Inside"? upRange_Aggr or insideDayDown :
     dirBarModeS == "Without"   ? true : false

// === Entry & Exit Logic === //
longCondition  = volume > rvolFast and rvolFast > rvolSlow and longBarOK  and rvol > rvolThreshold and (not useBreakout or close < breakoutHigh)
shortCondition = volume < rvolFast and rvolFast < rvolSlow and shortBarOK and rvol < (100 - rvolThreshold) and (not useBreakout or close > breakoutLow)

exitLongCondition  = strategy.opentrades > 0 and strategy.opentrades.entry_bar_index(0) + exitBars <= bar_index and strategy.opentrades.entry_id(0) == "Long"
exitShortCondition = strategy.opentrades > 0 and strategy.opentrades.entry_bar_index(0) + exitBars <= bar_index and strategy.opentrades.entry_id(0) == "Short"

atr = ta.atr(math.round(math.avg(rvolFastLength, rvolSlowLength)))
longSL = useSLTP ? close - atrSLMult * atr : na
longTP = useSLTP ? close + atrTPMult * atr : na
shortSL = useSLTP ? close + atrSLMult * atr : na
shortTP = useSLTP ? close - atrTPMult * atr : na

// === Strategy Execution === //
if (tradeDirection == "Long Only" or tradeDirection == "Both")
    if (longCondition)
        strategy.entry("Long", strategy.long, stop=longSL, limit=longTP)

if (tradeDirection == "Short Only" or tradeDirection == "Both")
    if (shortCondition)
        strategy.entry("Short", strategy.short, stop=shortSL, limit=shortTP)

if (exitLongCondition)
    strategy.close("Long")

if (exitShortCondition)
    strategy.close("Short")

// === Plotting === //
plot(rvol, title="Relative Volume %R", color=color.orange, style = plot.style_columns, format = format.price)
plot(rvolFast, title="Fast Volume MA", color=color.green, format = format.volume)
plot(rvolSlow, title="Slow Volume MA", color=color.red, format = format.volume)