I want to use SSA in Zorro so please teach me how to implement it. My base code is a MQL file which is libSSA.zip SSA normalized end-pointed & alert advanced.mq4
You need to open the SSA function from the DLL, and feed it with the price data that it needs. I've uploaded the DLL file here separately so that other users can reproduce the script whithout the need to register on other forums.
This is the mq4 file where we can see how the DLL function is called:
I presume that you have the author's permission to use his stuff. We'll have to make a Zorro script from the mq4. It will be far shorter because all the MQL4 Indexbuffers, loops and other workarounds are not required in C. We'll do that step by step in the next days.
Yes. For using a function inside a DLL, we define the function prototype and use the API macro:
Code:
void __stdcall fastSingular(double* sourceArray,int arraySize, int lag, int numberOfComputationLoops, double* destinationArray);
API(fastSingular,libSSA)
The libSSA.dll must be copied into the Zorro folder.
Next, we're going to reproduce what the EA does. All the complicated stuff with Indexbuffers, loops, ArrayCopy etc. is only required in MQL4, which does not natively support data series. It's not needed in a C script. The only needed part is the code where the data input to the SSA function is calculated:
Code:
double ma = iMA(NULL,0,SSAPeriodNormalization,0,MODE_SMA,SSAPrice,i);
double dev = iStdDev(NULL,0,SSAPeriodNormalization,0,MODE_SMA,SSAPrice,i)*3.0;
double price = iMA(NULL,0,1,0,MODE_SMA,SSAPrice,i);
no[i] = (price-ma)/(MathMax(dev,0.000001));
no[i] is normalized data, calculated similar to Zorro's Fisher transform function from Workshop 5. The same code in lite-C:
Code:
vars close = series(priceClose());
var ma = SMA(close,SSAPeriodNormalization);
var dev = StdDev(close,SSAPeriodNormalization,1)*3.0;
vars no = series((close[0]-ma)/max(dev,0.000001));
You can now plot the normalized data for checking if it looks correct:
Code:
plot("Normalized",no[0],NEW,RED);
This is the input to the fastSingular function from the SSA DLL. Unfortunately I just found that the function does not work - it crashes when called. So, either the DLL has a bug, or more likely, fastSingular must be called with different parameters than I expected. It's sort of nontrivial to figure out the parameters of a function without having either the source code of the DLL or a proper documentation of it. But I'll experiment a little and think that I can find the correct parameters for getting the function not to crash.
Anyway, this is the basic way when you want to call functions from an external DLL in Zorro.
No, because it's a MA with a 1-bar period, which is identical to the price itself. I have no idea why this line was required in the mq4 file, but programming in MQL4 is often a matter of trial and error. You find many strange things in mq4 EAs.
The reason of the crash was a size requirement for the output array.
Only one element of the fastSingular output array is used and it is unknown what that element really contains, as there is no documentation or source code. So it's up to you what you do with that SSA function. From the original EA above I assume that the output contains the basic trend of the price series. The alerts are triggered by that signal.
Anyway here's the complete code for the SSA implementation:
Code:
#define SSALag 25
#define SSANumberOfComputations 2
#define SSAPeriodNormalization 10
#define SSANumberOfBars 300
void __stdcall fastSingular(double* sourceArray,int arraySize, int lag, int numberOfComputationLoops, double* destinationArray);
API(fastSingular,libSSA)
// helper function to reverse a series
vars reverse(vars Data)
{
vars Reversed = series();
int i;
for(i=0; i<LookBack; i++)
Reversed[i] = Data[LookBack-i-1];
return Reversed;
}
function run()
{
LookBack = SSANumberOfBars;
StartDate = 20121001;
EndDate = 20130101;
vars close = series(priceClose());
var ma = SMA(close,SSAPeriodNormalization);
var dev = StdDev(close,SSAPeriodNormalization,1);
vars no = series((close[0]-ma)/max(dev,0.000001));
var out[SSANumberOfBars];
fastSingular(reverse(no),SSANumberOfBars,SSALag,SSANumberOfComputations,out);
plot("Normalized",no[0],NEW,RED);
plot("SSA",out[0],AXIS2,BLUE);
set(PLOTPRICE+PLOTNOW);
}
The fastSingular function expects the series in reverse order, that's why we need the additional "reverse" function for reversing a series. The blue line in the chart is the SSA output.
The color of lines is the last parameter in the plot call, use something different than "BLUE", and a black line at -0.25 goes like this: plot("Line",-0.25,0,BLACK). Hope I could help.