// Licensed under the Apache License, Version 2.0 // © mihakralj //@version=6 indicator("Log-Cosh Loss", "LogCosh", overlay=false) //@function Computes log(cosh(x)) in a numerically stable way //@param x The input value //@returns log(cosh(x)) stable_logcosh(float x) => float LOG2 = 0.6931471805599453 float absX = math.abs(x) // For large values, use asymptotic approximation to avoid overflow absX > 20.0 ? absX - LOG2 : math.log((math.exp(x) + math.exp(-x)) / 2.0) //@function Calculates Log-Cosh Loss //@param actual Series of actual values //@param predicted Series of predicted/forecast values //@param length Rolling window for averaging //@returns Mean log-cosh loss over the window logcosh_loss(series float actual, series float predicted, simple int length) => // Compute log-cosh loss for current bar float error = nz(actual, 0.0) - nz(predicted, 0.0) float loss = stable_logcosh(error) // Rolling mean of losses float result = ta.sma(loss, length) result // ---------- Main loop ---------- // Inputs i_length = input.int(14, "Length", minval=1) i_actual = input.source(close, "Actual") i_predicted = input.source(open, "Predicted") // Calculation logcosh_value = logcosh_loss(i_actual, i_predicted, i_length) // Plot plot(logcosh_value, "Log-Cosh Loss", color=color.yellow, linewidth=2) hline(0, "Zero", color=color.gray, linestyle=hline.style_dotted)