MQL4 Trend Indicator With Filters EA
Many intraday trend systems can be enhanced with a separate trend filter. This is an indicator that looks at recent price action and determines whether the overall trend is up, down, or neutral. Learn in this MQL4 Trend Indicator With Filters EA article how to avoid unnecessary losses whenever the EA trades contrary to the larger trend.
A trend filter is a way for the system to trade in the direction of the overall trend, filtering out trades that are contrary to the trend with the hope (proven from back testing) that the trend filter is filtering out more losing trades than winning trades.
We system traders often find or create an interesting trending system on a smaller time frame chart like the M30, and we can see through back testing that the system can profitably exploit many trend opportunities on this relatively smaller time frame.
However, we may also see from visual back testing that the system, though ultimately profitable, takes a lot of unnecessary losses whenever it trades contrary to the larger trend. When we see this, it behooves us to look for a trend filter of the same or alternate indicator, set on a larger time frame or period, that can help the system identify the lager trend of the market and only allow trades to occur in the direction of that larger trend.
It helps if we also code in a true / false bool for that trend filter, so that we can easily back test with the filter on or off to see if it is enhanced or not by its addition.
We will look at the construction of a simple trend filter, the Moving Average Trend Filter, in order to give you an idea of the process of creating and implementing a trend filter. Once you know how to code up this one trend filter, you can easily code up many alternative ones based on different indicators, until you finally discover the right set of trending filters to test upon all your trending strategies.
Moving Average Trend Filter
We are going to code up a moving average filter that when set to true only trades longs when the closing price is above the moving average and only trades shorts when the closing price is below the moving average. Simple enough.
Long Positions: When close is above moving average.
Short Positions: When close is below moving average.
Parameters
MAFilter
Bool: Indicate whether or not you want the Moving Average Filter on or off. Trades from primary entry system are only taken in the direction of the moving average: only long when close is above moving average, only short when close is below. Default is false.
MAFilterRev
Bool: Indicate whether or not you want the Moving Average Filter Reversed on or off. Trades from primary entry system are only taken in the opposite direction of the moving average: only long when close is below moving average, only short when close is above. Default is false. Though this reversed filter is not often used, it can be useful if you discovered through back testing that applying the MAFilter above severely diminished your strategy. You may then want to see if applying the MAFilterRev can then super charge it.
MATime
Int: This is the time frame of your moving average. Default is 0, which means same time frame of the chart. You should test the same time frame first, and then move upwards in your tests, testing on each larger time frame. For instance, if your primary strategy was set on a M30 chart, you would test your Moving Average with the default of 0, which would be your M30, then you would test it with 60, which would be H1, then 240, which would be H4, and 14440, which would be D1.
MAPeriod
Int: This is the period of your moving average. Default is 50, which is a common longer period for the Moving Average to determine trend direction. Another common longer period is 200. I would advise setting an optimization between 50 to 200, with a step interval of 25 or 50, to see which of the longer MA periods can best identify the trend for that currency on each of the time frames you test upon.
MAMethod
Int: This is the method or mode of the moving average, which is defaulted to 1, the exponential moving average. Remember: in the method parameter, 0 = Simple, 1 = Exponential, 2 = Smoothed, 3 = Linear Weighted. I think 1 or exponential is the best type of moving average. The other good one to test with is 0, the simple moving average. Both are very popular and effective modes of the moving average.
MT4 Code Snippets
The block of code below is placed in the external variables section.
extern bool MAFilterRev = false;
extern int MATime = 0;
extern int MAPeriod = 50;
extern int MAMethod=1;
The block of code below is placed in the indicator calling section.
double mafilter=iMA(NULL,MATime,MAPeriod,0,MAMethod,PRICE_CLOSE,shift);
MT4 Code Usage Example
Below is an example of a MAFilter being interwoven into the code of the Moving Average Cross strategy. We earlier detailed how to construct a moving average cross strategy, so it should be familiar. One might imagine that a MAFilter added to a moving average cross tehnique would be redundant; however, there is a case to be made for how it can act as a compliment. For instance, if the moving average cross were to take trades based on period of 30 on a M30 time frame, it may be enhanced if it were complimented with a 200 period MAFilter on a H4 time frame. It may benefit by taking trades on the trends of the shorter time frame and period that are ultimately in the direction of the longer time frame and period.
bool SellCondition = false;
if (
FastMACurrent > SlowMACurrent && FastMAPrevious < SlowMAPrevious){
BuyCondition=true;
if (OppositeClose) CloseSell=true;
}
if (
FastMACurrent < SlowMACurrent && FastMAPrevious > SlowMAPrevious){
SellCondition=true;
if (OppositeClose) CloseBuy=true;
}
if (BuyCondition
&&
(MAFilter==false || (MAFilter && Ask>mafilter))
&&
(MAFilterRev==false || (MAFilter && Ask< mafilter))
OpenBuy = true;
if (SellCondition
&&
(MAFilter==false || (MAFilter && Bid<mafilter))
< mafilter))
&&
(MAFilterRev==false || (MAFilter && Bid> mafilter))
OpenSell = true;
</mafilter))
Explanation
In the MT4 usage section above, there are 5 blocks of code. In the first block of code I create a bool for BuyCondition and a bool for SellCondition, and default them both to false. I set them to false initially because I only want them to true when the logic I subscribe to them becomes true. The second and third blocks of code set out to identify the buy and sell conditions based on the moving average crossover. When the fast moving average crosses over slow moving average, then BuyCondition=true; when fast moving average crosses under slow moving average, then SellCondition=true. We have already gone over these conditions in the Basic Expert Advisor: MA cross. The only difference is that I have subsumed these conditions into the bools of BuyCondition and SellCondition instead of the bools of OpenBuy and OpenSell, which I make reference to in the fourth and fifth blocks of code.
It is the fourth and fifth blocks of code that implement the MAFilter. Each one starts with an “if ( )” condition that has three conditions set within the brackets. The first condition, the BuyCondition or SellCondition, subsumes the entry logic of the moving average crossover.
The second condition, the MAFilter condition, is a compound statement within parenthesis separated by a || (“or”) operator. The first part of the statement indicates that if MAFilter is set to false (MAFilter==false), then the MAFilter is not operational. The second part of the statement (after the ||) indicates that if the MAFilter is set to true (notice it does not have to say == true, for the bool by itself means true), then it can proceed to the MAFilter rule. Under the BuyCondition, the MAFilter rule is that Ask must be greater than (>) mafilter. Note: the variable for mafilter (in lower case) is defined in the MT4 snippet placed in the indicator calling section.
The third condition, the MAFilterRev condition, is also a compound statement within parenthesis separated by a || (“or”) operator. The first part of the statement indicates that if MAFilterRev is set to false (MAFilterRev==false), then the MAFilterRev is not operational. The second part of the statement (after the ||) indicates that if the MAFilterRev is set to true, then it can proceed to the MAFilterRev rule. As you can see the MAFilterRev rule is the opposite of the MAFilter rule. If the MAFilter rule indicated that the Ask must be greater than (>) the mafilter, then the MAFilterRev indicates that the Ask must be less than (<) the mafilter.
If all three of the above conditions are met, then the EA can proceed to OpenBuy = True or OpenSell=true, which triggers the buy or sell entry signal in my code.
Conclusion
The above MAFilter is just one of one many possible trend filters one can construct and implement. I have chosen the MAFilter because it is perhaps one of the simplest and most effective for identifying trend direction.
Other good indicators that can act as trend filters are variations of the moving average: JMA, Hull, NonLagMA, and Slope Directional Line. I have used all four indicators as reliable trend filters. One can also experiment with momentum oscillators like RSI and Stochastics. With whatever indicator used, one should experiment with different periods and time frames to see which ones can best filter for the larger trend. Trend is only relevant in conjunction to the time frame, and once you identify the time frame, there is nothing fancy about the concept of trend.
It is not necessary to try to find or construct super fancy, mathematical trend filters. Many traders attempt to over complicate the problem of trend identification. They invent all kinds of fancy mathematical equations and methods of massaging past price action to more precisely determine whether the trend is up or down, and most attempts at such are pointless. The simplest and most popular approaches to trend identification are often the best.
Not every EA can benefit from having a trend filter. Some EAs incorporate trending indicators that work well enough without additional trending filters. Other EAs try to predict trend reversals or counter trend conditions, and therefor enter the trade when the trend is against them at the time.
Bear in mind that all filters prevent trades from occurring and we want the trades prevented to be be mostly losing ones. It is often best to back test one filter at a time and to try not to use too many. Your strategy should be good enough to stand on its own, without the need for a filter. The trending filter applied to a good strategy should be tested out as an optional enhancement. If we discover that the filter is preventing a good number, or even an equal number of winning trades, it is not a good filter to have working for you. It is only acceptable if it can prevent a greater percentage of losing trades under a lengthy 5-10 year back test.