다중 지표 돌파 및 반전 거래 전략: 시작 가격 범위 최적화와 결합된 이중 진입 시스템

EMA SMA RSI ATR VWAP ORB
생성 날짜: 2025-04-01 16:00:37 마지막으로 수정됨: 2025-04-01 16:00:37
복사: 0 클릭수: 382
avatar of ianzeng123 ianzeng123
2
집중하다
319
수행원

다중 지표 돌파 및 반전 거래 전략: 시작 가격 범위 최적화와 결합된 이중 진입 시스템 다중 지표 돌파 및 반전 거래 전략: 시작 가격 범위 최적화와 결합된 이중 진입 시스템

개요

다중 지표 돌파 및 반전 거래 전략은 기술 분석 지표와 가격 행동을 결합한 양적 거래 방법이며, 시장의 두 가지 주요 거래 기회를 잡기 위해 고안되었습니다. 가격 반전 및 트렌드 돌파. 이 전략은 이동 평균, 상대적으로 약한 지수 (RSI), 평균 실제 범위 (ATR) 및 거래량 중화 평균 가격 (VWAP) 과 같은 여러 가지 기술 지표를 교묘하게 통합하고 있으며, 진입 신호의 신뢰성을 높이기 위해 오프 리치 돌파 (ORB) 메커니즘을 도입합니다. 이 전략은 두 개의 목표 스톱을 설계하고 있으며, 자동으로 스톱 손실을 평형 손실점으로 조정하는 위험 관리 장치가 있습니다.

전략 원칙

이 전략의 핵심 원칙은 3가지 종류의 잠재적으로 유리한 거래 기회를 여러 지표에 의해 필터링하고 확인하는 것입니다.

  1. 반전 거래 신호

    • 다중 리버스: 가격이 50단계 간단한 이동 평균 ((SMA50) 을 통과하고 RSI가 초상 판매 시한부 (default 30) 보다 낮으며 가격이 VWAP보다 낮으며 전체적인 추세가 상승하면 (가격이 SMA200보다 높을 때)
    • 공백 반전: 가격이 SMA 50을 넘어서 RSI가 초과 구매 경계를 넘어섰을 때 (기본 70), 그리고 가격이 VWAP보다 높을 때, 전체적인 추세는 하향으로 (가격이 SMA 200보다 낮다) 가 촉발됩니다.
  2. 트렌드 브레이크 신호

    • 다단계 돌파구: 9기 지수 이동 평균 ((EMA9)) 에 20기 지수 이동 평균 ((EMA20) 을 뚫고, 가격이 VWAP보다 높고, 전체적인 추세가 상승할 때 촉발된다.
    • 공중 돌파구: EMA9 아래 EMA20을 통과하고 VWAP보다 낮은 가격으로 전체 추세가 하향을 향할 때 촉발됩니다.
  3. 오브 리브 (ORB) 신호

    • 다중 헤드 ORB: 가격이 오픈 전 특정 수의 기둥을 (> 15 기둥을 기본으로) 뚫고 거래량이 오픈 간 평균 거래량의 기본 배수를 (> 1.5 배 이상 기본으로) 초과했을 때 촉발됩니다.
    • 공백 ORB: 가격이 오픈 전에 형성 된 최저 가격으로 떨어지고 거래량이 하락 조건을 충족하면 촉발됩니다.

전략은 ATR 지표를 사용하여 동적 스톱로스 위치를 계산하고, 특정 기간의 최저 가격/최고 가격과 ATR 값의 배수를 더하고 감소시켜 설정합니다. 진입 후, 전략은 두 가지 스톱 포지션을 설정합니다.

  • 첫 번째 목표 (TP1): 리스크의 0.5배 (기본), 25%의 평점 포지션
  • 목표 2 (TP2): 위험의 1.1배 (설정), 잔여 75%의 청산 포지션

첫 번째 정지 목표가 달성되면, 전략은 자동으로 정지를 입시 가격으로 조정하고, 이미 얻은 이익을 효과적으로 보호한다.

전략적 이점

  1. 다양한 입구 신호이 전략은 반전, 파격, 그리고 개장 간격의 세 가지 다른 입력 신호를 통합하여 여러 시장 환경에 적응할 수 있으며, 거래 기회를 효과적으로 증가시키면서도 높은 신호 품질을 유지할 수 있습니다.

  2. 좋은 위험 관리이 전략은 단계적 정지 메커니즘을 적용하여 수익의 일부를 확보하면서 잠재적으로 더 큰 수익을 유지할 수 있습니다. 첫 번째 정지 목표가 달성되면 자동으로 정지 손실이 이익 손실의 균형 지점으로 조정되어 “이익을 뛸 수 있도록” 동시에 자본을 보호합니다.

  3. 동적 스톱 손실 계산: ATR 지표를 사용하여 스톱 포지션을 계산하여 스톱 레벨이 시장의 변동적 동력에 따라 조정될 수 있도록, 현재의 시장 상황을 더 정확하게 반영하고, 너무 엄격하거나 너무 느슨한 스톱 설정을 피한다.

  4. 거래량 확인: 특히 ORB 신호에 거래량 확인 메커니즘을 도입하여, 거래량이 개장 기간 동안의 평균 거래량보다 특정 배수를 초과해야 한다고 요구하여, 낮은 품질의 돌파구를 효과적으로 필터링한다.

  5. 트렌드 필터: 200기 간단한 이동 평균 ((SMA200) 을 통해 장기적인 트렌드 방향을 판단하여 거래 방향이 주요 트렌드와 일치하도록 하여 거래 성공률을 높인다.

  6. 자금 관리 통합전략: 내장된 자금 관리 메커니즘, 각 거래에 사용되는 자금 비율을 제한하는 것 (본금의 기본 50%), 자금의 다양화 배치를 보장하고 단일 거래의 위험 을 낮추는 것.

전략적 위험

  1. 지표 지연전략은 주로 이동 평균과 같은 지연된 지표에 의존하며, 이는 빠르게 변화하는 시장에서 진입 시간을 지연시키거나, 좋은 진입 지점을 놓치거나, 불필요한 손실을 초래할 수 있다.

해결 방법: 가격 행동 패턴 식별과 같은 미래 지향적 지표를 추가하거나, 시장 변화에 대한 민감성을 높이기 위해 더 긴 주기 이동 평균의 매개 변수를 줄이는 것을 고려하십시오.

  1. 매개변수 민감도많은 조정 가능한 변수들 (EMA 길이, RSI 미지수, ATR 계수 등) 은 전략 최적화를 복잡하게 만들며, 역사적 데이터에 과도하게 맞추어 미래 시장에서 좋지 않은 성과를 낼 수 있습니다.

해결 방법: 적절한 변수 최적화 방법을 사용하십시오. 예를 들어, 전진 검증, 몬테카로 시뮬레이션, 과잉 최적화를 피하십시오. 또는 고정된 변수를 사용하여 더 안정적인 규칙 설계에 집중하십시오.

  1. 다중 신호 충돌: 특정 시장 환경에서, 서로 다른 입시 신호는 서로 상반된 거래 제안을 만들어서 전략의 불안정한 성과를 초래할 수 있다.

해결책: 더 엄격한 신호 우선 순위 시스템을 구축하거나, 거래가 높은 확률에서만 실행되도록 추가 확인 메커니즘을 도입하십시오.

  1. 공중에서 뛰어내리는 위험을 막는 것: 큰 변동이나 낮은 유동성이있는 시장에서, 가격은 스톱로스를 뛰어넘을 수 있으며, 예상보다 실제 손실을 초래할 수 있습니다.

해결 방법: 옵션 헤지 전략을 사용하거나, 높은 변동성 시장 조건에서 스톱 라인지를 늘리거나, 심지어 일시적으로 포지션 크기를 줄이는 것을 고려하십시오.

  1. 체계적 위험전략: 동시에 여러 관련 거래를 실행하여 시장의 급격한 변동이 있을 때 시스템적 위험에 직면하여 여러 거래가 동시에 손실을 초래할 수 있습니다.

해결 방법: 전체적인 위험 통제를 실시하고, 전체적인 포지션 규모를 제한하거나, 다른 자산 클래스 사이에 분산 거래하여 연관성 위험을 줄입니다.

전략 최적화 방향

  1. 기계학습 모델을 도입합니다.: 기계 학습 알고리즘을 지표 무게 최적화 또는 시장 환경 분류에 적용하여 다양한 시장 조건에서 각 지표의 상대적 중요성을 자동으로 조정하여 전략의 적응성을 향상시킵니다.

최적화 이유: 기존의 고정 가중치 지표 조합은 시장의 다른 단계에 적응하기가 어렵고, 기계 학습은 역사적 데이터에서 최적의 지표 조합 패턴을 자동으로 학습할 수 있다.

  1. 시장 감정 지표 통합: 변동률 지수 ((VIX) 또는 고주파 시장 감정 지표를 추가하여 전략이 시장 환경을 더 잘 인식하고, 진입 조건과 위험 매개 변수를 조정하는 데 도움이됩니다.

최적화 이유: 시장의 감정은 단기 가격 움직임에 중요한 영향을 미치며, 이러한 지표를 통합하면 시장의 전환점을 사전에 포착하고, 진입 및 출구 시기를 최적화 할 수 있다.

  1. 동적으로 조정된 정지 비율• 역대 변동성이나 지지부진 수준에 따라 자동으로 정지 목표를 조정하여 전략이 다양한 변동 환경에서 합리적인 수익을 얻을 수 있도록합니다.

최적화 이유: 고정된 리스크 수익률은 다른 시장 환경에서 충분히 유연하지 않을 수 있으며, 동적 조정은 높은 변동성 시장에서 더 먼 목표를 설정하고, 낮은 변동성 시장에서 더 보수적인 목표를 설정할 수 있다.

  1. 시간 필터를 도입시장시간에 기반한 필터링 메커니즘을 적용하여 시장 개시 후 첫 몇 분이나 유동성이 낮은 12시 시간 같은 낮은 변동성이나 불리한 시간에 거래하는 것을 피하십시오.

최적화 이유: 시장 활동은 하루의 다른 시간대에 뚜렷한 차이를 나타냅니다. 시간 필터는 전략이 가장 유리한 거래 시간에 집중하도록 도와줍니다.

  1. 포지션 규모를 최적화: 고정자금 비율에서 변동성에 기반한 포지션 규모 계산으로 전환하여, 높은 변동성이있는 기간 동안 자동으로 포지션을 줄이고 낮은 변동성이있는 기간 동안 포지션을 적절하게 증가시킵니다.

최적화 이유: 위험은 시장의 변동성과 직결되어 있으며, 동적 포지션 관리는 더 일관된 위험 수준을 유지하여 장기적인 위험 조정 후 수익을 개선할 수 있다.

요약하다

다중 지표 돌파 및 반전 거래 전략은 여러 가지 기술적 분석 방법을 결합한 통합적인 양자 거래 시스템으로, 반전, 트렌드 돌파 및 오픈 영역 돌파 신호를 통합하여, 완벽한 위험 관리 및 자금 관리 메커니즘과 결합하여, 다양한 시장 환경의 거래 기회를 잡기 위해 고안되었습니다. 이 전략의 핵심 장점은 신호 다원화, 위험 관리의 개선 및 파라미터의 사용자 정의성이 강하며, 특히 단기 거래에 적합합니다. 동시에, 전략은 지표 지연, 파라미터 민감성 및 신호 충돌 잠재적인 위험과 같은 위험에 직면하고 있으며, 기계 학습, 시장 감정 분석, 동적 정지 설정 등의 방향에 대한 추가 최적화가 필요합니다.

전략 소스 코드
/*backtest
start: 2025-01-01 00:00:00
end: 2025-03-31 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("Reversal & Breakout Strategy with ORB", overlay=true, pyramiding=2, initial_capital=50000)

// --- Inputs ---
ema9Length = input.int(9, "9 EMA Length", minval=1)
ema20Length = input.int(20, "20 EMA Length", minval=1)
sma50Length = input.int(50, "50 SMA Length", minval=1)
sma200Length = input.int(200, "200 SMA Length", minval=1)
rsiLength = input.int(14, "RSI Length", minval=1)
rsiOverbought = input.int(70, "RSI Overbought", minval=0, maxval=100)
rsiOversold = input.int(30, "RSI Oversold", minval=0, maxval=100)
atrLength = input.int(14, "ATR Length", minval=1)
stopMulti = input.float(0.5, "Stop Loss ATR Multiplier", minval=0.1, step=0.1)
stopLookback = input.int(7, "Stop Loss Lookback", minval=1)
rr1 = input.float(0.5, "Risk:Reward Target 1", minval=0.1, step=0.1)
rr2 = input.float(1.1, "Risk:Reward Target 2", minval=0.1, step=0.1)
target1Percent = input.float(25, "Profit % Target 1", minval=0, maxval=100)
orbBars = input.int(15, "Opening Range Bars", minval=1, tooltip="Number of bars to define the opening range (e.g., 15 bars = 30 min on 2-min chart)")
volThreshold = input.float(1.5, "Volume Threshold Multiplier", minval=1.0, step=0.1, tooltip="Volume must be this multiple of the opening range average")

// --- Indicators ---
// Moving Averages
ema9 = ta.ema(close, ema9Length)
ema20 = ta.ema(close, ema20Length)
sma50 = ta.sma(close, sma50Length)
sma200 = ta.sma(close, sma200Length)

// VWAP
vwapValue = ta.vwap(close)

// RSI
rsi = ta.rsi(close, rsiLength)

// ATR
atr = ta.atr(atrLength)

// --- Opening Range Breakout ---
var float openingRangeHigh = na
var float openingRangeLow = na
var float openingRangeAvgVol = na
if bar_index < orbBars
    openingRangeHigh := na
    openingRangeLow := na
    openingRangeAvgVol := na
else if bar_index == orbBars
    openingRangeHigh := ta.highest(high, orbBars)
    openingRangeLow := ta.lowest(low, orbBars)
    openingRangeAvgVol := ta.sma(volume, orbBars)

orbLong = not na(openingRangeHigh) and ta.crossover(close, openingRangeHigh) and volume > openingRangeAvgVol * volThreshold
orbShort = not na(openingRangeLow) and ta.crossunder(close, openingRangeLow) and volume > openingRangeAvgVol * volThreshold

// --- Trend Detection ---
trendUp = close > sma200
trendDown = close < sma200

// --- Reversal Conditions ---
reversalLong = ta.crossover(close, sma50) and rsi < rsiOversold and close < vwapValue and trendUp
reversalShort = ta.crossunder(close, sma50) and rsi > rsiOverbought and close > vwapValue and trendDown

// --- Range Breakout Conditions ---
breakoutLong = ta.crossover(ema9, ema20) and close > vwapValue and trendUp
breakoutShort = ta.crossunder(ema9, ema20) and close < vwapValue and trendDown

// Combine conditions
longCondition = (reversalLong or breakoutLong or orbLong)
shortCondition = (reversalShort or breakoutShort or orbShort)

// --- Calculate Position Size ---
equityPerPosition = 25000.0  // $50,000 / 2 positions
positionSizeLong = math.floor(equityPerPosition / close)
positionSizeShort = math.floor(equityPerPosition / close)

// --- Stop Loss Calculation ---
longStop = ta.lowest(low, stopLookback) - (atr * stopMulti)
shortStop = ta.highest(high, stopLookback) + (atr * stopMulti)

// --- Variables to Store Trade Levels ---
var float tradeStop = na
var float tradeTarget1 = na
var float tradeTarget2 = na
var float initialPositionSize = na
var bool breakEvenSet = false  // Track if stop has been moved to break-even
var float stopLevel = na       // Dedicated variable for stop loss in exits
var float target1Level = na    // Dedicated variable for first take profit
var float target2Level = na    // Dedicated variable for second take profit
var float qtyTotal = na        // Track total quantity

// --- Reset Levels Before New Trade ---
var bool newTrade = false
if longCondition or shortCondition
    newTrade := true
else
    newTrade := false

if strategy.position_size == 0 and newTrade
    tradeStop := na
    tradeTarget1 := na
    tradeTarget2 := na
    stopLevel := na
    target1Level := na
    target2Level := na
    initialPositionSize := na
    qtyTotal := na
    breakEvenSet := false

// --- Strategy Entries ---
if longCondition and strategy.position_size == 0
    strategy.entry("Long", strategy.long, qty=positionSizeLong * 2)
    tradeStop := longStop
    stopLevel := longStop
    stopDistance = close - tradeStop
    tradeTarget1 := close + (stopDistance * rr1)
    tradeTarget2 := close + (stopDistance * rr2)
    target1Level := tradeTarget1
    target2Level := tradeTarget2
    initialPositionSize := positionSizeLong * 2
    qtyTotal := positionSizeLong * 2
    breakEvenSet := false  // Reset break-even flag

if shortCondition and strategy.position_size == 0
    strategy.entry("Short", strategy.short, qty=positionSizeShort * 2)
    tradeStop := shortStop
    stopLevel := shortStop
    stopDistance = tradeStop - close
    tradeTarget1 := close - (stopDistance * rr1)
    tradeTarget2 := close - (stopDistance * rr2)
    target1Level := tradeTarget1
    target2Level := tradeTarget2
    initialPositionSize := positionSizeShort * 2
    qtyTotal := positionSizeShort * 2
    breakEvenSet := false  // Reset break-even flag

// --- Trade Exits ---
if strategy.position_size > 0
    qty_tp1 = qtyTotal * (target1Percent / 100)
    qty_tp2 = qtyTotal * ((100 - target1Percent) / 100)
    strategy.exit("Long Exit 1", "Long", qty=qty_tp1, stop=stopLevel, limit=target1Level)
    strategy.exit("Long Exit 2", "Long", qty=qty_tp2, stop=stopLevel, limit=target2Level)

if strategy.position_size < 0
    qty_tp1 = qtyTotal * (target1Percent / 100)
    qty_tp2 = qtyTotal * ((100 - target1Percent) / 100)
    strategy.exit("Short Exit 1", "Short", qty=qty_tp1, stop=stopLevel, limit=target1Level)
    strategy.exit("Short Exit 2", "Short", qty=qty_tp2, stop=stopLevel, limit=target2Level)

// --- Move Stop to Break-even ---
if strategy.position_size != 0 and not na(initialPositionSize) and not breakEvenSet
    if math.abs(strategy.position_size) < math.abs(initialPositionSize)
        tradeStop := strategy.position_avg_price
        stopLevel := strategy.position_avg_price
        tradeTarget1 := na  // Clear first target for plotting
        breakEvenSet := true  // Mark break-even as set

// --- Manual Close Fallback ---
if strategy.position_size > 0
    if close >= target2Level or close <= stopLevel
        strategy.close("Long", qty=qtyTotal, comment="Manual Close")

if strategy.position_size < 0
    if close <= target2Level or close >= stopLevel
        strategy.close("Short", qty=qtyTotal, comment="Manual Close")

// --- Reset Levels When No Position ---
if strategy.position_size == 0 and not newTrade
    tradeStop := na
    tradeTarget1 := na
    tradeTarget2 := na
    stopLevel := na
    target1Level := na
    target2Level := na
    initialPositionSize := na
    qtyTotal := na
    breakEvenSet := false

// --- Plotting ---
plot(tradeStop, title="Stop Loss", color=color.red, linewidth=1, style=plot.style_linebr)
plot(tradeTarget1, title="Take Profit 1", color=color.green, linewidth=1, style=plot.style_linebr)
plot(tradeTarget2, title="Take Profit 2", color=color.blue, linewidth=1, style=plot.style_linebr)