You need to get a few things straight: Does it compile without errors or not?
0 errors.
If I can't use iCustom in an indicator, would that means that I have no choice but to integrate it's functionality directly into my EA?
Yes, the WAE has color changing bars. If I have investigated the indexes properly, it's index 1 that contains the color. 1 for green bars and 2 for red ones. I don't draw any of these. However, I do want to change the color of my dots based on the trend.
Yes, you can use iCustom() within another custom indicator, so ignore that comment, please.
Also, you are not checking if the handle returned in the OnInit() is valid or not, and you are proceeding under the assumption that that it will work.
With the CopyBuffer, you are simply returning (with zero), when it fails, but not reporting the conditions to your log file, so how will you know what is happening?
Print out the results to the log, including any error codes when something fails, so that you can debug it.
Yes, you can use iCustom() within another custom indicator, so ignore that comment, please.
Also, you are not checking if the handle returned in the OnInit() is valid or not, and you are proceeding under the assumption that that it will work.
With the CopyBuffer, you are simply returning (with zero), when it fails, but not reporting the conditions to your log file, so how will you know what is happening?
Print out the results to the log, including any error codes when something fails, so that you can debug it.
Excellent points. At that point I was basically just following what the tutorial said. Here is my new code.
//+------------------------------------------------------------------+ //| Phoenix Trend.mq5 | //| Copyright 2022, Phoenix Investments | //| https://www.phoenixinvestments.com | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Properties and Buffers | //+------------------------------------------------------------------+ #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_ARROW #property indicator_label1 "Trend Indicator" #property indicator_color1 clrRoyalBlue, clrCrimson #property indicator_width1 5 //+------------------------------------------------------------------+ //| Indicator Settings | //+------------------------------------------------------------------+ input int macdFast = 20, // MACD Fast macdSlow = 40, //MACD Slow bbPeriod = 20, //BB Period bbDeviation = 2, // BB Deviation sensitive = 150, //Sensitivity deadZoneLevel = 400, //Deadzone Level explosionLevel = 15, //Explosion Level trendPower = 150; //Trend Power //+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ enum Status {UNSET, INVALID, LONG, SHORT}; double waeHandle; double waeValueBuffer[], waeDZBuffer[], waeColorBuffer[], arrowBuffer[]; int maxPeriod; Status curTrend = UNSET; bool once = false; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { Print("Initialized!"); SetIndexBuffer(0, arrowBuffer, INDICATOR_DATA); //SetIndexBuffer(1, waeValueBuffer, INDICATOR_DATA); //SetIndexBuffer(2, waeDZBuffer, INDICATOR_DATA); //SetIndexBuffer(3, waeColorBuffer, INDICATOR_DATA); maxPeriod = (int)MathMax(MathMax(macdFast, macdSlow), bbPeriod); if(waeHandle = iCustom(_Symbol,_Period,"Waddah Attar Explosion", macdFast, macdSlow, bbPeriod, bbDeviation, sensitive, deadZoneLevel, explosionLevel, trendPower) == -1){ ResetLastError(); Print("Error: ", GetLastError()); } PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, maxPeriod); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator Deinitialization function | //+------------------------------------------------------------------+ int OnDeinit(){ if(waeHandle != INVALID_HANDLE) IndicatorRelease(waeHandle); return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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(IsStopped()) return(0); if(rates_total < maxPeriod) return(0); if(BarsCalculated(waeHandle) < rates_total)return(0); int copyBars = 0; int startBar = 0; if(prev_calculated < rates_total || prev_calculated <= 0){ copyBars = rates_total; startBar = maxPeriod; } else { copyBars = rates_total-prev_calculated; if(prev_calculated > 0) copyBars++; startBar = prev_calculated - 1; } if(IsStopped()) return(0); for(int bar = startBar; bar < rates_total && !IsStopped(); bar++){ if(CopyBuffer(waeHandle, 0, bar, 1, waeValueBuffer) <= 0){ ResetLastError(); Print("Error: ", GetLastError()); return(0); } if(CopyBuffer(waeHandle, 1, bar, 1, waeColorBuffer) <= 0){ ResetLastError(); Print("Error: ", GetLastError()); return(0); } if(CopyBuffer(waeHandle, 3, bar, 1, waeDZBuffer) <= 0){ ResetLastError(); Print("Error: ", GetLastError()); return(0); } if(IsStopped()) return(0); //Print(waeValueBuffer[0], " || ", waeDZBuffer[0]); if(waeValueBuffer[0] > waeDZBuffer[0]){ //Print(waeColorBuffer[0]); curTrend = (waeColorBuffer[0] == 1.0) ? LONG : SHORT; //Print(EnumToString(curTrend)); } if(curTrend == LONG){ arrowBuffer[bar] = low[bar]; }else if (curTrend == SHORT){ arrowBuffer[bar] = high[bar]; }else{} } return(rates_total); } //+------------------------------------------------------------------+No errors printed
NO! If you reset the error AFTER it has occurs, obviously it will ALWAYS report there being "no error".
ResetLastError(); Print("Error: ", GetLastError());
Reset the error before executing the code that you want to trace, and identify what is being done in the log entry so you know where it occurred.
// Reset last error ResetLastError(); // Obtain handle to custom indicator waeHandle = iCustom( _Symbol, _Period, "Waddah Attar Explosion", macdFast, macdSlow, bbPeriod, bbDeviation, sensitive, deadZoneLevel, explosionLevel, trendPower ); // Check validity of indicator handle if( waeHandle == INVALID_HANDLE ) { Print( "Invalid indicator handle! Error code: ", _LastError ); return INIT_FAILED; // Initialisation has failed };
Also, add more log prints all over you code to detect how the code progresses and how each section is working. This is important, as you have so many "return(0)" in so many places, that one has no idea if any of your code is actually getting executed at all.
NO! If you reset the error AFTER it has occurs, obviously it will ALWAYS report there being "no error".
Reset the error before executing the code that you want to trace, and identify what is being done in the log entry so you know where it occurred.
Also, add more log prints all over you code to detect how the code progresses and how each section is working. This is important, as you have so many "return(0)" in so many places, that one has no idea if any of your code is actually getting executed at all.
The tutorial that I was following *** had a bunch of return(0) in his videos. Is this a bad idea?
I removed all of the ResetLastErrors from the different spots, and I still am not getting any errors anywhere.
Yes, it's a bad idea. Code should flow logicically, so that it can be followed and "read". Think about it this way — imagine writing a novel and at every negative decision in the story, it sent you to the last page of the book - The End -. This is just my personal opinion, but I have yet to see any Videos on coding that are worth while, but I digress.
For a beginner, learning is difficult enough, so trying to code something complex is even more difficult. There is a reason, why in programming lessons, they always start with simplest and most famous of tasks, namely to code the printing of "Hello World!" Unfortunately for MQL, everyone is so preoccupied in wanting to make "lots of money", that they throw away all sense of learning the language properly.
So, I suggest the following. Throw away this code for now. Start by coding the simplest of indicators. The task is basically so that you can learn the basics of how a custom indicator needs to be constructed. How to use the OnCalculate() event handler; how to declare and use buffers, how to use the "rates_total" and "prev_calculated", etc.
As you do this, you can come here and ask questions about what you don't understand, and slowly add more and more functionality to it, until you have reached a level good enough to start coding what you really need for your trading. In the beginning, code only with the aim of learning. Code only the simplest of tasks, even if they are useless. Then progress to more difficult stuff.
Yes, it's a bad idea. Code should flow logicically, so that it can be followed and "read". Think about it this way — imagine writing a novel and at every negative decision in the story, it sent you to the last page of the book - The End -. This is just my personal opinion, but I have yet to see any Videos on coding that are worth while, but I digress.
For a beginner, learning is difficult enough, so trying to code something complex is even more difficult. There is a reason, why in programming lessons, they always start with simplest and most famous of tasks, namely to code the printing of "Hello World!" Unfortunately for MQL, everyone is so preoccupied in wanting to make "lots of money", that they throw away all sense of learning the language properly.
So, I suggest the following. Throw away this code for now. Start by coding the simplest of indicators. The task is basically so that you can learn the basics of how a custom indicator needs to be constructed. How to use the OnCalculate() event handler; how to declare and use buffers, how to use the "rates_total" and "prev_calculated", etc.
As you do this, you can come here and ask questions about what you don't understand, and slowly add more and more functionality to it, until you have reached a level good enough to start coding what you really need for your trading. In the beginning, code only with the aim of learning. Code only the simplest of tasks, even if they are useless. Then progress to more difficult stuff.
I can understand what you are saying, but there are so few guides and tutorials for writing indicators and EAs. So, I wouldn't even know where to begin with such a thing. In all honesty, I didn't see my indicator as being all that complicated, all things considered.
I saw a guide on writing a simple moving average. But to be honest, I don't think it would teach me much by itself. That being said, I will happily go through it and do the tutorial. But it's about the only one I could find. Otherwise it seems like articles and videos on this topic are sadly lacking.
It's not complicated, but it is "complicated" for you at your current skill level. I say this because one can clearly see that there are several basic level things that you don't quite comprehend yet.
That is where I believe you are may misjudging the situation.
That is absolutely true. The reason being that most that are learning MQL, are being driven mostly by greed. And those teaching it in videos and books, are exploiting that greed.
I would recommend you follow resources aimed at learning C and C++. Start by first learning the basics of C/C++ without looking at MQL. Then once you understand the basics, then continue learning C/C++ at the same time as MQL.
***
I would recommend you follow resources aimed at learning C and C++. Start by first learning the basics of C/C++ without looking at MQL. Then once you understand the basics, then continue learning C/C++ at the same time as MQL.
This is the worst advice you can give to a beginner! If you are just starting to learn the MQL5 language, you are simply FORBIDDEN (as it will only harm you) to learn 'C/C++'!
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Ok,
I'm working on a simplified indicator that I plan on using in my EA.
First off, I am not looking for it to be done for me. If you like, give me a hint and I'll try to figure it out.
What I have done:
I have watched the*** videos on making an indicator for MT5. In fact, the framework of my indicator is based on that.
I've read the documentation of all of the key functions and constants etc etc.
And I've Googled numerous issues.
I was having trouble with SetIndexBuffer altering the values I was getting from the buffers. But now I think I'm getting good values. Which I determined by printing out the variables and traced it back the the SetIndexBuffer. I took that function off of all but the arrow buffer and it seems like that did it for those issues.
It's printing out the dots, and even changing their locations, but not at the right points. And I can't figure out why.
Errors:
0 Errors on compile
The Goal:
The indicator is based on the Waddah Attar Explosion. Basically, when a bar rises above the deadzone level it's suppose to change the trend in that direction till a bar of the opposite color rises above the deadzone and changes it to the other direction.
I will be adding other filters later, but I just want to figure out the basics of how to get it all running smoothly first.
I'm willing to do the legwork (head work) but I need a pointer.