diff --git a/pyproject.toml b/pyproject.toml index 646fbe1..d3dc106 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "aiomql" -version = "3.16" +version = "3.17" readme = "README.md" requires-python = ">=3.10" classifiers = [ diff --git a/src/aiomql/account.py b/src/aiomql/account.py index 1db21e6..b072347 100644 --- a/src/aiomql/account.py +++ b/src/aiomql/account.py @@ -64,8 +64,7 @@ class Account(AccountInfo): bool: True if login was successful else False """ acc = self.get_dict(include={'login', 'server', 'password'}) - await self.mt5.initialize(**acc, path=self.config.path) - self.connected = await self.mt5.login(**acc) + self.connected = await self._login(acc=acc) if self.connected: await self.refresh() self.symbols = await self.symbols_get() @@ -73,6 +72,18 @@ class Account(AccountInfo): await self.mt5.shutdown() return False + async def _login(self, *, acc:dict, tries=3): + res = False + if tries == 0: + return False + ini = await self.mt5.initialize(**acc, path=self.config.path) + if ini: + res = await self.mt5.login(**acc) + if ini and res: + return True + else: + return await self._login(acc=acc, tries=tries-1) + def has_symbol(self, symbol: str | SymbolInfo): """Checks to see if a symbol is available for a trading account. diff --git a/src/aiomql/bot_builder.py b/src/aiomql/bot_builder.py index 32f059d..11c93f8 100644 --- a/src/aiomql/bot_builder.py +++ b/src/aiomql/bot_builder.py @@ -1,4 +1,5 @@ import asyncio +from concurrent.futures import ProcessPoolExecutor from typing import Type, Iterable, TypeVar, Callable, Coroutine import logging @@ -35,6 +36,14 @@ class Bot: self.symbols = set() self.executor = Executor(bot=self) + @classmethod + def run_bots(cls, bots: dict[Callable: dict] = None, num_workers: int = None): + """Run multiple bots at the same time.""" + num_workers = num_workers or len(bots) * 2 + with ProcessPoolExecutor(max_workers=num_workers) as executor: + for bot, kwargs in bots.items(): + executor.submit(bot, **kwargs) + async def initialize(self): """Prepares the bot by signing in to the trading account and initializing the symbols for the trading session. Starts the global task queue. @@ -44,7 +53,7 @@ class Bot: """ init = await self.account.sign_in() if not init: - logger.warning("Unable to sign in to MetaTrder 5 Terminal") + logger.warning(f"Unable to sign in to MetaTrder 5 Terminal") raise SystemExit logger.info("Login Successful") await self.init_symbols()