Arrays related bugs
Forums › ProRealTime English forum › ProBuilder support › Arrays related bugs
-
-
12/28/2024 at 10:45 AM #241837
Below are 2 strange bugs I have encountered while using Arrays extensively :
1 – Using the instruction “Lastset” in order to fill the arrays possibly resulting in errors. ProrealTime will not send an error message but you may see strange things on the screen…
While filling Arrays12345678910$MyTab[Lastset($MyTab)+1] = value //should be avoid////////////////////////////////once MyTabIndex = -1...MyTabIndex = MyTabIndex +1$MyTab[MyTabIndex] = value //More safe to avoid strange bugs// MyTabIndex is last index of the array $MyTab defined2 – Sometimes you will get an error message from ProrealTime saying that the code is trying to reach an index of an array that is not strictly positive integer…
And that is weird as i use one variable pointing to lastset element for each array i use… (like mentioned above)First, i mention that i always have this condition in my code :
12345If MyArrayIndex >= 0 then...Drawtext($Myarray[MyArrayIndex], barindex, high+10) //like this it may lead to an error message from ProrealTime...endifI always add this condition before trying to reach any value of the array, because of course you don’t know if it had been already filled or not…
But even with this condition before trying to get a value of the array, you may have the error message from Prorealcode, which is really strange!The only way i found to solve this problem is to use an other variable just before accessing to the array, like this below :
123456If MyArrayIndex >= 0 then...Mytemporaryvariable = MyArrayIndexDrawtext($Myarray[Mytemporaryvariable], barindex, high+10) //like this i have no error message...endifHave you also experiences such errors/bugs with arrays ?
12/29/2024 at 5:25 AM #241869Hi Lucas,
I think it all comes down to the same issue : the index variables you use to access the array are maintained at bar close only, while the array is maintained each tick. That is, when you work with the arrays from an Indicator – which is what you do in your examples (not really the first example, but I estimate you’re in Indicator code there as well).
Just take this into account very explicitly and see whether you still receive the errors.
Side note : that you – when solved – cannot achieve your original goals is something else; the solution to solve these issues would be to create the same code in Strategy Code (not Indicator code) and obviously you won’t achieve your goals any more. Still it would tell you where the problem lays : inconsistency between the state of array elements and your variables trying to capture that state. Again, from within Indicator code this can only be done at the end of the bar.The error you receive on the LastSet function requires some more thinking or reasoning, because that also should work from within Indicator code. However, here you now deal with the fact that ticks may come in faster than the whole lot under the hood can process. Think of the array being changed (the elements get added) in a parallel process, that process assuming that the initiating process (your Indicator code) will wait until the array has been changed (the new element has been added). But this can not exist and the code that changes the array will get behind because your Indicator (code) has to continue. And when the state of the array gets behind, the LastSet will be “out of order” and things go bananas internally.
It is my idea that these situations can not be solved except for not challenging for it.
To prove that this is going on indeed, you could try to count the ticks (= calls) in the Indicator code, know that the variable will save its contents at the end of the bar only, and next compare the number of array elements with the number in the variable. I think you will see that the array size (the number of elements in it) starts to run behind. But, perform this at more busy times; also, I think you should not try this in backtest because in backtest this will always work (nothing can run behind because all processes will nicely wait for each other’s task to finish).
Fill the variable in Indicator code and preferably do the comparison in Strategy code; this frees you of thinking on how to perform the comparison in decent fashion from within Indicator code, which is the whole subject of your issue …2 – Sometimes you will get an error message from ProrealTime saying that the code is trying to reach an index of an array that is not strictly positive integer…
That is the very general error you’ll receive when you try to access a non-existing array variable (or other “collection” means). Meanwhile the message tells you that you can not use negative indices to an array (collection).
Please notice that I am not talking from PRT experience as such, but from the general coding environment, and general means handing out error messages (think in terms of the Operating System doing this). PRT just passes those messages on to the user (you).I hope I made some sense, and feel free to ask to clarify more/better !
Peter1 user thanked author for this post.
12/29/2024 at 12:26 PM #241879Thank you for replying Peter.
I understand your explanations on how those bugs may happen, but i don’t agree totaly.
It can explan why when Lastset intruction is used things can go crazy because the indicators which i taling about are about 1000 lines of codes and can take little bit time to update at the end of the bar for the new bar…First, let you know that these bugs happen in real time (in prorealtime haha), but also in Market replay mode.
Second, as i mentioned, when i use a temporary variable it works fine… even if in your explanation this temporary variable would normaly have the same issue (of being updated only at the end of the bar). Isn’t it ?
How do you explain that the use of the temporary variable solve the problem and the error code never appears again (even in the same bars where it happens everytime without the use of this trick) ?12/29/2024 at 4:04 PM #241890Hi Lucas,
I forgot to elaborate on that one. But here it is (FWIW) :
The variables themselves bear history. Thus, [1],[2],[3] etc. for 1, 2, 3 bars back. This already goes wrong when “it” relates to arrays which do not go back in history (they don’t have a [1] etc. reference), while the variables need to maintain the internal collection for it. The newly assigned value to another variable may internally refresh the value of the original variable which goes wrong. Btw, if that would really be so, you could use the original variable without error, after assigning the value to the “new” variable. If this still goes wrong, we need a plan B.
Plan B would be a long shot again, because it would depend on what you all do with this “new” variable. Is it a first time declared with ONCE ? Is is never declared with ONCE ? Does the new assignment incur for collecting the current data from the data stream ? (which all easily happens internally – same ticks can be repeated on request). In order to understand what happens for real we must first very thoroughly have this all under control, while we clearly have that not by far (yet). Chicken-egg problem.
What is crucial of course is that you are able to tame the issue … (unless you are not sure about that).The general message remains : we can’t do anything with variables at the in-bar level. Only at the close of the bar …
12/29/2024 at 6:19 PM #241906The temporary variable (let’s call it “temp”) does not need to be declared by “once temp = …” and may be used in different part of the code before, just as a temporary variable… (it is the case of “i” or “n” you can use anywhere with “for i = …”)
The code act really as if it is not possible to use the variable (let’s call it “index”) that is used from the begining of the code, that is pointing to the last index of the array. If you try to use that variable to draw a text (“drawtext”) or anything else, then the code will send that error message (that you are trying to access an index of the array that is not an integer strickly positive) even if you test that variable “index” just before you use it (to be sure it will be used only if it is an integer stricly positve).
So you need to do the test (with “if index >=0 then”), but also to “transfer” the value of that variable (“index”) to an other variable (“temp” or “i” or “n” : even a variable that have been used before in the code).
Maybe i can also use the formula : “MyArray[Max(Round(index),0)]” but i think it will make the code slower…
Don’t know why this bug happen even if i check my “index” variable before using it to access the array with : “If index = Max(Round(index),0) then” to be sure that is is strickly positive integer, i need to use that temporary variable… Weird, isn’t it? For me there is some bug there…
Anyway, the solution i found works well, and i posted this for all who have met the same problem… maybe it can help anyone. I say that there is others who complain about that error message.
12/29/2024 at 8:40 PM #24191512/29/2024 at 9:29 PM #241918It has always been the case that you need to convert an array variable into a non-array variable to use it in ‘DrawText’… (no bug)
I do not convert the value that is inside the array at index : myarrayindex.
I don’t do this :
temp = $Myarray[myarrayindex]
Drawtext(temp, barindex, high+10)I do this :
temp = myarrayindex
Drawtext($Myarray[temp], barindex, high+10)And it works fine… So it is not true that you need to convert an array variable into a non array variable to use it with drawtext or any over instruction.
In the picture below, i would have to change “ObS1” by “temp” (for exemple)
and to add before the drawtext instruction : “temp = ObS1”And that is why it is really STRANGE! Because it does not change anything from a logical point of vbiew… But in the first case it leads to an error and in the second case no error.
12/29/2024 at 9:36 PM #241920Example 512345678910111213141516171819202122232425262728293031323334353637// https://www.prorealcode.com/topic/array-variables-availability-in-prorealtime/// (please do not remove the link above for future reference)// Example #5: tag exact time and price of an event (2 MA cross over) in real time, during the same bar//declare the moving averagesf=average[7]s=average[10]//declare the events (trading signals)bullish = (f > s and f[1] < s[1])bearish = (f < s and f[1] > s[1])if islastbarupdate then//check and store the signalif (bullish or bearish) and lastset($crosstime)<barindex then //if no signal already occurred on that bar then ..$crosstime[barindex]=time //store the time of event$crossprice[barindex]=close //store the price of eventif bullish then$signal[barindex]=1 //store the signal directionelsif bearish then$signal[barindex]=-1endifendif//draw the graphic componentif isset($signal[barindex]) then //if an event occurred on that bar then do somethingif $signal[barindex]=1 then //bullish casedrawarrowup(barindex,$crossprice[barindex]) coloured(0,255,255)else //bearish casedrawarrowdown(barindex,$crossprice[barindex]) coloured(0,255,255)endifitime=$crosstime[barindex] //create time readable variable for drawtextiprice=$crossprice[barindex] //create price readable variable for drawtextdrawtext("time=#itime#",barindex,0,serif,bold,20) //plot the time of the eventdrawtext("price=#iprice#",barindex,0.4,serif,bold,20) //plot the price of the eventendifendifreturn12/29/2024 at 11:40 PM #241923As long as you don’t need to use “” and # in drawtext instruction, you can use the array directly in drawtext or drawsegment or etc…
Same Result123456789101112131415161718192021222324252627282930313233343536373839// https://www.prorealcode.com/topic/array-variables-availability-in-prorealtime/// (please do not remove the link above for future reference)// Example #5: tag exact time and price of an event (2 MA cross over) in real time, during the same bar//declare the moving averagesf=average[7]s=average[10]//declare the events (trading signals)bullish = (f > s and f[1] < s[1])bearish = (f < s and f[1] > s[1])if islastbarupdate then//check and store the signalif (bullish or bearish) and lastset($crosstime)<barindex then //if no signal already occurred on that bar then ..$crosstime[barindex]=time //store the time of event$crossprice[barindex]=close //store the price of eventif bullish then$signal[barindex]=1 //store the signal directionelsif bearish then$signal[barindex]=-1endifendif//draw the graphic componentif isset($signal[barindex]) then //if an event occurred on that bar then do somethingif $signal[barindex]=1 then //bullish casedrawarrowup(barindex,$crossprice[barindex]) coloured(0,255,255)else //bearish casedrawarrowdown(barindex,$crossprice[barindex]) coloured(0,255,255)endif//itime=$crosstime[barindex] //create time readable variable for drawtext//iprice=$crossprice[barindex] //create price readable variable for drawtextdrawtext("time=",barindex-6,0,serif,bold,20)drawtext($crosstime[barindex],barindex,0,serif,bold,20) //plot the time of the eventdrawtext("price=",barindex-6,0.4,serif,bold,20)drawtext($crossprice[barindex],barindex,0.4,serif,bold,20) //plot the price of the eventendifendifreturn12/29/2024 at 11:58 PM #24192412/30/2024 at 12:48 AM #241926You’re absolutely right and Nicolas examples are wrong…
Have Nicolas said “Never use arrays value directly in any graphical instructions ? I don’t think so
Did i said Nicolas is wrong anywhere ? No
Is it written in the Bible that you should never use arrays directly inside drawtext, otheirwise you will burn in Hell ? I asked ChatGPT and it says “No”Just try and see… What else can i say?
Anyway, the bug i’m talking about is not because of that.
12/30/2024 at 3:51 AM #24192812/30/2024 at 5:26 AM #241930From your first post I can derive that MyArrayIndex not necessarily is an integer. Btw, you suggested something of the kind yourself :
Don’t know why this bug happen even if i check my “index” variable before using it to access the array with : “If index = Max(Round(index),0) then” to be sure that is is strickly positive integer, i need to use that temporary variable…
but use it slightly differently from how I would do it. What I mean is :
When you know how to look for it, you can see that variables – by you set to e.g. 12 – end up as 12.000000000001 (don’t pin me down on the number of decimals, but something like that). That would *not* suffice as an index reference for an array, obviously. This addition of a very small decimal in itself is a bug of course.
Because this is a buggy situation to begin with, equaling that variable to another variable (MyTemp) will remove the extra decimals. Why ? because with PRT you can’t work with more than 5 decimals to begin with (some times you can, but for my case in this post you will trust me). Thus, the MyTemp = MyArrayIndex would be sufficient to solve this buggy / erroneous situation (!).There is another situation which incurs for error : use MyArrayIndex as an Optimization parameter. It is far-sought because you probably don’t do this, but *if* you do, I think it could go wrong in the very first usage of that variable as an index. Here too, if you know where and how to look for it, you will see that ALL your defined integer variables end up as decimal variables. Thus, a set MyArrayIndeex as 12, will end up as 12.0. Without guarantee, I bet you that this goes wrong when used as index variable.
In order for further (re)search, be warned that rounding a variable (like Round,0) internally already will lead to an output with decimals, or better put : an output which is not an integer variable. If you know a normal programming language like C++ or C# (or VB to a lesser extent), you will know what I mean (int vs double vs decimal and such).
… I implied it before … you really should not approach this as a bug because then you will not find the cause. Thus, my 12.00000001 example would be the real bug which you won’t look for. And I definitely bet you it is something like that (not exactly this, but something which leads to the error you receive and the error WILL be justified).
Can’t you hand a working code which produces the bug ?
I ask this, because then we can work together on finding the culprit. This is – as you say it yourself – very important because others will be “bugged” by it as well, and it is very hard to track down. Thus, would we be able to find a real underlaying cause, then PRT will solve that (I will take care of that myself). Deal ?
If you can hand a working code, please mention the instrument and timeframe of the chart.1 user thanked author for this post.
12/30/2024 at 10:56 AM #241944Hey Peter,
i think you found the issue from the begining when you wrote : “I think it all comes down to the same issue : the index variables you use to access the array are maintained at bar close only, while the array is maintained each tick.”
I was not aware that array were updated each tick… The bug occurs when an array need an other array to be updated and so on, while applyed on a source that take some times to calculate. Here is an exemple :
Array's BUG12345678910111213141516171819202122Once RSILen = 14Once prd = 1Once pBcTi = -1Once pBmTi = -1src = RSI[RSILen](close)If src[prd] = lowest[2*prd+1](src) thenpBcTi=pBcTi+1$pBcT[pBcTi]= Barindex-1if pBcTi > 2 thenif src[barindex-$pBcT[pBcTi-1]] <= src[barindex-$pBcT[pBcTi-2]] and src[barindex-$pBcT[pBcTi-1]] <= src[barindex-$pBcT[pBcTi]] thenpBmTi=pBmTi+1$pBmT[pBmTi]= $pBcT[pBcTi-1]drawpoint($pBcT[pBcTi-1],src[barindex-$pBcT[pBcTi-1]],3) coloured("red",100)endifendifendifReturn srcNote that variables i use as index for the arrays can be only integers as i increment them only with 1 (which is interger too) : MyArrayIndex = MyArrayIndex + 1 (thus MyArrayIndex remain integer from the begining to the end.
In order to solve the bug, i do like this (in this exemple) :
Array's BUG solved!123456789101112131415161718192021222324Once RSILen = 14Once prd = 1Once pBcTi = -1Once pBmTi = -1src = RSI[RSILen](close)If src[prd] = lowest[2*prd+1](src) thenpBcTi=pBcTi+1$pBcT[pBcTi]= Barindex-1if pBcTi > 2 thenpb1 = pBcTi-2pb2 = pBcTi-1pb3 = pBcTiif src[barindex-$pBcT[pb2]] <= src[barindex-$pBcT[pb1]] and src[barindex-$pBcT[pb2]] <= src[barindex-$pBcT[pb3]] thenpBmTi=pBmTi+1$pBmT[pBmTi]= $pBcT[pb2]drawpoint($pBcT[pb2],src[barindex-$pBcT[pb2]],3) coloured("red",100)endifendifendifReturn srcMaybe the fact to use normal variable in between make prorealtime wait until the close of the bars and not use not permanent updates of the arrays…
12/30/2024 at 12:13 PM #241947Ha !
Maybe the fact to use normal variable in between make prorealtime wait until the close of the bars and not use not permanent updates of the arrays…
Great thinking !
Yea, this is all very mystique. So, would you use that variable further down the line in the same call of the code (at this particular tick) then you can just do that. But would you, for example, add a tick count to that/a variable, then it will add per the next bar only. So for example, 10 ticks may pass during a 1 second bar, but your incrementing variable will have added 1 only.I now suddenly wonder … If we’d increment $MyArray[17] each tick (thus call of the code) would *that* then be remembered in element 17 ?? … I think so ?
If that is so, this really would (be news ? and) bring new opportunities.1$MyArray[17] = $MayArray[17] + 1Thus, use an Array element as vehicle to perform math per tick after all and save that to the calling program.
-
AuthorPosts