Tutorial: Creating Custom Indicator with Forex Strategy Builder
by Denny Imanuel [email protected]
1. Preparing the Tools
Forex Strategy Builder indicators are developed in C# (CSharp) Language. So the basic C# programming knowledge is necessary if you want to develop a custom indicator on this platform. In this tutorial I assumed that the reader has the basic knowledge of C# programming language. If you need to learn the C# programming language you can find a lot of free resources in internet. In order to develop the indicator firstly you need the C# IDE (Integrated Development Environment) software, such as:
1. Notepad: a basic ASCII editor.
2. Notepad++: free source code editor that support several programming language downloadable from Sourceforge website.
3. Visual C# Express Edition: a free version of Visual Studio downloadable from Microsoft website.
Forex Strategy Builder comes in bundle with the debugger, so all you need is just the ASCII editor and may be syntax checker. And for this tutorial purpose we will use Notepad++. How to use these softwares is beyond this tutorial topic.
Next you need to download the basic original indicator source code from Forexsb website. These original indicators are your template to create your own custom indicator. So all you need to do is to select one of the original indicators that most suitable to your current indicator. You don’t need to write all the code from scratch.
2. Understanding the Original Indicator Code Structures
Let’s open up one of the original indicator source code for an example “Momentum.cs”. You can narrow down the sourcode view by clicking minus sign below the procedure in order to see the overall structures of the code as shown below.
The momentum indicator consists of Momentum main class declaration inside namespace Forex_Strategy_Builder. One indicator must be represented by one class. And inside this Momentum class there are four main procedure:
− Momentum(), this is a constructor procedure which contains class initiation. When you set the indicator’s input parameters on FSB (setting the indicator logic, choosing the smoothing method, setting the period value), this procedure is executed. Your custom indicators parameters input should be located here. This procedure is only called once when the indicator is loading.
− Calculate(), this is the main procedure for the indicator where the indicator algorithm is performed. Your main custom indicator code should be located here. This procedure is called repeatedly on tick by tick basis when the backtesting is simulated on FSB or trading is performed in FST.
− SetDescription(), this is the additional part of the indicator which lest important to take a look currently. It contains the strategy overview and description. This procedure is called when you click the strategy overview on the FSB.
− ToString(), this is also the minor part of the indicator which shows the label name for the indicator which displayed on the top left corner of charts data.
Constructor() Procedure
So let’s focus on the first two procedure and take a look at the breakdown. On the beginning of this procedure the IndicatorName is set to “Momentum” and then the new object IndParam is created.
The IndParam object consists of SlotType parameter which describe which slot the indicator can be applied to. The possible value will be: SlotType.Open, SlotType.Close, SlotType.OpenFilter, SlotType.CloseFilter, as show on the picture below.
The IndParam object consist of ListParam which represent the list box control, NumParam which represent the up down numeric control, CheckParam which represent the checkbox control.
IndParam.IndicatorName IndParam.ListParam[0] IndParam.ListParam[1] IndParam.ListParam[2] IndParam.NumParam[0] IndParam.NumParam[2] IndParam.NumParam[1] IndParam.CheckParam[2] SlotType.Open SlotType.Close SlotType.OpenFilter SlotType.CloseFilter
Calculate() Procedure
Calculate() procedure is the main calculation of the overall indicator. Here you will see four major portion of the this procedure, as shown on the picture below:
1. Initiation Part, in this part, some of the parameters selected on the input controls are transferred to the initial variables, and some of the initial variables are initiated.
2. Calculation Part, this is where the actual indicator calculation is scripted. So, as the programmer you can focus on this part more. Usually the indicator is calculated on an array of bars from the first bar until the last bar. So the loop start from iFirstBar (that you must initiate) and end before the number of bar represented by Bars:
for(int iBar = iFirstBar; iBar<Bars; iBar++) {
adMomentum[iBar] = … ; }
3. Component Creation, in this part, the components are created and the calculation data is stored in these components. These components can either represent the indicator value which will be used as a chart plot data or represent the trading signal which will be used as trading entry or exit signal.
a. Plotting the Graph:
- If the Component.DataType=IndicatorValue then the data stored in Component.Value will be passed to the chart to be plotted. There are a few chart types are available:
Component.ChartType=IndChartType.Line; Component.ChartType=IndChartType.Histogram; Component.ChartType=IndChartType.Level; Component.ChartType=IndChartType.CloudUp; Component.ChartType=IndChartType.CloudDown; b. Setting the Trading Signal:
- Otherwise, the data stored in Component.Value will be used as trading signals, which generates opening or closing position for specific slot type as follows:
Component.DataType=OpenPrice SlotType.Close Component.DataType=ClosePrice SlotType.Open Component.DataType=AllowOpenLong/AllowOpenShort SlotType.OpenFilter Component.DataType=ForceCloseLong/ForceCloseShort SlotType.CloseFilter 1 2 3a
4. Execution of Logic, the last portion of the Calculate() procedure consist of standard logic depending on what type of indicator being executed. If the indicator is oscillator type then use OscillatorLogic() method, and if indicator is band type then use BandIndicatorLogic(), if it is a non directional indicator you can use NoDirectionOscillatorLogic(). May be some combination can be used depending on the usage. Available method are: OscillatorLogic() NoDirectionOscillatorLogic() BandIndicatorLogic() IndicatorRisesLogic() IndicatorFallsLogic() IndicatorIsHigherThanAnotherIndicatorLogic() IndicatorIsLowerThanAnotherIndicatorLogic() IndicatorCrossesAnotherIndicatorUpwardLogic() IndicatorCrossesAnotherIndicatorDownwardLogic() BarOpensAboveIndicatorLogic() BarOpensBelowIndicatorLogic() BarOpensAboveIndicatorAfterOpeningBelowLogic() 3b 4
BarOpensBelowIndicatorAfterOpeningAboveLogic() BarClosesAboveIndicatorLogic()
BarClosesBelowIndicatorLogic()
This logic is the smart brain where your indicator rising up or falling down, crossing up or crossing down, etc. are executed. You don’t need to worry about this logic at the moment because you only need to modify the available indicators, so you don’t need to write your own program from scratch on this part.
3. Modifying the Original Indicator and Create a Custom Indicator
Now, let’s try to make a simple indicator. For an example, you want to make an indicator that count up when the price is increasing and counting down when the price is decreasing. We call it as directional counter indicator. So, you can conceptualize your code in the pseudo code as follow:
- If Current Close > Current Open then Counter = Counter + 1; - If Current Close < Current Open then Counter = Counter – 1;
However the counter value must reset to zero when the price is reverse it’s direction.
- If (Current Close > Current Open) and (Previous Close < Previous Open) then Counter=0; - If (Current Close < Current Open) and (Previous Close > Previous Open) then Counter=0;
And when this code is translated into the C# with loop from first bar to last bar it feels and appears like below:
for (int iFirstBar; iBar<Bars; iBar++) {
if (Close[iBar]>Open[iBar] && Close[iBar-1]<Open[iBar-1]) adCounter[iBar] = 0; if (Close[iBar]<Open[iBar] && Close[iBar-1]>Open[iBar-1]) adCounter[iBar] = 0; if (Close[iBar]>Open[iBar]) adCounter[iBar] += 1;
if (Close[iBar]<Open[iBar]) adCounter[iBar] += 1; }
Don’t worry whether this code is correct or not because you are going to debug it later. Imagine that the resulting array will produce a double side sawtooth wave, and the indicator logic that we can use is oscillator indicator. So, we can use Momentum Indicator as a template for our new indicator. You can use another type of indicator depends on your preference, but make sure that the logic is still using oscillator type.
The first step is to open “Momentum.cs” file and save it into a new filename, let’s say “Directional Counter.cs”. Then change the class name, constructor name, indicator name, and don’t forget to insert CustomIndicator = true;
Then replace all the “Momentum” words inside the code with “DC” which stand for Directional Counter.
Take a look at the Indicator Parameter part of the program, and check whether you need to add some parameters or delete some parameters. In this case we don’t need the” Smoothing Method”, “Base Price”, and ”Period “parameter, so we can delete portion of code related to this parameter on the whole of part of the program. However, we want to retain “Level” and “Use Previous Bar” parameter.
Special note: “Use Previous Bar” is standard parameter that must be available for all the indicators, the reason is that the last bar is always changing from tick to tick, so we can’t use this bar to do the calculation before this bar is fully closed, because it will generate false entry and exit signal. That the reason why we can only use the previous bar.
DELETE
You need to delete or change the initialization part of the indicator the calculation part of the indicator. Then after that, inserting your own indicator calculation and initiation of the variables used in the calculation. And finally, don’t forget to pass on the resulting calculation array, in this case adCounter, to the component to be plotted.
May be you need to check the Indicator Logic part of the Calculate() procedure if some changes needed. On this case, we do not need to change this part. And also check on the SetDescription() part of the program and finally on the ToString() part of the program for some changes might be required. In the ToString() procedure, we need to make a slight change because we already deleted some of the ListParam and NumParam above.
4. Debugging the Code
Now the program is already finish, however we are not sure whether it is correct or not, so we must debug it. Before debugging, we must put the program on the “Custom Indicator” folder of your Forex Strategy Builder installation folder. Now you can run Forex Strategy Builder after the custom indicator located on this folder. Forex Strategy Builder automatically runs and compiles the custom indicator during start-up and display all the error message.
And from the displayed error message you can refer to which line and column part of the program does the error comes from. In our case above the iBar, iFirsBar, and adCounter are not initiated, and the adMomentum is not fully replaced by adCounter. So we need to do the necessary correction and after that you don’t need to re-run the Forex Strategy Builder anymore in order to recompile the program, you can save the code and then press Ctrl+I shortcut in the Forex Strategy Builder to recompile the program.
After debugging it seems that the data is not displayed properly even though there is no error message. So there must be something wrong with the algorithm. We have to check again the source code and find out that the data is not reset-ing as required. Because adCounter[iBar]+=1 is actually the same with adCounter[iBar]=adCounter[iBar]+1, and the adCounter[iBar], is actually empty even after each loop is increased. So now, we change the algorithm of the code by inserting a dCounter variable and it’s initiation as shown below.
Finally, you want the data to be displayed as histogram so you need to change this portion of the code.
Ok, after recompiling (press Ctrl+I on FSB), and add your indicator, you can see on the graph below your indicator is increasing its value by one-step when the price bar is increase (white bar) and decreasing its value by one-step when the price bar is decrease (black bar). And it will reset the value to zero when the price bar is reverse, or turning black to white or turning white to black. So, congratulation! You have made a great job!
So until here is my tutorial. Try your own indicator idea and don’t forget to upload your indicator to our website forum and share with others.
Warmest Regards,
Denny Imanuel