동적 가격 범위 돌파-풀백-반전 다중 전략 거래 시스템

FVG 5M 1M R:R RANGE TRADING SCALPING
생성 날짜: 2025-08-22 09:55:06 마지막으로 수정됨: 2025-08-22 09:55:06
복사: 0 클릭수: 333
avatar of ianzeng123 ianzeng123
2
집중하다
319
수행원

동적 가격 범위 돌파-풀백-반전 다중 전략 거래 시스템 동적 가격 범위 돌파-풀백-반전 다중 전략 거래 시스템

개요

동적 가격 간격 돌파-탈퇴-반전 다중 전략 거래 시스템 (Dynamic Price Range Breakout-Retreat-Reverse Multi Strategy Trading System) 은 단선 거래자를 위해 특별히 설계된 일일 거래 전략으로, 아침 상장 후 첫 5분 K선에서 형성되는 가격 간격에 기반하여 운영한다. 이 전략은 세 가지 다른 입문 모드를 통합한다.

전략 원칙

이 전략의 핵심 원리는 가격의 초기 범위를 형성한 후의 행동 패턴에 기반하며, 구체적인 동작은 세 단계로 나뉘어집니다:

  1. 9:30 AM):

    • K 라인: 9:30-9:35 종료 후 첫 5 분
    • K 선의 최고점과 최저점을 거래 구역으로 표시합니다.
    • 1분 차트로 전환하여 실제 거래
  2. 입시점을 찾아라 (거래가 시작된 지 1시간 후에만): 이 전략은 세 가지 다른 진입 방법을 제공합니다.

    • 브레이크 엔트리:

      • 공정 가치 격차 (FVG) 조건을 충족해야 한다.
      • FVG의 임의의 K 선의 종결 가격 돌파구
      • FVG는 3개의 K선으로 형성된 비행 패턴 ((wick-gap) 으로 정의된다
    • 트랩 엔트리:

      • 가격도 지역 경계를 넘어섰습니다.
      • 그 다음, 칸막이 안에
      • 마지막으로, 다시 한 번 둥글게 닫혔습니다.
    • 리버스 엔트리:

      • 한쪽 방향의 돌파구가 실패한 후
      • 반방향으로 보이는 FVG가 구역으로 돌아옵니다.
  3. 거래 관리:

    • 손해 중지 설정:
      • 돌파 / 함정 전략: 첫 번째 근접을 사용하여 K 라인의 최저 / 최고 지점을 범위를 벗어
      • 역전 전략: FVG 모드에서 첫 번째 K 선의 최저/최고
    • 정지 설정:
      • 항상 2:1의 리스크와 수익 비율을 사용하세요.
      • 100달러의 위험 200달러의 이익

전략 코드는 자동으로 거래 간격을 감지하고, 다양한 입시 조건을 식별하고, 스톱 스톱 레벨을 설정하고, 적절한 포지션 크기를 계산하는 등 전체 논리 프레임워크를 구현합니다. 시스템에는 시간 필터가 포함되어 있으며, 특정 시간 동안만 거래되도록 보장하며, 선택적으로 다른 입시 전략을 활성화하거나 비활성화 할 수 있습니다.

전략적 이점

  1. 규칙이 간단하고 명확합니다.: 전략 규칙은 명확하고 직관적이며, 주관적인 판단이 필요하지 않으며, 감정이 거래 결정에 미치는 영향을 줄인다. 코드 내의 조건적 논리와 상태 추적은 규칙의 엄격한 실행을 보장한다.

  2. 다양한 입학 방식의 유연성3가지의 다른 입문 전략을 제공함: , 함정, 반전, 이는 상인들이 다른 시장 환경에 적응할 수 있도록 해준다.enableBreakenableTrap그리고enableReversal이 변수는 이러한 유연성을 구현합니다.

  3. 높은 확률에 집중하세요.이 전략은 상장 후 첫 시간 내에 거래하는 것으로, 이 기간 동안 일반적으로 존재하는 높은 변동성과 유동성을 이용합니다.inWindow조건은 거래가 9시 30분에서 10시 30분 사이에만 이루어지는 것을 보장합니다.

  4. 엄격한 위험 관리: 고정된 2:1 리스크/이익 비율과 특정 가격 행동에 따른 스톱로스 설정으로, 각 거래에 대한 명확한 리스크 관리를 제공합니다.riskPct매 거래의 위험 비율을 사용자 자신의 위험 취향에 따라 조정할 수 있도록 허용합니다.

  5. 복잡한 지표가 필요하지 않습니다.이 전략은 복잡한 기술 지표에 의존하지 않고, 순수하게 가격 행동과 구조에 기반하여 과다 적합성의 위험을 줄입니다.

  6. 계절적 회피: 코드는 휴일 블랙리스트를 내장하고 있다 ((12월 15일부터 1월 15일까지), 시장이 불안정하거나 유동성이 낮은 기간을 피한다。

  7. 유연한 포지션 관리: 시스템은 위험 비율이나 고정 계약 수에 기반한 두 가지 포지션 관리 방식을 제공하며, 서로 다른 자금 관리 요구에 적합합니다.

전략적 위험

  1. 가짜 침입 위험: 시장은 가짜 돌파구가 발생할 수 있으며 거래가 발생하면 가격이 빠르게 반전될 수 있다. 이 위험을 완화하기 위해, 전략은 함정과 반전 입구 모드를 통합하지만, 여전히 신중한 모니터링이 필요합니다.

  2. 빈도 문제: 개시 후 첫 5 분 K 라인 간격이 너무 넓거나 너무 좁으면 전략의 효과에 영향을 줄 수 있습니다. 너무 좁은 간격은 빈번한 트리거 신호를 유발할 수 있으며, 너무 넓은 간격은 정지점이 너무 멀어질 수 있습니다.

  3. 시간적 제약의 기회비용그러나, 이 제한은 과도한 거래를 막기 위한 징계이기도 합니다.

  4. 고정된 리스크/수익률의 한계2: 1의 리스크/이익 비율이 일관성을 제공하지만, 특정 시장 환경에서 최적의 선택이 아닐 수 있습니다. 강한 추세 시장에서 더 높은 리스크/이익 비율이 더 적합 할 수 있습니다.

  5. 휴가철 시장의 이상성이 전략은 12월 15일부터 1월 15일까지의 기간을 회피했지만, 다른 휴일 전후의 시장행동도 비정상적일 수 있으며, 전략의 성과에 영향을 줄 수 있다.

  6. FVG에 대한 의존전략: 돌파구와 역전입시에서 FVG 패턴에 의존하지만, 특정 시장 조건에서 FVG는 쉽게 형성되거나 식별되지 않을 수 있다.

  7. 단일 시간 프레임의 한계1분 차트에 전적으로 의존하면 전략이 더 큰 시간 프레임의 중요한 시장 구조를 무시할 수 있습니다.

전략 최적화 방향

  1. 칸의 폭을 조정: 시장의 변동성에 따라 범위를 조정하는 것을 고려할 수 있습니다. 예를 들어, 변동성이 높은 날에는 넓은 범위를 사용하고, 변동성이 낮은 날에는 좁은 범위를 사용합니다. 이것은 최근 평균 실제 변동 범위를 계산하여 (ATR) 또는 유사한 지표를 통해 달성 할 수 있습니다.

  2. 시간 창을 최적화9:30-10:30에 고정되는 것이 아니라 다양한 시장의 최적 거래 시간 창을 연구 할 수 있습니다. 일부 시장은 다른 시간대에 더 명백한 간격 돌파 패턴을 나타낼 수 있습니다.

  3. 동적 리스크 수익 설정: 시장 상태와 변동적 동력에 따라 리스크 수익률을 조정할 수 있습니다. 예를 들어, 트렌드가 강할 때 목표를 높이고, 마켓을 정리할 때 목표를 줄일 수 있습니다.

  4. 시장 감정 지표 통합: 시장 폭 지표 또는 변동성 지표를 필터로 추가하여 시장 환경이 좋지 않을 때 거래를 피하는 것을 고려할 수 있습니다.

  5. 다중 시간 프레임 확인: 실행 거래는 1분 차트 상에 남아 있지만, 15분 또는 1시간 차트 상의 트렌드 방향 일치 점검과 같은 더 높은 시간 프레임의 확인 조건을 추가할 수 있습니다.

  6. FVG 정의를 최적화: 현재의 FVG 정의는 비교적 간단하며, 더 복잡한 또는 더 정확한 불균형 영역 정의를 고려할 수 있습니다. 예를 들어, 그림자 라인이 아닌 체를 고려하십시오.

  7. 거래량 확인을 추가합니다.: 입시 조건에 거래량 확인을 추가하는 것은 신호의 질을 향상시킬 수 있습니다.

  8. 자율적 제약: 시장의 변동성에 따라 중지 수준을 조정하는 것은 다양한 시장 환경에서 전략의 적응성을 향상시킬 수 있습니다.

요약하다

동적 가격 범위를 돌파-탈퇴-반전 다중 전략 거래 시스템은 명확하고 규칙이 명확한 일일 거래 전략으로, 이른 시판이 형성되는 가격 범위를 식별하고 그 후의 돌파, 함정 또는 반전 패턴을 통해 거래 기회를 찾습니다. 이 전략의 주요 장점은 간결성과 다양한 입구 방식의 유연성이며, 엄격한 시간 제한과 위험 관리 원칙은 거래 규율을 유지하는 데 도움이됩니다.

그러나, 이 전략은 또한 가짜 돌파구, 부적절한 범주 폭 및 특정 가격 패턴에 대한 의존 등의 위험에 직면합니다. 최적화된 범주 설정 방법, 시간 창 조정, 동적으로 설정된 위험 보상 비율 및 다중 시간 프레임 분석을 통합하는 등의 방법으로 전략의 안정성과 적응성을 더욱 높일 수 있습니다.

결국, 이 전략은 단선 거래자에게 체계화된 프레임워크를 제공하며, 특히 매일 개시 시간에 효율적인 거래를 추구하는 투자자에게 적합합니다. 모든 거래 전략과 마찬가지로 실제 적용 전에 충분한 피드백과 적절한 위험 관리가 수행되어야합니다.

전략 소스 코드
/*backtest
start: 2025-07-22 00:00:00
end: 2025-08-21 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT","balance":500000}]
*/

//@version=5
strategy("Three-Step 9:30 Range Scalping (Backtest)", overlay=true, calc_on_every_tick=false, process_orders_on_close=true,
     initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, pyramiding=0)

// -------------------- Inputs
enableBreak    = input.bool(true,  "Enable Break Entry")
enableTrap     = input.bool(false, "Enable Trap Entry")
enableReversal = input.bool(true, "Enable Reversal Entry")
rr             = input.float(2.0,  "Take-Profit R Multiple", step=0.25, minval=0.25)
oneTradePerDay = input.bool(false,  "One Trade Per Day")
showRange      = input.bool(true,  "Show 9:30 5m Range")

// Risk management
riskPct        = input.float(1.0,  "Risk % of Equity per Trade", step=0.1, minval=0.1, maxval=100.0)
sizeMode       = input.string("Risk %", "Position Sizing Mode", options=["Risk %", "Fixed contracts"])
fixedContracts = input.int(1, "Fixed Contracts", minval=1)

// Optional: warn if not on 1-minute chart (execution timeframe per PRD)
onOneMinute = timeframe.isminutes and timeframe.multiplier == 1

// -------------------- Time helpers (chart is assumed New York time)
newDay   = ta.change(time("D")) != 0
// Trade the first hour only: 9:30:00 to 10:29:59
inWindow = (hour == 9 and minute >= 30) or (hour == 10 and minute <= 29)
// Holiday blackout window: Do not trade Dec 15 – Jan 15
inBlackout = (month == 12 and dayofmonth >= 15) or (month == 1 and dayofmonth <= 15)

// -------------------- First 5-min range (use the actual 9:30 5m candle via security())
var float rangeHi = na
var float rangeLo = na
var bool  haveRange = false

// -------------------- State for entries
var bool  breakUpFound           = false
var bool  breakDownFound         = false
var float initBreakUpLow         = na    // for Break/Trap long SL
var float initBreakDownHigh      = na    // for Break/Trap short SL
var bool  trapUpRetestedInside   = false
var bool  trapDownRetestedInside = false
var bool  tradedToday            = false

// Reset daily state at midnight (chart timezone)
if newDay
    rangeHi := na
    rangeLo := na
    haveRange := false
    breakUpFound := false
    breakDownFound := false
    initBreakUpLow := na
    initBreakDownHigh := na
    trapUpRetestedInside := false
    trapDownRetestedInside := false
    tradedToday := false

// Pull the 5-minute bar that STARTS at 9:30 (value available on its close at 9:35)
sess0930Hi = request.security(syminfo.tickerid, "5", (hour == 9 and minute == 30) ? high : na, barmerge.gaps_off, barmerge.lookahead_off)
sess0930Lo = request.security(syminfo.tickerid, "5", (hour == 9 and minute == 30) ? low  : na, barmerge.gaps_off, barmerge.lookahead_off)

// Lock the range when the 9:30 5m candle closes (value appears non-na exactly then)
if not haveRange and not na(sess0930Hi) and not na(sess0930Lo)
    rangeHi := sess0930Hi
    rangeLo := sess0930Lo
    haveRange := true
    // reset session-specific flags at start of trading window
    breakUpFound := false
    breakDownFound := false
    initBreakUpLow := na
    initBreakDownHigh := na
    trapUpRetestedInside := false
    trapDownRetestedInside := false
    tradedToday := false

// -------------------- Visuals
plot(showRange and haveRange ? rangeHi : na, "Range High", color=color.new(color.teal, 0), style=plot.style_linebr, linewidth=2)
plot(showRange and haveRange ? rangeLo : na, "Range Low",  color=color.new(color.orange, 0), style=plot.style_linebr, linewidth=2)

plotchar(not onOneMinute, title="Use 1-minute chart", char="⚠", location=location.top, color=color.new(color.red, 0), size=size.tiny)
plotchar(inBlackout, title="Holiday blackout (Dec 15–Jan 15)", char="⛔", location=location.top, color=color.new(color.red, 0), size=size.tiny)

// -------------------- Convenience conditions
closeAbove  = haveRange and close > rangeHi
closeBelow  = haveRange and close < rangeLo
closeInside = haveRange and close <= rangeHi and close >= rangeLo

// Track first body-close outside the range in each direction (initial break-close)
if haveRange and inWindow and not tradedToday
    if not breakUpFound and closeAbove
        breakUpFound := true
        initBreakUpLow := low
        trapUpRetestedInside := false
    if not breakDownFound and closeBelow
        breakDownFound := true
        initBreakDownHigh := high
        trapDownRetestedInside := false

// Trap retest flags (retest back inside after first break)
if haveRange and inWindow and not tradedToday
    if breakUpFound and not trapUpRetestedInside and closeInside
        trapUpRetestedInside := true
    if breakDownFound and not trapDownRetestedInside and closeInside
        trapDownRetestedInside := true

// -------------------- FVG detectors (three-candle imbalance)
// Simple wick-gap definition, preserved through the third candle
// Bullish: gap exists if Candle C low > Candle A high AND Candle B low > Candle A high
// Bearish: gap exists if Candle C high < Candle A low  AND Candle B high < Candle A low
bullFVG = not na(high[2]) and (low[1] > high[2]) and (low > high[2])
bearFVG = not na(low[2])  and (high[1] < low[2])  and (high < low[2])

// -------------------- Entry gating
allowEntry = haveRange and inWindow and not inBlackout and strategy.position_size == 0 and (not oneTradePerDay or not tradedToday)

// Calculate contracts based on selected sizing mode
calcOrderQty(entryPrice, stopPrice) =>
    qty = 0
    if sizeMode == "Fixed contracts"
        qty := fixedContracts
    else
        riskCash = strategy.equity * riskPct / 100.0
        riskPerContract = math.abs(entryPrice - stopPrice) * syminfo.pointvalue
        qty := riskPerContract > 0 ? math.floor(riskCash / riskPerContract) : 0
    qty

// -------------------- BREAK Entries (needs FVG and ANY of the 3 bars closes outside)
if enableBreak and allowEntry
    // Long BREAK
    breakLongOk  = bullFVG and (close > rangeHi or close[1] > rangeHi or close[2] > rangeHi)
    if breakLongOk
        // Stop at the FIRST candle that closed outside among the 3 FVG candles
        float stopL = na
        stopL := close[2] > rangeHi ? low[2] : stopL
        stopL := na(stopL) and close[1] > rangeHi ? low[1] : stopL
        stopL := na(stopL) and close > rangeHi ? low : stopL
        entryL = close
        if entryL > stopL
            tpL = entryL + rr * (entryL - stopL)
            qtyL = calcOrderQty(entryL, stopL)
            if qtyL > 0
                strategy.entry("LONG_BREAK", strategy.long, qty=qtyL)
                strategy.exit("LONG_BREAK_TP/SL", from_entry="LONG_BREAK", stop=stopL, limit=tpL)
                tradedToday := oneTradePerDay ? true : tradedToday
    // Short BREAK
    breakShortOk = bearFVG and (close < rangeLo or close[1] < rangeLo or close[2] < rangeLo)
    if breakShortOk
        // Stop at the FIRST candle that closed outside among the 3 FVG candles
        float stopS = na
        stopS := close[2] < rangeLo ? high[2] : stopS
        stopS := na(stopS) and close[1] < rangeLo ? high[1] : stopS
        stopS := na(stopS) and close < rangeLo ? high : stopS
        entryS = close
        if entryS < stopS
            tpS = entryS - rr * (stopS - entryS)
            qtyS = calcOrderQty(entryS, stopS)
            if qtyS > 0
                strategy.entry("SHORT_BREAK", strategy.short, qty=qtyS)
                strategy.exit("SHORT_BREAK_TP/SL", from_entry="SHORT_BREAK", stop=stopS, limit=tpS)
                tradedToday := oneTradePerDay ? true : tradedToday

// -------------------- TRAP Entries (Break → Retest inside → Reclose outside; FVG not required)
if enableTrap and allowEntry
    // Long TRAP
    if breakUpFound and trapUpRetestedInside and closeAbove
        stopL  = na(initBreakUpLow) ? low : initBreakUpLow
        entryL = close
        if entryL > stopL
            tpL = entryL + rr * (entryL - stopL)
            qtyL = calcOrderQty(entryL, stopL)
            if qtyL > 0
                strategy.entry("LONG_TRAP", strategy.long, qty=qtyL)
                strategy.exit("LONG_TRAP_TP/SL", from_entry="LONG_TRAP", stop=stopL, limit=tpL)
                tradedToday := oneTradePerDay ? true : tradedToday
    // Short TRAP
    if breakDownFound and trapDownRetestedInside and closeBelow
        stopS  = na(initBreakDownHigh) ? high : initBreakDownHigh
        entryS = close
        if entryS < stopS
            tpS = entryS - rr * (stopS - entryS)
            qtyS = calcOrderQty(entryS, stopS)
            if qtyS > 0
                strategy.entry("SHORT_TRAP", strategy.short, qty=qtyS)
                strategy.exit("SHORT_TRAP_TP/SL", from_entry="SHORT_TRAP", stop=stopS, limit=tpS)
                tradedToday := oneTradePerDay ? true : tradedToday

// -------------------- REVERSAL Entries (Failed break + opposite FVG back into range)
if enableReversal and allowEntry
    // After bearish break, bullish FVG back into range → LONG
    if breakDownFound and bullFVG and closeInside
        stopL  = low[2]  // first candle of the FVG
        entryL = close
        if entryL > stopL
            tpL = entryL + rr * (entryL - stopL)
            qtyL = calcOrderQty(entryL, stopL)
            if qtyL > 0
                strategy.entry("LONG_REV", strategy.long, qty=qtyL)
                strategy.exit("LONG_REV_TP/SL", from_entry="LONG_REV", stop=stopL, limit=tpL)
                tradedToday := oneTradePerDay ? true : tradedToday
    // After bullish break, bearish FVG back into range → SHORT
    if breakUpFound and bearFVG and closeInside
        stopS  = high[2] // first candle of the FVG
        entryS = close
        if entryS < stopS
            tpS = entryS - rr * (stopS - entryS)
            qtyS = calcOrderQty(entryS, stopS)
            if qtyS > 0
                strategy.entry("SHORT_REV", strategy.short, qty=qtyS)
                strategy.exit("SHORT_REV_TP/SL", from_entry="SHORT_REV", stop=stopS, limit=tpS)
                tradedToday := oneTradePerDay ? true : tradedToday

// -------------------- Markers
plotshape(enableBreak and (bullFVG and (close > rangeHi or close[1] > rangeHi or close[2] > rangeHi)) and allowEntry,  title="Break Long",  style=shape.triangleup,   color=color.new(color.teal, 0),   size=size.tiny, location=location.belowbar, text="Break")
plotshape(enableBreak and (bearFVG and (close < rangeLo or close[1] < rangeLo or close[2] < rangeLo)) and allowEntry,  title="Break Short", style=shape.triangledown, color=color.new(color.orange, 0), size=size.tiny, location=location.abovebar, text="Break")
plotshape(enableTrap  and breakUpFound   and trapUpRetestedInside   and closeAbove and allowEntry,  title="Trap Long",  style=shape.circle, color=color.new(color.teal, 0),   size=size.tiny, location=location.belowbar, text="Trap")
plotshape(enableTrap  and breakDownFound and trapDownRetestedInside and closeBelow and allowEntry,  title="Trap Short", style=shape.circle, color=color.new(color.orange, 0), size=size.tiny, location=location.abovebar, text="Trap")
plotshape(enableReversal and breakDownFound and bullFVG and closeInside and allowEntry, title="Reversal Long",  style=shape.diamond, color=color.new(color.teal, 0),   size=size.tiny, location=location.belowbar, text="Rev")
plotshape(enableReversal and breakUpFound   and bearFVG and closeInside and allowEntry, title="Reversal Short", style=shape.diamond, color=color.new(color.orange, 0), size=size.tiny, location=location.abovebar, text="Rev")