From 08e534f6880926d80565d1889c2f2c5f90b2451d Mon Sep 17 00:00:00 2001 From: mraniki <8766259+mraniki@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:24:32 +0100 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=A5=9A=20addind=20back=20metatrader?= =?UTF-8?q?=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cefi/handler/metatrader.py | 264 ++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/cefi/handler/metatrader.py b/cefi/handler/metatrader.py index ff1eef9..a318723 100644 --- a/cefi/handler/metatrader.py +++ b/cefi/handler/metatrader.py @@ -1,161 +1,161 @@ -# """ +""" -# Metatrader 5 client +Metatrader 5 client -# """ +""" -# from loguru import logger -# from mt5linux import MetaTrader5 as mt5 +from loguru import logger +from mt5linux import MetaTrader5 as mt5 -# from ._client import CexClient +from ._client import CexClient -# class MetatraderHandler(CexClient): -# """ -# library: https://github.com/lucas-campagna/mt5linux -# leveraging metatrader python integration: -# https://www.mql5.com/en/docs/integration/python_metatrader5/ +class MetatraderHandler(CexClient): + """ + library: https://github.com/lucas-campagna/mt5linux + leveraging metatrader python integration: + https://www.mql5.com/en/docs/integration/python_metatrader5/ -# You can use MT5 via the docker image -# gmag11/metatrader5_vnc which include the python integration -# if your metatrader container is named metatrader5 -# and the python port is 8001 it will connect + You can use MT5 via the docker image + gmag11/metatrader5_vnc which include the python integration + if your metatrader container is named metatrader5 + and the python port is 8001 it will connect -# Args: -# None + Args: + None -# Returns: -# None + Returns: + None -# """ + """ -# def __init__( -# self, -# **kwargs, -# ): -# """ -# Initialize the client + def __init__( + self, + **kwargs, + ): + """ + Initialize the client -# """ -# super().__init__(**kwargs) -# self.client = mt5(host=self.host or "metatrader5", port=self.port or 8001) -# if not self.client.initialize(): -# logger.error("initialize() failed") -# mt5.shutdown() -# logger.info( -# "MT5 initialized\n{}\n{}", -# self.client.terminal_info(), -# self.client.version(), -# ) + """ + super().__init__(**kwargs) + self.client = mt5(host=self.host or "metatrader5", port=self.port or 8001) + if not self.client.initialize(): + logger.error("initialize() failed") + mt5.shutdown() + logger.info( + "MT5 initialized\n{}\n{}", + self.client.terminal_info(), + self.client.version(), + ) -# async def get_account_info(self): -# """ -# Returns: -# str -# """ -# self.accounts_data = self.client.get_account_info() -# return self.accounts_data + async def get_account_info(self): + """ + Returns: + str + """ + self.accounts_data = self.client.get_account_info() + return self.accounts_data -# async def shutdown(self): -# self.client.shutdown() + async def shutdown(self): + self.client.shutdown() -# async def get_account_balance(self): -# """ -# return account balance + async def get_account_balance(self): + """ + return account balance -# Args: -# None + Args: + None -# Returns: -# balance + Returns: + balance -# """ -# if account_info := self.get_account_info(): -# return account_info.balance + """ + if account_info := self.get_account_info(): + return account_info.balance -# async def get_trading_asset_balance(self): -# """ """ -# return self.get_account_balance() + async def get_trading_asset_balance(self): + """ """ + return self.get_account_balance() -# async def get_account_free_margin(self): -# """ -# return account balance + async def get_account_free_margin(self): + """ + return account balance -# Args: -# None + Args: + None -# Returns: -# balance + Returns: + balance -# """ -# if account_info := self.get_account_info(): -# return account_info.margin_free + """ + if account_info := self.get_account_info(): + return account_info.margin_free -# async def get_account_position(self): -# """ -# Return account position. -# of a given exchange + async def get_account_position(self): + """ + Return account position. + of a given exchange -# Args: -# None + Args: + None -# Returns: -# position - -# """ -# if account_info := self.get_account_info(): -# currency = account_info.currency -# if positions := self.client.positions(): -# return [f"{p.symbol} {p.profit} {currency}" for p in positions if p] -# else: -# return [] - -# async def get_quote(self, instrument): -# """ -# Return a quote for a instrument - - -# Args: -# cex -# instrument - -# Returns: -# quote -# """ -# if not instrument: -# raise ValueError("instrument cannot be empty") -# if quote := self.client.symbol_info_tick(instrument): -# return quote.bid -# else: -# raise ValueError("quote is empty") - -# async def execute_order(self, order_params): -# """ -# Execute order - -# Args: -# order_params (dict): -# action(str) -# instrument(str) -# quantity(int) - -# Returns: -# trade_confirmation(dict) - -# """ -# pass - -# async def calculate_pnl(self, from_date, to_date): -# """ -# Calculate the PnL for a given period. - -# Parameters: -# period (str): The period for which -# to calculate PnL ('W', 'M', 'Y', or None). + Returns: + position + + """ + if account_info := self.get_account_info(): + currency = account_info.currency + if positions := self.client.positions(): + return [f"{p.symbol} {p.profit} {currency}" for p in positions if p] + else: + return [] + + async def get_quote(self, instrument): + """ + Return a quote for a instrument + + + Args: + cex + instrument + + Returns: + quote + """ + if not instrument: + raise ValueError("instrument cannot be empty") + if quote := self.client.symbol_info_tick(instrument): + return quote.bid + else: + raise ValueError("quote is empty") + + async def execute_order(self, order_params): + """ + Execute order + + Args: + order_params (dict): + action(str) + instrument(str) + quantity(int) + + Returns: + trade_confirmation(dict) + + """ + pass + + async def calculate_pnl(self, from_date, to_date): + """ + Calculate the PnL for a given period. + + Parameters: + period (str): The period for which + to calculate PnL ('W', 'M', 'Y', or None). -# Returns: -# pnl: The calculated PnL value. -# """ + Returns: + pnl: The calculated PnL value. + """ -# return self.client.history_orders_get(from_date, to_date) + return self.client.history_orders_get(from_date, to_date) diff --git a/pyproject.toml b/pyproject.toml index fd00050..c1fa2a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ capitalcom-python = "0.2.3" degiro-connector = "3.0.23" easyoanda = {version ="1.0.19", python = ">=3.11,<4.0"} ib_insync = "0.9.86" -# mt5linux = "0.1.9" +mt5linux = "0.1.9" # pyetrade = {version ="2.1.0"} From 18144c03b037345f357cec48945d305bcee1c181 Mon Sep 17 00:00:00 2001 From: mraniki <8766259+mraniki@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:28:10 +0100 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=9A=91=20missing=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cefi/handler/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cefi/handler/__init__.py b/cefi/handler/__init__.py index 3832198..671289c 100644 --- a/cefi/handler/__init__.py +++ b/cefi/handler/__init__.py @@ -1,14 +1,15 @@ from .capitalcom import CapitalHandler from .ccxt import CcxtHandler from .degiro import DegiroHandler - -# from .ibkr import IbHandler +from .ibkr import IbHandler +from .metatrader import MetatraderHandler from .oanda import OandaHandler __all__ = [ "CapitalHandler", "CcxtHandler", "DegiroHandler", - # "IbHandler", + "IbHandler", + "MetatraderHandler", "OandaHandler", ] From 60c92cc4df3b373a843c70b245c9292cc7a75953 Mon Sep 17 00:00:00 2001 From: mraniki <8766259+mraniki@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:32:54 +0100 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=9A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cefi/handler/_client.py | 1 + cefi/handler/metatrader.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cefi/handler/_client.py b/cefi/handler/_client.py index 2f21d41..7f5c0fd 100644 --- a/cefi/handler/_client.py +++ b/cefi/handler/_client.py @@ -147,6 +147,7 @@ async def calculate_pnl(self, from_date=None, to_date=None): Parameters: from_date: The start date for which to calculate PnL. + to_date: The end date for which to calculate PnL. Returns: pnl: The calculated PnL value. diff --git a/cefi/handler/metatrader.py b/cefi/handler/metatrader.py index a318723..6acb8ca 100644 --- a/cefi/handler/metatrader.py +++ b/cefi/handler/metatrader.py @@ -144,15 +144,15 @@ async def execute_order(self, order_params): trade_confirmation(dict) """ - pass + # TODO: implement async def calculate_pnl(self, from_date, to_date): """ - Calculate the PnL for a given period. + Calculate the PnL for a given start date. Parameters: - period (str): The period for which - to calculate PnL ('W', 'M', 'Y', or None). + from_date: The start date for which to calculate PnL. + to_date: The end date for which to calculate PnL. Returns: pnl: The calculated PnL value. From 3a669a9635bc17158f2a8510c8724b47c6efad02 Mon Sep 17 00:00:00 2001 From: mraniki <8766259+mraniki@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:38:09 +0100 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=94=A5=20black?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c1fa2a5..20b7263 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,6 @@ mt5linux = "0.1.9" [ tool.poetry.group.dev.dependencies] python-semantic-release = ">=8.0.8" ruff = "^0.6.0" -black = "24.10.0" pre-commit = "^3.3.1" [tool.ruff] From 404e462ad3ab5a8f33005f59f39dbfe2fb2d43a8 Mon Sep 17 00:00:00 2001 From: mraniki <8766259+mraniki@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:45:16 +0100 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=94=A5=20=E2=AC=86=EF=B8=8F=20mt5linu?= =?UTF-8?q?x=20dep=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cefi/handler/metatrader.py | 264 ++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/cefi/handler/metatrader.py b/cefi/handler/metatrader.py index 6acb8ca..5f88d9d 100644 --- a/cefi/handler/metatrader.py +++ b/cefi/handler/metatrader.py @@ -1,161 +1,161 @@ -""" +# """ -Metatrader 5 client +# Metatrader 5 client -""" +# """ -from loguru import logger -from mt5linux import MetaTrader5 as mt5 +# from loguru import logger +# from mt5linux import MetaTrader5 as mt5 -from ._client import CexClient +# from ._client import CexClient -class MetatraderHandler(CexClient): - """ - library: https://github.com/lucas-campagna/mt5linux - leveraging metatrader python integration: - https://www.mql5.com/en/docs/integration/python_metatrader5/ +# class MetatraderHandler(CexClient): +# """ +# library: https://github.com/lucas-campagna/mt5linux +# leveraging metatrader python integration: +# https://www.mql5.com/en/docs/integration/python_metatrader5/ - You can use MT5 via the docker image - gmag11/metatrader5_vnc which include the python integration - if your metatrader container is named metatrader5 - and the python port is 8001 it will connect +# You can use MT5 via the docker image +# gmag11/metatrader5_vnc which include the python integration +# if your metatrader container is named metatrader5 +# and the python port is 8001 it will connect - Args: - None +# Args: +# None - Returns: - None +# Returns: +# None - """ +# """ - def __init__( - self, - **kwargs, - ): - """ - Initialize the client +# def __init__( +# self, +# **kwargs, +# ): +# """ +# Initialize the client - """ - super().__init__(**kwargs) - self.client = mt5(host=self.host or "metatrader5", port=self.port or 8001) - if not self.client.initialize(): - logger.error("initialize() failed") - mt5.shutdown() - logger.info( - "MT5 initialized\n{}\n{}", - self.client.terminal_info(), - self.client.version(), - ) +# """ +# super().__init__(**kwargs) +# self.client = mt5(host=self.host or "metatrader5", port=self.port or 8001) +# if not self.client.initialize(): +# logger.error("initialize() failed") +# mt5.shutdown() +# logger.info( +# "MT5 initialized\n{}\n{}", +# self.client.terminal_info(), +# self.client.version(), +# ) - async def get_account_info(self): - """ - Returns: - str - """ - self.accounts_data = self.client.get_account_info() - return self.accounts_data +# async def get_account_info(self): +# """ +# Returns: +# str +# """ +# self.accounts_data = self.client.get_account_info() +# return self.accounts_data - async def shutdown(self): - self.client.shutdown() +# async def shutdown(self): +# self.client.shutdown() - async def get_account_balance(self): - """ - return account balance +# async def get_account_balance(self): +# """ +# return account balance - Args: - None +# Args: +# None - Returns: - balance +# Returns: +# balance - """ - if account_info := self.get_account_info(): - return account_info.balance +# """ +# if account_info := self.get_account_info(): +# return account_info.balance - async def get_trading_asset_balance(self): - """ """ - return self.get_account_balance() +# async def get_trading_asset_balance(self): +# """ """ +# return self.get_account_balance() - async def get_account_free_margin(self): - """ - return account balance +# async def get_account_free_margin(self): +# """ +# return account balance - Args: - None +# Args: +# None - Returns: - balance +# Returns: +# balance - """ - if account_info := self.get_account_info(): - return account_info.margin_free +# """ +# if account_info := self.get_account_info(): +# return account_info.margin_free - async def get_account_position(self): - """ - Return account position. - of a given exchange +# async def get_account_position(self): +# """ +# Return account position. +# of a given exchange - Args: - None +# Args: +# None - Returns: - position - - """ - if account_info := self.get_account_info(): - currency = account_info.currency - if positions := self.client.positions(): - return [f"{p.symbol} {p.profit} {currency}" for p in positions if p] - else: - return [] - - async def get_quote(self, instrument): - """ - Return a quote for a instrument - - - Args: - cex - instrument - - Returns: - quote - """ - if not instrument: - raise ValueError("instrument cannot be empty") - if quote := self.client.symbol_info_tick(instrument): - return quote.bid - else: - raise ValueError("quote is empty") - - async def execute_order(self, order_params): - """ - Execute order - - Args: - order_params (dict): - action(str) - instrument(str) - quantity(int) - - Returns: - trade_confirmation(dict) - - """ - # TODO: implement - - async def calculate_pnl(self, from_date, to_date): - """ - Calculate the PnL for a given start date. - - Parameters: - from_date: The start date for which to calculate PnL. - to_date: The end date for which to calculate PnL. +# Returns: +# position + +# """ +# if account_info := self.get_account_info(): +# currency = account_info.currency +# if positions := self.client.positions(): +# return [f"{p.symbol} {p.profit} {currency}" for p in positions if p] +# else: +# return [] + +# async def get_quote(self, instrument): +# """ +# Return a quote for a instrument + + +# Args: +# cex +# instrument + +# Returns: +# quote +# """ +# if not instrument: +# raise ValueError("instrument cannot be empty") +# if quote := self.client.symbol_info_tick(instrument): +# return quote.bid +# else: +# raise ValueError("quote is empty") + +# async def execute_order(self, order_params): +# """ +# Execute order + +# Args: +# order_params (dict): +# action(str) +# instrument(str) +# quantity(int) + +# Returns: +# trade_confirmation(dict) + +# """ +# # TODO: implement + +# async def calculate_pnl(self, from_date, to_date): +# """ +# Calculate the PnL for a given start date. + +# Parameters: +# from_date: The start date for which to calculate PnL. +# to_date: The end date for which to calculate PnL. - Returns: - pnl: The calculated PnL value. - """ +# Returns: +# pnl: The calculated PnL value. +# """ - return self.client.history_orders_get(from_date, to_date) +# return self.client.history_orders_get(from_date, to_date) diff --git a/pyproject.toml b/pyproject.toml index 20b7263..7440c88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ capitalcom-python = "0.2.3" degiro-connector = "3.0.23" easyoanda = {version ="1.0.19", python = ">=3.11,<4.0"} ib_insync = "0.9.86" -mt5linux = "0.1.9" +# mt5linux = "0.1.9" # pyetrade = {version ="2.1.0"} From 5c3938ce3f9817277f6f782b4b2cf1e8414a79bd Mon Sep 17 00:00:00 2001 From: mraniki <8766259+mraniki@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:55:26 +0100 Subject: [PATCH 6/6] update cefi/handler/__init__.py --- cefi/handler/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cefi/handler/__init__.py b/cefi/handler/__init__.py index 671289c..b1f0b48 100644 --- a/cefi/handler/__init__.py +++ b/cefi/handler/__init__.py @@ -2,7 +2,8 @@ from .ccxt import CcxtHandler from .degiro import DegiroHandler from .ibkr import IbHandler -from .metatrader import MetatraderHandler + +# from .metatrader import MetatraderHandler from .oanda import OandaHandler __all__ = [ @@ -10,6 +11,6 @@ "CcxtHandler", "DegiroHandler", "IbHandler", - "MetatraderHandler", + # "MetatraderHandler", "OandaHandler", ]