Untitled

 avatar
unknown
plain_text
a month ago
16 kB
4
Indexable
// @version=5
indicator("Current Timeframe Two-Candle Pattern", overlay=true, max_bars_back=5000)

//-----------------------------------------------------------------------------// Input Parameters
//-----------------------------------------------------------------------------
rr = input.float(defval=2.0, title="Risk:Reward Ratio", minval=0.1, step=0.1)
showStats = input.bool(defval=true, title="Show Performance Statistics")
//showStats = input.bool(defval=true, title="Show Performance Statistics")
lineLength = input.int(defval=20, title="Line Length", minval=5, maxval=100)

//-----------------------------------------------------------------------------// Pattern Detection (directly on current timeframe)
//-----------------------------------------------------------------------------
// Determine candle colors for current and previous candles
isGreen_prev = close[1] > open[1]
isRed_prev = close[1] < open[1]
isGreen_current = close > open
isRed_current = close < open

// Bearish Pattern Conditions
bearishPattern = isGreen_prev and isRed_current and high > high[1] and close < open[1]

// Bullish Pattern Conditions
bullishPattern = isRed_prev and isGreen_current and low < low[1] and close > open[1]

//-----------------------------------------------------------------------------// Variable Initialization
//-----------------------------------------------------------------------------
// Variables to track pattern detection state
var bool patternActive = false
var bool bullishActive = false
var bool bearishActive = false
var int patternStartTime = 0
var int patternEndTime = 0

// Variables to track pattern bar index
var int patternBarIndex = 0
var bool waitingForSecondBar = false

// Variables to store long and short position levels
var float longEntryLevel = na
var float longStopLevel = na
var float longTargetLevel = na
var float shortEntryLevel = na
var float shortStopLevel = na
var float shortTargetLevel = na

// Variables for trade tracking and performance statistics
var int totalTrades = 0
var int longTrades = 0
var int shortTrades = 0
var int winningTrades = 0
var int losingTrades = 0
var int breakEvenTrades = 0
var int consecutiveWins = 0
var int consecutiveLosses = 0
var int maxConsecutiveWins = 0
var int maxConsecutiveLosses = 0
var float winRate = 0.0
var float maxDrawdown = 0.0
var float currentDrawdown = 0.0
var float peakEquity = 0.0
var float currentEquity = 0.0
var float totalRRGain = 0.0  // Total risk-reward gain

// Variables to track active trade status
var bool inLongTrade = false
var bool inShortTrade = false
var float tradeEntryPrice = na
var float tradeStopLevel = na
var float tradeTargetLevel = na

// Variables to draw trade entry, stop, and target levels
var line entryLine = na
var line stopLine = na
var line targetLine = na

//-----------------------------------------------------------------------------// Pattern Detection
//-----------------------------------------------------------------------------
// New pattern detection
newBullishPattern = bullishPattern and (not bullishPattern[1])
newBearishPattern = bearishPattern and (not bearishPattern[1])

// Reset state on new pattern
if newBullishPattern or newBearishPattern
    patternActive := true
    bullishActive := newBullishPattern
    bearishActive := newBearishPattern
    patternStartTime := time
    // Set pattern expiry based on the current timeframe (6 bars in the current timeframe)
    patternEndTime := time + (6 * (time - time[1]))
    
    // Mark this bar as the pattern detection bar
    patternBarIndex := bar_index
    waitingForSecondBar := true

// Check if we're on the second bar after pattern detection
if waitingForSecondBar and bar_index == (patternBarIndex + 2)
    waitingForSecondBar := false
    
    // Clean up previous lines
    if not na(entryLine)
        line.delete(entryLine)
    if not na(stopLine)
        line.delete(stopLine)
    if not na(targetLine)
        line.delete(targetLine)
        
    // For bullish pattern, enter on second bar after pattern
    if bullishActive
        // Find the lowest low of the last two candles from pattern detection
        float lowestLow = math.min(low[2], low[1])
        longEntryLevel := close
        longStopLevel := lowestLow
        longTargetLevel := longEntryLevel + ((longEntryLevel - longStopLevel) * rr)
        
        // Draw entry, stop, and target lines for bullish pattern
        entryLine := line.new(bar_index, longEntryLevel, bar_index + lineLength, longEntryLevel, color=color.blue, width=2)
        stopLine := line.new(bar_index, longStopLevel, bar_index + lineLength, longStopLevel, color=color.red, width=2)
        targetLine := line.new(bar_index, longTargetLevel, bar_index + lineLength, longTargetLevel, color=color.green, width=2)
        
        // Track trade
        if not inLongTrade and not inShortTrade
            inLongTrade := true
            tradeEntryPrice := longEntryLevel
            tradeStopLevel := longStopLevel
            tradeTargetLevel := longTargetLevel
            totalTrades := totalTrades + 1
            longTrades := longTrades + 1
            
    // For bearish pattern, enter on second bar after pattern
    if bearishActive
        // Find the highest high of the last two candles from pattern detection
        float highestHigh = math.max(high[2], high[1])
        shortEntryLevel := close
        shortStopLevel := highestHigh
        shortTargetLevel := shortEntryLevel - ((shortStopLevel - shortEntryLevel) * rr)
        
        // Draw entry, stop, and target lines for bearish pattern
        entryLine := line.new(bar_index, shortEntryLevel, bar_index + lineLength, shortEntryLevel, color=color.blue, width=2)
        stopLine := line.new(bar_index, shortStopLevel, bar_index + lineLength, shortStopLevel, color=color.red, width=2)
        targetLine := line.new(bar_index, shortTargetLevel, bar_index + lineLength, shortTargetLevel, color=color.green, width=2)
        
        // Track trade
        if not inLongTrade and not inShortTrade
            inShortTrade := true
            tradeEntryPrice := shortEntryLevel
            tradeStopLevel := shortStopLevel
            tradeTargetLevel := shortTargetLevel
            totalTrades := totalTrades + 1
            shortTrades := shortTrades + 1

// Check if pattern should be deactivated
if patternActive and time > patternEndTime
    patternActive := false

//-----------------------------------------------------------------------------// Background Color for Active Pattern
//-----------------------------------------------------------------------------
// Background color to show active pattern
bgColor = color.new(color.white, 100)  // Initialize with transparent color
if patternActive
    bgColor := bullishActive ? color.new(color.green, 90) : color.new(color.red, 90)

bgcolor(bgColor)

//-----------------------------------------------------------------------------// Trade Outcome Tracking
//-----------------------------------------------------------------------------
// Check active long trade outcome
if inLongTrade
    if high >= tradeTargetLevel
        // Winner - Target hit
        inLongTrade := false
        winningTrades := winningTrades + 1
        consecutiveWins := consecutiveWins + 1
        consecutiveLosses := 0
        maxConsecutiveWins := math.max(maxConsecutiveWins, consecutiveWins)
        
        // Update equity curve
        currentEquity := currentEquity + (rr * (tradeEntryPrice - tradeStopLevel))
        peakEquity := math.max(peakEquity, currentEquity)
        
        // Update total RR gain - add the full RR value
        totalRRGain := totalRRGain + rr
    else if low <= tradeStopLevel
        // Loser - Stop hit
        inLongTrade := false
        losingTrades := losingTrades + 1
        consecutiveLosses := consecutiveLosses + 1
        consecutiveWins := 0
        maxConsecutiveLosses := math.max(maxConsecutiveLosses, consecutiveLosses)
        
        // Update equity curve and drawdown
        currentEquity := currentEquity - (tradeEntryPrice - tradeStopLevel)
        currentDrawdown := currentEquity - peakEquity
        maxDrawdown := math.min(maxDrawdown, currentDrawdown)
        
        // Update total RR gain - subtract 1R for loss
        totalRRGain := totalRRGain - 1

// Check active short trade outcome
if inShortTrade
    if low <= tradeTargetLevel
        // Winner - Target hit
        inShortTrade := false
        winningTrades := winningTrades + 1
        consecutiveWins := consecutiveWins + 1
        consecutiveLosses := 0
        maxConsecutiveWins := math.max(maxConsecutiveWins, consecutiveWins)
        
        // Update equity curve
        currentEquity := currentEquity + (rr * (tradeStopLevel - tradeEntryPrice))
        peakEquity := math.max(peakEquity, currentEquity)
        
        // Update total RR gain - add the full RR value
        totalRRGain := totalRRGain + rr
    else if high >= tradeStopLevel
        // Loser - Stop hit
        inShortTrade := false
        losingTrades := losingTrades + 1
        consecutiveLosses := consecutiveLosses + 1
        consecutiveWins := 0
        maxConsecutiveLosses := math.max(maxConsecutiveLosses, consecutiveLosses)
        
        // Update equity curve and drawdown
        currentEquity := currentEquity - (tradeStopLevel - tradeEntryPrice)
        currentDrawdown := currentEquity - peakEquity
        maxDrawdown := math.min(maxDrawdown, currentDrawdown)
        
        // Update total RR gain - subtract 1R for loss
        totalRRGain := totalRRGain - 1

// Calculate win rate (use totalTrades > 0 to avoid division by zero)
winRate := totalTrades > 0 ? (winningTrades / totalTrades) * 100 : 0

//-----------------------------------------------------------------------------// Pattern Visualization
//-----------------------------------------------------------------------------
// Add candle pattern markers
plotshape(newBullishPattern, title="Bullish Pattern", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.normal)
plotshape(newBearishPattern, title="Bearish Pattern", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.normal)

//-----------------------------------------------------------------------------// Performance Statistics Table
//-----------------------------------------------------------------------------
if showStats
    // Create table with only 13 rows (0-12)
    var table statsTable = table.new(position.top_right, 2, 13, color.new(color.black, 20), color.white, 2, color.new(color.gray, 20), 2)
    var int firstBarTime = 0
    var int lastBarTime = 0
    var int firstTradeTime = 0
    
    // Capture first bar time
    if firstBarTime == 0 and barstate.isfirst
        firstBarTime := time
    
    // Capture first trade time
    if firstTradeTime == 0 and (newBullishPattern or newBearishPattern)
        firstTradeTime := time
    
    // Capture last bar time
    if barstate.islast
        lastBarTime := time
    
    // Update the table on every bar
    if barstate.islast
        // Format dates
        firstDateStr = str.format("{0,date,yyyy-MM-dd}", firstBarTime)
        lastDateStr = str.format("{0,date,yyyy-MM-dd}", lastBarTime)
        
        // Calculate trading duration
        int tradingDays = 0
        if firstTradeTime > 0
            // Convert milliseconds to days (86400000 ms = 1 day)
            tradingDays := math.round((time - firstTradeTime) / 86400000)
        
        // Title and date
        table.cell(statsTable, 0, 0, "Performance Statistics", text_color=color.white, bgcolor=color.new(color.blue, 20), text_size=size.normal)
        table.cell(statsTable, 1, 0, "", bgcolor=color.new(color.blue, 20))
        
        // Backtest date range
        table.cell(statsTable, 0, 1, "Date Range:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 1, firstDateStr + " to " + lastDateStr, text_color=color.white, text_size=size.normal)
        
        // Trading days
        table.cell(statsTable, 0, 2, "Days Since First Trade:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 2, str.tostring(tradingDays), text_color=color.white, text_size=size.normal)
        
        // Trading symbol
        table.cell(statsTable, 0, 3, "Symbol:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 3, syminfo.ticker, text_color=color.white, text_size=size.normal)
        
        // Trade counts
        table.cell(statsTable, 0, 4, "Total Trades:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 4, str.tostring(totalTrades), text_color=color.white, text_size=size.normal)
        
        table.cell(statsTable, 0, 5, "Long Positions:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 5, str.tostring(longTrades), text_color=color.white, text_size=size.normal)
        
        table.cell(statsTable, 0, 6, "Short Positions:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 6, str.tostring(shortTrades), text_color=color.white, text_size=size.normal)
        
        // Win/Loss
        table.cell(statsTable, 0, 7, "Winning Trades:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 7, str.tostring(winningTrades), text_color=color.white, text_size=size.normal)
        
        table.cell(statsTable, 0, 8, "Losing Trades:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 8, str.tostring(losingTrades), text_color=color.white, text_size=size.normal)
        
        // Win rate
        table.cell(statsTable, 0, 9, "Win Rate:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 9, str.tostring(math.round(winRate, 2)) + "%", text_color=color.white, text_size=size.normal)
        
        // Consecutive wins/losses
        table.cell(statsTable, 0, 10, "Max Consecutive Wins:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 10, str.tostring(maxConsecutiveWins), text_color=color.white, text_size=size.normal)
        
        table.cell(statsTable, 0, 11, "Max Consecutive Losses:", text_color=color.white, text_size=size.normal)
        table.cell(statsTable, 1, 11, str.tostring(maxConsecutiveLosses), text_color=color.white, text_size=size.normal)
        
        // Current streak (row 12 - the final row in a 0-indexed table of 13 rows)
        table.cell(statsTable, 0, 12, "Current Streak:", text_color=color.white, text_size=size.normal)
        if consecutiveWins > 0
            table.cell(statsTable, 1, 12, str.tostring(consecutiveWins) + " Wins", text_color=color.green, text_size=size.normal)
        else if consecutiveLosses > 0
            table.cell(statsTable, 1, 12, str.tostring(consecutiveLosses) + " Losses", text_color=color.red, text_size=size.normal)
        else
            table.cell(statsTable, 1, 12, "0", text_color=color.white, text_size=size.normal)

//-----------------------------------------------------------------------------// Alerts
//-----------------------------------------------------------------------------
// Entry alerts
alertcondition(newBullishPattern, title="Bullish Pattern Detected", message="Bullish Pattern Detected - Prepare For Potential Entry")
alertcondition(newBearishPattern, title="Bearish Pattern Detected", message="Bearish Pattern Detected - Prepare For Potential Entry")
alertcondition(waitingForSecondBar and bar_index == (patternBarIndex + 1), title="Entry Coming Soon", message="Entry Signal Coming on Next Bar")
alertcondition(not waitingForSecondBar and bar_index == (patternBarIndex + 2) and (bullishActive or bearishActive), title="Entry Now", message="Take Entry Now")
Editor is loading...
Leave a Comment