지지 및 저항 돌파 전략과 추세-ADX 필터 양적 거래 시스템

ADX SMA 支撑阻力位 趋势滤波器 突破策略 枢轴点 动向指标 风险管理
생성 날짜: 2025-05-30 11:58:27 마지막으로 수정됨: 2025-05-30 11:58:27
복사: 0 클릭수: 367
avatar of ianzeng123 ianzeng123
2
집중하다
319
수행원

지지 및 저항 돌파 전략과 추세-ADX 필터 양적 거래 시스템 지지 및 저항 돌파 전략과 추세-ADX 필터 양적 거래 시스템

개요

지지부진 전략과 트렌드-ADX 필터 수량 거래 시스템은 기술 분석의 지지부진 지점 식별, 트렌드 확인 및 시장 강도 검증을 결합한 통합 거래 전략이다. 이 전략은 시장 가격의 핵심 가격 수준에 대한 돌파 행동을 기반으로 하고, 이동 평균과 평균 방향 지수 ((ADX) 를 필러로 사용하여 거래 신호의 신뢰성을 높인다. 시스템은 1 시간 시간 프레임을 사용하여 중심축 고점과 낮은 점을 식별하여 역동적인 지지부진 지역을 구성하고, 가격 돌파구가 발생하면 거래 신호를 발산하며, 동시에 위험을 제어하기 위해 고정된 비율의 중지 손실 장치를 설정한다.

전략 원칙

이 전략의 핵심 원칙은 가격의 중요한 지지 저항점에서의 돌파 행동을 기반으로, 트렌드 방향과 시장 강도 필터링과 결합하여 완전한 거래 시스템을 형성한다. 구체적인 구현 원칙은 다음과 같다:

  1. 지원 저항 위치 인식: 시스템은 Pivot Points를 이용하여 중요한 가격 수준을 식별한다.ta.pivothigh그리고ta.pivotlow함수, 5주기를 기본 파라미터로 삼아 축의 고점과 저점을 계산하고, 이 점들을 잠재적인 저항점과 지지점으로 꼽는다.

  2. 역동적인 지역 관리시스템 사용 배열 구조:supportLevels그리고resistanceLevels저장된 저항을 지원하고, 사용자 정의 함수를 통해f_add_level이러한 가격 레벨을 지능적으로 관리한다. 이 함수는 새로 추가된 레벨이 기존 레벨과 충분한 거리를 확보하도록 하고, 지역이 너무 붐비는 것을 방지하며, 최대 5개의 최신 레벨을 유지하도록 제한한다.

  3. 트렌드 확인 필터: 전략은 50주기 간단한 이동 평균 ((SMA) 을 트렌드 방향 지표로 사용한다. 가격이 평균선 위에 있을 때만 더 많은 것을 고려하고, 평균선 아래에 있을 때만 공백을 고려하여 전체 시장 추세에 부응한다.

  4. 시장 강도 검증: 사용자 정의 ADX ((평균 방향 지수) 함수를 통해 시장 강도를 평가한다. ADX 값은 설정된 스레드값 (예기 25) 보다 높아야 하며, 시장이 충분히 강할 때만 거래에 진입하는 것을 보장하며, 약한 시장 환경에서 가짜 돌파구를 피한다.

  5. 입력 신호 생성:

    • 다단 신호: 가격이 아래에서 지지를 뚫을 때 (최저가 지지를 넘어섰지만 종결 가격이 지지를 넘어섰을 때) 그리고 가격이 50주기 평균선 위에 있고 ADX가 부진보다 높을 때 발동된다.
    • 허공 신호: 가격이 위쪽에서 저항 지점을 돌파했을 때 (최고 지점은 저항 지점보다 높지만 폐쇄 가격은 저항 지점보다 낮습니다) 50주기 평균선 아래의 가격과 ADX 값이 하락 값보다 높을 때 촉발됩니다.
  6. 위험 관리 메커니즘이 전략은 고정된 비율의 스톱 스톱 스로드 설정을 사용하며, 멀티 헤더는 15%의 스톱 스로드 및 10%의 스로드를 기본으로 설정하고, 빈 헤더는 10%의 스톱 스로드 및 10%의 스로드를 기본으로 설정합니다. 가격이 이러한 수준에 도달하면 시스템이 자동으로 포지션을 청산하고 거래 상태를 재설정합니다.

전략적 이점

코드의 심층적인 분석을 바탕으로, 이 전략은 다음과 같은 중요한 장점을 가지고 있다:

  1. 다중 인증 메커니즘: 지지부진, 트렌드 방향 및 ADX 강도를 결합하여 트리플 확인을 통해 가짜 브레이크의 위험을 효과적으로 감소시킵니다. 단일 지표에 비해 다중 확인 메커니즘은 거래 신호의 신뢰성을 향상시킵니다.

  2. 역동적인 지지 저항 영역시스템 동적으로 지원 저항 지점을 식별하고 관리하여 다양한 시장 환경에 적응할 수 있습니다. 최대 5 개의 최신 지원 저항 지점을 유지하여 전략이 가장 관련 된 가격 수준에 초점을 맞추도록합니다.

  3. 지능형 지역 집합: 최대 영역 너비 비율 변수 ((maxZoneWidthPct) 를 통해 너무 가까운 지지 저항 지점을 재계산하는 것을 피하고, 불필요한 신호를 줄인다.

  4. 사용자 정의 ADX 계산전략: 사용자 정의 ADX 함수를 사용하여 실제 파장, 방향 이동 및 부드러운 처리를 직접 계산하여 지표 계산의 정확성과 유연성을 보장합니다.

  5. 유연한 변수 구성: 전략은 여러 조정 가능한 매개 변수를 제공 합니다. 이 중 중심축 길이, 회귀 주기, 최대 영역 폭, 스톱 스톱 손실 비율 및 ADX 마이너스 등이 있습니다. 사용자는 다른 시장 조건과 거래 선호도에 따라 최적화 할 수 있습니다.

  6. 위험관리가 명확합니다.: 사전 설정된 스톱 스톱 손실 비율을 통해 각 거래에 대한 명확한 위험 관리 프레임 워크를 제공하여 거래 단위의 과도한 손실을 방지하고 합리적인 수익을 확보합니다.

  7. 직관적인 시각화전략: 차트 상에서 지지부진과 거래 신호를 표시하고, 컬러 코딩 (지원부진 녹색, 저항부진 빨간색) 과 표기 (LONG, SHORT, EXIT) 를 통해 직관적인 시각적 피드백을 제공하여 분석 및 실시간 모니터링을 가능하게 합니다.

전략적 위험

이 전략은 합리적으로 설계되었지만 다음과 같은 잠재적인 위험과 한계가 있습니다.

  1. 높은 변동성 시장에서 가짜 돌파구: 높은 변동성 시장 환경에서, 가격이 자주 지지부진 저항점을 뚫고 다시 원래의 영역으로 돌아갈 수 있으며, 이로 인해 가짜 돌파 신호가 증가한다. 해결 방법: 확인 주기를 늘리는 것을 고려할 수 있으며, 돌파 이후 가격이 일정 시간 동안 유지되거나 특정 형태를 형성하기 전에 신호를 확인한다.

  2. 역사적인 지지부진에 지나치게 의존하는 것전략은 역사적으로 형성된 지지부진을 기반으로 하며, 시장 구조에 근본적인 변화가 있을 때 (매저 뉴스 사건과 같은) 이 역사적 수준은 무효가 될 수 있다. 해결 방법: 동적 조정 메커니즘을 추가하여 시장의 변동에 따라 지지부진을 자동으로 조정하는 유효 기간을 고려할 수 있다.

  3. 고정 비율 스탠프 손실의 제한: 고정 비율의 스톱 로즈는 모든 시장 환경에 적합하지 않을 수 있으며, 낮은 변동률의 시장에서 너무 커지고, 높은 변동률의 시장에서 너무 작을 수 있습니다. 해결 방법: ATR (진짜 파동폭) 에 따라 스톱 로즈 수준을 동적으로 조정하는 것이 고려 될 수 있습니다.

  4. 추세 반전 위험: 50주기 SMA를 트렌드 지표로 사용하는 것은 트렌드 반전의 초기 반응에 지연되어 트렌드가 끝나갈 때 여전히 순조로운 입구를 초래할 수 있다. 해결 방법: 더 민감한 단기 트렌드 지표 또는 동력 지표를 보조 판단으로 추가하는 것을 고려할 수 있다.

  5. 컴퓨터 집약적 전략전략은 여러 배열과 지표를 실시간으로 계산하고 유지해야 하며, 고주파 거래 또는 자원이 제한된 환경에서 성능 과제를 겪을 수 있다. 해결 방법: 알고리즘의 효율성을 최적화, 불필요한 계산을 줄이거나, 업데이트 빈도를 낮추는 것을 고려한다.

  6. 매개변수 민감도: 전략 성능은 변수 설정에 민감하다 (축축 길이, ADX 값과 같은), 변수 선택이 잘못되면 과도한 거래 또는 기회를 놓치게 될 수 있다. 해결 방법: 다양한 시장 조건에서 변수 성능을 재검토하여 변수 최적화 프레임 워크를 구축한다.

전략 최적화 방향

전략 코드의 심층적인 분석을 바탕으로 다음과 같은 잠재적인 최적화 방향이 있습니다.

  1. 적응 변수 메커니즘: 시장의 변동에 따라 중요한 매개 변수를 자동으로 조정하는 메커니즘을 도입한다. 예를 들어, 높은 변동 동안 ADX 경계를 증가 시키거나 저항 영역의 폭을 지원하고 낮은 변동 동안 이러한 매개 변수를 감소시켜 전략이 다른 시장 환경에 더 잘 적응하도록 한다. 이것은 부적절한 시장 조건에서 잘못된 거래를 줄일 수 있다.

  2. 다중 시간 프레임 분석: 더 높은 시간 프레임의 지원 저항 수준을 확인한다. 일선 또는 둘레 차트의 지원 저항 수준이 현재 1 시간 차트의 수준과 일치하는지 확인함으로써 더 강한, 다중 시간 프레임 인정을 받는 중요한 가격 영역을 식별할 수 있으며, 신호 품질을 향상시킬 수 있다.

  3. 거래량 확인: 거래량 분석과 함께 브레이크의 유효성을 검증한다. 실제로 유효한 브레이크는 일반적으로 거래량이 크게 증가하는 것을 동반하며, 거래량 필터 조건을 추가함으로써 낮은 거래량으로 인한 가짜 브레이크의 위험을 줄일 수 있다.

  4. 동적 중지 중지 손실: 시장의 변동률 (예: ATR) 에 따라 고정된 비율이 아닌 동적으로 스톱 로드 수준을 설정합니다. 이것은 위험 관리를 더 유연하게 만들어 현재 시장 조건에 따라 보호 수준을 자동으로 조정할 수 있으며, 변동성이 높은 시장에서 더 느슨한 스톱 로드를 설정하고, 변동성이 낮은 시장에서 더 긴밀한 스톱 로드를 설정합니다.

  5. 일부 수익 잠금 메커니즘: 일정 수준의 수익을 달성 한 후 손실을 비용 가격으로 이동하거나 수익의 일부를 잠금 할 수 있는 분기 수익 메커니즘을 도입하십시오. 이 방법은 높은 수익 잠재력을 유지하면서 철회 위험을 줄일 수 있습니다.

  6. 감정 지표 통합: 추가적인 필터링 조건으로 시장 감정 지표 (VIX 또는 상대적으로 강한 지표와 같은) 를 통합하는 것을 고려하십시오. 시장 감정은 종종 돌파구의 지속 가능성에 영향을 미치며, 감정 분석 차원을 추가하여 전략이 시장 상태에 대한 이해를 향상시킬 수 있습니다.

  7. 지원 저항 강도 등급지원 저항점 강도를 평가하는 메커니즘을 도입하여, 역사 테스트 횟수, 형성 시간 길이 등의 요인에 따라 각 레벨에 강도 평가를 한다. 이렇게 하면 더 강하고 효과적인 반응을 일으킬 가능성이 있는 가격 레벨에 우선주의를 줄 수 있다.

  8. 기계 학습 최적화: 기계 학습 방법을 사용하여 매개 변수 선택 및 신호 생성을 최적화하는 것을 고려하십시오. 기계 학습 알고리즘은 역사적 데이터에서 성공 및 실패한 거래 패턴을 분석하여 가장 효과적인 매개 변수 조합과 시장 조건을 식별하는 데 도움이 될 수 있습니다.

요약하다

지지부진 전략과 트렌드-ADX 필터 양적 거래 시스템은 기술 분석의 여러 핵심 요소를 결합한 잘 설계된 통합 거래 시스템입니다. 이 전략은 지지부진 지점을 동적으로 식별하고 모니터링하여 트렌드 방향과 시장 강도 필터링과 결합하여 비교적 신뢰할 수있는 거래 신호 생성 장치를 만듭니다.

전략의 핵심 장점은 여러 확인 메커니즘과 완벽한 위험 관리 프레임 워크로, 가짜 돌파의 위험을 효과적으로 낮추고 단일 거래의 잠재적 인 손실을 제한합니다. 동시에, 전략은 풍부한 변수 구성 옵션을 제공하여 거래자가 개인 위험 선호도와 시장 환경에 따라 유연하게 조정할 수 있습니다.

그러나, 이 전략은 또한, 높은 변동성 시장에서의 가짜 돌파의 위험, 고정된 정지 손실의 제한, 그리고 변수 민감성 등과 같은 몇 가지 도전에 직면하고 있다. 적응된 변수 메커니즘, 다중 시간 프레임 분석, 거래량 확인 및 동적 위험 관리와 같은 최적화 조치를 도입함으로써, 전략 성능이 더욱 향상될 전망이다.

전반적으로, 이것은 논리적으로 명확하고 합리적으로 설계된 양적 거래 전략이며, 기술 분석과 시장 구조에 대한 어느 정도의 이해를 가진 거래자가 사용할 수 있습니다. 이 전략은 지속적인 최적화와 시장 변화에 적응함으로써 다양한 시장 환경에서 안정적인 성능을 유지할 수 있습니다.

전략 소스 코드
/*backtest
start: 2024-05-30 00:00:00
end: 2025-05-29 00:00:00
period: 3d
basePeriod: 3d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=6
strategy("S/R Breakout Strategy (1H) with Trend and ADX Filter", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// ─────────────────────────────────────────────────────────────
// INPUTS
// ─────────────────────────────────────────────────────────────
pivotLen        = input.int(5, title="Pivot Length")
lookbackBars    = input.int(300, title="Lookback Bars")
maxZoneWidthPct = input.float(2.0, title="Max Zone Width %")
tpLong          = input.float(0.15, title="Take Profit % (Long)")
slLong          = input.float(0.10, title="Stop Loss % (Long)")
tpShort         = input.float(0.10, title="Take Profit % (Short)")
slShort         = input.float(0.10, title="Stop Loss % (Short)")
allowLong       = input.bool(true, title="Allow Long Trades")
allowShort      = input.bool(true, title="Allow Short Trades")

// ADX settings
adxThreshold    = input.float(25.0, title="ADX Threshold")
adxLen          = input.int(14, title="ADX Length")

// Trend filter: 50-period moving average
ma50 = ta.sma(close, 50)

// ─────────────────────────────────────────────────────────────
// CUSTOM ADX FUNCTION
// ─────────────────────────────────────────────────────────────
// This function calculates ADX using the common method based on true range,
// directional movement and smoothing it with the RMA.
f_adx(len) =>
    // true range for the current bar
    tr = ta.tr
    // Calculate upward and downward moves
    upMove   = high - high[1]
    downMove = low[1] - low
    // Determine directional movements
    plusDM  = (upMove > downMove and upMove > 0) ? upMove : 0.0
    minusDM = (downMove > upMove and downMove > 0) ? downMove : 0.0
    // Smooth the values using RMA (running moving average)
    smPlusDM  = ta.rma(plusDM, len)
    smMinusDM = ta.rma(minusDM, len)
    smTR      = ta.rma(tr, len)
    // Calculate the directional indicators, avoid division by zero
    plusDI  = (smTR != 0) ? 100 * smPlusDM / smTR : 0.0
    minusDI = (smTR != 0) ? 100 * smMinusDM / smTR : 0.0
    diSum   = plusDI + minusDI
    dx      = (diSum != 0) ? 100 * math.abs(plusDI - minusDI) / diSum : 0.0
    // Smooth the DX to get ADX
    ta.rma(dx, len)

// Compute ADX value using the custom function
adxValue = f_adx(adxLen)

// ─────────────────────────────────────────────────────────────
// PIVOT DETECTION & SUPPORT/RESISTANCE LEVELS
// ─────────────────────────────────────────────────────────────
pivotHigh = ta.pivothigh(high, pivotLen, pivotLen)
pivotLow  = ta.pivotlow(low, pivotLen, pivotLen)

// Declare arrays for support and resistance levels
var float[] supportLevels    = array.new_float()
var float[] resistanceLevels = array.new_float()

// Function to add a level into the provided array if it meets the criteria.
// Always returns a float (0.0) for consistency.
f_add_level(arr, newLevel) =>
    if array.size(arr) == 0
        array.push(arr, newLevel)
    else
        shouldAdd = true
        for i = 0 to (array.size(arr) - 1)
            existing = array.get(arr, i)
            if math.abs(existing - newLevel) / newLevel * 100 <= maxZoneWidthPct
                shouldAdd := false
        if shouldAdd
            array.push(arr, newLevel)
            if array.size(arr) > 5
                array.shift(arr)
    0.0

// Update support and resistance arrays once sufficient bars have formed
if bar_index > pivotLen * 2
    if not na(pivotLow)
        f_add_level(supportLevels, pivotLow)
    if not na(pivotHigh)
        f_add_level(resistanceLevels, pivotHigh)

// ─────────────────────────────────────────────────────────────
// TRADE MANAGEMENT VARIABLES
// ─────────────────────────────────────────────────────────────
var bool   inTrade    = false
var bool   isLong     = false
var float  entryPrice = na

// Signal flags
longSignal  = false
shortSignal = false

// Detect long signal: price crosses above support level
if array.size(supportLevels) > 0
    for i = 0 to (array.size(supportLevels) - 1)
        lvl = array.get(supportLevels, i)
        if low < lvl and close > lvl
            longSignal := true

// Detect short signal: price crosses below resistance level
if array.size(resistanceLevels) > 0
    for i = 0 to (array.size(resistanceLevels) - 1)
        lvl = array.get(resistanceLevels, i)
        if high > lvl and close < lvl
            shortSignal := true

// ─────────────────────────────────────────────────────────────
// ENTRY CONDITIONS & EXECUTION
// ─────────────────────────────────────────────────────────────
if not inTrade
    // Long entry: require long signal, price above 50MA, and ADX above threshold
    if allowLong and longSignal and close > ma50 and adxValue > adxThreshold
        strategy.entry("Long", strategy.long)
        label.new(x=bar_index, y=low, text="LONG", xloc=xloc.bar_index, style=label.style_label_up, color=color.green, textcolor=color.white)
        entryPrice := close
        isLong     := true
        inTrade    := true
    // Short entry: require short signal, price below 50MA, and ADX above threshold
    else if allowShort and shortSignal and close < ma50 and adxValue > adxThreshold
        strategy.entry("Short", strategy.short)
        label.new(x=bar_index, y=high, text="SHORT", xloc=xloc.bar_index, style=label.style_label_down, color=color.red, textcolor=color.white)
        entryPrice := close
        isLong     := false
        inTrade    := true

// ─────────────────────────────────────────────────────────────
// EXIT CONDITIONS
// ─────────────────────────────────────────────────────────────
if inTrade
    ret = isLong ? (close - entryPrice) / entryPrice : (entryPrice - close) / entryPrice
    tp  = isLong ? tpLong : tpShort
    sl  = isLong ? slLong : slShort
    if ret >= tp or ret <= -sl
        strategy.close_all()
        label.new(x=bar_index, y=close, text="EXIT", xloc=xloc.bar_index, style=label.style_label_left, color=color.orange, textcolor=color.black)
        inTrade    := false
        entryPrice := na

// ─────────────────────────────────────────────────────────────
// ALERT CONDITIONS
// ─────────────────────────────────────────────────────────────
alertcondition(longSignal and allowLong, title="Long Breakout", message="🚀 Long breakout on {{ticker}} at {{close}}")
alertcondition(shortSignal and allowShort, title="Short Breakout", message="🔻 Short breakout on {{ticker}} at {{close}}")