Use MetaTrader with Python 3 on financial stock exchanges, Forex, CFD and Futures. From MetaTrader, you can get quotes in Python, but no complete connection between them. This post is one of the developers (RU).
This wrapper was created with changes in Python 3.7 Download ZIP from GitHub.
Python is now the standard for machine learning libraries (TensorFlow, PyTorch, etc.). Python itself is quite slow and therefore all machine learning library on C/C++ using it only for user interaction. It is not always possible to connect machine learning libraries directly to the C/C++ code without problems.
The main idea and the difference of this wrapper: a data exchange between the MQL and Python via pre-created function. This is the fastest and most reliable data exchange method. There is no time spent on parsing and compiling Python code that appears when using eval().
There is a class (the actual code here):
class MQL(): def getLong(self, magic: int, value: int, array: tuple) -> tuple or list: raise NotImplementedError def getULong(self, magic: int, value: int, array: tuple) -> tuple or list: raise NotImplementedError def getDouble(self, magic: int, value: float, array: tuple) -> tuple or list: raise NotImplementedError def getString(self, magic: int, value: str, array: bytes) -> str: raise NotImplementedError __mql__ = MQL()
The class name does not matter, because the reflection of the functions is via the variable
pyEval(..., override_class) function has the argument
override_class=true when the variable
You can define the Python code execution environment:
if globals().get('__PythonDLL__'): print('run in MetaTrader') elif __name__ == '__main__': print('run as script')
When testing is required “Allow DLL imports” at the global level.
The search for the necessary python3.dll occurs in the following order:
If python3.dll is not found:
Cannot load 'Roffild\PythonDLL\x64\Release\PythonDLL.dll'  Cannot call 'pyInitialize', 'Roffild\PythonDLL\x64\Release\PythonDLL.dll' is not loaded unresolved import function call
Python is not only python3.dll, but also its environment that needs to be configured. The most popular and simple solution is to install Anaconda. There is also Miniconda (minimum 200MB), if you clearly know which packages will be needed when running the script.
Python was created as a separate application, and with embeddability there are problems that are unlikely to ever be fixed:
With the active console, you can notice the output of Py_FatalError() until it disappears:
Fatal Python error: Py_Initialize: unable to load the file system codec
Compile errors and Python code execution errors are not automatically displayed on the active console. But when using the class CPythonDLL, errors are displayed in the terminal log.
There is always only one instance of Python to execute code. If several experts, indicators and scripts simultaneously use this Python wrapper without synchronization in one MetaTrader, then the result is not guaranteed. There is no such problem when testing.
Memory allocation is a long operation, but it doesn’t depend on the amount of memory requested. It will be faster to pre-allocate one megabyte per line and use this buffer several times rather than requesting the required amount of memory each time.
The wrapper was created with sub-interpreters, but I had to use a simple GIL.
Sub-interpreters are not compatible with the popular libraries for Python.
But you can build this wrapper with
When you run in the terminal several independent experts, indicators and scripts that use this wrapper for each thread gets its own isolated interpreter using Py_NewInterpreter(). But there may be a delay in switching the thread, because Python does not have full multi-threaded execution, but a global interpreter lock (GIL) that blocks other threads when executing Python code.
When testing, there is always only one interpreter.
Addition to the article:
The int type in Python is infinite:
int("9999999999999999999999999999999999999999999999", 10).bit_length() == 153
Types in MQL:
long = 8 bytes (64 bits) = -9 223 372 036 854 775 808 ... 9 223 372 036 854 775 807 ulong = 8 bytes (64 bits) = 0 ... 18 446 744 073 709 551 615