How to change the time frame to 2 days back

Hi,

How to find price of a stock at 2 days back particular time.
For example i want to compare today 10 AM stock price with 2 days back same 10 AM stock price(If i am using 5 minute interval). If any pseudo code is available that is much helpful.

Thanks

There are several ways. One way is using ValueWhen.

/// @link https://forum.amibroker.com/t/how-to-change-the-time-frame-to-2-days-back/11008/2
daysback = 2;
time = 100000; // timenum
SetBarsRequired((daysback+1)*inDaily/Max(1,Interval()));
tn = TimeNum();
time_cond = tn == time;// equality check so time bar has to exists
today_price = ValueWhen(time_cond, C);
n_days_back_price = ValueWhen(time_cond, C, daysback+1);
printf( "timenum: %06.0f\n", time);
printf("today's price: %g\nprice of %g days back: %g", today_price, daysback, n_days_back_price );

47

4 Likes

@TRDK, getting "ready to use" code is always nice, but we will learn more if we also spend time studying the corresponding AFL functions reference pages and additional examples.

For instance, the above posted answer uses the following functions:

So even a short snippet of code can be a good starting point to increase our knowledge of the wide range of functions that are ready for use in AFL.

In particular, I also suggest reviewing this previous thread to better understand the use of ValueWhen(), which is quite a useful function, but seems to be a little difficult for many AmiBroker users to understand.

3 Likes

Hi @fxshrat

Can you pls explain your thinking behind:

, I understand that you're limiting the number of prior bars to the condition set by the OP, but the logic of it escapes me at the moment.

Ordinarily I'd just use SetBarsRequired(sbrAll,0) to ensure that all the bars needed are available, leaving it up to the logic in code to manage the actual number of bars used, and not rely on/ be restricted by limits set by AB's internal decision-making.

@phase21,

No, setting SetBarsRequired(sbrall) would be insane idea. If you would have a symbol with one million 5-min bars then it would load all 1 million bars.

The reason for my version is that I am not restricting but just making sure that minimum number of bars is activated.

Why that way? It's not difficult.

He is using 5-minute. Maximum possible bars per day on 5-minute (== 300 seconds) time frame are 86400/300 = 288 bars. 86400 == inDaily. A single day has maximum 86400 seconds or 1440 minutes or 24 hours. Since he wants to get two days back from today it is today+yesterday+day before yesterday. So ensuring three days (since daysback is a variable it is not just 3 days being ensured but n-days look back are getting ensured depending on which lookback day you want to compare with). 3 days x 288 bars = 864 bars minimum on 5-minute TF to ensure proper output on large zoom in (e.g if zooming in so far that only todays data being visible on chart, or even further zoom in). daysback with "+1" within SetBarsRequired in case someone would set zero daysback. Anyway just try yourself, zoom in to just few bars being visible (let's say 20 bars) on 5 minute and then comment SetBarsRequired. You will get Null (-1e+10) output then.

Now, Interval() ensures that it works on any intraday time frame but not just 5-minute. Interval() returns seconds. And using max(1, Interval()) ensures that if applying indicator from editor it does not return error because Interval function returns zero on formula verification.

Mysteries solved?

7 Likes

Thanks @fxshrat,

Yes "Mysteries solved"!

I tend to analyse/ trade on daily timeframe, so wasn't thinking about the explosion of bars on intra-day - your code and logic makes sense. :smile:

Thanks @fxshrat. Now i am getting the desired output for 10 AM.
Ami_price
But if i want to compare all the 5 minute intervals i am removing the timenum condition .
But not getting the desired output.. Can you please let me know what modification do i need to do?

daysback = 2;
//time = 100000; // timenum

SetBarsRequired((daysback+1)*inDaily/Max(1,Interval()));
//tn = TimeNum();
//time_cond = tn == time;// equality check so time bar has to exists

today_price = ValueWhen(C,1);
n_days_back_price = ValueWhen(C, daysback+1);

When you set all the bars required, then you are telling AB to use all bars so "leaving it up to the logic" will be discounted by AB.
Its either "you tell me how many bars" OR "i'll calculate it myself", but not both.

You are effectively disabling QuickAFL for that code, and all bars will be forced into computation.

Since I didn't design, cant commit, but Array processing works on the whole array, so you cant then have partial arrays being computed, and all Arrays are of size BarCount (excluding Matrices)
In other words, last half of Barcount in Array won't(cannot) be processed alone is what I mean.

If you have a chart, say updating every 1 second, the moment you change code and save the AFL, you will see Barcount using all the Bars (or a preety large number), and from the 2nd run onwards, QuickAFL(TM) kicking in and reducing the Bars drastically.

1 Like

You cannot remove parts of a code and then expect it to work like that.
When you ask for something, be sure its what you want, a small change in your thinking could change the whole approach.

If you want a bar by bar comparison, you might as well Ref() the whole array forward by a certain bars instead.
have a look at this:

Post you have withdrawn:

Listen, the code of 2nd post works exactly as you described in first post!
You do not believe it? (Besides in your quote there is not a single exploration code to be seen).
Re-read loudly and clearly your post:

So just adding exploration output code without changing any previous code.

/// Do NOT remove link from code you did NOT create yourself!
/// If you do changes then add changes and add your name below and describe changes done
/// @link https://forum.amibroker.com/t/how-to-change-the-time-frame-to-2-days-back/11008/11
/// by fxshrat@gmail.com
daysback = 2;
time = 100000; // timenum -> so e.g. it means "10:00:00 AM"
SetBarsRequired((daysback+1)*inDaily/Max(1,Interval()));
tn = TimeNum();// array of time numbers
time_cond = tn == time;// equality check so time bar has to exists
today_price = ValueWhen(time_cond, C);// gets "today's" price of specified time
n_days_back_price = ValueWhen(time_cond, C, daysback+1);// gets price of specified time of a past day
/// Now printing result
printf( "timenum: %06.0f\n", time);
printf("today's price: %g\nprice of %g days back: %g", today_price, daysback, n_days_back_price );
/// Now exploration output code
Filter = time_cond;
AddRow( "\tSpecified time" );
AddTextColumn(Interval(2), "Interval");
AddColumn( today_price, "Today's price", 1.2 );
AddColumn( n_days_back_price, StrFormat("Price of %g days back", daysback), 1.2 );

And what do we get then?
Right, we get what is described in 1st post (once again).
Do you understand term "days back"? Do you understand meaning of term "2 days back"? Two days back from today is not yesterday.

319


I am not sure whether you are serious?
Once again please re-read your own post carefully

So what do you think does 100000 mean? Is it really such a one billion $ brain twister?
No, it is not. It is a time number. A time number consists of max. 6 digits.
Since it is a time number then e.g. 100000 stands for -> "10:00:00 AM". Your mentioned time. Wow...amazing, isn't it. What a "Sixth Sense" revelation. Not!

We specify time number and then compare it with TimeNum() array via equality check ( == ) since we want to get values if true.

So the code is exactly doing what you described in first post.
Since it is exactly doing what you have described the issue is solved from my POV. It is even so much solved that it works on any intraday time frame. If something is solved we hit thanks button as token of appreciation here and to distinguish contributors from non contributors. And in addition there is solution forum button below of a post so that other users can easily recognize solved threads.


That change is incorrect! Please read formula reference of ValueWhen. It clearly and unmistakably says that

when the EXPRESSION was true on the n -th most recent occurrence

So first argument has to be true/false expression.... an array condition returning true(1) / false(0). If you add C then it is always returning true since price is greater than zero (false) (so output of your change will be "1" for today_price and "3" for n_days_back_price from start to end. So clearly nonsense output). time_cond of my posted code is a true/false array. It checks for equality ( via == operator).

You have to iterate to precisely shift entire array forward for each time number (precisely means it has to work for cases where number of intraday bars differ). And what you mean is not interval but times. And your first post mentions single time only! Do you understand? Now please do your homework.


Now another thing, if you copy code you did not create yourself then you leave everything in which includes double-clickable reference link to source but you do not remove (as you did). It is exactly not you who came up with idea. Absolutely not you. This is disrespectful and will put you quickly on ignore list. Do we understand each other? You may wail as much as you want now but having zero clue in the first place, being absolute beginner and begging for copy&paste code and not showing any own effort in first place and then removing on top of that... is no go!

2 Likes

Let's 1st learn how to encourage the ones who are HELPing the learners. Otherwise....... The Learners will remain learners because the Help/Guide will remain Silent.
Edit:
Please understand that when i disrespect someone who is selflessly Helping/Guiding me and he goes silent , it's not just my loss but a huge loss to all the genuine learners.

1 Like

First learn how to show some appreciation and respect! Maybe this forum is not for you!

Statements from both @TRDK and @fxshrat went into "inappropriate" zone. Closing this thread now.