Correlations P/L Range (in percent)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © mpeick (Michael Peick)

// This script shows the inefficiency of the markets.
//
// Comparing two (correlated) symbols, the values above 0 means the main symbol (at the top of the graph)
// outperforms the other. A value below 0 means the main symbol underperforms the other.
// 
// The band displays different entries until the last candle. Any P/L (of the band range)
// is visible in the band. Example: given a band range length of 5, then all last 5 values
// are compares with the current value for both symbols. Or in other words:
// If symbol A, lets say ETHUSD outperforms, lets say BITCOIN (the main symbol), in the last
// 5 candles, then we would see all values of the band are negative.

//@version=5
indicator("Correlations P/L Range (in percent)", precision=2)

// input data:
which_symbol = input.symbol("FTX:ETHUSD", "symbol")
length = input.int(5, "Band range length", minval=1)
stretch_factor = input.int(1, "Stretch Correlation Factor", minval=1)

main_data = close
second_data = request.security(which_symbol, "", close)

// define profit/loss function for all values from 1 to length (input value)
pl_range(source1, source2, min_length, max_length) =>
    big = 10000.0       // there's no infinity value in pinescript, so we use a ridiculous big number (for P/L)
    min_out = big
    max_out = -big
    for offset = min_length to max_length
        pl_source1 = (source1[0] - source1[offset]) / source1[offset]
        pl_source2 = (source2[0] - source2[offset]) / source2[offset]
        pl_diff = pl_source1 - pl_source2
        min_out := math.min(min_out, pl_diff)
        max_out := math.max(max_out, pl_diff)
    [min_out * 100, max_out * 100]

// plotting:
[min_out, max_out] = pl_range(main_data, second_data, 1, length)
col_min = (min_out > 0) ? color.green : ((min_out < 0) ? color.red : color.white)
plt_max = plot(max_out, color=color.orange, title="Line range max values")
plt_min = plot(min_out, color=color.yellow, title="Line range min values")
plt_max_above_0 = plot(math.max(0, max_out), display=display.none, editable=false)
plt_min_above_0 = plot(math.max(0, min_out), display=display.none, editable=false)
plt_max_below_0 = plot(math.min(0, max_out), display=display.none, editable=false)
plt_min_below_0 = plot(math.min(0, min_out), display=display.none, editable=false)

hline(price=0, linestyle=hline.style_dotted, color=color.white, title="Base line")
fill(plt_max_above_0, plt_min_above_0, color=color.new(color.green, 50), title="Fill above base line")
fill(plt_max_below_0, plt_min_below_0, color=color.new(color.red, 50), title="Fill below base line")

// display correction with a stretch factor to better visualize tops and bottoms
cor = math.pow(ta.correlation(main_data, second_data, length), stretch_factor)
plot(cor, color=color.blue, linewidth=2, title="Correlation", display=display.none)