Count Number of Bars Since A Date

I am looking for a way to count the number of bars since a date. Anyone have a snippet that does this?

(i.e since July 1, 2017, how many bars are there)?

BarsSince( DateTime() <= _DT("2017-07-01") );
6 Likes

Similar thread recently on this forum might be of interest to you,

2 Likes

i had a question what if i want to know the value of High low close on a particular bar

say closing (10 bars or 10 days from current closing )

samething with HIGH ( -10 bars) OPEN (-10 bars )

this sia good one barcount but on that bar which has a HIGH ---- DATE on that bar

Use the Ref function, References a previous or subsequent element in a ARRAY. A positive period references “n” periods in the future; a negative period references “n” periods ago. The function accepts periods parameter that can be constant as well as time-variant (array).

The formula “ref( CLOSE, -14 )” returns the closing price 14 periods ago

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

1 Like

I have a question. How can I count bars since cond1 is true or vice versa cond2 is true and
plot this figure in the chart or see this in the explorer. Thanks for any hint.

[bars = 10;

cond1 = HHVBars( IndikatorHigh, bars ) == 0;
cond2 = LLVBars( IndikatorLow, bars ) == 0;

state = Flip( cond1, cond2 );/]

1 Like

Use the BarsSince() function.

1 Like

I am using the code snippet from earlier in this thread:

BarsSince( DateTime() <= _DT("2017-07-01") );

I have assigned it to an array in this way:

barsToCount =  BarsSince( DateTime() <= _DT("2017-07-01") );

I am having some problem with certain instances. The issue is that I am running the code across a list of securities. So really I want to count the number of bars back to that specified date, but there are some securities that do not have full history back to that date. (They began trading after the date.) In those cases, I want to count the number of bars in total. I have made several attempts with NZ and LOOKUP and can't seem to get the syntax correct. Appreciate any suggestions.

Thanks.

Can you post all the codes that you attempted with?
Happy to help.

Anyway, the interval() used for calculation is important and you have not mentioned it.
I'm assuming it's daily.

In this case, you know how many real trading days there are since that date, so BarCount, a system defined variable, will return that.

Pseudo code:
If BarCount is less than Num of trading days
Return BarCount
Else
Return barsToCount = BarsSince....

BarCount guaranteed check can be done by

bi = BarIndex();
actualBars = LastValue ( bi );

@QEdges if I understand you correctly, this might be of help

// how many bars of data do you have for this symbol
//  I didn't keep track for proper attribution but I think this is somewhere on the forum

bi = BarIndex();
NullsInCount = NullCount( C, 1 ); // a function that counts the number of Null's in an array
SymbolBarCount = ( bi - NullsInCount ) + 1;

//////////////////////////////////
// Explore all bars for debugging
//////////////////////////////////
Filter = 1;
AddColumn( BarIndex(), "BI", 1.0 ); // a reminder and check is Pad & Align on?
AddColumn( SymbolBarCount, "Symbol BarCount", 1.0 );
AddColumn( C, "Close" );

Then perhaps using your code you could calculate something like this

Count = Min(SymbolBarCount, barsToCount);

A reminder that your bar index changes depending on the usage of Pad & Align,

It also matters whether or not you are using Pad & Align. If not, then you can use BarCount as @travick suggested, or just look at the date as of Bar 0 to see if it's after your desired start date. If you are using Pad & Align, then you can find the inception date of the symbol by looking for the first valid price.

//SetBarsRequired(-2);
dt = DateTime();
dt_str = "2017-07-01";
startdate = _DT(dt_str);
barsince = BarsSince(dt <= startdate);
barsToCount = IIf(IsNull(barsince), Cum(1), barsince);
printf( "Bars since %s: %g", dt_str, barsToCount );
1 Like

Thanks for all the replies! Unfortunately, I continue to fail in my attempts. So to answer the questions posed by @travick , @portfoliobuilder and @mradtke , here is a more descriptive summary and coding.

First, yes, I am looking at daily bars. Second, yes, I am using "pad and align".

The code below will seek out a simple trigger signal where the security closes at a 20-day low but above the 50-day moving average. The trigger is nullified when the security closes back above its 10-day moving average.

      
//barsToCount =  BarsSince( DateTime() <= _DT("2000-01-01") );  //my 1st try

//SetBarsRequired(-2);  /////////////////////////////////////
dt = DateTime();
dt_str = "2000-01-01";
startdate = _DT(dt_str);
barsince = BarsSince(dt <= startdate);
barsToCount = IIf(IsNull(barsince), Cum(1), barsince); 
/// //this was my most recent attempt to implement fxshrat's suggestion
///////////////////////////////////////////////

triggerBuy = C == LLV(C,20) AND C > MA(C,50);
triggerBuyPrice = C;
exitTriggerSell = C >= MA(C, 10);
						
							
triggerBuy = ExRem(triggerBuy, exitTriggerSell);
exitTriggerSell = ExRem(exitTriggerSell, triggerBuy);
									
				
triggerTrades = Sum(exitTriggerSell,barsToCount);				


// Exploration / Scan displays
Filter = triggerBuy ; 
AddColumn(barsToCount, "barsToCount");
AddColumn(triggerTrades, "Trades");


And below are the results I am seeing.

The exploration results show the date of each new trigger event. It also shows the bars that are being counted since 1/1/2000, and then the "trades" column is the count of separate signals prior to the current one. The exploration is run on 4 securities. AAPL and ABT show correct results. They both have history prior to 1/1/2000. ABBV and ACN both show wacky answers. They began trading after 1/1/2000.

I will note both my original single line of code and the code from @fxshrat are giving the same results.

exploreResults

exploreResults2

Sorry I did not include all this info the 1st time. Thanks all for your ideas and insights!

When you literally have 3 lines of code and get whacky results, there's something not right probably with data or maybe the overall logic b/w Buy and Sell.

Just to be sure, are the prices clear and clean of all adjustments like splits/bonuses etc ?

triggerBuy = C == LLV(C,20) AND C > MA(C,50);
triggerBuyPrice = C;
exitTriggerSell = C >= MA(C, 10);

Can you rewrite the code to be more explicit since you have a target Buy and sell which may not stick in some scenario.

Can you make sure this way:

triggerBuy = C == LLV(C,20) AND C > MA(C,50) AND C < MA(C, 10);

also. can you assure that the Target price exists some point later after a buy occurs?

I'm just thinking because the above code is not using bar count at all for entry purposes, what happens when you buy some thing at $50 and then you have a split and price never trades above $15.

You're just trying to get sum of all Sell. What to do you get for sum of all Buy?

1 Like

@QEdges maybe you could use a different method to count the trades:

// "barinrange" array is used to limit the result to the trades in the scan interval
// delete (or set to 1) if you want to count ALL the trades after the StartDate
bir = Status( "BarInRange" );
triggerTrades = Cum( iif( bir AND( dt >= startDate ) AND exitTriggerSell, 1, 0 ) );
3 Likes

Thanks for the input @travick

I am using Norgate data, and I can see the charts, so I am confident in the data.

Changing the trigger buy as you suggest SHOULD not change anything, since any time a security closes at a 20-day low it will be below its 10-day moving average. Adding it in to make sure gave the same results.

The target price exists in all cases for these stocks. The entry price does not matter for exit. So even if there was a split that was not adjusted, all the stock needs to do is eventually close above its "current" 10-day moving average and it will be exited. That is a moving target, so you could buy at $50, and then sell somewhere below $15 a couple of weeks later if there was a huge price drop right after your buy entry.

As you suggested, I added the count of triggerBuy signals, and interestingly, it does count those correctly. Here is a screenshot of the exploration with the complete new code:

exploreResults3

I am still of the opinion that I am doing something wrong with the barsToCount calculation. If you look at the results in the "barsToCount" column of the exploration, you see that ABBV on 1/6/2014 is showing a reading of 3524. That is actually the number of days back to 1/1/2000. (AAPL shows 3523 the day before as proof of this.) ABBV only started trading in December of 2012, and should only have about 270 or so bars in January of 2014 and only 1500 bars up until today.

Here is full updated code used to run the exploration.

      
//barsToCount =  BarsSince( DateTime() <= _DT("2000-01-01") );  //my 1st try

//SetBarsRequired(-2);  /////////////////////////////////////
dt = DateTime();
dt_str = "2000-01-01";
startdate = _DT(dt_str);
barsince = BarsSince(dt <= startdate);
barsToCount = IIf(IsNull(barsince), Cum(1), barsince);  //this was my most recent attempt to implement fxshrat's suggestion
///////////////////////////////////////////////

triggerBuy = C == LLV(C,20) AND C > MA(C,50) AND C < MA(C,10);
triggerBuyPrice = C;
exitTriggerSell =  C >= MA(C, 10);
						
							
triggerBuy = ExRem(triggerBuy, exitTriggerSell);
exitTriggerSell = ExRem(exitTriggerSell, triggerBuy);
									
				
triggerTrades = Sum(exitTriggerSell,barsToCount);
triggerBuyTtl = Sum(triggerBuy, barsToCount);				


// Exploration / Scan displays
Filter = triggerBuy ; 
AddColumn(barsToCount, "barsToCount");
AddColumn(triggerTrades, "Trades");
AddColumn(triggerBuyTtl, "TotalBuySignals");


Thanks!

Thanks @beppe Your idea seems to get "less" wacky results in the trades column.

exploreResults4

But for some reason it thinks there has already been an exit signal on the day the first entry happens for the securities that have not been around as long. In the screenshot, ABT shows the correct count for the 1st possible trade. ABBV does not.

The bigger problem for me remains the barsToCount. I cannot figure out why that is off, or how I would count from inception date if the inception date occurs after my input date. I believe if I can fix that, then triggerTrades would work fine using either method.

Thanks!

@QEdges I will probably use again Cum (supposing that the first trading day has a non empty or zero Close price):

cumBarsSinceSD = Cum( iif( IsTrue( Close ) AND( dt >= startDate ) , 1, 0 ) );
1 Like

Thanks @beppe

I seem to be getting closer. Your calc works to get the barsToCount correct. And so for counting the exitTriggerSell I am able to get proper results for those securities that originated after the start date (1/1/2000). But I now have a new problem with the securities that have been around longer. Some of them are missing "trades" early on. So the trade count starts at 3 or 4 and misses the first couple.

A big issue in my trying to fix this is that I cannot see or use the startDate. In my exploration it always shows up as 0.

exploreResults5

In the code you suggest and @fxshrat ‘s code, you both refer to startDate to see if dt is greater than startdate or less than startDate. But I think I need logic to say “if startDate > 1/1/2000 then…else…”.

Sounds simple, but it appears that with “Pad and Align” turned on, that all the bars between the first one shown on the chart and 1/1/2000 are automatically filled in. I believe that is why I was getting bar counts back to 2000 with securities that did not start trading until 2012.

So is there a way to identify (and store) the date of the 1st bar shown on the chart while "pad and align" is on? I believe that is what I need. Perhaps using a static variable, saying “if close > 0” and yesterday it was null then static variable = that date, or some similar logic?

If that makes sense, could someone suggest code for that? No way I get the syntax right.

Wrong. The code snippet I posted does not do the same thing as your single line and it does not return the same results. That code snippet I posted does exactly what you were asking for originally. I wasn't born yesterday. I do not post code that is not working.
Your problem.... you did not say where you (want to) use it and that you apply pad & align. You did not mention anything about pad&align originally.
As you can see the snippet I have posted was using printf. So by that line I was clearly saying that it was run in chart pane. Chart pane does not have pad & align option. Analysis does have (if checked). But again you did not say where you run. I said where it was run (by using printf()). Big difference. And "Running a code across a list of" can be applied via chart pane too by individually selecting symbol of a list (via up/down keys of keyboard).

So again it is important where code is used. If using chart then you don't need to take care of pad&align of analysis.

Now, since you apply pad & align here is update of my code snippet which will now also run in pad&align mode of analysis and return same result as is if running in chart pane (if both call same amount of bars).

/// @link https://forum.amibroker.com/t/count-number-of-bars-since-a-date/1276/21
/// working also with pad&align being checked.
//SetBarsRequired(-2);
dt = DateTime();
dt_str = "2000-01-01";
startdate = _DT(dt_str);
notNULL = !IsNull(C);// AND Status("barinrange");
barsince  = BarsSince(notNULL AND dt <= startdate);
barsToCount = IIf(IsNull(barsince), Cum(notNULL), barsince );
printf( "Bars since %s: %g", dt_str, barsToCount );

Filter = 1;
AddColumn( barsToCount, "Bars since " + dt_str, 1 );
1 Like