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

//@version=5

// @description TODO: add library description here
library("Polynomial",overlay = true)

// @function TODO: add function description here
// @param x TODO: add parameter x description here
// @returns TODO: add what function returns
export PolyNomial(int Dop,int n,int step,int nonp) =>
	// l = ta.pivotlow(low,len,len)
	// h = ta.pivothigh(high,len,len)
	// n = math.max(ta.barssince(na(l)==false),ta.barssince(na(h)==false))+len
	Y = matrix.new<float>(1,1,0)
	X = matrix.new<float>(1,Dop+1,0)
	dataY = array.new<float>(1)
	dataX = array.new<float>(Dop+1)
	j = n
	Indexes = array.new<int>()
	while j>0
		array.push(Indexes,bar_index[j])
		array.set(dataY,0,close[j])
		for i=0 to Dop
			xv = (n-j)/step
			array.set(dataX,i,math.pow(xv,i))
		matrix.add_row(Y,matrix.rows(Y),dataY)
		matrix.add_row(X,matrix.rows(X),dataX)
		j:=j-step
	matrix.remove_row(Y,0)
	matrix.remove_row(X,0)
	endIndex = j+step
	XtX = matrix.mult(matrix.transpose(X),X)
	B = matrix.mult(matrix.transpose(X),Y)
	A = matrix.mult(matrix.pinv(XtX),B)
	Error = array.avg(array.abs(matrix.col(matrix.diff(Y,matrix.mult(X,A)),0)))/n
	x = matrix.new<float>(nonp,Dop+1,0)
	for i=0 to nonp-1
		array.push(Indexes,bar_index[endIndex]+(i+1)*step)
		for k=0 to Dop
			xv = (n-j)/step
			matrix.set(x,i,k,math.pow(xv,k))
		j:=j-step
	// matrix.concat(X,x)
	Y := matrix.mult(x,A)
	[Y,Error]
// ======================================
// Test PolyNomial===================================
// [A,X,Indexes,Error] = PolyNomial(4,50,5,4)
// var Lines = array.new_line()
// if barstate.islast
// 	Y = matrix.mult(X,A)
// 	for i=0 to array.size(Indexes)-2
// 		x1 = array.get(Indexes,i)
// 		x2 = array.get(Indexes,i+1)
// 		y1 = matrix.get(Y,i,0)
// 		y2 = matrix.get(Y,i+1,0)
// 		if array.size(Lines)>50
// 			ln = array.shift(Lines)
// 			line.delete(ln)
// 		array.push(Lines,line.new(x1, y1, x2, y2))
	
// 	var t = table.new(position.bottom_center,2, 1, color.green)
// 	table.cell(t, 0, 0, "Error: ")
// 	table.cell(t, 1, 0, str.tostring(Error))
// ======================================================