Compatible with C/C++/MQL ~

WEB Trader Get it on Google Play
  • Post by Fintechee
  • Jan 17, 2020
Fintechee developed a Nodejs package to help traders compile C/C++/MQL-based expert advisors or custom indicators

You can use our plugins(extensions) to make your existing EA based on MQL run on our WEB Trader. Most importantly, it can run on a WEB browser. Let me guide you on how to do step by step.

We open these plugins’ source codes in Github. Please check our repository in Github to get the latest head files for the compilation.


How to Compile the Existing MQL-based Programs


How to Re-define the Data Structure


How to Solve the Issues that You May Encounter


Custom Indicators

1. Re-define Data Structure

To make custom indicators based on MQL run on our WEB Trader, we need to compile the old source codes to WebAssembly. Because Fintechee has a different architecture from MQL, we need to re-define parameters, data input, and data output.

We made a tool to help you generate the corresponding data structure and the configuration that will be used in the next steps.

Let’s make an example by using ATR indicator.

Name and Description(the 1st line: name, the 2nd line: desciption, the 3rd line: URL):
Parameters(name, type, required, default value, minimum value, maximum value):

“type” should be Integer or Number or String or Boolean.

Data Input(name, index):
Data Output(name, visible, render type, color):

“render type” should be Histogram or Line or Round or Dasharray

Source Codes:
Definition(JSON format):

2. Compile the MQL Source Codes

Then we concatenate the generated source codes with our old MQL source codes’ main part. OnInit function is not needed for the compilation and the declarements of external input variables in MQL are generated in the 1st step for re-defining the data structure, so we remove them from the old MQL file. Just keep the OnCalculation remain.

Before we compile the source codes, we need to change the suffix from mq4 to cpp. Because we don’t use MQL’s compiler, instead, we use C++'s compiler – Emscripten.

Emscripten is a toolchain for compiling to asm.js and WebAssembly, built using LLVM, that lets you run C and C++ on the web at near-native speed.

Please download and install it in advance. You can refer to Emscripten’s official site to know the details.

Now we use the command line to execute the compilation:

emcc atr.cpp -o atr.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap", "getValue", "setValue", "addFunction", "UTF8ToString", "lengthBytesUTF8", "stringToUTF8"]' -s RESERVED_FUNCTION_POINTERS=100 -s MODULARIZE=1 -s 'EXPORT_NAME="IndiPlugIn"' -s ENVIRONMENT=web -s ALLOW_MEMORY_GROWTH=1

“atr.cpp” is the source code, “atr.js” is the output WebAssembly.

If you failed to execute the compilation, the most possibility would be that the PATH was not set correctly.

Please check this issue post that discussed the solution to solve the problem: emcc command not found.

3. Run the WebAssembly

If the compilation is successfully done, then we can try to run it on the browser.

Because we can’t load it by opening a local file straightforward, we need to load it via an HTTP server CORS-enabled.

There are a ton of solutions to load the compiled WebAssembly, we recommend you try a static page HTTP server due to the high performance and simplicity.

Nodejs’s “http-server” package is a good solution. You can install it via Nodejs CLI and run it by the command below.

http-server -p 8082 --cors=Authorization

After boosting the HTTP server(we assume that the “atr.js” is stored in the server’s root directory, and the port is 8082), we open our WEB Trader and run the plugin for MQL-based indicators.

We copy-paste the definition(JSON format) that we generated in the 2nd step into the form field of the prompted dialog.

An indicator wrapper will be generated to assist the loading of the compiled WebAssembly.

Then we add it to the chart just like what we usually do.


Expert Advisors

1. Re-define Data Structure

To make expert advisors(EAs) based on MQL run on our WEB Trader, we need to compile the old source codes to WebAssembly. Because Fintechee has a different architecture from MQL, we need to re-define parameters.

We made a tool to help you generate the corresponding data structure and the configuration that will be used in the next steps.

Let’s make an example by using a trading strategy based on MACD.

Name and Description(the 1st line: name, the 2nd line: desciption, the 3rd line: URL):
Parameters(name, type, required, default value, minimum value, maximum value):

“type” should be Integer or Number or String or Boolean.

Source Codes:
Definition(Json format):

2. Compile the MQL Source Codes

Then we concatenate the generated source codes with our old MQL source codes’ main part. The declarements of external input variables in MQL are generated in the 1st step for re-defining the data structure, so we remove them from the old MQL file. Just keep the OnTick remain.

Before we compile the source codes, we need to change the suffix from mq4 to cpp. Because we don’t use MQL’s compiler, instead, we use C++'s compiler – Emscripten.

Emscripten is a toolchain for compiling to asm.js and WebAssembly, built using LLVM, that lets you run C and C++ on the web at near-native speed.

Please download and install it in advance. You can refer to Emscripten’s official site to know the details.

Now we use the command line to execute the compilation:

emcc ea_basedon_macd.cpp -o ea_basedon_macd.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap", "getValue", "setValue", "addFunction", "UTF8ToString", "lengthBytesUTF8", "stringToUTF8"]' -s RESERVED_FUNCTION_POINTERS=100 -s MODULARIZE=1 -s 'EXPORT_NAME="EAPlugIn"' -s ENVIRONMENT=web -s ASYNCIFY -s 'ASYNCIFY_IMPORTS=["jOrderSend", "jOrderModify", "jOrderClose", "jOrderDelete"]' -O3

“ea_basedon_macd.cpp” is the source code, “ea_basedon_macd.js” is the output WebAssembly.

3. Run the WebAssembly

If the compilation is successfully done, then we can try to run it on the browser.

Because we can’t load it by opening a local file straightforward, we need to load it via an HTTP server CORS-enabled.

There are a ton of solutions to load the compiled WebAssembly, we recommend you try a static page HTTP server due to the high performance and simplicity.

Nodejs’s “http-server” package is a good solution. You can install it via Nodejs CLI and run it by the command below.

http-server -p 8082 --cors=Authorization

After boosting the HTTP server(we assume that the “ea_basedon_macd.js” is stored in the server’s root directory, and the port is 8082), we open our WEB Trader and run the plugin for MQL-based EAs.

We copy-paste the definition(JSON format) that we generated in the 2nd step into the form field of the prompted dialog.

An EA wrapper will be generated to assist the loading of the compiled WebAssembly.

Then we can find it in the EAs panel and run it just like what we usually do.


Troubleshooting

Because MQL is not 100% the same with C++, so we may encounter errors when we compile our existing MQL4-based programs.

We made several examples here to show you some solutions to solve the issues.

1. ArrayResize

double a[10][8];
ArrayResize(a, 12);

In our C++ source codes, we don’t support a two-dimensional array. So we need to recode the source codes as below when we need to allocate space for an array. In this example, 12 stands for the row number, 8 stands for the column number.

double **a;
ArrayResize(a, 12 * 8);

2. ArrayInitialize

double *a;
ArrayInitialize(a, 0.0);

In our C++ source codes, we must pass the size that we allocate explicitly to ArrayInitialize. So we need to recode the source codes as below.

double **a;
ArrayInitialize(*a, 0.0, size);

3. int Start()

int Start()

In our source codes, the event triggered function is not Start function, we need to use OnTick instead. And, because “OnTick” has no return value, we need to remove the return values in each corresponding line.

void OnTick()
return (0);

And, because “OnTick” has no return value, we need to remove the return values in each corresponding line.

return;

4. Point, Digits

The two global variables are already supported by the current version.

5. RefreshRates

We can get refreshed rates always, so we don’t need RefreshRates. So please keep it the way it was.

6. Time, Open, High, Low, Close, Volume

datetime t = Time[0];
double o = Open[0];
double h = High[0];
double l = Low[0];
double c = Close[0];
double v = Volume[0];

In our trading platform, there are no time-series arrays. So you can’t use the Time, Open, High, Low, Close, Volume as we code in the MQL4-based source codes. Instead, we can use the time-series related functions as below.

datetime t = iTime(NULL,0,0);
double o = iOpen(NULL,0,0);
double h = iHigh(NULL,0,0);
double l = iLow(NULL,0,0);
double c = iClose(NULL,0,0);
double v = iVolume(NULL,0,0);
Please note:

All the arrays in Fintechee are indexed from the left to the right. That means you can get the oldest element by referring to the zero-indexed element and get the latest element by referring to the (length-1) indexed element.

All the time-series related functions(including iTime, iOpen, …, and the technical indicator functions) are indexed from the right to the left. That means you can get the latest element by referring to the zero-indexed element and get the oldest element by referring to the (length-1) indexed element.

7. Blocked Mixed Content

If you can’t load the compiled Javascript or WebAssembly file from your local HTTP server, please check the definition JSON string and replace “localhost” with “127.0.0.1” and then try again.