// Linear-regression family (TA-Lib "Statistic Functions"): slope, intercept,
// regression endpoint, angle in degrees and one-bar forecast. All five share
// the least-squares core `linreg_at`.
///|
/// Least-squares slope and intercept of the last `period` values ending at
/// index `i`, using the bar offset 0..period-1 as x. A NaN inside the window
/// yields (NaN, NaN).
fn linreg_at(
data : Array[Double],
i : Int32,
period : Int32,
) -> (Double, Double) {
let mut sx = 0.0
let mut sy = 0.0
let mut valid = true
for j in (i - period + 1)..<(i + 1) {
let y = data[j]
if @base.is_nan(y) {
valid = false
break
}
sx += (j - i + period - 1).to_double()
sy += y
}
if !valid {
return (@base.nan(), @base.nan())
}
let pd = period.to_double()
let x_bar = sx / pd
let y_bar = sy / pd
let mut num = 0.0
let mut den = 0.0
for j in (i - period + 1)..<(i + 1) {
let dx = (j - i + period - 1).to_double() - x_bar
let dy = data[j] - y_bar
num += dx * dy
den += dx * dx
}
if den == 0.0 {
return (@base.nan(), @base.nan())
}
let slope = num / den
(slope, y_bar - slope * x_bar)
}
///|
/// Least-squares slope over a rolling window. A window shorter than 2 bars
/// cannot define a slope; `period` must be at least 2.
pub fn linearreg_slope(
data : Array[Double],
period : Int32,
) -> Array[Double] raise @base.TaError {
@base.validate_series(data, period)
if period < 2 {
raise @base.InvalidPeriod("period must be at least 2, got \{period}")
}
let n = data.length()
let out : Array[Double] = []
for i in 0.. Array[Double] raise @base.TaError {
@base.validate_series(data, period)
if period < 2 {
raise @base.InvalidPeriod("period must be at least 2, got \{period}")
}
let n = data.length()
let out : Array[Double] = []
for i in 0.. Int32 {
period - 1
}
///|
/// Linear regression endpoint: the fitted value at the current bar,
/// `intercept + slope * (period - 1)`.
pub fn linearreg(
data : Array[Double],
period : Int32,
) -> Array[Double] raise @base.TaError {
@base.validate_series(data, period)
if period < 2 {
raise @base.InvalidPeriod("period must be at least 2, got \{period}")
}
let n = data.length()
let out : Array[Double] = []
for i in 0.. Array[Double] raise @base.TaError {
@base.validate_series(data, period)
if period < 2 {
raise @base.InvalidPeriod("period must be at least 2, got \{period}")
}
let n = data.length()
let rad_to_deg = 180.0 / 3.141592653589793
let out : Array[Double] = []
for i in 0.. Array[Double] raise @base.TaError {
@base.validate_series(data, period)
if period < 2 {
raise @base.InvalidPeriod("period must be at least 2, got \{period}")
}
let n = data.length()
let out : Array[Double] = []
for i in 0..