Untitled
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