Day of High and Low within a monthly bar

Hello Everybody,
I am trying to get the day of the month when the high and low value occurred within a monthly bar.
I am not sure how to proceed with that..
Could you please give me some advice on how to do it?

I am struggling with the timeframeset options but I do not know if there is a built in function for that.

Thanks a lot

You only know high/low within time range at the end of time range so i.e. we only know it for sure at start of new time range.

So we have to get highest high's and lowest low's date of (previous) month at start of new month.

New month flag we get like this:

mth = Month();
new_mth = mth != Ref(mth, -1 );// new month flag (is an array)

To get bars having passed since HighestSince(new_mth, ... ) and LowestSince(new_mth, ...) we may use:

hh_bars = HighestSinceBars(new_mth, ...);
ll_bars = LowestSinceBars(new_mth, ...);

To get date array we may use dt = DateTime() function.

To get date ll_bars and hh_bars ago we use Ref() function.

ref_dt1 = Ref(dt, -hh_bars);// dt at HighestSince(...)
ref_dt2 = Ref(dt, -ll_bars);// dt at LowestSince(...)

Since we look for date at start of new month we have to fix it by using ValueWhen() function and looking back 1 bar at start of (new) month.

result1 = ValueWhen(new_mth, Ref(ref_dt1, -1));
result2 = ValueWhen(new_mth, Ref(ref_dt2, -1));

So as two functions:

function ValueAtPrevRangeHighest(start_of_range, array1, array2) {
	/// code source:
	/// @link https://forum.amibroker.com/t/day-of-high-and-low-within-a-monthly-bar/14175/2	
	local hh_bars, ref_array2;
	// bars that have passed since highestsince()
	hh_bars = HighestSinceBars(start_of_range, array1, 1);
	// get array2 at highestsince() by "looking" backwards hh_bars
	ref_array2 = Ref(array2, -hh_bars);
	// only get prev. array2 at start of new time range
	result = ValueWhen(start_of_range, Ref(ref_array2, -1));
	return result;
}
function ValueAtPrevRangeLowest(start_of_range, array1, array2) {
	/// code source:
	/// @link https://forum.amibroker.com/t/day-of-high-and-low-within-a-monthly-bar/14175/2
	local ll_bars, ref_array2;
	// bars that have passed since lowestsince()
	ll_bars = LowestSinceBars(start_of_range, array1, 1);
	// get array2 at lowestsince() by "looking" backwards ll_bars
	ref_array2 = Ref(array2, -ll_bars);
	// only get prev. array2 at start of new time range
	result = ValueWhen(start_of_range, Ref(ref_array2, -1));
	return result;
}

dt = DateTime();
mth = Month();
new_mth = mth != Ref(mth, -1 );

prev_mth_high_date = ValueAtPrevRangeHighest(new_mth, H, dt);
prev_mth_low_date = ValueAtPrevRangeLowest(new_mth, L, dt);

Plot( C, "Price", colorDefault, styleBar );
Plot( TimeFrameGetPrice("H", inMonthly, -1), "Previous Month's High", colorGreen, styleDots );
Plot( TimeFrameGetPrice("L", inMonthly, -1), "Previous Month's Low", colorRed, styleDots );

printf( "Previous month's HHV's date %s\n", DateTimeToStr(SelectedValue(prev_mth_high_date)));
printf( "Previous month's LLV's date %s", DateTimeToStr(SelectedValue(prev_mth_low_date)));

6


Now some people may ask why not nth = 2 as 3rd argument of Highest/LowestSinceBars(..., ..., nth = 2) functions. And then continuing like this:

// ...
hh_bars = HighestSinceBars(start_of_range, array1, 2);
ref_array2 = Ref(array2, -hh_bars);
result = ValueWhen(start_of_range, ref_array2);
// ...

Answer:
Because then bar at new month's start would be included for checking for Highest/Lowest.
So in upper picture instead of 2019-03-28 it would return 2019-04-01 (April) as date at HighestSince.

15 Likes

Thank you very much!!
To be honest, I have to read it carefully and try it a little bit.

Thanks for your help! :wink:

1 Like

@fxshrat, this is an excellent and well-written tutorial. Thank you for putting it together.

6 Likes

@fxshrat, I agree with @ghanson, and would like to salute your well-written tutorial. This forum owes you and others a debt of gratitude. Thank you and best regards, John.

2 Likes