Untitled
unknown
plain_text
7 months ago
16 kB
5
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