Skip to main content

A drop in replacement wrapper for the MetaTrader5 package

Project description

Introduction

pymt5adapter is a drop-in replacement (wrapper) for the MetaTrader5 python package by MetaQuotes. The API functions simply pass through values from the MetaTrader5 functions, but adds the following functionality in addition to a more pythonic interface:

  • Typing hinting has been added to all functions and return objects for linting and IDE integration. Now intellisense will work no matter how nested objects are. alt text

  • Docstrings have been added to each function (see official MQL documentation). Docs can now be accessed on the fly in the IDE. For example: Ctrl+Q in pycharm. alt text

  • All params can now be called by keyword. No more positional only args.

  • Testing included compliments of pytest

  • A new context manager has been added to provide a more pythonic interface to the setup and tear-down of the terminal connection. The use of this context-manager can do the following:

    • Ensures that mt5.shutdown() is always called, even if the user code throws an uncaught exception.
    • Modifies the global behavior of the API:
      • Ensure the terminal has enabled auto-trading.
      • Prevents running on real account by default
      • Accepts a logger and automatically logs function API calls and order activity.
      • Can raise the custom MT5Error exception whenever last_error()[0] != RES_S_OK (off by default)

Installation

pip install -U pymt5adapter

The MetaTrader5 dependency sometimes has issues installing with the pip version that automatically gets packaged inside of the virualenv environment. If cannot install MetaTrader5 then you need to update pip inside of the virtualenv. From the command line within the virual environment use:

(inside virtualenv):easy_install -U pip

Import

This should work with any existing MetaTrader5 script by simply changing the import statement from:

import MetaTrader5 as mt5 

to:

import pymt5adapter as mt5 

Context Manager

The connected function returns a context manager which performs all API setup and tear-down and ensures that mt5.shutdown() is always called.

Hello world

Using the context manager can be easy as...

import pymt5adapter as mt5

with mt5.connected():
    print(mt5.version())

and can be customized to modify the entire API

import pymt5adapter as mt5
import logging

logger = mt5.get_logger(path_to_logfile='my_mt5_log.log', loglevel=logging.DEBUG, time_utc=True)

mt5_connected = mt5.connected(
    path=r'C:\Users\user\Desktop\MT5\terminal64.exe',
    portable=True,
    server='MetaQuotes-Demo',
    login=1234567,
    password='password1',
    timeout=5000,
    logger=logger, # default is None
    ensure_trade_enabled=True,  # default is False
    enable_real_trading=False,  # default is False
    raise_on_errors=True,  # default is False
    return_as_dict=False, # default is False
    return_as_native_python_objects=False, # default is False
)
with mt5_connected as conn:
    try:
        num_orders = mt5.history_orders_total("invalid", "arguments")
    except mt5.MT5Error as e:
        print("We modified the API to throw exceptions for all functions.")
        print(f"Error = {e}")
    # change error handling behavior at runtime
    conn.raise_on_errors = False
    try:
        num_orders = mt5.history_orders_total("invalid", "arguments")
    except mt5.MT5Error:
        pass
    else:
        print('We modified the API to silence Exceptions at runtime')

Output:

MT5 connection has been initialized.
[history_orders_total(invalid, arguments)][(-2, 'Invalid arguments')][None]
We modified the API to throw exceptions for all functions.
Error = (<ERROR_CODE.INVALID_PARAMS: -2>, "Invalid arguments('invalid', 'arguments'){}")
[history_orders_total(invalid, arguments)][(-2, 'Invalid arguments')][None]
We modified the API to silence Exceptions at runtime
[shutdown()][(1, 'Success')][True]
MT5 connection has been shutdown.

Exception handling

The MetaTrader5 package does not raise exceptions and all errors fail silently by default. This behavior forces the developer to check each object for None or empty state and then call last_error() to resolve any possible errors. One of the primary features of the context manager is extend the ability to toggle exceptions on/off globally. All raised exceptions are of type MT5Error. The MT5Error exception has two properties which are error_code and description.

with mt5.connected(raise_on_errors=True) as conn:
    try:
        invalid_args = mt5.history_deals_get('sdf', 'asdfa')
        print(invalid_args)
    except mt5.MT5Error as e:
        print(e.error_code, e.description)
        if e.error_code is mt5.ERROR_CODE.INVALID_PARAMS:
            print('You can use "is" to check identity since we use enums')
    conn.raise_on_errors = False
    print('Errors will not raise exceptions and default behavior has bene restored at runtime')
    invalid_args = mt5.history_deals_get('sdf', 'asdfa')
    if not invalid_args:
        print(mt5.last_error())

OUTPUT

ERROR_CODE.INVALID_PARAMS Invalid arguments('sdf', 'asdfa'){}
You can use "is" to check identity since we use enums
Errors will not raise exceptions and default behavior has bene restored at runtime
(-2, 'Invalid arguments')

Logging

Logging functionality has been added to the API and can be utilized by passing any logger that implements the logging.Logger interface to the logger param in connected context manager. Messages generated from the API functions are always tab deliminated and include two parts:

  1. A short human readable message.
  2. A JSON dump for easy log parsing and debugging.
2020-07-22 18:54:10,399	INFO	Terminal Initialize Success	{"type": "terminal_connection_state", "state": true}

For convenience, a preconfigured logger can be retrieved by calling get_logger

logger = mt5.get_logger(path_to_logfile='my_mt5_log.log', loglevel=logging.DEBUG, time_utc=True)

with mt5.connected(logger=logger):
    main()

Note: The API will only automatically log if a logger is passed into the context manager. The intent was to provide convenience but not force an opinionated logging schema.

Additional features not included in the MetaTrader5 package

Filter function callbacks

The following API functions can now except an optional callback for filtering using the named parameter, function:

  • symbols_get
  • orders_get
  • positions_get
  • history_deals_get
  • history_orders_get

Example:

visible_symbols = mt5.symbols_get(function=lambda s: s.visible)

def out_deal(deal: mt5.TradeDeal):
    return deal.entry == mt5.DEAL_ENTRY_OUT

out_deals = mt5.history_deals_get(function=out_deal)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymt5adapter-0.4.4.tar.gz (31.6 kB view details)

Uploaded Source

Built Distribution

pymt5adapter-0.4.4-py3-none-any.whl (32.1 kB view details)

Uploaded Python 3

File details

Details for the file pymt5adapter-0.4.4.tar.gz.

File metadata

  • Download URL: pymt5adapter-0.4.4.tar.gz
  • Upload date:
  • Size: 31.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.4

File hashes

Hashes for pymt5adapter-0.4.4.tar.gz
Algorithm Hash digest
SHA256 ab3c20e892d160fca243c7b5868339fde9eb0898910c68a90143048f91b52b60
MD5 64ca3d5f5ca13305fc7e0a84d8730319
BLAKE2b-256 57687cfa973c271918c300c9ae044cb4650e3c4c17aa6825fc9d17fa8634c02a

See more details on using hashes here.

File details

Details for the file pymt5adapter-0.4.4-py3-none-any.whl.

File metadata

  • Download URL: pymt5adapter-0.4.4-py3-none-any.whl
  • Upload date:
  • Size: 32.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.4

File hashes

Hashes for pymt5adapter-0.4.4-py3-none-any.whl
Algorithm Hash digest
SHA256 5ee39cdadc60d1b986229105724952eb7f950b710a4be3d4b13b9e0d6bbf8cb4
MD5 382fb9cd5df3cb7823b0b81f16ae95f8
BLAKE2b-256 c1ca59212919454c5084571f5269798da946380f2b9c0983019acf20a76eca04

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page