if(zScore[i] > 4.36 && i > 0) //if range is large AND not the { //first bar... j = i; daily_time = iTime(NULL,PERIOD_D1,j - 1); //select the opening time of //previous daily candle if(iClose(NULL,PERIOD_D1,j) - iOpen(NULL,PERIOD_D1,j) >= 0)
- You are mixing apples and oranges Use iBarShift.
- For time you can just compute it.
#define HR2400 86400 SECONDS time(datetime when=0){ return SECONDS(when == 0 ? TimeCurrent() : when) % HR2400; } datetime date(datetime when=0){ return datetime( (when == 0 ? TimeCurrent() : when) - time(when) ); } datetime tomorrow( datetime when=0){ // Weekends not accounted return date(when) + HR2400; } /// Returns previous trading day. datetime yesterday(datetime when=0) /**< Previous relative to * when. */{ if(when==0) when = TimeCurrent(); // Make sure I have daily history. download_history(_Symbol, PERIOD_D1); INDEX iD1 = iBarShift(NULL, PERIOD_D1, when); // Find today. return iTime(NULL, PERIOD_D1, iD1 + 1); // Return yesterday. } //////////////////////////////////////////////////////////////////////////////// daily_time = date(Time[i]);
- You are mixing apples and oranges Use iBarShift.
ObjectCreate("Quasimodo" + j,OBJ_HLINE,0,0,oneHourRate[secondExtreme]);
- Don't use shift numbers in object names. You created a Quasimodo1 then the next day you'll try to again. Make your names unique "Quasimodo"+Time[j].
- You would know this had you Check your return codes What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
- Don't use shift numbers in object names. You created a Quasimodo1 then the next day you'll try to again. Make your names unique "Quasimodo"+Time[j].
-
- You are mixing apples and oranges Use iBarShift.
- For time you can just compute it.
- You are mixing apples and oranges Use iBarShift.
- Don't use shift numbers in object names. You created a Quasimodo1 then the next day you'll try to again. Make your names unique "Quasimodo"+Time[j].
- You would know this had you Check your return codes What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
- Don't use shift numbers in object names. You created a Quasimodo1 then the next day you'll try to again. Make your names unique "Quasimodo"+Time[j].
Hello, WHRoeder
Thank you very much for your help again.
There are two things I don't understand from your reply:
- "You are mixing apples and oranges";
- Your computing for time;
1. Why am I mixing apples with oranges? i, j and shift are all int types and they represent shift in the context of my indicator. I don't understand why this prevents my indicator from performing the calculations all the way to the end.
2. With regards to your "computing for time" algorithm, the following are the points I don't understand:
- I wasn't familiar with the series array Time[]. Why did you choose Time[] over iTime?
- What is download_history(_Symbol, PERIOD_D1)?
- I noticed you initialise with SECONDS and INDEX (like int, double, etc). Is that MQL5 language?
- I suppose when = 0 is just your way of illustrating your point, right? I'm not expected to actually type when = 0, correct? Just datetime date(datetime when) {... no?
- After daily_time = date(Time[i]), yesterday(daily_time) will give me the iTime for the previous daily bar, no?
I would greatly appreciate if you could clarify these questions for me.
Thanks in advance,
Thad
I have added the following to the top of my code, just below the #property(s):
#define HR2400 86400 datetime time(datetime when=0) { return (when == 0 ? TimeCurrent() : when) % HR2400; } datetime date(datetime when=0) { return ((when == 0 ? TimeCurrent() : when) - time(when)); } datetime tomorrow(datetime when=0) { return date(when) + HR2400; } datetime yesterday(datetime when=0) { if(when == 0) when = TimeCurrent(); int iD1 = barID(when); return iTime(NULL, PERIOD_D1, iD1 + 1); } int barID (datetime when) { return iBarShift(NULL,PERIOD_D1, when); }
Inside the body (int start()), I have called the above functions, but it is still not working properly:
daily_time = date(Time[i]); //select the opening time of daily candle
j = barID(daily_time);
The code is still not performing the calculations to the end.
What am I missing?
Cheers,
Thad
Thaddeus_39: 1. Why am I mixing apples with oranges? i, j and shift are all int types and they represent shift in the context of my indicator.
- I wasn't familiar with the series array Time[]. Why did you choose Time[] over iTime?
- What is download_history(_Symbol, PERIOD_D1)?
- I noticed you initialise with SECONDS and INDEX (like int, double, etc). Is that MQL5 language?
- I suppose when = 0 is just your way of illustrating your point, right? I'm not expected to actually type when = 0, correct? Just datetime date(datetime when) {... no?
- After daily_time = date(Time[i]), yesterday(daily_time) will give me the iTime for the previous daily bar, no?
- They do not "represent shift in the context of your indicator." i is the shift for your indicator on the current chart. j is the shift on the D1 chart. Read and understand the links provided. Then look at the yesterday function and compare it to the your code:
if(zScore[i] > 4.36 && i > 0) //if range is large AND not the { //first bar... j = i; daily_time = iTime(NULL,PERIOD_D1,j - 1); //select the opening time of //previous daily candle if(iClose(NULL,PERIOD_D1,j) - iOpen(NULL,PERIOD_D1,j) >= 0)
- Why use a function call when you can use a Predefined Variables - MQL4 Reference Perhaps you should read the manual.
- Check that D1 chart is loaded. For indicators:
bool download_history( #define THIS_SYMBOL "" SYMBOL symbol=THIS_SYMBOL, ///< The symbol required. ENUM_TIMEFRAMES period=PERIOD_CURRENT) /**< Standard timeframe. */{ if(symbol == THIS_SYMBOL) symbol = _Symbol; if(period == PERIOD_CURRENT) period = ENUM_TIMEFRAMES(_Period); ResetLastError(); datetime other = iTime(symbol, period, 0); return _LastError == 0; } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]){ if(!download_history(THIS_SYMBOL, PERIOD_D1) return prev_calculated; // Keep D1 loaded
- No, #defines to document type usage.
- No. Formal Parameters - Variables - Language Basics - MQL4 Reference
- Obviously. As would yesterday() with no argument, see #5
Thanks, WHRoeder
I understood your code (or I think I did).
I have added your "Time computing" code to the beginning (which I think is super clever, by the way)
(...) #property indicator_buffers 1 #define HR2400 86400 datetime time(datetime when=0) { return (when == 0 ? TimeCurrent() : when) % HR2400; } datetime date(datetime when=0) { return ((when == 0 ? TimeCurrent() : when) - time(when)); } datetime tomorrow(datetime when=0) { return date(when) + HR2400; } (...)
and then called the function tomorrow(), thus eliminating the useless variable j:
(...) zScore[i]=((iHigh(NULL,PERIOD_D1,i)-iLow(NULL,PERIOD_D1,i)) - Sum_R/Aver_Bars) / Std_Dev; //calculation of z_score //+--------------------------------------------------------------------+ //If z-score > 3.00, the code will zoom into the one hour bars that | //make up the daily bar and find the second extreme. The code will | //then print a line from such extreme. | //+--------------------------------------------------------------------+ if(zScore[i] > 3.0) //if range is large AND not the { //first bar... daily_time = tomorrow(Time[i]); //select the opening time of daily candle if(iClose(NULL,PERIOD_D1,i) - iOpen(NULL,PERIOD_D1,i) >= 0) Bullish = True; //checking feature of candle else Bullish = False; (...)
(I read your apples and oranges link and the difference between that example and mine is that I only refer to the daily chart: if I couldn't use i in iClose and iOpen, then I could certainly not use it in iHigh and iLow - but the zScore[i] calculations worked perfectly until I started trying to draw lines so using i in iClose and iOpen can't be the issue)
This is what is happening.
When I choose if(zScore[i] > 3.0), the calculations only go as far as 23/01/2014, when the zScore is 4.3501.
3" alt="zScore[i]>3" style="vertical-align: middle;">
When I choose if(zScore[i] > 4.36), the final chart is the same as the first chart on this thread (as far as 24/08/2015 when zScore = 4.74).
Finally, when I choose if(zScore[i] > 5.0), then it performs the calculations all the way (and I only get one line).
I think the issue could be when executing CopyLow(...) or CopyHigh(...)
What do you think?
Cheers,
Thad
if(zScore[i] > 3.0) //if range is large AND not the { //first bar... daily_time = tomorrow(Time[i]); //select the opening time of daily candle if(iClose(NULL,PERIOD_D1,i) - iOpen(NULL,PERIOD_D1,i) >= 0)
You read but did not understand. The difference is my code used iBarShift.
If you are on the M1 chart and i is 2, your iClose(D1,2) is two days ago. If i is 5, your iClose(D1,5) is 5 days ago. You want the day containing your bar shift i.
You read but did not understand. The difference is my code used iBarShift.
If you are on the M1 chart and i is 2, your iClose(D1,2) is two days ago. If i is 5, your iClose(D1,5) is 5 days ago. You want the day containing your bar shift i.
1. That is what I understood from the apples and oranges link, which was quite insightful.
So, for consistency, your argument implies that I must change the calculation of zScore[i] as well, to be computed with iBarShift instead of n or i. Do you agree?
(...) #define LOOKBACK Aver_Bars - 1 counted_bars = IndicatorCounted(); //# of calculated bars i = Bars - MathMax(LOOKBACK,counted_bars) - 1; //#index of 1st uncounted while(i>=0) //Cycle of uncounted bars { Sum_R=0; Sum_Dev=0; Std_Dev=0; //Nulling at beginning of loop for(n=i;n<=i+Aver_Bars-1;n++) //Loop of summing values Sum_R=Sum_R + (iHigh(NULL,PERIOD_D1,n)-iLow(NULL,PERIOD_D1,n));//Accumulating range values for(n=i;n<=i+Aver_Bars-1;n++) //Loop of summing values Sum_Dev=Sum_Dev+((iHigh(NULL,PERIOD_D1,n)-iLow(NULL,PERIOD_D1,n))-Sum_R/Aver_Bars)* ((iHigh(NULL,PERIOD_D1,n)-iLow(NULL,PERIOD_D1,n))-Sum_R/Aver_Bars); //Sum of sq deviations from mean Std_Dev = MathSqrt(Sum_Dev/(Aver_Bars-1));//Std Deviation zScore[i]=((iHigh(NULL,PERIOD_D1,i)-iLow(NULL,PERIOD_D1,i)) - Sum_R/Aver_Bars) / Std_Dev; //calculation of z_score //+--------------------------------------------------------------------+ //If z-score > 3.0, the code will zoom into the one hour bars that | //make up the daily bar and find the second extreme. The code will | //then print a line from such extreme. | //+--------------------------------------------------------------------+ if(zScore[i] > 4.36 && i > 0) //if range is large AND not the { //first bar... (...)
2. With respect to the outcome that I described in my last post, where the indicator stops short of calculating all the way, I run into such problem even when my main window displays the daily chart.
So the problem will persist even when I change my code to accommodate iBarShift. Wouldn't you agree?
Cheers,
Thad
- Yes. i and PERIOD_D1 can not be used together.
- Yes, that has nothing to do with your other problem. Have you looked in the log? Have you added a print statement inside your loop?
Thanks, WHRoeder
When I load the indicator, I get the following under the Experts tab:
- Custom Indicator loaded successfully;
- Initialised;
- Incorrect start position 24 for ArrayMaximum function;
- Array out of range in "NameOfIndicator.mq4" (116,81)
When I change my if expression from
(...) if(zScore[i] > 4.36) //if range is large AND not the { //first bar... daily_time = tomorrow(Time[i]); //select the opening time of daily candle (...)
to
(...) if(zScore[i] > 3.00) //if range is large AND not the { //first bar... daily_time = tomorrow(Time[i]); //select the opening time of daily candle (...)
I get:
- Incorrect start position 0 for ArrayMaximum function;
- Incorrect start position 0 for ArrayMaximum function;
- array out of range in "NameOfIndicator.mq4" (116,81);
Please let me know what you think.
Cheers,
Thad
OK, I understand what's causing the first set of errors, when if(zScore[i] > 4.36).
Sometimes there is an incompatibility between the open time of the daily candle and the opening time of the first hourly candle of that particular day.
The open time of the daily is always 00:00 but sometimes the 1 hour bar for 00:00 doesn't exist. I mention that here: https://www.mql5.com/en/forum/159693
When I add one extra hour to the calculation of daily_time = tomorrow(Time[i]) the indicator works fine, calculates all the way.
That's good, because I believe the code is easy to fix. Just add a condition such as the following to deal with the mismatch:
(...) MqlRates rates[]; ArraySetAsSeries(rates,true); int copied=CopyRates(Symbol(),0,0,100,rates); if(copied>0) { Print("Bars copied: "+copied); (...)
However, the quick fix didn't work for the errors and warnings under if(zScore[i] > 3.00).
Any ideas?
Cheers,
Thad
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello, MQL community.
I hope you can help me with the following issue:
I am trying to print a zScore of daily ranges (which is just the standardize function in excel) and horizontal lines in the same chart.
When the zScore[i] > 4.36, the code zooms into the 1H time frame of daily bar[i], looks for the 2nd lowest/highest price (depends if daily bar is bull/bear) and prints a H_Line.
However, the indicator stops in the middle of the way, it doesn't perform the calculations all the way to the last bar.
How can I fix this? I can't figure out what's causing this.
The code follows below.
I know the zScore works fine on its own because I tested it and MQL experts from this community helped me get it right (https://www.mql5.com/en/forum/159623) (Thanks WHRoeder and ffoorr!)
The creation of the H_Lines also work fine because I've tested a script of it here: https://www.mql5.com/en/forum/159693
Thanks in advance