array variables availability in ProRealTime – examples and discussions
Forums › ProRealTime English forum › ProBuilder support › array variables availability in ProRealTime – examples and discussions
- This topic has 246 replies, 50 voices, and was last updated 1 month ago by
Nicolas.
-
-
07/13/2024 at 12:15 PM #23523107/13/2024 at 12:22 PM #235232
Not sure if this is helpful but…
In your example,
if ‘a’ is a valid integer for the index, and $avg[a] has not been assigned a prior value,
then equation may look something like undefined[a] = undefined[a] + 1.
When plotting the undefined version of $avg[a] on return line , no line is drawn or acknowledged,
using ONCE $avg[a] = 0, defining it with a value, before use, appears to make a difference.
if a = 0 then output expected should be increment by ‘1’ every bar.
You get this when you use the once … statement, or maybe just setting to zero before you use it may work, so its been defined.
In this case, array variables may need declaring with a value before use.
Could no get to the post you referenced for some reason, could you post a link.
07/13/2024 at 12:35 PM #235233Hi Druby, the first post was by Vonasi on page 3 of this lot, and the 2nd post was by PeterSt on page 13.
I’ll have to try setting the array to zero with ONCE.
The reason I can’t use A=A+B is because I’m using an loop, where the array index is also the corresponding value of the loop iteration (this array index number/loop value is also used as a variable setting for the creation of the wanted value to store), and not only do i want each value of the loop to be stored separately, if I just used A=A+B, only a single, erroneous value, seems to be created.
07/13/2024 at 1:05 PM #235234I’m trying to count the increase of A over time
The code works, but arrays are special variable that are not related to time (barindex)…
If you want this to work, you will have to use an extra normal variable (related to the barindex/time), for example:
x=x+1 //related to the bar index
$Avg[0]=$Avg[0]+x
Return $Avg[a]
07/13/2024 at 1:28 PM #235236“I’m trying to count the increase of A over time”
The code works, but arrays are special variable that are not related to time (barindex)…
If you want this to work, you will have to use an extra normal variable (related to the barindex/time), for example:$Avg[0]=0
x=x+1 //related to the bar index
$Avg[0]=$Avg[0]+x
Return $Avg[0]1 user thanked author for this post.
07/13/2024 at 1:35 PM #23523807/13/2024 at 2:33 PM #23523907/13/2024 at 2:45 PM #23524007/13/2024 at 2:58 PM #23524107/13/2024 at 3:35 PM #235242I might be missing something since the ‘Array Post’ went down.
When I jump in the $Avg[a] = $Avg[a] + 1 appeared not to work in the same way as b=b+1 for a normal variable.
Also I looked at earlier reference, and though I’m not sure I got what the problem was, I found a problem.
When you used only var in a indicator, you get the variable undefined error message.
Defining it with a value ‘var=0’ everything’s ok.
Now defining it to itself, ‘var = var’ avoids error message and value assigned is automagically set to zero, still ok.
With an array, ‘arr[0] = arr[0]’ doesn’t define the array, but it quietly errors, or stays undefined.
Adding the +1, ‘arr[0] = arr[0]+1 ‘ doesn’t make a difference because the array is still undefined.
I suppose you cannot assign an undefined array to an undefined array or, do arithmetic operations on a undefined array either.
Only solution is to defined the array element with a value before use, by using ‘once’ or checking/setting using ‘isset()’.
Then ‘arr[0] = arr[0]+1 ‘ does work.
1 user thanked author for this post.
07/14/2024 at 5:39 AM #235246All is ambiguous because normal variables are “set” to be 0 when they are assigned a value all right, but later in the program than where they are used. Example (untested) :
12a = a + 1a = 0So yes, this can be the only two lines in a program and they will just work without error.
It is the craziest thing I have ever seen, especially because PRT does it like this on purpose. The reason is even more spooky : “Otherwise users receive too many error messages and they don’t know what to do”. <– official PRT statement.That example will lead to numerous unpredictable errors – or erroneous situations without you knowing.
With this as the context, you may understand that the way normal variables work is totally wrong; how the array variables work is correct; something which was not assigned a value, should also not be able to be referenced to (use).
This way of working with the normal variables was introduced with V11.1 (or was it v11.0 ?) and the logic behind it – apart from avoiding error messages – seems to be situations like this :
123456789if not PriceSet then // This will not error out because the parser detects that somewhere (down the line !) PriceSet will be assigned a value.[...]endifIf c1 thenPriceSet = 1elsePriceSet = 0endifIt is to be noted that these days even I abuse this way of working, because when a program evolves (gets larger), it becomes more and more difficult to have things in the decent sequence.
Decent Sequence : always first “declare” your variables, and only after that (sequentially in the program) use them.Hence, once you understand this way of working, you can happily abuse it.
Of course it is a bit sad that when people get used to this “bad habit”, they can not understand why array elements (-variables) don’t work this way, and can’t work this way. And please notice : they could when each element is assigned an initial value (like 0, or whatever you want), but with a 1 million elements possible in an array, this is not really efficient usage of memory.You might think that the solution is easy : let PRT just assign a 0 value when it runs into a reference to a variable or array element which was not assigned a value yet. But this is not the general principle with PRT, because this is : [and now look at my first little sample code above] – variable a there *is* assigned a 0 value (on the 2nd line). So I bet you that this a = a + 1 on the first line in that program, leads to just the same “undefined” with unpredictable result. But you won’t run into that because 1. PRT just does not show you the error and 2. a few lines later a is assigned the value of 0 and in the next bar call all is fine. It is only that after two bar calls a will be 1 while you’d expect it to be 2.
Only solution is to defined the array element with a value before use, by using ‘once’ or checking/setting using ‘isset()’.
Saying it like that (kind of out of context) it would imply the same “logic mistake” I made at first in that Arrays topic (currently dead);
Possibly I am wrong again, but what works with normal variables, like123Once counter = 0counter = counter + 1 // Count number of bars processed.can not work with Array elements (not how PRT uses them). Or maybe it does ? Someone might test this :
12345Once a = 17Once $var(a) = 0$var(a) = $var(a) + 1a = a + 1 // Comment out this line and it may still go wrong ?Can we even follow the logic in this ? I can not. This is completely out of control and fails for sure with the a = a + 1 in there.
All right, this means we should not write code like that. Right.
But without the a = a + 1 it still may fail because I don’t think anything in there will later (next call of the bar) know that the a value of 17 was “Once” applied to element 17 of $var. So it will assign 0 to element 17 always, or never, or … or maybe it works. Curious …1 user thanked author for this post.
07/14/2024 at 9:55 AM #235249You threw me a bit with the lack of square bracket in example, got me good for a couple of minutes in editor with warnings before I realised. Just got up. Well done!.
I changed example so ‘a=0’ , just so index didn’t change.
With this example array not defined though ‘a’ is.I see what you mean with example, with ‘a = a + 1’ commented out, ‘a’ and ‘$var[a]’ appear to be both defined.
However, image, I was running, commented out version example in 1hr chart, It appeared to work as expected when it built the chart, incrementing the array by 1 every bar, but as time then moved on, each tick of a 1Tick chart, increased array value, not each bar.
Placing the, ‘a = a +1’ prior to array appears to work as expected with the incrementing by 1 of the array.
This appears to mean, apart from weird, that there’s a state where the array is defined and holds values independent of the normal bar end.
Say, to define, normal bar values is barState, this other state appears to be tickState, where the tick is of a 1tick chart tick.
One other thing I noticed is that, if you only use ‘once a = 17’ in a file on its own with return a, it appears defined.
Adding in, ‘once $var[a] = 0, appears to define the array.
Adding in, ‘$var[a] = $var[a] + 1’ seems to be in this barState when chart building, and then, tickState when continuing.
Adding in, ‘a = a + 1’ after array, just undefines the array, and ‘a’ continues as expected.1 user thanked author for this post.
07/14/2024 at 10:45 AM #235254Nicolas wrote:
IMPORTANT: arrays are not historized, they are decorrelated from the BARINDEX, it means that the arrays value from X bars ago is not saved in memory. It is not a drawback since you can save up to 1 million index which is the maximum of data history allowed now with version 11. Also, you can save your index into a normal variable and refer to it with its barindex offset (see example below, the ‘delta’ variable is used to store the difference of the 2 arrays, so that we can use it to compute an average over the last X periods!).
07/14/2024 at 10:58 AM #235256Druby, This is not easy for me to follow, because it seems (!) that you incorporate a signal which indeed works with ticks, while externally from that (Strategy code) nothing can be obtained from that.
Am I right that you are doing that ?
On the other hand, might you succeed with that, it would be a very welcomed mile stone.incrementing the array by 1 every bar, but as time then moved on, each tick of a 1Tick chart, increased array value, not each bar.
With the danger of missing all the/your points …
Are you saying that with this you try to achieve the tick values to get known in Strategy code ? Even if you say No, I’d say that you may be on to something in the direction of a solution to that. This would change the subject somewhat 😉 but who cares.Without really knowing how to proceed (this is all stupid theory now), I would not use an a = a + 1 or something, but try to get hold of the last filled element in the array. Something like looping through the elements (start with the last element examined in the previous bar) and IsSet returns a false, you know where the end is. This can be used in the Indicator code, but also in the Strategy code.
Then set a normal variable to the found end, and then do your thing (examine tick data) across normal bars.I know, this is full with too much creativity on my end, but I am thinking of this (and thus have changed the subject definitely – at least for myself) :
The normal variables live their own life in Strategy vs Signal. You can pass a variable (-value) to a Signal, but the signal can not adjust it back to the calling Strategy. Yeah, once, at the end of the bar (of 1 Hour, or 1 Second etc.). From Arrays we know that they do do NOT have a separate life. It is only that we can not communicate an a (= a + 1) from the one side to the other (what we mainly need is from Signal to Strategy). This is how I landed on the IsSet in the above. So once the Signal can give back an IsSet of 1070 (first 1070 Elements have been set), you would be able to freely loop through those first 1070 elements in the Strategy code.
All in other words : the Signal would fill the elements all right, but normally (till today 😉 ) we just would not know about it. It seems it does not, but it would do it after all.Also think about internal “series” (which are arrays again, but now in C++ or whatever PRT uses), which are continuously copied or manipulated otherwise (pointers) so we can apply not only a, but also a[1] and a[410] and a[1070] etc. etc. This can NOT be done with exposed arrays because when you’d have a 1 million elements, each of those 1 million would need to bear a [1] and [410] and [1070] version as well, which implies a 1 billion size array (or maybe not, but that is for another day). And exactly because *that* is not done, we’d have the “state” version of the array available everywhere. But as said … we only don’t know it.
This will not be easy to test;
In the Signal it would require a new Element to be added each time the signal is triggered (which is per each tick). The newly to add Element will be the lastly added Element + 1 (when the Signal finished the previous bar (say 1 second for easier testing), which Element can be exposed as usual (it is our a variable). So a would be e.g. 410 when the bar is finished, and when the signal is called the first time in the new bar it will start with element 411. Probably this does not require communication between signal and strategy because the a variable can continue within the signal solely. However, our strategy would need to know the value of a (return a) so we can do our thing in the currently populated array (loop to the first 410 elements after the first bar/second).As said, the proof that it works would be more than tedious, because you don’t have the possibility to graph or print each element from within strategy code. You could add them up for value though. Thus, supposed that each element would contain the price (this is just an example !), then each “tick” with a price of 20100 (current Nasdaq) would add ~ 20100 to the total value. Thus, having two ticks in there would show a total of ~40200. Ran into 410 ticks ? then it should be 410 * 20100 and come up with 86.100.000. You surely can graph or print *that* !
If this is all old news, then I missed it all.
We must be careful with this in practice;
What will happen in practice is that 10K ticks may pass per second. At least at “News” times this will be so. So the maximum of 1 million Elements will be consumed soon and some error will spring from that when it happens. So in any event it should be tested with very few data only. Making that 1 hour bars instead of 1 second will have an adverse effect (the number of ticks won’t change while I think you can’t put up a 1 hour signal of 1 hour only). 10K ticks would allow for 100 seconds (100 * 10000 = 1M). But, try it over an easy period (5am Amsterdam) would allow for more. Or use something with less ticks (DAX, S&P).???
07/14/2024 at 11:08 AM #235257Hi all,
thanks for the great ideas.
@PeterSt, it looks like your idea of:1234567Once $var(a) = 0$var(a) = $var(a) + 1//is the equivalent ofa = a + 1actually works!! And seems to work well. A very useful insight.
I’m not a true coder/non IT/non computing science background, so your insight of how the variable has to be set to something for it to work, if it doesn’t have a value, is very interesting, and has now proved to be very useful.
You’re right, this error must just be cancelled out/not shown for non-array variables, and PRT must be set up to appease us baby-coder/general public sorts as a target audience. Love to do the whole python thingo one day and do some proper coding, but this is great easy way to get something working first I guess.
One thing I will say for this “Once $var(a) = 0”, if you are using a loop, even if it is a test loop with “From X to X do” (single value) this initial setting of the array needs to be inside the loop (between the For and the Next), and not outside of it, for it to work.
Though you can’t historize an array, this is a great way to bring counts/sums forwards, if you are using an array to try and bring forwards multiple streams of data, as with what you would see in a loop scenario.
Many thanks all for this great help!!
Cheers,
Finning
-
AuthorPosts
Find exclusive trading pro-tools on