FunctionForecastLinear
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RicardoSantos

//@version=5

// @description Method for linear Forecast, same as found in excel and other sheet packages.
library(title='FunctionForecastLinear')

import RicardoSantos/ArrayGenerate/1 as ag

// @function linear forecast method.
// @param sample_x float array, sample data X value.
// @param sample_y float array, sample data Y value.
// @param target_x float, target X to get Y forecast value.
// @returns float
export forecast (float[] sample_x, float[] sample_y, float target_x) =>  //{
//  @function: Linear forecast, same as excel and other sheet packages. calculates the future value given known data.
//  @parameters:
//      sample_x: float[] or int[], data sample for X.
//      sample_y: float[] or int[], data sample for Y.
//      target_x: float or int, 0>x, value of X to predict Y.
//  @reference:
//      https://support.microsoft.com/en-us/office/forecast-and-forecast-linear-functions-50ca49c9-7b40-4892-94e4-7ad38bbeda99?ui=en-us&rs=en-us&ad=us
//      https://stackoverflow.com/questions/39373328/forecast-formula-from-excel-in-javascript
    int _size_x = array.size(sample_x)
    int _size_y = array.size(sample_y)
    //
    switch
        (_size_x < 1) => runtime.error('FunctionForecastLinear -> forecast(): "sample_x" has the wrong size.')
        (_size_x != _size_y) => runtime.error('FunctionForecastLinear -> forecast(): "sample_x" and "sample_y" size does not match.')
    //
    float _nr = 0.
    float _dr = 0.
    float _ax = array.avg(sample_x)
    float _ay = array.avg(sample_y)
    for _i = 0 to _size_x - 1 by 1
        _xi = array.get(sample_x, _i)
        _yi = array.get(sample_y, _i)
        _nr := _nr + (_xi - _ax) * (_yi - _ay)
        _dr := _dr + (_xi - _ax) * (_xi - _ax)
    //
    float _b = _nr / _dr
    float _a = _ay - _b * _ax
    _a + _b * target_x
//{ usage:
//{ remarks:
//}}}

//test samples from: https://corporatefinanceinstitute.com/resources/excel/functions/forecast-linear-function/
test_earnings = array.from(879., 1259., 1230., 1471., 1562., 1526., 1437., 1637., 1689., 1720., 1456., 1653.)
test_expenses = array.from(263.7, 377.7, 369., 441.3, 468.6, 457.8, 431.1, 491.1, 506.7, 516., 436.8, 495.9)

f0 = forecast(array.from(1, 2, 3, 4, 5), array.from(6., 7., 8., 9., 10.), 6)
f1 = forecast(test_earnings, test_expenses, 1705.25)
// f0 = forecast(array.from(20, 28, 31, 38, 40), array.from(6, 7, 9, 15, 21), 30)
f2 = bar_index <= 100 ? 0.0 : forecast(ag.sequence_from_series(bar_index, 100, 0, true), ag.sequence_from_series(close, 100, 0, true), bar_index + 30)

t = str.format('forecast linear sample: {0}\nforecast from data sample: {1}\nforecast from series: {2}', f0, f1, f2)

if barstate.islast

    label.new(bar_index, 0.0, t)


