Go on! please.
Thanks for the encouragement!
You are very thoughtful to have considered this contribution at all... My impression is that most folks here are looking for someone to solve all their problems for them, rather than learn to solve problems for themselves.
Now I have actually contributed the very heart of a solid tri-state logic EA in a very few lines of code... capable of handling many indicators simultaneously, reliably. I am sure that a few enterprising people will benefit from this foundation concept, and hopefully more develop it for themselves, as I love to do things...
Personally, I benefitted enormously from the contributions of the MACD sample, for a basic framework of understanding an EA, which I have completely changed to suit myself now, and the DIN_Kukus_EA located here, as well as some of it's key developers... who are definitely worth paying attention to. Thanks Mr. Pips if you are out there...
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi fellow traders and coders...
It appears that this is a possible new discussion thread, so maybe we can consolidte many coding tools and ideas in one place. Also, this is my first post of this type, and I hope it comes out alright in terms of the formatting...
I have tried my best, and we will see what happens... or maybe this will never see the light of day... ![](https://c.mql5.com/forextsd/smiles/cry_smile.png)
I am not a professional programmer, but have done a lot of programming... and I have been transitioning to MLQ4 now for about six months... determined to create my own grail, which I would never publish... or even sell but, I do believe in sharing fundamental knowledge to help others formulate unique solutions for themselves...
I will give an example of how I use a couple of handlers in my EA, and how I think I improved on the coding practices I have seen in use for similar purposes.
I am going to give long function names to help in understanding the following example.
In the main EA (Start()) cycle code, I have three references to a single function that reads indicator data, and renders buy, sell, exit buy, and exit sell opinions. That single function I will name IndicatorSet(). Within IndicatorSet() is a "switch" command with five cases...
Case 0 read indicator data called by: IndicatorSet(0);
Case 1 render a buy opinion IndicatorSet(1);
Case 2 render a sell opinion IndicatorSet(2);
Case 3 render an exit buy opinion IndicatorSet(3);
Case 4 render an exit sell opinion IndicatorSet(4);
Example function code for IndicatorSet():
bool IndicatorSet(int cmd)
{
switch(cmd)
{case 0: // Command to read indicator data.
*** Example indicator ***
SD_0 = iStdDev(NULL,0,SD_period,0,3,6,0);
SD_1 = iStdDev(NULL,0,SD_period,0,3,6,1);
break;
case 1: // Command to check for a buy possibility.
*** Logic for rendering a buy signal or opinion using the indicator data.
When buy criteria are met, this block executes return(true); otherwise it
executes return(false); ***
break;
case 2: // Command to check for a sell possibility.
*** Same as Case 1 but for a sell opinion ***
break;
case 3: // Command to check for an exit buy possibility.
*** Same as Case 1 but for an exit buy opinion ***
break;
case 4: // Command to check for an exit sell possibility.
*** Same as Case 1 but for an exit sell opinion ***
break;
}
}[/CODE]
From the EA main cycle code (Start()), I reference IndicatorSet(int cmd) first to read indicator data into individual variables, or arrays... including the command for the switch function... So, IndicatorSet(0) is used to call the logic block within Case 0 of IndicatorSet() to do just that.
Also in the EA main cycle code are two "handlers"... HandleEntryExecutions() and HandleExitExecutions() which also reference IndicatorSet() for entry and exit opinions. I have split the entry and exit handler functions for my own reasons rather than combine them, and will not elaborate on that... so, just accept it.
Normally I have seen and used code that would work like this...
From the HandleEntryExecutions() function I would call IndicatorSet(1) for a buy opinion, and IndicatorSet(2) for a sell opinion using coding like this:
Example code:
HandleEntryExecutions()
{
if(IndicatorSet(1)) // Called the indicator set using an "if" comparison and receiving a "true" or "false"
{ // in reply from the bool IndicatorSet(1) function Case 1 block of code.
*** code to be executed
when there is a buy opinion rendered, or stated ***
}
}[/CODE]
The same technique would be used to extract a sell opinion from the IndicatorSet(2) Case 2 block of code.
The HandleExitExecutions() would work the same as well for exit opinion extraction.
All of this is according to conventional coding practices that I am aware of, and that I have used. The problem I have noted with this approach is that if there is some defect in the logic, the handler can easily receive a "true" or
"false" conditon from any number of possible sources or conditions, and sometimes... it is difficult to track down or even discover that there is even a fault!!! So, I devised a method of ensuring that when a logical block of code is called upon by a handler that the handler receives not only the opinion it seeks, but verification that it is in fact "talking" or communicating with the correct block of logic. This makes it easy to troubleshoot any faults, and very easy to add coding to deal with logical or communication errors which I will demonstrate as well.
For the sake of brevity, I will call this coding technique "integer query verification" or IQV. This is what is different about using IQV and how it works...
Instead of addressing a boolean type IndicatorSet() function, we will change it to an integer type function.
Instead of receiving a return "true" or "false" from the IndicatorSet() logical case blocks, we will use a "positive" or "negative" unique integer for the response and handle that.
Here are examples...
Example function code for an IQV version of IndicatorSet():
Note the difference in the responses of Case 1 thru 4... Case 0 will remain unaffected in this example.
[CODE]
int IndicatorSet(int cmd)
{
switch(cmd)
{case 0: // Command to read indicator data.
*** Example indicator ***
SD_0 = iStdDev(NULL,0,SD_period,0,3,6,0);
SD_1 = iStdDev(NULL,0,SD_period,0,3,6,1);
break;
case 1: // Command to check for a buy possibility.
*** Logic for rendering a buy signal or opinion using the indicator data.
When buy criteria are met, this block executes return(1); otherwise it
executes return(-1); ***
break;
case 2: // Command to check for a sell possibility.
*** Same as Case 1 but for a sell opinion. Returns 2 or -2. ***
break;
case 3: // Command to check for an exit buy possibility.
*** Same as Case 1 but for an exit buy opinion. Returns 3 or -3. ***
break;
case 4: // Command to check for an exit sell possibility.
*** Same as Case 1 but for an exit sell opinion. Returns 4 or -4. ***
break;
}
}So instead of Case 1 thru 4 returning a "true" or "false", they instead return a unique functional integer, or it's opposite...
For comparison... Conventional response to query/IQV response to query
Case 1 render a buy opinion true or false/+1 or -1
Case 2 render a sell opinion true or false/+2 or -2
Case 3 render an exit buy opinion true or false/+3 or -3
Case 4 render an exit sell opinion true or false/+4 or -4
Simple right??? And, now this is how we can use this new response to advantage...
Here is an example of a new IQV HandleEntryExecutions() function...
Example code:
[CODE]
void HandleEntryExecutions()
{int x;
x = IndicatorSet(1); // Solicit an open buy opinion from the indicator set.
if(MathAbs(x) == 1) // Verify that the correct indicator logic responded. We know it is the correct
// indicator because we receive a unique number... 1 in reply...
{if(x == 1) // If the unique number is a positive number then execute a buy position if it is a
// negative number then do not place a buy order.
{if(!Buy()) // If the boolean type Buy function returns false, there was an error... otherwise it was executed.
{ *** Code to be executed if Buy() function failed to properly execute a buy order. ***}
else // If x turns out to be anything but our expected unique number... we have a problem and
// can handle that problem with code offered in the else condition...
{ *** Code to executed to handle an indicator error here ***}
x = IndicatorSet(2); // Same type of coding to handle a sell order entry....
if(MathAbs(x) == 2) // A number 2 identifies sell opinions...
{if(x == 2) // If a positive 2 is received execute the sell order, if negative skip placing an order.
{if(!Sell()) // If the Sell function returns false, there was an error...
{ *** Code to be executed if Sell() function failed to properly execute a buy order. ***}
else // x is not our expected unique number, so handle the error...
{ *** Code to executed to handle an indicator error here ***}
}The comments in the coding above explain how the IQV process works, and as you can see it is very powerful in verifying correct indicator responses, and providing for easy error handling...
Try this system, and if you are like me, you will love it... because it becomes so easy to detect coding or real-time execution errors and to add the "bells and whistles" so to speak for handling any errors that may arise.