From 4439c9351836c96d816285a2119ab6b68e7e2d5a Mon Sep 17 00:00:00 2001 From: Ichinga Samuel Date: Tue, 17 Sep 2024 17:07:31 +0100 Subject: [PATCH] testdata --- data.json | 0 src/aiomql/contrib/backtester/test_account.py | 6 ++-- src/aiomql/contrib/backtester/test_data.py | 31 ++++++++++++------- 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 data.json diff --git a/data.json b/data.json new file mode 100644 index 0000000..e69de29 diff --git a/src/aiomql/contrib/backtester/test_account.py b/src/aiomql/contrib/backtester/test_account.py index e49d612..f3b3dbb 100644 --- a/src/aiomql/contrib/backtester/test_account.py +++ b/src/aiomql/contrib/backtester/test_account.py @@ -2,6 +2,9 @@ from dataclasses import dataclass, asdict, field, fields from typing import ClassVar from ...core.constants import AccountTradeMode, AccountMarginMode, AccountStopOutMode +from MetaTrader5 import AccountInfo + +__match_args__ = SymbolInfo @dataclass @@ -38,8 +41,7 @@ class AccountInfo: _fields: list[ClassVar[str]] = field(default_factory=list) def asdict(self): - res = asdict(self) - res.pop('_fields', None) + res = {key: getattr(self, key) for key in __match_args__} return res def set_attrs(self, **kwargs): diff --git a/src/aiomql/contrib/backtester/test_data.py b/src/aiomql/contrib/backtester/test_data.py index 38e1fcd..872798c 100644 --- a/src/aiomql/contrib/backtester/test_data.py +++ b/src/aiomql/contrib/backtester/test_data.py @@ -216,7 +216,12 @@ class TestData: @cached_property def symbols(self) -> dict[str, SymbolInfo]: - return {symbol: SymbolInfo(info.values()) for symbol, info in self._data.symbols.items()} + ma = SymbolInfo.__match_args__ + symbols = {} + for symbol, info in self._data.symbols.items(): + sym = {key: info.get(key) for key in ma} + symbols[symbol] = SymbolInfo(sym) + return symbols @error_handler async def order_send(self, request: dict, use_terminal: bool = True) -> OrderSendResult: @@ -277,24 +282,28 @@ class TestData: return OrderSendResult(osr) @error_handler - async def order_check(self, request: dict, use_terminal=True) -> OrderCheckResult: + async def order_check(self, request: dict) -> OrderCheckResult: action, symbol, volume = request.get('action'), request.get('symbol'), request.get('volume') price = request.get('price') ocr = {'retcode': 0, 'balance': 0, 'profit': 0, 'margin': 0, 'equity': 0, 'margin_free': 0, 'margin_level': 0, 'comment': 'Done', request: TradeRequest(request)} - - margin = 0 + + # check margin and confirm order can go through + margin = 0 if all([action, symbol, volume, price]): - margin = await self.order_calc_margin(action, symbol, volume, price, use_terminal=use_terminal) - - acc = self.get_account_info() + margin = await self.order_calc_margin(action, symbol, volume, price) + acc = self._account equity = acc.equity used_margin = acc.margin + margin free_margin = acc.margin_free - margin - margin_level = (equity / used_margin) * 100 if ( - acc.margin_mode == AccountStopOutMode.PERCENT and used_margin > 0) else free_margin - - if use_terminal and self.mt5.config.use_terminal_for_backtesting: + + if used_margin == 0: + margin_level = 0 + else: + level = equity / used_margin * 100 + margin_level = level if acc.margin_mode == AccountStopOutMode.PERCENT else free_margin + + if self.mt5.config.use_terminal_for_backtesting: ocr_t = await self.mt5.order_check(request) # return order check result if invalid stops level are detected or bad request if ocr_t.retcode in (10016, 10013, 10014):