diff --git a/.gitignore b/.gitignore index 981a792..b89c4ab 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ __pycache__/ .Python env/ venv/ +.venv/ build/ develop-eggs/ dist/ diff --git a/.png b/.png deleted file mode 100644 index 603f14f..0000000 Binary files a/.png and /dev/null differ diff --git a/ifo.bak b/ifo.bak deleted file mode 100644 index e69de29..0000000 diff --git a/ifo.dat b/ifo.dat deleted file mode 100644 index e69de29..0000000 diff --git a/ifo.dir b/ifo.dir deleted file mode 100644 index e69de29..0000000 diff --git a/info.dat b/info.dat deleted file mode 100644 index e69de29..0000000 diff --git a/info.dir b/info.dir deleted file mode 100644 index e69de29..0000000 diff --git a/src/aiomql/lib/backtester/check.py b/src/aiomql/lib/backtester/check.py new file mode 100644 index 0000000..5bcd9c8 --- /dev/null +++ b/src/aiomql/lib/backtester/check.py @@ -0,0 +1,21 @@ +from collections import namedtuple +class ITR: + + def __init__(self) -> None: + self.span = iter(range(0, 10)) + self.start = 0 + + def __next__(self): + self.start = next(self.span) + return self.start + + +Gender = namedtuple('Gender', ['man', 'woman']) +gen = Gender(man='Manny', woman='Babe') +gend = gen._asdict() +genz = Gender(gend) +print(gen, genz) +# b = ITR() +# print(next(b)) +# print(next(b)) +# print(next(b)) \ No newline at end of file diff --git a/src/aiomql/lib/backtester/get_data.py b/src/aiomql/lib/backtester/get_data.py index 02735b1..5c67ffe 100644 --- a/src/aiomql/lib/backtester/get_data.py +++ b/src/aiomql/lib/backtester/get_data.py @@ -26,26 +26,24 @@ class Data(TypedDict): prices: DataFrame ticks: DataFrame rates: DataFrame - span: range + interval: range class GetData: config: Config = Config() def __init__(self, *, start: datetime, end: datetime, timeframes: set[TimeFrame], symbols: set[str], - interval: int = 60, name: str = '', tz: str = 'Etc/UTC'): + name: str = '', tz: str = 'Etc/UTC'): """""" super().__init__() self.tz = pytz.timezone(tz) self.start = start.replace(tzinfo=self.tz) self.end = end.replace(tzinfo=self.tz) - self.interval = interval self.symbols = symbols self.timeframes = timeframes - self.counter = 0 self.name = name or f"{start:%d-%m-%y}_{end:%d-%m-%y}" diff = int((self.end - self.start).total_seconds()) - self.span = range(start := int(self.start.timestamp()), diff + start) + self.interval = range(start := int(self.start.timestamp()), diff + start) self.mt5 = MetaTrader() async def get_data(self) -> Data: @@ -60,7 +58,7 @@ class GetData: data['prices'] = prices data['symbols'] = symbols data['account'] = account - data['range'] = self.span + data['range'] = self.interval return Data(**data) @@ -149,7 +147,7 @@ class GetData: res = pd.DataFrame(res) res.drop_duplicates(subset=['time'], keep='last', inplace=True) res.set_index('time', inplace=True, drop=False) - res = res.reindex(self.span, method='nearest') + res = res.reindex(self.interval, method='nearest') return symbol, res @backoff_decorator(max_retries=5) diff --git a/src/aiomql/lib/backtester/meta_tester.py b/src/aiomql/lib/backtester/meta_tester.py index 0521701..31a6d6a 100644 --- a/src/aiomql/lib/backtester/meta_tester.py +++ b/src/aiomql/lib/backtester/meta_tester.py @@ -15,19 +15,27 @@ from ...core.errors import Error from ...core.constants import TimeFrame, CopyTicks, OrderType from ...core.models import (AccountInfo, SymbolInfo, BookInfo, TradeOrder, OrderCheckResult, OrderSendResult, TradePosition, TradeDeal) + from ...utils import backoff_decorator from .test_data import TestData +from .get_data import GetData + logger = getLogger(__name__) class MetaTester(MetaTrader): """A class for testing trading strategies in the MetaTrader 5 terminal. A subclass of MetaTrader.""" + data: TestData - def __init__(self, data: TestData): + def __init__(self, data: TestData = None): super().__init__() - self.error = None self.data = data - + + async def initialize(self, path: str = "", login: int = 0, password: str = "", server: str = "", + timeout: int | None = None, portable=False, compressed: bool = False) -> bool: + self.data = await GetData.load_data(name=path, compressed=compressed) + return True + async def account_info(self) -> AccountInfo: """""" res = self.data.account diff --git a/src/aiomql/lib/backtester/test_data.py b/src/aiomql/lib/backtester/test_data.py index 83533f0..7efb383 100644 --- a/src/aiomql/lib/backtester/test_data.py +++ b/src/aiomql/lib/backtester/test_data.py @@ -1,6 +1,6 @@ -from ...core.models import AccountInfo, SymbolInfo +from ...core.models import AccountInfo, SymbolInfo, TickInfo from .get_data import Data, GetData - +from MetaTrader5 import Tick, SymbolInfo class TestData: def __init__(self, data: Data): @@ -10,5 +10,35 @@ class TestData: self.prices = data['prices'] self.ticks = data['ticks'] self.rates = data['rates'] - self.span = data['span'] + self.interval = data['interval'] self.cursor = 0 + self.iter = iter(self.interval) + + def __next__(self): + self.cursor = next(self.iter) + return self.cursor + + def reset(self): + self.iter = iter(self.interval) + return self.iter + + def get_symbol_info_tick(self, symbol: str) -> Tick: + tick = self.prices[symbol].iloc[self.cursor] + return Tick(**tick) + + def get_symbol_info(self, symbol: str) -> SymbolInfo: + symbol = self.symbols[symbol] + symbol |= {'bid': tick.bid, 'bidhigh': tick.bid, 'bidlow': tick.bid, 'bid': tick.bid, 'bidhigh': tick.bid, 'bidlow': tick.bid} + symbol = SymbolInfo(**symbol) + tick = self.get_symbol_info_tick(symbol) + symbol.bid = tick.bid + symbol.bidhigh = 120.506 + symbol.bidlow = tick. + ask=120.041 + askhigh=120.526 + asklow=118.828 + symbol.update() + + + +