Pine Scipt conversion – Polynomial Regression Extrapolation
Forums › ProRealTime English forum › ProBuilder support › Pine Scipt conversion – Polynomial Regression Extrapolation
- This topic has 22 replies, 6 voices, and was last updated 1 year ago by LucasBest.
-
-
10/05/2022 at 10:30 AM #201933
Hello, can someone please help converting this code?
I’m aware we don’t have multidimentional Arrays in PRT yet. I suspect, we can come over by splitting into multiple Arrays.
Thank you in advance
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/// © LuxAlgo//@version=5indicator("Polynomial Regression Extrapolation [LuxAlgo]", overlay = true, max_lines_count = 500)//------------------------------------------------------------------------------//Settings//-----------------------------------------------------------------------------{length = input.int(100, minval = 0)extrapolate = input.int(10, minval = 0)degree = input.int(3, 'Polynomial Degree', minval = 0, maxval = 8)src = input(close)lock = input(false, 'Lock Forecast')//Styleup_css = input.color(#0cb51a, 'Upward Color', group = 'Style')dn_css = input.color(#ff1100, 'Downward Color', group = 'Style')ex_css = input.color(#ff5d00, 'Extrapolation Color', group = 'Style')width = input(1, 'Width', group = 'Style')//-----------------------------------------------------------------------------}//Fill lines array//-----------------------------------------------------------------------------{var lines = array.new_line(0)if barstate.isfirstfor i = -extrapolate to length-1array.push(lines, line.new(na, na, na, na))//-----------------------------------------------------------------------------}//Get design matrix & partially solve system//-----------------------------------------------------------------------------{n = bar_indexvar design = matrix.new<float>(0, 0)var response = matrix.new<float>(0, 0)if barstate.isfirstfor i = 0 to degreecolumn = array.new_float(0)for j = 0 to length-1array.push(column, math.pow(j,i))matrix.add_col(design, i, column)var a = matrix.inv(matrix.mult(matrix.transpose(design), design))var b = matrix.mult(a, matrix.transpose(design))//-----------------------------------------------------------------------------}//Get response matrix and compute roling polynomial regression//-----------------------------------------------------------------------------{var pass = 1var matrix<float> coefficients = navar x = -extrapolatevar float forecast = naif barstate.islastif passprices = array.new_float(0)for i = 0 to length-1array.push(prices, src[i])matrix.add_col(response, 0, prices)coefficients := matrix.mult(b, response)float y1 = naidx = 0for i = -extrapolate to length-1y2 = 0.for j = 0 to degreey2 += math.pow(i, j)*matrix.get(coefficients, j, 0)if idx == 0forecast := y2//------------------------------------------------------------------//Set lines//------------------------------------------------------------------css = y2 < y1 ? up_css : dn_cssget_line = array.get(lines, idx)line.set_xy1(get_line, n - i + 1, y1)line.set_xy2(get_line, n - i, y2)line.set_color(get_line, i <= 0 ? ex_css : css)line.set_width(get_line, width)y1 := y2idx += 1if lockpass := 0elsey2 = 0.x -= 1for j = 0 to degreey2 += math.pow(x, j)*matrix.get(coefficients, j, 0)forecast := y2plot(pass == 0 ? forecast : na, 'Extrapolation', color = ex_css, offset = extrapolate, linewidth = width)//-----------------------------------------------------------------------------}08/27/2023 at 10:09 AM #219832If you want to come over multidimentional Arrays in PRT, the solution is not to split it into multiple Arrays, because this would mean changing the code of the script each time one or both size of the multidimentional Arrays will change… which is not possible!
In reality, coming over 2 dimensions arrays (in PRT) with only 1 dimension array is not a big deal. It has ben done for years since early stage of computer science. What you see on your screen can be compared to a 2 dimentional array (rows and columns of the screen) and it is simply stored in the memory of the computer in a one dimention array… It is possible as far as you know how much rows and columns you need to store in your 1 dimension array.
I did the conversion of the begining of Polynomial Regression Extrapolation by LuxAlgo. You can find it below.
The biggest deal here is to come over those built-in function for multidimentional Arrays that come with pine script.
For example “matrix.inv” calculate the inverse of a square matrix, which is not easy to code and will require several lines of code and take long time to calculate if it is not done in a built-in function…
Polynomial Regressi Extrapolat1234567891011121314151617181920212223242526272829303132333435defparam drawonlastbaronly = trueMaxlength = 500long = Min(barindex,Min(Maxlength,length))// degree = 0-8 Polynomial Degreesrc = customclose// lock = Lock Forecastonce init = 1n = barindexIf init = 1 thenFor k = 0 to degree*long-1 do$design[k]=0NextFor i = 0 to degree doFor j = 0 to long-1 doP = pow(j,i)$designT[i*long+j]= P$design[j*degree+i]= PNextNext//Matrix.multFor i = 0 to degree doFor j = 0 to degree dosum = 0For k = 0 to long-1 dosum=sum+$designT[i*long+k]*$design[k*degree+j]Next$produit[i*degree+j]=sumNextNextinit = 0Endif...1 user thanked author for this post.
08/27/2023 at 10:30 AM #219834@LucasBest Bravo. It’s clear, you’re talented. How can I finish translating the remaining part so that I can get the full code working? Thanks
08/27/2023 at 10:46 AM #219835I am trying to found a way to code simply the calculation of the inverse of a square matrix.
If someone can help me to do so, it would be appreciate, because all i learned in school about matrix is very far now… 🙂
The rest of LuxAlgo pine script will be quit easy to translate then.
For example, in the link below the script in c++ for inverse matrix calculation…
https://www.tutorialspoint.com/cplusplus-program-to-find-inverse-of-a-graph-matrix
1 user thanked author for this post.
08/27/2023 at 10:53 AM #21983608/27/2023 at 11:08 AM #21983908/27/2023 at 11:17 AM #21984108/27/2023 at 11:33 AM #219846will require several lines of code and take long time to calculate
like cooking a sauerkraut without cabbage
The latter can be overwon by a. growing the gabbage and b. ferment it. Yes, take many months for that indeed. The semolina needs further investigation.
08/27/2023 at 11:46 AM #219847The latter can be overwon by a. growing the gabbage and b. ferment it. Yes, take many months for that indeed. The semolina needs further investigation.
Hey Peter,
this is funny, but it does not help me to code the inverse function of a matrix… 😉
08/27/2023 at 6:52 PM #219882Polynomial Regressi Extrapolat123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869defparam drawonlastbaronly = trueMaxlength = 500long = Min(barindex,Min(Maxlength,length))// degree = 0-8 Polynomial Degreesrc = customclose// lock = Lock Forecastonce init = 1n = barindexIf init = 1 thenFor k = 0 to degree*long-1 do$design[k]=0NextFor i = 0 to degree-1 doFor j = 0 to long-1 doP = pow(j,i)$designT[i*long+j]= P$design[j*degree+i]= PNextNext//Matrix.multFor i = 0 to degree-1 doFor j = 0 to degree-1 dosum = 0For k = 0 to long-1 dosum=sum+$designT[i*long+k]*$design[k*degree+j]Next$produit[i*degree+j]=sumNextNext//Extracting Minors Matrix i,jMinordegree = degree-1For i = 0 to Minordegree doFor j = 0 to Minordegree dom = 0For k = 0 to degree*degree-1 doIf (j<>k mod degree) and (i<>floor(k/degree)) then$Minor[m]=$produit[k]m=m+1EndifNext//Calculation DeterminantIf Minordegree = 1 thendeterminant = $Minor[1]Elsif Minordegree = 2 thendeterminant = $Minor[1]*$Minor[4]-$Minor[2]*$Minor[3]Elsif Minordegree = 3 thendeterminant = $Minor[1]*($Minor[5]*$Minor[9]-$Minor[6]*$Minor[8])-$Minor[2]*($Minor[4]*$Minor[9]-$Minor[6]*$Minor[7])+$Minor[3]*($Minor[4]*$Minor[8]-$Minor[5]*$Minor[7])Endif//Setting cofactor Matrix$cofactor[i*degre+j]=pow(-1,i+j)*determinantNextNext//Calculating overall determinantdeterminant = 0For k = 0 to degree-1 dodeterminant = determinant + $produit[k]*$cofactor[k]$Inverse[k] = 0Next//Setting Inverse MatrixFor i = 0 to degree-1 doFor j = 0 to degree-1 do$Inverse[i+j*degree] = $cofactor[i*degree+j]*(1/determinant)NextNextinit = 0EndifLucas, can i suggest that you replace this inverse matrix by whatever pleases you to get over this step (for now until we find a solution) and continue the rest with an alternative option to this inverse matrix? Thanks
Ok, i did not replace, but i found a solution for calculating the inverse of the matrix, until degree 4… Now i can finish and will found a solution later for inversing bigger square matrix
1 user thanked author for this post.
08/28/2023 at 9:16 AM #219918It is working now, but there is still some bugs…
Polynomial Regressi Extrapolat123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148defparam drawonlastbaronly = trueMaxlength = 500long = Min(barindex,Min(Maxlength,length))// degree = 0-8 Polynomial Degreesrc = customclose// lock = Lock Forecastonce init = 1n = barindexIf init=1 and long=length thenFor k = 0 to degree*long-1 do$design[k]=0NextFor i = 0 to degree-1 doFor j = 0 to long-1 doP = pow(j,i)$designT[i*long+j]= P$design[j*degree+i]= PNextNext//Matrix.multFor i = 0 to degree-1 doFor j = 0 to degree-1 dosum = 0For k = 0 to long-1 dosum=sum+$designT[i*long+k]*$design[k*degree+j]Next$produit[i*degree+j]=sumNextNext//Extracting Minors Matrix i,jMinordegree = degree-1For i = 0 to Minordegree doFor j = 0 to Minordegree dom = 0For k = 0 to degree*degree-1 doIf (j<>k mod degree) and (i<>floor(k/degree)) then$Minor[m]=$produit[k]m=m+1EndifNext//Calculation DeterminantIf Minordegree = 1 thendeterminant = $Minor[0]Elsif Minordegree = 2 thendeterminant = $Minor[0]*$Minor[3]-$Minor[1]*$Minor[2]Elsif Minordegree = 3 thendeterminant = $Minor[0]*($Minor[4]*$Minor[8]-$Minor[5]*$Minor[7])-$Minor[1]*($Minor[3]*$Minor[8]-$Minor[5]*$Minor[6])+$Minor[2]*($Minor[3]*$Minor[7]-$Minor[4]*$Minor[6])Endif//Setting cofactor Matrix$cofactor[i*degree+j]=pow(-1,i+j)*determinantNextNext//Calculating overall determinantdeterminant = 0For k = 0 to degree-1 dodeterminant = determinant + $produit[k]*$cofactor[k]Next//Setting Inverse Matrix => $aFor k = 0 to degree*degree-1 do$a[k]=0NextFor i = 0 to degree-1 doFor j = 0 to degree-1 do$a[i+j*degree] = $cofactor[i*degree+j]*(1/determinant)NextNextFor i = 0 to degree-1 doFor j = 0 to degree-1 do$a[i+j*degree] = $cofactor[i*degree+j]*(1/determinant)NextNext//Setting Mult matrice => $bFor i = 0 to degree-1 doFor j = 0 to long-1 dosum = 0For k = 0 to degree-1 dosum=sum+$a[i*degree+k]*$designT[k*long+j]Next$b[i*long+j]=sumNextNextinit = 0Endifonce pass = 1once x = -1 * Extrapolateonce forecast = 0If IsLastBarUpdate thenIf pass = 1 thenFor i = 0 to long-1 do$response[i] = src[i]Next//Setting Mult matrice => $coefficientsFor i = 0 to degree-1 doj = 0sum = 0For k = 0 to long-1 dosum=sum+$b[i*long+k]*$response[k]Next$coefficients[i]=sumNextonce y1 = 0idx = 0For i = -Extrapolate to long-1 doy2 = 0for j = 0 to degree-1 doy2 = y2+pow(i,j)*$coefficients[j]NextIf idx = 0 thenforecast = y2EndifIf y2 < y1 thenr = 10g = 255b = 10elser = 255g = 10b = 10EndifDRAWSEGMENT(n-i, y2, n-i+1, y1)style(line,5)coloured(r,g,b,100)y1 = y2idx = idx+1If lock thenpass = 0EndifNextelsey2 = 0x = x -1For j = 0 to degree doy2 = y2+pow(x,j)*$coefficients[j]Nextforecast = y2EndifIf pass = 0 thenDRAWPOINT(n+extrapolate, forecast, 5)EndifEndifReturn08/28/2023 at 9:34 AM #219923With 3 and 4 degree and a different lngth… forecast can be completly different while increasing/decreasing degree or length.
I think this kind of indicator, that repaint, and only shows what we want to see are completly useless for trading.08/28/2023 at 9:37 AM #21992708/28/2023 at 9:47 AM #219930Bravo Lucas. Yes, it repaints like the Center of Gravity. But anyway, bravo for having solved such a complex mathematical/coding problem. We can have separate discussion on the relevance of Indicators in general for a Retail Trader. After a few yers of observation of the Futures markets (never trader Forex), the Indicators do offer very limited success for day trading. They might be uselful on higher timeframe, but up to 30 minutes, what matters is Order Flow and Price Action, which unless you have access to sophisticated tools and an army of quants and programmers can be a huge task for a Retail Trader. The HFT Algos use the information available in the DOM to grab a few ticks and play games of manipulation and spoofing. Merci encore!
08/28/2023 at 3:36 PM #219955 -
AuthorPosts