Unable to fetch the correct Previous Day close Price from 5 min Timeframe

Hello,

(I’m using Amibroker 6.30.5 64bit licensed version.)

When I try to fetch Previous Day Close price from 5 min timeframe (using TimeFrameGetPrice( "C", inDaily, -1 )), I get the Close price of the last 5 min candle of yesterday, rather than the actual close price of yesterday (daily).
Sample code:

_SECTION_BEGIN( "Previous Day" );

	 PDH =  TimeFrameGetPrice( "H", inDaily, -1 );
	 PDL =  TimeFrameGetPrice( "L", inDaily, -1 );
	 PDC =  TimeFrameGetPrice( "C", inDaily, -1 );
	 
_SECTION_END();
	 
	 Filter = 1;

	AddColumn (PDH, "Prev Day High");
	AddColumn (PDL, "Prev Day Low");
	AddColumn (PDC, "Prev Day Close");

Picture 1:

Picture 2:

If I change the periodicity to ‘Daily’ in Analysis window, and fetch the Close price of previous day (using TimeFrameGetPrice( "C", inDaily, -1 )), I get the correct value as per the NSE stock exchange data.

Picture 3:

Picture 4:
4

Picture 5:

I have referred to an earlier post on this in 2017 [Previous day close from intraday time frame (5M,15m,30m etc.)]

I see there is no issue with the data provider (Global Data Feeds) as the ‘Daily’ data is indeed received correctly and stored in the database.
I’m able to fetch the actual daily close price in the Daily timeframe. So no issues in AmiBroker as well.
But when attempted to fetch in 5 min timeframe it doesn’t give the actual daily close price but the close price of the last 5 min candle of previous day.
I have tried using the timeframe set, restore and expand method, but still get the close price of the last 5 min candle of previous day.

(I understand that the Close price of the Daily candle will be the weighted average price of the last 30 mins and will differ from the lower timeframe last candle close. So no confusions there.)

The implication of the issue is in calculating the Pivot, Support, Resistance values for Intraday trading with yesterday’s OHLC. As there is difference in Yesterday Close value, the pivots shift affecting entry and exit.

Hope I have provided enough details and have communicated the issue properly.
Could someone assist me in getting the actual daily close from the 5 min timeframe.
Thanks.

Karthik P

_SECTION_BEGIN( "Previous Day" );
TimeFrameCompress(C,inDaily);
	 PDH =  TimeFrameGetPrice( "H", inDaily, -1 );
	 PDL =  TimeFrameGetPrice( "L", inDaily, -1 );
	 PDC =  TimeFrameGetPrice( "C", inDaily, -1 );
TimeFrameRestore();	 
_SECTION_END();
	 
	 Filter = 1;

	AddColumn (PDH, "Prev Day High");
	AddColumn (PDL, "Prev Day Low");
	AddColumn (PDC, "Prev Day Close");

You can also use ValueWhen() to find the close at a particular time, assuming that there was a bar at that time (which may not be the case if the market closed early, like for a holiday).

1 Like

small correction, you need TimeFrameSet and not TimeFrameCompress

TimeFrameSet( inDaily );

and then later Restore it as you wrote.

1 Like
_SECTION_BEGIN( "Previous Day" );
TimeFrameSet( C,inDaily );
	 PDH =  TimeFrameGetPrice( "H", inDaily, -1 );
	 PDL =  TimeFrameGetPrice( "L", inDaily, -1 );
	 PDC =  TimeFrameGetPrice( "C", inDaily, -1 );
TimeFrameRestore();	 
_SECTION_END();
	 
	 Filter = 1;

	AddColumn (PDH, "Prev Day High");
	AddColumn (PDL, "Prev Day Low");
	AddColumn (PDC, "Prev Day Close");

Thanks nsm51 for showing correction.

Thanks @brajeevn and @nsm51. But I had tried that already and I had mentioned in my initial post.

@PeterD, Thanks for your suggestion to use Valuewhen, i did try that with condition as end of day, still getting close price of the last 5 min Candle but not the actual close price of the Day candle.

your initial post is not setting timeframe, look at code posted by brajeevn properly. It has to work bcos it is working for us.

see this thread also, this kind of problem is sorted by above method or this one.

Display correct daily close of foreign symbols - AFL Programming - AmiBroker Community Forum

Hello @nsm51 ,

Below excerpt from my initial post.

Dint include that code, though I have tried it already and dint get the actual daily close price.
Thanks anyways.

Karthik P

Hello @nsm51,

For now, I have changed the Intraday Settings - Trading Hours timing to 15:34 instead of 15.29 and that seems to address the issue. I have checked couple of symbols and it seems fine - fetching the actual previous day close.
Will post if i see any discrepancies. If i still face an issue, I have to resort to populating an artificial tick for 4 PM, as you have mentioned in the other post.

Thanks for your inputs.

Thanks,
Karthik P

1 Like

15:29 would be incorrect, should be 15:30 or higher but all the methods if understood and used properly should sort the issue. Next time if you have different data vendor, you can use another fix.

another note is AB has groups (symbol > categories) from there each group can set its own intraday settings.
The global one you have used can then break Forex and MCX ( just fyi :slight_smile: ) in same DB

1 Like

Thanks @nsm51. I have set it as 15:35 now and validating/testing.
Appreciate your time & inputs.

1 Like

That is totally wrong code. Please DO READ instructions CAREFULLY:
https://www.amibroker.com/guide/h_timeframe.html

TimeFrameCompress is used wrongly.

@karthikeyanp: Many thanks for raising this question. Coincidentally enough I was also facing the same problem.

@brajeevn: Looking at your code

TimeFrameSet( C,inDaily );
	 PDH =  TimeFrameGetPrice( "H", inDaily, -1 );
	 PDL =  TimeFrameGetPrice( "L", inDaily, -1 );
	 PDC =  TimeFrameGetPrice( "C", inDaily, -1 );
TimeFrameRestore();

The TimeFrameSet function only accepts one parameter, not two.
When I tried the corrected version in chart AFL, as follows, it still doesn't work:

TimeFrameSet(inDaily);
CDC = TimeFrameGetPrice( "C", inDaily);
PDC = TimeFrameGetPrice( "C", inDaily, -1);
PPDC = TimeFrameGetPrice( "C", inDaily, -2);
_TRACE(ticker + ": CDC " + CDC + ", PDC " + PDC + ", PPDC " + PPDC);
TimeFrameRestore();

@MESZ23: CDC 4573.75, PDC 0, PPDC 0

Looking at the page quoted by @Tomasz: the function TimeFrameGetPrice is not used:

TimeFrameSet(in5Minute); // switch to 5 minute frame
ma5_13 = MA( C, 13 );
TimeFrameRestore(); // restore time frame to original

However, using the following seems to work:

TimeFrameSet(inDaily);
CDC = C;
PDC = Ref(C,-1);
PPDC = Ref(C,-2);
_TRACE(ticker + ": CDC " + CDC + ", PDC " + PDC + ", PPDC " + PPDC);
TimeFrameRestore();

Update to my reply.

The above works, so long that no bar is selected on the intraday screen in which case the Close for the current day and the previous day are displayed. That is: C and Ref(C,-1) taken from the daily timeframe, as expected.

However, if for example the 2nd last bar is selected on the intraday, the Close for the previous day and the day before that are displayed. That is Ref(C,-1) and Ref(C,-2) taken from the Daily timeframe, instead of displaying C and Ref(C,-1) as before.

In summary:

Selected bar on intraday TF     Current C on day TF     Previous C on day TF
last (or none)                  C                       Ref(C,-1)
-1                              Ref(C,-1)               Ref(C,-2)
-2                              Ref(C,-2)               Ref(C,-3)
-3                              Ref(C,-3)               Ref(C,-4)

The behaviour is consistent with AB, that is why TImeFrameExpand() is there to align Higher TF with the lower one when it is required.
So it is up to individual to understand whether expansion is required or not in proper context.

Hello @nsm51 ,

Thanks for the reply. In the meantime I discovered that the following also works, without the surrounding TimeFrameSet() and TimeFrameRestore():

  CDC = TimeFrameGetPrice( "C", inDaily);
  PDC = TimeFrameGetPrice( "C", inDaily, -1);
1 Like

This is the intended way to use but this whole thread and the other one is about some edge cases where the exchange or data vendor sends last ticks that are not aligned because of different "last" timestamps in post-closing session.

Also OP had mistakenly set the wrong closing time in intraday settings for the exchange there by losing last tick, so OP has mentioned/corrected that.

2 Likes

(Kicking up the topic just in time)

I'm trying to get PDC and PDH as a line in a chart.
As for PDH, thanks @polomora , this displays the line, but not quite as wanted:

PDH = TimeFrameGetPrice( "H", inDaily, -1); 
Plot(PDH, "PDH", colorLightBlue, styleThick | styleNoRescale);

My problem is, that when calculating Daily High it uses data from the whole day, whereas I would like it to use only the trading hours as set in intraday settings, regardless of what times I have displayed. I have tried several settings, but it seems to me that the only way to get Daily High calculated within trading hours is to display trading hours only, but that's not what I want to do.
Example (CET):
capture_001_12022024_124106

I drew the yellow line to show what I would like the blue line to do.
Am I mising a setting or can this not be done?

As for PDC, thanks @PeterD , Valuewhen() works for PDC and solves this problem (but this obviously does not work for PDH):

TimeFrameSet(in1minute);
PDC = ValueWhen(TimeNum() == 215900, C,  1);
TimeFrameRestore();
Plot(TimeFrameExpand(PDC, in1Minute, expandLast),"PDC",colorRed, styleLine | styleNoRescale); 

The only (minor) problem here is that it does not show up in timeframes that do not have a bar ending 215900 (currently 4min and 60 min). But as I have many timeframes open, I can live with that.

Any suggestions, especially regarding PDH, will be appreciated.

That depends on FILTERING that you have enabled in the VIEW menu.
If you have no filtering (24 hours) then it would use all data.

It is all described in the KB:

AFL functions always work WITHIN selected context. So if your chart is NOT using filtering, then AFL functions would also use no filtering.