다중 수렴 스윙 헌터 전략: 고급 스코어링 시스템 기반 로우 타임 프레임 추세 포착

MACD RSI 多重会聚 趋势捕捉 摆动交易 计分系统 交易策略 低时间框架 价格行为 技术分析 动量指标 趋势识别 风险管理
생성 날짜: 2025-06-30 13:46:39 마지막으로 수정됨: 2025-06-30 13:46:39
복사: 0 클릭수: 239
avatar of ianzeng123 ianzeng123
2
집중하다
319
수행원

다중 수렴 스윙 헌터 전략: 고급 스코어링 시스템 기반 로우 타임 프레임 추세 포착 다중 수렴 스윙 헌터 전략: 고급 스코어링 시스템 기반 로우 타임 프레임 추세 포착

개요

다중 집합 스윙 헌터 전략은 낮은 시간 프레임 거래에 특화된 고급 수치화 전략으로, 최적화된 기술 지표, 가격 행동 분석 및 반전 패턴 식별을 결합하여 정확한 거래 신호를 생성하는 포괄적 인 점수 기반의 점수 시스템을 사용합니다. 이 전략의 핵심 혁신은 독특한 이중 점수 메커니즘을 도입하는 데 있습니다.

이 전략은 광범위하게 재검토된 최적화된 지표 파라미터를 활용하고 있으며, 특히 구성된 MACD[3,10,3]와 RSI[21]를 포함하고 있으며, 이 파라미터는 표준 구성보다 빠르게 변화하는 시장 변화에 더 잘 적응한다. 이 전략은 진입과 출퇴근 모두에 최소 13점의 높은 점수 임계점을 요구하며, 높은 신뢰도 신호만이 거래를 유발할 수 있도록 한다.

전략 원칙

다중 회합 스윙 헌터 전략의 핵심은 다양한 기술 조건을 정량적으로 평가하여 거래 시기를 결정하는 통합 점수 시스템입니다. 입시 점수 시스템은 다음과 같은 네 가지 주요 구성 요소로 구성됩니다.

  1. RSI 신호(최대 5점):

    • RSI < 30: + 2 점
    • RSI <25+2초
    • RSI 상승 1점
  2. MACD 신호(최대 8점):

    • MACD는 0보다 낮습니다.
    • MACD가 상승했다: +2
    • MACD 기둥 그래프 개선: +2점
    • MACD는 +3점으로 뒤바뀌었습니다.
  3. 가격행동(최대 4점)

    • 아래 그림자선 (<50%):+2점
    • 소규모 기업 (<30%):+1점
    • +1점
  4. 패턴 인식(최대 8점):

    • RSI: +4점
    • 빠른 복구 모드: +2 점
    • +4점

출전 점수 시스템은 비슷한 무게 시스템을 사용하지만, 반대의 기준을 사용하여 흔들리는 상점을 식별한다. 이 전략은 출전과 출전 점수가 최소 13점을 합쳐야 하며, 이는 높은 확신도 신호만 실행될 수 있도록 하고, 가짜 신호의 가능성을 줄여준다.

전략의 또 다른 핵심 요소는 최적화된 지표입니다.

  • MACD 구성: 표준 (~12,26,9) 보다 빠른 구성을 통해 신호를 더 일찍 감지할 수 있으며, 신뢰성을 유지할 수 있다
  • RSI 구성 ((21주기)14주기 RSI보다 가짜 신호가 적지만 오버셀 조건을 효과적으로 포착할 수 있습니다.

이 매개 변수들은 급격한 가격 변화와 높은 주파수 변동성을 포착하기 위해 특별히 최적화되었습니다.

전략적 이점

  1. 객관적이고 정량적인 의사 결정 과정: 점수 기반의 점수 시스템을 통해, 이 전략은 주관적 판단을 제거하고 명확한 거래 기준을 제공합니다. 이 방법은 거래 결정을 감정이 아닌 데이터에 기초하여 거래 규율을 크게 향상시킵니다.

  2. 다중 인증 메커니즘이 전략은 여러 기술 지표와 가격 패턴을 동시에 확인하도록 요구하여 신호의 신뢰도를 크게 높였습니다. 최소 13 점의 기준이 충족되면 거래가 이루어지므로 가짜 신호의 위험이 낮아집니다.

  3. 최적화된 시간 민감성이 전략은 최적화된 MACD[3,10,3] 및 RSI[21] 파라미터를 사용하여 가격 동력의 변화를 더 일찍 포착할 수 있으며, 시장 소음을 필터링하여 더 나은 시간적 감수성을 제공합니다.

  4. 유연한 위험 관리: 전략은 위험 기반의 중지 및 수익 목표 계산을 내장하고, 5: 1의 리스크 수익률을 기본으로 채택하여 거래에 대한 명확한 위험 관리 프레임 워크를 제공합니다.

  5. 고도로 시각화된 거래 시스템전략: 녹색 표기 ((입장 점수 ≥10) 와 빨간 표기 ((출장 점수 ≥10) 를 포함한 점수를 표시하는 시스템과 거래 입출장 표시를 제공하여 거래자가 시스템의 작동을 명확하게 볼 수 있습니다.

  6. 매우 적응력이 좋다: 전략의 매개 변수는 최적화되었지만, 다양한 시장 환경과 거래 품종에 따라 조정할 수 있어 전략의 적용 범위가 넓다.

전략적 위험

  1. 고위치의 위험 배분전략: 100%의 자금 분배 방식을 기본으로 채택하고, 이러한 집중적 투자는 단일 거래의 위험 을 증가시킵니다. 시장의 급격한 변동이나 예상치 못한 사건이 발생했을 때, 이는 중요한 계정 변동으로 이어질 수 있습니다.

  2. 시장 조건 의존성: 이 전략은 명백한 추세와 변동 시장에서 가장 잘 작동하지만, 매우 불안정하고 수평 시장에서 효과가 떨어질 수 있습니다. 다양한 시장 환경에서 신중하게 사용해야하며, 변수를 조정하거나 거래를 중단하는 것을 고려해야합니다.

  3. 오버피칭 위험을 최적화: 전략 매개 변수가 최적화되면, 역사 데이터에 대한 과정칭의 위험이 있을 수 있다. 미래의 시장 조건의 변화는 전략의 성능이 재검토 결과보다 떨어질 수 있다. 전략의 유효성을 유지하기 위해 매개 변수를 정기적으로 재검토하고 조정해야 한다.

  4. 다양성이 없는 보호: 단일 포지션 전략으로서, 다양화 보호가 부족하여 특정 시장의 위험을 증가시킵니다. 실제 적용에서, 이 전략을 더 넓은 포트폴리오의 일부로 고려하거나 다양성을 높이기 위해 다중 품종 거래를 도입 할 수 있습니다.

  5. 기술 실패의 위험복잡한 평가 시스템과 여러 가지 조건은 특정 시장 환경에서, 특히 극한 시장 조건에서 작동하지 않을 수 있습니다. 최대 손실 제한을 설정하거나 변동성 필터를 사용하는 것과 같은 추가 위험 관리 조치를 시행하는 것이 좋습니다.

최적화 방향

  1. 사용자 정의 변수를 입력합니다.: 현재 전략은 고정된 MACD와 RSI 파라미터를 사용하며, 시장의 변동성이나 트렌드 강도에 따라 자율 적응 파라미터를 도입하는 것을 고려할 수 있습니다. 예를 들어, 높은 변동성 환경에서 MACD 파라미터를 자동으로 조정하거나, 현재 시장 상태에 따라 RSI 과매매 / 과매매 수준을 조정하여 다양한 시장 환경에서 전략의 적응성을 향상시킵니다.

  2. 통합적 가격관계 분석: 현재 전략은 주로 가격 행동과 동력 지표에 기반하며, 거래량 분석을 통합하여 신호 품질을 향상시킬 수 있습니다. 특히 역전 모드 확인에서 거래량 확인은 추가 신뢰성을 제공 할 수 있습니다. 거래량 관련 점수 기준을 추가하는 것을 고려하십시오.

  3. 시장 환경 필터 추가: 시장 환경 식별 메커니즘을 구현하여 전략에 적합하지 않은 시장 조건에서 거래 주파수를 자동으로 줄이거나 매개 변수를 조정합니다. 예를 들어, 높은 수평 시장에서 점수 임계치를 높이거나 낮은 변동성 환경에서 스톱 스레인지를 줄이십시오.

  4. 자금 관리 시스템을 최적화: 현재 전략은 100%의 포지션 분배를 사용하며, 더 복잡한 자금 관리 시스템을 구현할 수 있으며, 신호 강도, 시장의 변동성 또는 역사적인 성과에 따라 포지션 크기를 동적으로 조정할 수 있습니다. 예를 들어, 점수가 높을수록 더 많은 자금을 배분하거나 연속적인 손실 후 포지션 크기를 줄일 수 있습니다.

  5. 다중 시간 프레임 분석 통합: 더 높은 시간 프레임의 트렌드 확인을 추가하여 입시 신호의 품질을 향상시킵니다. 예를 들어, 더 높은 시간 프레임의 트렌드 방향이 일치하는 경우에만 거래를 실행하거나 주 트렌드에 부응하는 거래에 더 많은 점수를 할당합니다.

  6. 기계 학습 최적화: 기계 학습 방법을 사용하여 점수 무게와 마이너스를 최적화하는 것을 고려하십시오. 역사적 데이터를 분석하여 특정 시장 환경에서 어떤 신호 조합이 가장 효과적인지를 결정하고 점수 시스템을 적절하게 조정할 수 있습니다.

요약하다

다중 회합 스윙 헌터 전략은 다양한 기술 분석 지표와 가격 행동 특성을 통합하여 데이터에 기반한 거래 의사 결정 시스템을 만드는 포괄적이고 체계화된 낮은 시간 프레임 거래 방법을 나타냅니다. 이 전략의 핵심 장점은 객관적인 다중 표준 평가 방식이며, 감정적 인 결정을 효과적으로 제거하면서 다양한 거래 종류와 시장 환경에 적응 할 수있는 충분한 유연성을 유지합니다.

이 전략은 최적화된 MACD[3,10,3] 및 RSI[21] 파라미터를 통해 엄격한 입출장 조건과 결합하여 시장의 흔들림을 효과적으로 포착할 수 있습니다. 특히 변동성이 높은 시장에서. 내장 된 위험 관리 기능과 시각화 도구는 전략의 실용성과 사용자 친화성을 더욱 강화합니다.

그러나, 전략은 또한 높은 포지션 배분, 시장 조건 의존성 및 최적화 과 적합성의 가능성을 포함하여 특정 한계와 위험을 가지고 있습니다. 제안 된 최적화 방향을 구현하여, 적응 파라미터를 도입하고, 물가 관계 분석을 통합하고, 시장 환경 필터를 추가하는 것과 같은 전략의 안정성과 적응성을 더욱 향상시킬 수 있습니다.

경험있는 거래자에게, 다중 회합 스윙 헌터 전략은 낮은 시간 프레임의 트렌드를 포착하고 거래를 스윙하는 데 사용할 수있는 강력한 프레임 워크를 제공합니다. 거래자는 핵심 원칙을 이해하고 특정 요구에 따라 조정함으로써이 전략을 사용하여 빠르게 변화하는 시장에서 높은 확률의 거래 기회를 찾을 수 있습니다.

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

//   ____                    _     _______            _ _               _____  
//  / __ \                  | |   |__   __|          | (_)             |  __ \ 
// | |  | |_   _  __ _ _ __ | |_     | |_ __ __ _  __| |_ _ __   __ _  | |__) | 
// | |  | | | | |/ _` | '_ \| __|    | | '__/ _` |/ _` | | '_ \ / _` | |  ___/ '__/ _ \ 
// | |__| | |_| | (_| | | | | |_     | | | | (_| | (_| | | | | | (_| | | |   | | | (_) |
//  \___\_\\__,_|\__,_|_| |_|\__|    |_|_|  \__,_|\__,_|_|_| |_|\__, | |_|   |_|  \___/
//                                                               __/ |     
//                                                              |___/   
// Quant Trading Pro
//@version=6
strategy("Multi-Confluence Swing Hunter V1", overlay=true, 
         default_qty_type=strategy.percent_of_equity, default_qty_value=100,
         commission_type=strategy.commission.percent, commission_value=0.1,
         slippage=3, initial_capital=1000, margin_long=0, margin_short=0)

// === DESCRIPTION ===
// High-conviction swing bottom entry strategy using optimized MACD(3,10,3) and RSI(21)
// Entry: Point-based scoring system for swing bottoms (divergences, momentum, price action)
// Exit: Inverse scoring system for swing tops (no stop-loss, exit only on swing top signals)
// Position: Single position with 100% allocation, scores displayed only when ≥10 points
// Based on analysis showing 23.7% improvement over standard parameters

// === INPUT PARAMETERS ===

// Optimized Indicator Settings
macdFast = input.int(3, "MACD Fast Length", minval=1, maxval=50, group="Optimized Indicators")
macdSlow = input.int(10, "MACD Slow Length", minval=1, maxval=100, group="Optimized Indicators") 
macdSignal = input.int(3, "MACD Signal Length", minval=1, maxval=50, group="Optimized Indicators")
rsiLength = input.int(21, "RSI Length", minval=2, maxval=100, group="Optimized Indicators")

// Entry Settings - Swing Bottom Scoring
minEntryScore = input.int(13, "Minimum Entry Score", minval=5, maxval=20, group="Entry Settings")
showEntryScores = input.bool(true, "Show Entry Scores (Above 10)", group="Entry Settings")

// Exit Settings - Swing Top Scoring (Inverse of Entry Criteria)
minExitScore = input.int(13, "Minimum Exit Score", minval=5, maxval=20, group="Exit Settings")
showExitScores = input.bool(true, "Show Exit Scores (Above 10)", group="Exit Settings")

// Price Action Settings
minLowerWickPercent = input.float(50.0, "Min Lower Wick %", minval=10.0, maxval=90.0, step=5.0, group="Price Action")
quickRecoveryPercent = input.float(0.3, "Quick Recovery %", minval=0.1, maxval=2.0, step=0.1, group="Price Action")
quickRecoveryBars = input.int(3, "Quick Recovery Bars", minval=1, maxval=10, group="Price Action")

// RSI Levels
rsiOversold = input.float(30.0, "RSI Oversold Level", minval=10.0, maxval=50.0, step=1.0, group="RSI Settings")
rsiExtremeOversold = input.float(25.0, "RSI Extreme Oversold", minval=10.0, maxval=40.0, step=1.0, group="RSI Settings")
rsiOverbought = input.float(70.0, "RSI Overbought Level", minval=50.0, maxval=90.0, step=1.0, group="RSI Settings")
rsiExtremeOverbought = input.float(75.0, "RSI Extreme Overbought", minval=60.0, maxval=90.0, step=1.0, group="RSI Settings")

// Reversal Signals Settings
reversalLookback = input.int(12, "Reversal Candle Lookback", minval=5, maxval=50, group="Reversal Signals")
reversalConfirm = input.int(3, "Reversal Confirm Within", minval=1, maxval=10, group="Reversal Signals")
useVolumeConfirmation = input.bool(false, "Use Volume Confirmation", group="Reversal Signals")

// Trade Management
allowShortTrades = input.bool(false, "Allow Short Trades?", group="Short Trades")

// Risk/Reward TP/SL Settings
useRiskReward = input.bool(true, "Use Risk/Reward TP/SL", group="Risk Management")
riskRewardRatio = input.float(5, "Risk/Reward Ratio", minval=1.0, maxval=5.0, step=0.1, group="Risk Management")
stopLossLookback = input.int(10, "Stop Loss Lookback Bars", minval=3, maxval=50, group="Risk Management")
stopLossBuffer = input.float(0.15, "Stop Loss Buffer %", minval=0.05, maxval=1.0, step=0.05, group="Risk Management")

// Advanced Settings
maxLookbackBars = input.int(8, "Divergence Lookback Bars", minval=3, maxval=20, group="Advanced")

// === 1️⃣ CALCULATIONS ===

// Optimized MACD Calculation
[macdLine, signalLine, macdHist] = ta.macd(close, macdFast, macdSlow, macdSignal)

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

// Price Action Calculations
bodySize = math.abs(close - open)
lowerWick = math.min(open, close) - low
upperWick = high - math.max(open, close)
totalRange = high - low
lowerWickPercent = totalRange > 0 ? (lowerWick / totalRange) * 100 : 0
upperWickPercent = totalRange > 0 ? (upperWick / totalRange) * 100 : 0
bodyPercent = totalRange > 0 ? (bodySize / totalRange) * 100 : 0

// Reversal Signals Calculation
var int bullCandleScore = 0
var int bearCandleScore = 0
var bool bullReversalCandidate = false
var bool bearReversalCandidate = false
var float bullReversalLow = 0.0
var float bullReversalHigh = 0.0
var float bearReversalLow = 0.0
var float bearReversalHigh = 0.0
var bool bullSignalConfirmed = false
var bool bearSignalConfirmed = false
var int bullCandleCounter = 0
var int bearCandleCounter = 0

volumeIsHigh = volume > ta.sma(volume, 20)

// Reset scores
bullCandleScore := 0
bearCandleScore := 0

// Calculate reversal scores
if bar_index >= reversalLookback
    for i = 0 to (reversalLookback - 1)
        if close < low[i]
            bullCandleScore += 1
        if close > high[i]
            bearCandleScore += 1

// Bear signal setup
if bearCandleScore == (reversalLookback - 1)
    bearReversalCandidate := true
    bearReversalLow := low
    bearReversalHigh := high
    bearSignalConfirmed := false
    bearCandleCounter := 0

if bearReversalCandidate
    bearCandleCounter += 1
    if close > bearReversalHigh
        bearReversalCandidate := false

bearCondition = bearReversalCandidate and close < bearReversalLow and not bearSignalConfirmed and bearCandleCounter <= (reversalConfirm + 1)
bearSignal = false
if bearCondition
    bearSignalConfirmed := true
    if not useVolumeConfirmation or volumeIsHigh
        bearSignal := true

// Bull signal setup
if bullCandleScore == (reversalLookback - 1)
    bullReversalCandidate := true
    bullReversalLow := low
    bullReversalHigh := high
    bullSignalConfirmed := false
    bullCandleCounter := 0

if bullReversalCandidate
    bullCandleCounter += 1
    if close < bullReversalLow
        bullReversalCandidate := false

bullCondition = bullReversalCandidate and close > bullReversalHigh and not bullSignalConfirmed and bullCandleCounter <= (reversalConfirm + 1)
bullSignal = false
if bullCondition
    bullSignalConfirmed := true
    if not useVolumeConfirmation or volumeIsHigh
        bullSignal := true

// === 2️⃣ ENTRY & EXIT LOGIC ===

// Helper Functions for Divergence Detection
findLowerLow(lookback) =>
    var float lowestPrice = na
    var int lowestIndex = na
    
    if bar_index >= lookback
        lowestPrice := low
        lowestIndex := bar_index
        
        for i = 1 to lookback
            if low[i] < lowestPrice
                lowestPrice := low[i]
                lowestIndex := bar_index - i
    
    [lowestPrice, lowestIndex]

findHigherHigh(lookback) =>
    var float highestPrice = na
    var int highestIndex = na
    
    if bar_index >= lookback
        highestPrice := high
        highestIndex := bar_index
        
        for i = 1 to lookback
            if high[i] > highestPrice
                highestPrice := high[i]
                highestIndex := bar_index - i
    
    [highestPrice, highestIndex]

// SWING BOTTOM SCORING SYSTEM

// 1. RSI Signals
rsiOversoldSignal = rsi < rsiOversold
rsiExtremeOversoldSignal = rsi < rsiExtremeOversold
rsiTurningUp = rsi > rsi[1]

// RSI Bullish Divergence
[prevLowPrice, prevLowIndex] = findLowerLow(maxLookbackBars)
rsiBullishDivergence = false
if not na(prevLowPrice) and not na(prevLowIndex) and bar_index > prevLowIndex
    prevRSI = rsi[bar_index - prevLowIndex]
    if low < prevLowPrice and rsi > prevRSI and not na(prevRSI)
        rsiBullishDivergence := true

// 2. MACD Signals  
macdNegative = macdLine < 0
macdTurningUp = macdLine > macdLine[1] 
macdHistImproving = macdHist > macdHist[1]

// MACD Bullish Divergence
macdBullishDivergence = false
if not na(prevLowPrice) and not na(prevLowIndex) and bar_index > prevLowIndex
    prevMACD = macdLine[bar_index - prevLowIndex]
    if low < prevLowPrice and macdLine > prevMACD and not na(prevMACD)
        macdBullishDivergence := true

// 3. Price Action Signals
longLowerWick = lowerWickPercent > minLowerWickPercent
smallBody = bodyPercent < 30.0
bullishClose = close > open

// 4. Quick Recovery Check
quickRecovery = false
if bar_index >= quickRecoveryBars
    recoveryTarget = close * (1 + quickRecoveryPercent / 100)
    for i = 1 to quickRecoveryBars
        if high[i] > recoveryTarget
            quickRecovery := true
            break

// ENTRY SCORE CALCULATION
entryScore = 0
entryScore := entryScore + (rsiOversoldSignal ? 2 : 0)
entryScore := entryScore + (rsiExtremeOversoldSignal ? 2 : 0)  
entryScore := entryScore + (rsiBullishDivergence ? 4 : 0)
entryScore := entryScore + (rsiTurningUp ? 1 : 0)
entryScore := entryScore + (macdNegative ? 1 : 0)
entryScore := entryScore + (macdTurningUp ? 2 : 0)
entryScore := entryScore + (macdHistImproving ? 2 : 0)
entryScore := entryScore + (macdBullishDivergence ? 3 : 0)
entryScore := entryScore + (longLowerWick ? 2 : 0)
entryScore := entryScore + (smallBody ? 1 : 0)
entryScore := entryScore + (bullishClose ? 1 : 0)
entryScore := entryScore + (quickRecovery ? 2 : 0)
entryScore := entryScore + (bullSignal ? 4 : 0)  // Green reversal signal +4

// SWING TOP SCORING SYSTEM (for exits)

// 1. RSI Exit Signals
rsiOverboughtSignal = rsi > rsiOverbought
rsiExtremeOverboughtSignal = rsi > rsiExtremeOverbought
rsiTurningDown = rsi < rsi[1]

// RSI Bearish Divergence
[prevHighPrice, prevHighIndex] = findHigherHigh(maxLookbackBars)
rsiBearishDivergence = false
if not na(prevHighPrice) and not na(prevHighIndex) and bar_index > prevHighIndex
    prevRSIHigh = rsi[bar_index - prevHighIndex]
    if high > prevHighPrice and rsi < prevRSIHigh and not na(prevRSIHigh)
        rsiBearishDivergence := true

// 2. MACD Exit Signals
macdPositive = macdLine > 0
macdTurningDown = macdLine < macdLine[1]
macdHistDeclining = macdHist < macdHist[1]

// MACD Bearish Divergence  
macdBearishDivergence = false
if not na(prevHighPrice) and not na(prevHighIndex) and bar_index > prevHighIndex
    prevMACDHigh = macdLine[bar_index - prevHighIndex]
    if high > prevHighPrice and macdLine < prevMACDHigh and not na(prevMACDHigh)
        macdBearishDivergence := true

// 3. Price Action Exit Signals
longUpperWick = upperWickPercent > minLowerWickPercent
bearishClose = close < open

// EXIT SCORE CALCULATION
exitScore = 0
exitScore := exitScore + (rsiOverboughtSignal ? 2 : 0)
exitScore := exitScore + (rsiExtremeOverboughtSignal ? 2 : 0)
exitScore := exitScore + (rsiBearishDivergence ? 4 : 0)
exitScore := exitScore + (rsiTurningDown ? 1 : 0)
exitScore := exitScore + (macdPositive ? 1 : 0)
exitScore := exitScore + (macdTurningDown ? 2 : 0)
exitScore := exitScore + (macdHistDeclining ? 2 : 0)
exitScore := exitScore + (macdBearishDivergence ? 3 : 0)
exitScore := exitScore + (longUpperWick ? 2 : 0)
exitScore := exitScore + (bearishClose ? 1 : 0)
exitScore := exitScore + (bearSignal ? 1 : 0)  // Red reversal signal +1

// SIGNAL CONDITIONS
longCondition = entryScore >= minEntryScore and barstate.isconfirmed
exitCondition = exitScore >= minExitScore and barstate.isconfirmed

// === TP/SL LEVELS (Clean Logic) ===
var float stopLossLevel = na
var float takeProfitLevel = na
var bool tpslSet = false

// Clear levels when no position
if strategy.position_size == 0
    stopLossLevel := na
    takeProfitLevel := na
    tpslSet := false

// Calculate TP/SL levels ONCE when position is opened
if strategy.position_size > 0 and strategy.position_size[1] == 0 and useRiskReward and not tpslSet
    // Find recent low for stop loss
    recentLow = low
    for i = 1 to stopLossLookback
        if low[i] < recentLow
            recentLow := low[i]
    
    // Set levels using actual entry price
    entryPrice = strategy.opentrades.entry_price(0)
    stopLossLevel := recentLow * (1 - stopLossBuffer / 100)  // Configurable buffer below recent low
    riskAmount = entryPrice - stopLossLevel
    takeProfitLevel := entryPrice + (riskAmount * riskRewardRatio)
    tpslSet := true

// === 3️⃣ TRADE EXECUTIONS ===

// Long Entry - Single Position Only
if longCondition and strategy.position_size == 0
    strategy.entry("Long", strategy.long, comment="Entry Score: " + str.tostring(entryScore))

// Set TP/SL ONLY ONCE per trade (when levels are calculated and not yet set)
if strategy.position_size > 0 and useRiskReward and tpslSet and not na(stopLossLevel) and not na(takeProfitLevel)
    strategy.exit("TP/SL", "Long", stop=stopLossLevel, limit=takeProfitLevel)

// Long Exit - Close Position on Swing Top Signal (Only when NOT using TP/SL)
if exitCondition and strategy.position_size > 0 and not useRiskReward
    strategy.close("Long", comment="Exit Score: " + str.tostring(exitScore))

// === 4️⃣ VISUALIZATIONS ===

// Entry Score Display (Only When Score ≥ 10) - Shows on ALL qualifying bars
if showEntryScores and entryScore >= 10 and barstate.isconfirmed
    label.new(bar_index, low, 
             text=str.tostring(entryScore), 
             yloc=yloc.belowbar,
             color=na,
             style=label.style_label_up, 
             textcolor=color.green, 
             size=size.small)

// Exit Score Display (Only When Score ≥ 10) - Shows on ALL qualifying bars  
if showExitScores and exitScore >= 10 and barstate.isconfirmed
    label.new(bar_index, high, 
             text=str.tostring(exitScore), 
             yloc=yloc.abovebar,
             color=na,
             style=label.style_label_down, 
             textcolor=color.red, 
             size=size.small)

// Large Trade Entry Triangle (Only when actually entering a position) - Using plotshape to avoid label limits
plotshape(longCondition and strategy.position_size == 0, title="Trade Entry", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.normal, text="BUY")

// Large Trade Exit Triangle (Only when actually exiting a position) - Using plotshape to avoid label limits  
plotshape(exitCondition and strategy.position_size > 0, title="Trade Exit", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.normal, text="SELL")

// Reversal Signal Triangles
plotshape(bullSignal, title="Bull Reversal", location=location.belowbar, 
         color=color.lime, style=shape.triangleup, size=size.tiny)

plotshape(bearSignal, title="Bear Reversal", location=location.abovebar, 
         color=color.red, style=shape.triangledown, size=size.tiny)

// === TP/SL LEVEL PLOTS ===
plot(strategy.position_size > 0 and useRiskReward ? stopLossLevel : na, title="Stop Loss", color=color.red, linewidth=2, style=plot.style_linebr)
plot(strategy.position_size > 0 and useRiskReward ? takeProfitLevel : na, title="Take Profit", color=color.green, linewidth=2, style=plot.style_linebr)

// MACD and RSI Plots (in separate panes)
macdPlot = plot(macdLine, title="MACD Line", color=color.blue, display=display.none)
signalPlot = plot(signalLine, title="Signal Line", color=color.red, display=display.none) 
histPlot = plot(macdHist, title="MACD Histogram", color=color.gray, style=plot.style_histogram, display=display.none)

rsiPlot = plot(rsi, title="RSI", color=color.purple, display=display.none)
rsiOverboughtLine = hline(rsiOverbought, title="RSI Overbought", color=color.red, linestyle=hline.style_dashed, display=display.none)
rsiOversoldLine = hline(rsiOversold, title="RSI Oversold", color=color.green, linestyle=hline.style_dashed, display=display.none)