I plan to take notes from this video and hopefully walk away with a real indicator I can actually use by Monday.
This ribbon indicator I am trying to code following the instruction in Joe’s video is simply a combination of three moving averages.
The moving averages will use the same values found in a MACD. It’s just that instead of displaying them in a separate window centered around a zero line, I am showing them based around the slow moving average line.
I am going to to the meta editor > going to new custom indicator (project?) and naming it "Trend Driven Ribbon" or something similar.
As a matter of habit, Joe does not fill in parameters at this next point. He prefers to get to the code screen and create them. So, this is all I am going to need to get the skeleton of the indicator written.
(I unclicked/unselected the OnChartEvent event handler in the next window, since Joe did not seem to have it selected...)
Again, we will be working in the main chart—not the lower panel. So, I skipped the “Drawing properties of the Custom indicator program” window, and I also one again switched from the mqproj tab to the mq4 tab.
Unlike the image below, the only thing showing in my formatted code (in the standard header block?) was
#property strict (and the "strict" was in red) so I guess I will need to type in or add
#property indicator_chart_window to what I understand to be the “standard header block” so I can have the indicator in the same window as the main chart rather than the secondary window for lower panel indicators.
The second thing I need to do is tell the program how many property buffers I need, which is two—one for the fast moving average and one for the slow moving average. (Property buffers are where Metatrader will store the information that’s going to be displayed on the screen.)
(Why don’t I need a third property buffer for the signal moving average? Perhaps it will have something to do with drawing the histograms at the end.)
And now I need some inputs…
input int SignalMAPeriod = 5;
input int FastMAPeriod = 13;
input int SlowMAPeriod = 34;
The above inputs will allow me to specify how I want the calculations done. In this instance, I am going to set my signal moving average to five periods, my fast moving average to 13 periods, and my slow moving average to 34 periods.
I am using the MA methods
Joe chose an exponential moving average for his calculations, but I use simple moving averages, which I am guessing is abbreviated by SMA:
input ENUM_MA_METHOD MAMethod = MODE_SMA;
These are the default values that I set up for when I’m running the indicator. Of course, I can change these by using the Edit tools once I have dropped the indicator on a chart, but the values I have put in the code are what will appear initially:
Now that I have set these values, I need a place to
store them so that the moving averages can be displayed on screen. I am therefore going to create two arrays.
(Why not three? Perhaps it will have something to do with drawing the histograms at the end.)
double BufferFast[];
double BufferSlow[];
So, these are arrays of double values because the values on a chart are doubles—the fast being my fast moving average array and the slow being my slow moving average array.
That's all I need to define them at this point, though a little later in the code I will need to show Metatrader how to use them.
So now, what is this. Am I assigning buffer values/labels to my indicators here?
#define FastIndicator 0
#define SlowIndicator 1
I guess that later on I am going to be associating these double buffers with those corresponding numbers in the init section. Or actually, I guess I am going to get to that right now.
In the init section, the first thing I am setting is the style.
SetIndexStyle(FastIndicator,DRAW_LINE,STYLE_DOT, 1, clrFireBrick);
What I am saying above is that the fast indicator (number zero) is a line, a dotted line. The numeral one is the width parameter. So, it’s just a narrow dotted line. And finally, I am selecting a color—in this case, firebrick. (I am going to use the same form of a statement here soon for the slow indicator.)
The next thing is the buffer. This is where I am associating the buffer value I am storing for the moving average with the indicator number. So, the fast indicator has the fast buffer:
SetIndexBuffer(FastIndicator,BufferFast);
And the label is simply a name that gets applied if I were to hover over the line on screen. I would see this name attached, and it’s useful if I wish to identify the values that are actually showing on screen.
SetIndexLabel(FastIndicator,"Fast");
Note that I've done exactly the same thing for both the fast and the slow indicator…
As you can see, Joe likes to group everything for a particular indicator/buffer in one block. Some people would set off the index styles first, then set off the index buffers, etc. But, Joe just finds this arrangement a little easier to follow, and I agree.
Now, next thing I need to do is to actually create the code.
Now, on calculate will run when something changes on the chart, which means that I need to get a calculation. And typically, that’s going to mean a market event, or in other words, a new trade (i.e., a price change).
There’s not really much point in doing the calculations any other time, though there are other options available in Metatrader based on timers. They would be for very specific purposes however, because typically, calculating this in between market events isn’t going to yield any different results.
So, in this case, I can just stay with the on calculate.
Now there are a number of things that I need to do. First, I’m going to set up the variable that I will use in here…
int limit;
double signalMa,
fastMa,
slowMa;
Now, Joe already knew these variable because he'd written them earlier.
(What Joe will normally do when he is writing code is he will just begin writing the code, and then come back and fill things in as he goes if he realizes there was something he missed.)
Now, I need to put in a little check here…
if(rates_total<=SlowMAPeriod)
return(0);
Rates total, which is being passed in here, shows me how many bars are available for performing calculation.
I know that I’ve set my slow moving average period above as part of the inputs.
If I don’t have at least as many rates as the slow moving average period, I can’t perform the calculation. So, I am just going to leave it at this point and wait until later when this gets called again and I might have enough rates to calculate.
(What?)
Next, I want to determine how many bars I will actually perform my calculation on. So, I limit my variable to what I said earlier is the number of rates that I have available minus the number that I’ve already calculated.
(What?)
So, the first line instructs Metatrader to keep track of what’s been done previously and won’t be forced to recalculate everything on the chart unless some event happens such that it becomes necessary to recalculate. So typically, this will cut down on the work that the computer is doing as each tick goes by.
The second and third lines are simply where, if there is already something that has been calculated, I am just making sure that Metatrader recalculates the last bars that may have changed as a result of price movement. (i.e., increasing the limit if the program has already done some calculations).
Now I’ll get into the calculation here…
I will have to run this in a loop. I believe that is what the first line up above does. Sometimes you will see this loop written in the opposite way, rather than as it is shown here (see below).
for (int i=0;i<limit; i++)
Joe will typically go from the limit minus one up to zero. The bars in Metatrader are counted such that the current bar is zero and the bar number increases as the bars get older. So, I am calculating here from left to right. Sometimes it makes sense to calculate from right to left, and some people simply prefer to do this form. But, Joe finds that by calculating from left to right, it avoids the possibility that the coder accidentally looks into the future when writing the code.