// Licensed under the Apache License, Version 2.0 // © mihakralj //@version=6 indicator("Kendall Rank Correlation (KENDALL)", "KENDALL", overlay=false, precision=4) //@function Calculates Kendall's Tau-a rank correlation coefficient. //@param source1 series float The first input series. //@param source2 series float The second input series. //@param length int The lookback period. Min 2, Max 60. //@returns series float Kendall's Tau-a coefficient, ranging from -1 to +1. kendall(series float source1, series float source2, simple int length) => if length < 2 float(na) else float[] src1_window = array.new_float(length) float[] src2_window = array.new_float(length) bool window_has_na = false for k = 0 to length - 1 val1_k = source1[length - 1 - k] val2_k = source2[length - 1 - k] if na(val1_k) or na(val2_k) window_has_na := true break array.set(src1_window, k, val1_k) array.set(src2_window, k, val2_k) if window_has_na float(na) else concordant_pairs = 0 discordant_pairs = 0 for i = 0 to length - 2 for j = i + 1 to length - 1 val1_i = array.get(src1_window, i) val2_i = array.get(src2_window, i) val1_j = array.get(src1_window, j) val2_j = array.get(src2_window, j) diff_val1 = val1_i - val1_j diff_val2 = val2_i - val2_j product_of_signs = diff_val1 * diff_val2 if product_of_signs > 0 concordant_pairs += 1 else if product_of_signs < 0 discordant_pairs += 1 denominator = length * (length - 1) / 2.0 if denominator == 0.0 float(na) else (concordant_pairs - discordant_pairs) / denominator // Inputs i_source1 = input.source(close, "Source 1") i_source2_ticker = input.symbol("SPY", "Source 2 Ticker (e.g., SPY, AAPL)") i_period = input.int(20, "Period", minval=2) i_source2 = request.security(i_source2_ticker, timeframe.period, close, lookahead=barmerge.lookahead_off) // Calculation kendall_value = kendall(i_source1, i_source2, i_period) // Plot plot(kendall_value, "Kendall's Tau", color=color.yellow, linewidth=2)