Status("BarInRange")

I'm trying to understand what this does exactly if added to BUY statement in portfolio backtests. I find very different results depending on whether I use this with a BUY in portfolio backtests only. Any references? I made a search in forum and I cannot find out how it can affect signals taken. Thank you all in advance and wishing you a Happy New Year.

https://www.amibroker.com/guide/afl/status.html

You’ll find a description.

I have seen the description. I know how to use help. The issue I have is as follows if I add this to BUY:

  1. For single ticker, if from-to is for example 01/03/2000 - present, and Status("BarinRange) is added to BUY, the backtest starts on 01/04/2000. It starts on 01/03/2000 when this is not added.

  2. For more complex portfolio backtests, the results can be quite different depending on whether it is used.

Therefore besides the description, I am trying to find out how this exactly operates. It is probably there for good reason I fail to understand why and I cannot find detailed description of what it does. I am not saying there is a problem, I try to find what it does exactly especially in portfolio backtests and how it can affect results.

Detailed description of what it does?
What more detail do you need when existing documentation clearly says what it does..

"barinrange" - returns 1 when current bar is within current auto-analysis From-To range

So it returns 1 (true) if bar is within set range of analysis. What else info do you need?
Also the help tells you that return of Status() may be either array OR number depending on used Status() code.
Take a look at the top
9

So to find out return type of barinrange code we use typeof() operator (mentioned in AFL basics of help too, see here)

Then in this forum there exists pinned thread by Tomasz by name "How to debug my formula".
Have you read it?
It lists methods on how to debug and check code, variables in detail.
So here we may use _TRACE / _TRACEF, for example.

bir = Status("barinrange");
_TRACEF("Type of Status('barinrange'): %s", typeof(bir));

So now with upper lines we know that with barinrange code Status() returns array.
9
So it is a True/False array... if bar is within set range then it returns 1 (True) else 0 (False).

So we can check from-to dates now.

// DateTime array
dt = DateTime();
// bar in range -> 0/1 array
bir = Status("barinrange");
// converting to Null/1 array
bir_true = IIf(bir, 1, Null);
// count Nulls at start of 'bir' array -> is number
first_bar = NullCount(bir_true);
// count Null at end of 'bir' array and subtract from last bar -> is number
last_bar = LastValue(BarIndex())-NullCount(bir_true, 2);
// Trace bars in range, from and to datetimes
_TRACEF("bars-in-range (array): %g, From-datetime: %s, To-datetime: %s", 
      Cum(bir), DateTimeToStr(dt[first_bar]), DateTimeToStr(dt[last_bar]));

and you will see that it returns start date of range. Double-check with chart.


Last but not least... we don't know your code and settings. We don't know your data.
Why? Because we don't sit in front of your screen!


What do you get?

bir = Status("barinrange");
bir_true = IIf(bir, 1, Null);
first_bar = NullCount(bir_true);
last_bar = LastValue(BarIndex())-NullCount(bir_true, 2);
_TRACEF("Type of Status('barinrange'): %s", typeof(bir));
_TRACEF("bars-in-range (array): %g, From-datetime: %s, To-datetime: %s", 
      Cum(bir), DateTimeToStr(dt[first_bar]), DateTimeToStr(dt[last_bar]));
//
m = MA( Close, 2); 
Buy = bir /*AND Cross( Close, m )*/; 
Sell = Cross( m, Close ); 
Short = Cover = 0;

First Buy in result list should be at date of _TRACE From-datetime.
If Trace from-date is later then Analysis toolbar's From-date then your symbol has missing data for that start date e.g. because of Holiday, weekend.

3 Likes

Thank you for the detailed response, Very useful. But I am not missing any data in SPY, I have all clean data from inception in 1993. It should be easy for you to check the code below

SetBacktestMode(backtestRegular );
SetTradeDelays( 1, 1, 1, 1);
Fast= 50;
Slow=200;
Buy = Cover=MA(Close, fast) > MA(Close,slow) AND Status("BarinRange");
Short= Sell= MA(Close, fast) < MA(Close,slow) AND Status("BarinRange");
BuyPrice=SellPrice=ShortPrice=CoverPrice=Open;
SetPositionSize( 100, spsPercentOfEquity);

The backtest starts on 01/04/2000 (first trade) when the From-To dates range is 01/03/200 to 01/15/2020

It starts on 01/03/2000 when Status("BarinRange") is removed from the code.

I could be missing something else. AFL is powerful but not easy, this is why I joined the forum.

I concluded that Status("BarinRange") and SetTradeDelays( 1, 1, 1, 1) play together.

So I tested for no delays with following changes:

SetTradeDelays( 0, 0, 0, 0);
BuyPrice=SellPrice=ShortPrice=CoverPrice=Close;

This worked, in both cases starting date was on 01/03/2000.

For daily it may not make a difference but for weekly and monthly it may. So I suppose one must know these details.

You see, that's why it is important to add complete information (such as full reproducible code) in the first place (which is not there in 1st post).

First of all everything is correct and AB as well as barinrange work correctly.

That's correct. You missed the fact that "barinrange" true/false check is added to delayed Buy (and Sell) rule(s)! As been shown in my previous post: "barinrange" code returns array. So it behaves like array.

Your set range starts at date 01/03/2000... so if you add trade delays larger zero (see your SetTradeDelays line) then previous bar is checked for true since you trade on next bar's open. So in other words previous bar must be within set range for buy signal returning true (if your MA rule is true in addition). On 01/03/2000 previous bar (-> which is date 01/02/2000, if it is daily data) was not yet within set range since your from date is... surprise, surprise...01/03/2000. Does it make sense to you now?

So all is correctly working as to be expected.