Problem with for loop and iteraction order of bars

Questions about MultiCharts and user contributed studies.
radekj
Posts: 103
Joined: 28 Apr 2008
Has thanked: 18 times
Been thanked: 1 time

Problem with for loop and iteraction order of bars

Postby radekj » 10 Jan 2009

Can somebody explain me this behavior ?

(Testet with 5min resolution timeserie)

The output of first code is ok:

BarCount set to 1
BarCount:
1.00
CurrentBat:
1.00
BarCount:
2.00
CurrentBat:
...

but the second output is:
(for loop, added at end of code 1)

BarCount set to 1
BarCount:
1.00
CurrentBat:
1.00
BarCount set to 1 <-Called second time, why !?
BarCount:
1.00
CurrentBat:
1.00
BarCount:
2.00
CurrentBat:
2.00
BarCount:
...

it look like that first bar was evaluted twice, when using for loop with data reference in the past ?

IntraBarPersist of BarCount have not influance of this behavior.

It hapend oftem that in code where i use for loop with reference of past data the code is starting from begin some times, exampel evaluting first 100 bars it start from first bar again and so on ...


code #1:

Code: Select all

variables:

IntraBarPersist BarCount(0), 
ii(0);

if currentbar = 1 then begin
   print("BarCount set to 1");
   BarCount = 1;
end else
   BarCount = BarCount +1;

print("BarCount:");print(BarCount);
print("CurrentBat:");print(currentbar);

code#2:

Code: Select all

variables:

IntraBarPersist BarCount(0), 
ii(0);

if currentbar = 1 then begin
   print("BarCount set to 1");
   BarCount = 1;
end else
   BarCount = BarCount +1;

print("BarCount:");print(BarCount);
print("CurrentBat:");print(currentbar);

for ii = 0 to 5 begin
   if Close[ii] = 0 then //Dummy statment without functionality
      Abort;  //Dummy statment without functionality
end;
Last edited by radekj on 10 Jan 2009, edited 1 time in total.

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

My variant on your code works fine. code and results below.
However, I should note that using intrabarpersist suggests you have "update on every tick" turned on and if you do then once all historic bars are completed and the current bar is being built barcount and currentbar will not have the same values ever again.
John.

P.S. I redid it with your comments and it worked too. I did not know you could do comments using //. I always use { and }.


Code: Select all

variables:
   IntraBarPersist BarCount(0), 
   ii(0);

if currentbar = 1 then
   begin
   print("BarCount set to 1");
   Print( File("C:\Access\ALog_Test.txt"),
         "BarCount set to 1");
   
   BarCount = 1;
   end
else
   BarCount = BarCount +1;

Print( File("C:\Access\ALog_Test.txt"),

      " BarCount", " " ,
      BarCount, " " ,

      " CurrentBar", " " ,
      CurrentBar, " " ,
      " ");

for ii = 0 to 5
   begin
   if Close[ii] = 0 then
      Abort;
   end;




BarCount set to 1
BarCount 1.00 CurrentBar 1.00
BarCount 2.00 CurrentBar 2.00
BarCount 3.00 CurrentBar 3.00
BarCount 4.00 CurrentBar 4.00
BarCount 5.00 CurrentBar 5.00
BarCount 6.00 CurrentBar 6.00
BarCount 7.00 CurrentBar 7.00
BarCount 8.00 CurrentBar 8.00
BarCount 9.00 CurrentBar 9.00
BarCount 10.00 CurrentBar 10.00
BarCount 11.00 CurrentBar 11.00
BarCount 12.00 CurrentBar 12.00
BarCount 13.00 CurrentBar 13.00
BarCount 14.00 CurrentBar 14.00
BarCount 15.00 CurrentBar 15.00
BarCount 16.00 CurrentBar 16.00
BarCount 17.00 CurrentBar 17.00
BarCount 18.00 CurrentBar 18.00
BarCount 19.00 CurrentBar 19.00
BarCount 20.00 CurrentBar 20.00
BarCount 21.00 CurrentBar 21.00
BarCount 22.00 CurrentBar 22.00
BarCount 23.00 CurrentBar 23.00
BarCount 24.00 CurrentBar 24.00
BarCount 25.00 CurrentBar 25.00
BarCount 26.00 CurrentBar 26.00
BarCount 27.00 CurrentBar 27.00
BarCount 28.00 CurrentBar 28.00
BarCount 29.00 CurrentBar 29.00
BarCount 30.00 CurrentBar 30.00
BarCount 31.00 CurrentBar 31.00
BarCount 32.00 CurrentBar 32.00
BarCount 33.00 CurrentBar 33.00
BarCount 34.00 CurrentBar 34.00
...
BarCount 21685.00 CurrentBar 21685.00
BarCount 21686.00 CurrentBar 21686.00
BarCount 21687.00 CurrentBar 21687.00
BarCount 21688.00 CurrentBar 21688.00


radekj
Posts: 103
Joined: 28 Apr 2008
Has thanked: 18 times
Been thanked: 1 time

Postby radekj » 10 Jan 2009

If you redirect the "print" to file than all is right,
but if you redirect the "print" to output window and you got the double call.

ciao
radekj
Attachments
DoubleCall.jpg
DoubleCall.jpg (125.06 KiB) Viewed 547 times

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

I never use print without redirecting to a file. I tried your print and my editor locked up. Does it go there?

I just found it in the editor output tab. Interesting.

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

I get the same thing if I send it to the editor output.

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

Try this one. It has time_s in it. Without the for statement I get one print statement. With the for statement I get two print statements. the second print has a different time_s value.

I think they call this a bug!


Code: Select all

variables:
   ii(0);


if currentbar = 1 then
   Print( time_s);

for ii = 0 to 5
   begin
   if Close[ii] = 0 then
      Abort;
   end;


bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

Take note of this. The first time_S is 200500 and the second time_s is 203500. That is exactly 6 of the 5 minute bars later. So that exactly matches your number of for loop iterations.

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

Okay so I tired changing the 0 to 5 such that I ran it with these values.
0 to 1
0 to 2
0 to 3
etc.

Nothing changed until I hit "0 to 7"
At that point I got this.

200500.00
203500.00
210500.00


Now this is not a bug but rather a "Strange bug"!!!!!

Maybe TS-Support can have fun with it. It seems the solution is to use the print to file instead.

radekj
Posts: 103
Joined: 28 Apr 2008
Has thanked: 18 times
Been thanked: 1 time

Postby radekj » 10 Jan 2009

bowlesj3,

exact this is my problem.

I often use loops to look for values of bars in the past,
but i get constantly strange site effects !

And i think all indicators with reference of past data have the same problems.

ciao
radekj
Last edited by radekj on 10 Jan 2009, edited 1 time in total.

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 10 Jan 2009

Try this function instead of looping back. It is the fastest method. It is designed for minute bars but it should work any above that. Of course you need to know the date and time of the bar you are looking for. Maybe you don't in your case.

Code: Select all

{
Written by John Bowles based off the web page "http://en.wikipedia.org/wiki/Binary_search" modified for EL offset.

Sample Call:
   offset = A_FindOffsetViaBinary(1,BarNumber,Arw1Date,Arw1Time);
   
   See the comments below for each input parameter to know how to run this function
   
   The above call submits the Arrow #1 Date and time along with the last bar in the chart bar number
   and you get the offset from the last bar in the chart where that arrow is located.
   your code can then figure out the high/low/close price data you want from that offset.
}

inputs:
   BarNumberLower(NumericSimple), {Normally value 1 which is the first bar of the chart}
   BarNumberUpper(NumericSimple), {Submit "BarNumber" for the last bar of the chart}
   DateIn(NumericSimple), {Submit the Arrow Date In}
   TimeIn(NumericSimple)  {submit the Arrow Time In}
    ;
variables:
   MyL(0),
   MyN(0),
   MyR(0),
   MyP(0),   {Pointer to the bar which is being changed throughout the code with the binary logic}
   Offset(0)
   ;

MyL = BarNumberLower;
MyN = BarNumberUpper;
MyR = MyN + 1; {Ending-Range is adjusted by 1}
MyP = IntPortion((MyR - MyL)/2); {We apply the binary division trimming off the decimal}


A_FindOffsetViaBinary = 0;
While MyP <> 0
   begin
   
   
   MyP = MyL + MyP;
   Offset = BarNumberUpper - MyP; {MyP is an index from the first bar. Offset is an offset from the last bar}

   If date[Offset] < DateIn or (date[Offset] = DateIn and time[Offset] < TimeIn) then
      begin
      MyL = MyP; {The price bar inspected is too far back so we bring our starting-range(MyL) up to MyP}
      MyP = IntPortion((MyR  - MyL)/2); {We apply the binary division trimming off the decimal}
      end
   else
      begin
      If date[Offset] > DateIn or (date[Offset] = DateIn and time[Offset] > TimeIn) then
         begin
         MyR = MyP; {The price bar just inspected is too far forward so we bring our ending-range(MyR) down to MyP}
         MyP = IntPortion((MyR  - MyL)/2); {We apply the binary division trimming off the decimal}
         end
      else
         begin
         If date[Offset] = DateIn and time[Offset] = TimeIn then
            begin
            {We found the Bar with matching date and time so we set the function output to the correct offset}
            A_FindOffsetViaBinary = BarNumberUpper - MyP;
            {Now that we have what we are looking for we force the loop to stop by setting MyP to zero}
            MyP = 0;
            end;
         end;
      end;

   end;


radekj
Posts: 103
Joined: 28 Apr 2008
Has thanked: 18 times
Been thanked: 1 time

Postby radekj » 10 Jan 2009

ok, thanks.

I will send this issue to ts-support.

ciao
Radek

User avatar
Marina Pashkova
Posts: 2758
Joined: 27 Jul 2007

Re: Problem with for loop and iteraction order of bars

Postby Marina Pashkova » 14 Jan 2009

Can somebody explain me this behavior ?

(Testet with 5min resolution timeserie)

The output of first code is ok:

BarCount set to 1
BarCount:
1.00
CurrentBat:
1.00
BarCount:
2.00
CurrentBat:
...

but the second output is:
(for loop, added at end of code 1)

BarCount set to 1
BarCount:
1.00
CurrentBat:
1.00
BarCount set to 1 <-Called second time, why !?
BarCount:
1.00
CurrentBat:
1.00
BarCount:
2.00
CurrentBat:
2.00
BarCount:
...

it look like that first bar was evaluted twice, when using for loop with data reference in the past ?

IntraBarPersist of BarCount have not influance of this behavior.

It hapend oftem that in code where i use for loop with reference of past data the code is starting from begin some times, exampel evaluting first 100 bars it start from first bar again and so on ...


code #1:

Code: Select all

variables:

IntraBarPersist BarCount(0), 
ii(0);

if currentbar = 1 then begin
   print("BarCount set to 1");
   BarCount = 1;
end else
   BarCount = BarCount +1;

print("BarCount:");print(BarCount);
print("CurrentBat:");print(currentbar);

code#2:

Code: Select all

variables:

IntraBarPersist BarCount(0), 
ii(0);

if currentbar = 1 then begin
   print("BarCount set to 1");
   BarCount = 1;
end else
   BarCount = BarCount +1;

print("BarCount:");print(BarCount);
print("CurrentBat:");print(currentbar);

for ii = 0 to 5 begin
   if Close[ii] = 0 then //Dummy statment without functionality
      Abort;  //Dummy statment without functionality
end;


The reason why you see the same line in the output, is that your second code
references past values. Also, most probably in your study settings you have
'Auto-Detect' checked in the "Max Number of Bars the Study will Reference".
This results in the following: the study starts calculating on the first
bar, then it comes to the following lines in your script:
-------------------------
for ii = 0 to 5 begin
if Close[ii] = 0 then //Dummy statment without functionality
Abort;
-------------------------
This line tells the code to reference a past value, but there are no past
values relative to the first bar of the series. So the code skips more bars
and starts the calculations all over again.

To prevent this from happening, go to Format Study -> Properties -> Max
Number of Bars the Study will Reference, enable "User Specified" and enter 5
in the respective field.

bowlesj3
Posts: 2088
Joined: 21 Jul 2007
Has thanked: 197 times
Been thanked: 416 times

Postby bowlesj3 » 17 Jan 2009

Hi Marina,

I got interested in this last week and finally had some time to look at your explaination today (Saturday). I understand your explaination but I am curious why the code works properly with a print to file statement rather than a print to the editor output. I should note that my version shown below is set to auto-detect. I adapted the print statement to display [ii] values during the loop for each print of the bar above it. It makes sense except for the currentbar value. Also I check the times actually showing on the bars of the chart and I listed them immediately below. Notice the first one to be printed within the loop. It missed 5 bars actually showing in the chart. So what I did next is I changed it to NOT auto-detect but rather I forced it to max bars back of 7 bars to match the loop and I got it to show the time of the very first bar on the chart (see the 2nd set of print statement output to see what I mean). Next I set maxbarsback to a value of 2 thinking I could get MC to bomb out. The result is at the very end (it missed one bar in the very first time through the loop).

So it seems that auto-detect does not work perfectly.

11:12
11:13
11:14
11:15
11:16
11:17 (first one printed in the first time through the loop Time[7]
11:18
11:19
11:20
etc.

John.


Code: Select all


variables:
   IntraBarPersist BarCount(0), 
   ii(0);

if currentbar = 1 then
   begin
   print("BarCount set to 1");
   Print( File("C:\Access\ALog_Test.txt"),
         "BarCount set to 1");
   BarCount = 1;
   end
else
   BarCount = BarCount +1;
   
   
Print( File("C:\Access\ALog_Test.txt"),

      " BarCount", " " ,
      BarCount, " " ,

      " CurrentBar", " " ,
      CurrentBar, " " ,

      " Time", " " ,
      Time, " " ,
     
     
      " ");   
   

for ii = 0 to 7
   begin
   Print( File("C:\Access\ALog_Test.txt"),

         " ii", " " ,
         ii, " " ,

         " BarCount[ii]", " " ,
         BarCount[ii], " " ,

         " CurrentBar[ii]", " " ,
         CurrentBar[ii], " " ,

         " Time[ii]", " " ,
         Time[ii], " " ,
        
         " ");   
   end;





This is auto-detect

BarCount set to 1
BarCount 1.00 CurrentBar 1.00 Time 1124.00
ii 0.00 BarCount[ii] 1.00 CurrentBar[ii] 1.00 Time[ii] 1124.00
ii 1.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1123.00
ii 2.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1122.00
ii 3.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1121.00
ii 4.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1120.00
ii 5.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1119.00
ii 6.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1118.00
ii 7.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1117.00
BarCount 2.00 CurrentBar 2.00 Time 1125.00
ii 0.00 BarCount[ii] 2.00 CurrentBar[ii] 2.00 Time[ii] 1125.00
ii 1.00 BarCount[ii] 1.00 CurrentBar[ii] 2.00 Time[ii] 1124.00
ii 2.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1123.00
ii 3.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1122.00
ii 4.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1121.00
ii 5.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1120.00
ii 6.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1119.00
ii 7.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1118.00
etc
etc




Maxbarsback set to 7

BarCount set to 1
BarCount 1.00 CurrentBar 1.00 Time 1119.00
ii 0.00 BarCount[ii] 1.00 CurrentBar[ii] 1.00 Time[ii] 1119.00
ii 1.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1118.00
ii 2.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1117.00
ii 3.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1116.00
ii 4.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1115.00
ii 5.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1114.00
ii 6.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1113.00
ii 7.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1112.00
BarCount 2.00 CurrentBar 2.00 Time 1120.00
ii 0.00 BarCount[ii] 2.00 CurrentBar[ii] 2.00 Time[ii] 1120.00
ii 1.00 BarCount[ii] 1.00 CurrentBar[ii] 2.00 Time[ii] 1119.00
ii 2.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1118.00
ii 3.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1117.00
ii 4.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1116.00
ii 5.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1115.00
ii 6.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1114.00
ii 7.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1113.00
etc
etc




Maxbarsback set to 2

BarCount set to 1
BarCount 1.00 CurrentBar 1.00 Time 1120.00
ii 0.00 BarCount[ii] 1.00 CurrentBar[ii] 1.00 Time[ii] 1120.00
ii 1.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1119.00
ii 2.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1118.00
ii 3.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1117.00
ii 4.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1116.00
ii 5.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1115.00
ii 6.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1114.00
ii 7.00 BarCount[ii] 0.00 CurrentBar[ii] 1.00 Time[ii] 1113.00
BarCount 2.00 CurrentBar 2.00 Time 1121.00
ii 0.00 BarCount[ii] 2.00 CurrentBar[ii] 2.00 Time[ii] 1121.00
ii 1.00 BarCount[ii] 1.00 CurrentBar[ii] 2.00 Time[ii] 1120.00
ii 2.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1119.00
ii 3.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1118.00
ii 4.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1117.00
ii 5.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1116.00
ii 6.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1115.00
ii 7.00 BarCount[ii] 0.00 CurrentBar[ii] 2.00 Time[ii] 1114.00


Return to “MultiCharts”