Can someone code TimeHigh and TimeLow function?

Studies that have been contributed to the community by other users. If you’ve got something useful to share, that’s great!
2haerim
Posts: 502
Joined: 01 Sep 2006
Been thanked: 2 times

Can someone code TimeHigh and TimeLow function?

Postby 2haerim » 10 Dec 2008

I'd like to define TimeHigh function as follows:

Function Name: TimeHigh
Parameters: StartTime(NumericSimple), EndTime(NumericSimple)
Return Value: The highest value between StartTime and EndTime

Please some one help.

User avatar
ABC
Posts: 718
Joined: 16 Dec 2006
Location: www.abctradinggroup.com
Has thanked: 125 times
Been thanked: 408 times
Contact:

Postby ABC » 11 Dec 2008

2haerim,

what exactly do you mean? Isn't it:

if EndTime>= StartTime: then the Endtime is obviously higher and
else: then the StartTime is higher.
The only special case would be if you go through midnight i.e. StartTime is one day before EndTime, in this case midnight (or 23:59) would be the highest time.
Is this what you are looking for?

Best regards,
ABC

2haerim
Posts: 502
Joined: 01 Sep 2006
Been thanked: 2 times

Postby 2haerim » 11 Dec 2008

ABC,

Thank you for your kind answer.

I apologize for not expressing clearly.

What I mean by "Highest value" is the highest price value between starttime and endtime, not the highest time value.

HR

brodnicki steven
Posts: 407
Joined: 01 Jan 2008
Been thanked: 3 times

Postby brodnicki steven » 11 Dec 2008

I think it's something like this (untested)

Inputs: Starttime(0730), Endtime(1400);
vars:hi(0);
if (date = currentdate) and (time >= starttime and time <= endtime) then begin
if hi < high then hi = high;
end;

Plot1(hi,"hi_betw_times");

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 12 Dec 2008

Hi 2haerim,

Its tested. Just convert the test to a function. The test calls a binary search function I wrote.

I was thinking that you could use TimeToMinutes(whatever) but once I started working on it I realized that "TimeToMinutes" will not work across different dates as the process below will do.

John.

Code: Select all

{A_MyA1_HighestPriceBetweenTimes_Test =======================================================}

{A_MyA1_HighestPriceBetweenTimes =================================================}

inputs:
StartDate(1081212),
StartTime(1500),
EndDate(1081212),
EndTime(1600);
variables:
StartTimeOffset(0),
EndTimeOffset(0),
OffsetDifference(0);

If LastBarOnChart then
begin
StartTimeOffset = A_FindOffsetViaBinary(1,BarNumber,StartDate,StartTime);
EndTimeOffset = A_FindOffsetViaBinary(1,BarNumber,EndDate,EndTime);
OffsetDifference = (StartTimeOffset - EndTimeOffset);
Print( File("C:\Access\ALog_HighestPrice.txt"),
" BarNumber", " " ,
BarNumber, " " ,

" StartTimeOffset", " " ,
StartTimeOffset, " " ,

" EndTimeOffset", " " ,
EndTimeOffset, " " ,

" OffsetDifference", " " ,
OffsetDifference, " " ,

" HighestPrice", " " ,
highest(high[EndTimeOffset],OffsetDifference + 1), " " ,
" ");

end;

Code: Select all

{
Written by John Bowles based off the web page "http://en.wikipedia.org/wiki/Binary_search" modified for EL offset.

Sample Call:
offset = A_FindOffsetViaBinary(1,BarNumber,Arw1Date,Arw1Time);

See the comments below for each input parameter to know how to run this function

The above call submits the Arrow #1 Date and time along with the last bar in the chart bar number
and you get the offset from the last bar in the chart where that arrow is located.
your code can then figure out the high/low/close price data you want from that offset.
}

inputs:
BarNumberLower(NumericSimple), {Normally value 1 which is the first bar of the chart}
BarNumberUpper(NumericSimple), {Submit "BarNumber" for the last bar of the chart}
DateIn(NumericSimple), {Submit the Arrow Date In}
TimeIn(NumericSimple) {submit the Arrow Time In}
;
variables:
MyL(0),
MyN(0),
MyR(0),
MyP(0), {Pointer to the bar which is being changed throughout the code with the binary logic}
Offset(0)
;

MyL = BarNumberLower;
MyN = BarNumberUpper;
MyR = MyN + 1; {Ending-Range is adjusted by 1}
MyP = IntPortion((MyR - MyL)/2); {We apply the binary division trimming off the decimal}


A_FindOffsetViaBinary = 0;
While MyP <> 0
begin


MyP = MyL + MyP;
Offset = BarNumberUpper - MyP; {MyP is an index from the first bar. Offset is an offset from the last bar}

If date[Offset] < DateIn or (date[Offset] = DateIn and time[Offset] < TimeIn) then
begin
MyL = MyP; {The price bar inspected is too far back so we bring our starting-range(MyL) up to MyP}
MyP = IntPortion((MyR - MyL)/2); {We apply the binary division trimming off the decimal}
end
else
begin
If date[Offset] > DateIn or (date[Offset] = DateIn and time[Offset] > TimeIn) then
begin
MyR = MyP; {The price bar just inspected is too far forward so we bring our ending-range(MyR) down to MyP}
MyP = IntPortion((MyR - MyL)/2); {We apply the binary division trimming off the decimal}
end
else
begin
If date[Offset] = DateIn and time[Offset] = TimeIn then
begin
{We found the Bar with matching date and time so we set the function output to the correct offset}
A_FindOffsetViaBinary = BarNumberUpper - MyP;
{Now that we have what we are looking for we force the loop to stop by setting MyP to zero}
MyP = 0;
end;
end;
end;

end;

2haerim
Posts: 502
Joined: 01 Sep 2006
Been thanked: 2 times

Postby 2haerim » 12 Dec 2008

Thank you John,

You must have spent lots of time for this.

I tried to test your work, but still don't know for sure how to use it.

I created a function A_MyA1_HighestPriceBetweenTimes as you advised:

Code: Select all

{A_MyA1_HighestPriceBetweenTimes =================================================}

inputs:
StartDate(NumericSimple),
StartTime(NumericSimple),
EndDate(NumericSimple),
EndTime(NumericSimple);
variables:
StartTimeOffset(0),
EndTimeOffset(0),
OffsetDifference(0);

//If LastBarOnChart then begin
StartTimeOffset = A_FindOffsetViaBinary(1,BarNumber,StartDate,StartTime);
EndTimeOffset = A_FindOffsetViaBinary(1,BarNumber,EndDate,EndTime);
OffsetDifference = (StartTimeOffset - EndTimeOffset);

A_MyA1_HighestPriceBetweenTimes = highest(high[EndTimeOffset],OffsetDifference + 1);

Print( File("C:\ALog_HighestPrice.txt"),
" BarNumber", " " ,
BarNumber, " " ,

" StartTimeOffset", " " ,
StartTimeOffset, " " ,

" EndTimeOffset", " " ,
EndTimeOffset, " " ,

" OffsetDifference", " " ,
OffsetDifference, " " ,

" HighestPrice", " " ,
A_MyA1_HighestPriceBetweenTimes, " " ,
" ");

//end;

Then created a signal A_MyA1_HighestPriceBetweenTimes_Test to test it:

Code: Select all

{A_MyA1_HighestPriceBetweenTimes_Test =======================================================}

{A_MyA1_HighestPriceBetweenTimes =================================================}

inputs:
StartDate(1081212),
StartTime(0900),
EndDate(1081212),
EndTime(1600);

//If LastBarOnChart then
begin
A_MyA1_HighestPriceBetweenTimes(StartDate, StartTime, EndDate, EndTime);
end;
And finally applied it to a chart to get the following results:

Code: Select all

BarNumber 1.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.00
BarNumber 2.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.30
BarNumber 3.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.20
BarNumber 4.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.15
BarNumber 5.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.05
BarNumber 6.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.15
BarNumber 7.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.45
BarNumber 8.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.45
BarNumber 9.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.35
BarNumber 10.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 148.25

...
...
...

BarNumber 308.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.05
BarNumber 309.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.10
BarNumber 310.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.20
BarNumber 311.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.10
BarNumber 312.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.15
BarNumber 313.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.10
BarNumber 314.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.05
BarNumber 315.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 144.05
BarNumber 316.00 StartTimeOffset 0.00 EndTimeOffset 0.00 OffsetDifference 0.00 HighestPrice 143.90

Strangely, all the offset values are always 0. I must have done something wrong.

Please check what is wrong.

2haerim
Posts: 502
Joined: 01 Sep 2006
Been thanked: 2 times

Postby 2haerim » 12 Dec 2008

BTW, it seems brodnik's code would work I think.

Wouldn't it?

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 13 Dec 2008

Hi, 2haerim

I already had the binary function written so it was not too bad.

Steven's code as it stands will work for the current date only and is designed to run on a "once through basis only" unless that end time is set to a future time in which it would keep searching for the highest high on each new tick that causes the study to execute over and over again. If you take the currentdate test out, Steven's code be modified to work any number of dates back.

My code has a different purpose actually and I probably should have pointed this out first. To maybe make it more confusing my test of the code does not indicate the way it is meant to be used (it is just a test). This approach is more for a discresionary trader I would say. In real life my code is designed to work on the LastBarOnChart such that it can get input from outside of MC such that (at any time) new start and end dates/times can be entered which are picked up when a new tick comes in via a global variable or a file read. The binary searches will find the offsets so the highest high can be found between the times. So the study never has to be turned off and on again. I my trading world I control MC via a database program changing inputs, forcing recalculates, whatever.

My second post below I think provides the best explaination as to why you are getting offsets of zero.

I ran a few tests before I cut and paste the code into the forum and it tested fine. Price data was not coming in (I use Interactive Brokers) thus I just turned the study off then on again. So the way it works is this. When you turn the study on it will process once for each bar that is already fully formed (completed). When it executes once for each completed bar your study executes basically once at the end of the bar using the bars data (high/low/close/open). During this process if you have a "lastBarOnChart" command the study will not execute that restricted code while it is executing the older bars. It will only execute the "lastBarOnChart" code when it hits the last bar on the chart. Now if you have the study set to execute on every tick after it has processed the last fully formed bar it will continue to process after that on every tick.

I have all my studies set to execute on every single tick. So while price data is not coming in the "lastBarOnChart" code will finally execute only once on that very last of the fully formed bars. So you should have a very high bar number in your print statement. You should not have a bar number 1.

John.
Last edited by bowlesj3 on 13 Dec 2008, edited 4 times in total.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 13 Dec 2008

I just retested my code and I correctly only get one line of output which is below.

BarNumber 1932.00 StartTimeOffset 68.00 EndTimeOffset 8.00 OffsetDifference 60.00 HighestPrice 883.75

I have 9 days worth of minute bars on the chart. My MaxBarsBack is set to automatic.

My start and end dates/times are
1081212
1500
1081212
1600

The last bar on the chart time is 16:08. So this is the bar that the code executed on (only once). This means that the offset of 8.00 is correct.

So you must somehow have run those tests on all the bars and the offsets will be zero when you are running on bars that do not have times high enough for the times you have inputed. The binary search searches from the first bar to the current bar only. If it gets a no find it returns zero. Again the option I submitted is only for executing on the last bar on the chart and during all subsequent live ticks from that point on. It is for a situation where you are changing the start and end times on the fly through out the trading day. I personally have no use for this. I use the binary search to do lookups for a totally different function.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 13 Dec 2008

Actually with this particular application, if a user wanted to change the inputs on the fly during the live trading day without having to do manual change of the standard EL inputs (which is rather slow) they could run Steven's code which is simpler but kick it off via a "recalculate" command. The inputs for date and time in this case would come in from global variables rather than the standard EL inputs and be picked up on the first bar. The code would need to check a global variable on every tick on the LastBarOnChart to decide of the study should be recalculated. This might be a bit faster. The downside is needing an external program to set the Global variables and needing to know how to program that. So in summary you can scan sequentially forward using a recalculate to kick it off or avoid the recalculate and scan backward using offsets either sequentially or in binary which is faster than sequential. You stop the sequential backward scan when you hit the start date/time. The problem with binary in this particular application is you still have to execute that highest(high[EndTimeOffset],OffsetDifference + 1); function which does an additional sequential offset search of its own.


Return to “User Contributed Studies and Indicator Library”