Ecco:
// ---------------------------------------------------------
// PRC_Echo Chamber (Pattern Projection)
// version = 0
// 04.12.2025
// Iván González @ www.prorealcode.com
// Sharing ProRealTime knowledge
// ---------------------------------------------------------
DEFPARAM DrawOnLastBarOnly = True
// --- PARAMETERS ---
// Length: Correlation window (bars to compare)
Length = 20
// Lookback: How many bars to look back in history
Lookback = 500
// ProjectionLen: How many bars to project into the future
ProjectionLen = 20
// --- INTERNAL VARIABLES ---
bestCorrelation = -1.0
bestIndex = 0
currentScale = 0.0
historyScale = 0.0
// Execute only on the last bar to optimize resources
IF islastbarupdate THEN
// 1. GET CURRENT SEQUENCE
// Fill an array with recent close prices
$currentSeq[0] = 0
SumX = 0.0
SumX2 = 0.0
FOR i = 0 TO Length - 1 DO
val = Close[i]
$currentSeq[i] = val
// Prepare data for correlation (X = Current Sequence)
SumX = SumX + val
SumX2 = SumX2 + (val * val)
NEXT
MeanX = SumX / Length
StDevX = SQRT((SumX2 / Length) - (MeanX * MeanX))
// 2. PATTERN SEARCH
// Iterate backwards in history to find the best match
// Start after the current window to avoid self-comparison
StartIndex = Length + ProjectionLen
EndIndex = Lookback
FOR k = StartIndex TO EndIndex DO
SumY = 0.0
SumY2 = 0.0
SumXY = 0.0
// Collect historical segment (Y)
FOR j = 0 TO Length - 1 DO
histVal = Close[k + j]
currVal = $currentSeq[j] // Note: currentSeq[0] is current Close
SumY = SumY + histVal
SumY2 = SumY2 + (histVal * histVal)
SumXY = SumXY + (currVal * histVal)
NEXT
// Calculate Pearson Correlation r
MeanY = SumY / Length
StDevY = SQRT((SumY2 / Length) - (MeanY * MeanY))
// Avoid division by zero if price is flat
IF (StDevX * StDevY) <> 0 THEN
Covariance = (SumXY / Length) - (MeanX * MeanY)
Correlation = Covariance / (StDevX * StDevY)
ELSE
Correlation = 0
ENDIF
// Save best result
IF Correlation > bestCorrelation THEN
bestCorrelation = Correlation
bestIndex = k
ENDIF
NEXT
// 4. DRAW RESULTS
IF bestIndex > 0 THEN
// A) Highlight found historical segment
// Calculate range to draw the box
maxH = High[bestIndex]
minL = Low[bestIndex]
FOR j = 0 TO Length - 1 DO
maxH = MAX(maxH, High[bestIndex + j])
minL = MIN(minL, Low[bestIndex + j])
NEXT
// Draw rectangle in the past
x1 = BarIndex - bestIndex - Length + 1
x2 = BarIndex - bestIndex
DRAWRECTANGLE(x1, maxH, x2, minL) COLOURED(100, 200, 250, 50) BORDERCOLOR(100, 200, 250)
DRAWTEXT("Match History", x1, maxH) ANCHOR(BOTTOM, INDEX, VALUE) COLOURED(100, 200, 250)
// B) Future Projection
// Scale historical price to current price
// Scale factor based on ranges (High - Low of the period)
rangeHist = maxH - minL
rangeCurr = Highest[Length](High) - Lowest[Length](Low)
IF rangeHist <> 0 THEN
scaleFactor = rangeCurr / rangeHist
ELSE
scaleFactor = 1
ENDIF
// Anchor point (last close)
anchorPrice = Close[0]
histAnchor = Close[bestIndex]
// Draw projection line by line
FOR m = 1 TO ProjectionLen DO
// bestIndex is the end of the pattern. The future is at bestIndex - m
idxFuture = bestIndex - m
// Stop if index is out of bounds (negative index)
IF idxFuture < 0 THEN
BREAK
ENDIF
priceHistFuture = Close[idxFuture]
priceHistPrev = Close[idxFuture + 1]
// Price transformation: Adjustment by scale and anchor
// Projecting the variation
price1raw = Close[bestIndex - (m - 1)]
price2raw = Close[bestIndex - m]
// Transform
val1 = anchorPrice + (price1raw - histAnchor) * scaleFactor
val2 = anchorPrice + (price2raw - histAnchor) * scaleFactor
// X Coordinates (Future)
xStart = BarIndex + m - 1
xEnd = BarIndex + m
DRAWSEGMENT(xStart, val1, xEnd, val2) COLOURED(255, 105, 180) STYLE(dottedline, 2)
NEXT
// 5. INFORMATION PANEL
txtCorr = round(bestCorrelation * 100, 2)
txtDateYear = year[bestIndex]
txtDateMonth = month[bestIndex]
txtDateDay = day[bestIndex]
txtTimehour = hour[bestIndex]
txtTimeminute = minute[bestIndex]
if gettimeframe<86400 then
DRAWTEXT("ECHO CHAMBER", -200, -100) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(0, 0, 0)
DRAWTEXT("Corr.: #txtCorr#%", -200, -120) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(125, 125, 220)
DRAWTEXT("Date: #txtDateYear#/#txtDateMonth#/#txtDateDay#", -200, -140) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(200, 200, 200)
DRAWTEXT("Time: #txtTimehour#:#txtTimeminute#", -200, -160) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(200, 200, 200)
drawrectangle(-290, -80, -110, -180)ANCHOR(TOPRIGHT, XSHIFT, YSHIFT)
else
DRAWTEXT("ECHO CHAMBER", -200, -100) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(0, 0, 0)
DRAWTEXT("Corr.: #txtCorr#%", -200, -120) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(125, 125, 220)
DRAWTEXT("Date: #txtDateYear#/#txtDateMonth#/#txtDateDay#", -200, -140) ANCHOR(TOPRIGHT, XSHIFT, YSHIFT) COLOURED(200, 200, 200)
drawrectangle(-290, -80, -110, -160)ANCHOR(TOPRIGHT, XSHIFT, YSHIFT)
endif
ENDIF
ENDIF
RETURN