mirror of
https://github.com/Ichinga-Samuel/aiomql.git
synced 2026-08-12 19:38:05 +00:00
testdata
This commit is contained in:
+155
-9
@@ -2,20 +2,166 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 5,
|
||||
"id": "f4500c8d-0e58-4d3f-8dd3-06a4896f397f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import shelve\n",
|
||||
"import pickle\n",
|
||||
"import zlib\n",
|
||||
"import lzma\n",
|
||||
"import pytz\n",
|
||||
"# import shelve\n",
|
||||
"# import pickle\n",
|
||||
"# import zlib\n",
|
||||
"# import lzma\n",
|
||||
"# import pytz\n",
|
||||
"from datetime import datetime, timedelta\n",
|
||||
"from aiomql import MetaTrader, MetaTester, TimeFrame, TestData, AccountInfo, TimeFrame, CopyTicks, Account, GetData\n",
|
||||
"# from MetaTrader5 import SymbolInfo\n",
|
||||
"import pandas as pd"
|
||||
"from aiomql import MetaTrader, TimeFrame, AccountInfo, TimeFrame, CopyTicks, Account, Symbol\n",
|
||||
"from MetaTrader5 import SymbolInfo\n",
|
||||
"import pandas as pd\n",
|
||||
"from pandas import DataFrame\n",
|
||||
"import pytz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "f2ef126c-6edc-4651-8a81-06bb97eed6f9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"True\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res = await Account().sign_in()\n",
|
||||
"print(res)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "2c598a85-1e90-49b0-abf1-87329597feae",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"4"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"tz = pytz.timezone('Etc/UTC')\n",
|
||||
"sym = Symbol(name='EURUSD')\n",
|
||||
"start = datetime(day=22, month=8, year=2024, tzinfo=tz)\n",
|
||||
"end = datetime(day=26, month=8, year=2024, hour=12, tzinfo=tz)\n",
|
||||
"# rates = await sym.mt5.copy_rates_from(symbol='EURUSD', date_from=end, count=5, timeframe=TimeFrame.H12)\n",
|
||||
"rates = await sym.mt5.copy_rates_from_pos(symbol='EURUSD', start_pos=0, count=5, timeframe=TimeFrame.H12)\n",
|
||||
"df = DataFrame(rates)\n",
|
||||
"df['time'] = pd.to_datetime(df['time'], unit='s')\n",
|
||||
"df.index[-1]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"id": "0a7d319c-5760-4058-994f-27e8d10df108",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>time</th>\n",
|
||||
" <th>open</th>\n",
|
||||
" <th>high</th>\n",
|
||||
" <th>low</th>\n",
|
||||
" <th>close</th>\n",
|
||||
" <th>tick_volume</th>\n",
|
||||
" <th>spread</th>\n",
|
||||
" <th>real_volume</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>2024-08-25 12:00:00</td>\n",
|
||||
" <td>1.11869</td>\n",
|
||||
" <td>1.11947</td>\n",
|
||||
" <td>1.11849</td>\n",
|
||||
" <td>1.11894</td>\n",
|
||||
" <td>4570</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>2024-08-26 00:00:00</td>\n",
|
||||
" <td>1.11894</td>\n",
|
||||
" <td>1.12016</td>\n",
|
||||
" <td>1.11628</td>\n",
|
||||
" <td>1.11652</td>\n",
|
||||
" <td>43583</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>2024-08-26 12:00:00</td>\n",
|
||||
" <td>1.11652</td>\n",
|
||||
" <td>1.11790</td>\n",
|
||||
" <td>1.11501</td>\n",
|
||||
" <td>1.11618</td>\n",
|
||||
" <td>45034</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" time open high low close tick_volume \\\n",
|
||||
"2 2024-08-25 12:00:00 1.11869 1.11947 1.11849 1.11894 4570 \n",
|
||||
"3 2024-08-26 00:00:00 1.11894 1.12016 1.11628 1.11652 43583 \n",
|
||||
"4 2024-08-26 12:00:00 1.11652 1.11790 1.11501 1.11618 45034 \n",
|
||||
"\n",
|
||||
" spread real_volume \n",
|
||||
"2 1 0 \n",
|
||||
"3 0 0 \n",
|
||||
"4 0 0 "
|
||||
]
|
||||
},
|
||||
"execution_count": 30,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.loc[2:6]"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -20,12 +20,13 @@ from ...utils import backoff_decorator
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class Data(TypedDict):
|
||||
account: AccountInfo
|
||||
symbols: dict[str, SymbolInfo]
|
||||
prices: DataFrame
|
||||
ticks: DataFrame
|
||||
rates: DataFrame
|
||||
prices: dict[str, DataFrame]
|
||||
ticks: dict[str, DataFrame]
|
||||
rates: dict[str, dict[str, DataFrame]]
|
||||
interval: range
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
from datetime import datetime, tzinfo
|
||||
|
||||
import pytz
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from pandas import DataFrame
|
||||
from MetaTrader5 import Tick, SymbolInfo, AccountInfo
|
||||
|
||||
from ..constants import TimeFrame, CopyTicks
|
||||
from .get_data import Data, GetData
|
||||
from ...utils import round_down, round_up
|
||||
|
||||
tz = pytz.timezone('Etc/UTC')
|
||||
|
||||
|
||||
class TestData:
|
||||
def __init__(self, data: Data):
|
||||
self._data = data
|
||||
self.account = data['account']
|
||||
self.symbols = data['symbols']
|
||||
self.prices = data['prices']
|
||||
self.ticks = data['ticks']
|
||||
self.rates = data['rates']
|
||||
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_symbols_total(self) -> int:
|
||||
return len(self.symbols)
|
||||
|
||||
def get_symbols(self) -> list:
|
||||
return list(self.symbols.keys())
|
||||
|
||||
def get_account_info(self) -> AccountInfo:
|
||||
return AccountInfo(**self.account.dict)
|
||||
|
||||
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:
|
||||
info = self.symbols[symbol]
|
||||
tick = self.get_symbol_info_tick(symbol)
|
||||
info = info.dict
|
||||
info |= {'bid': tick.bid, 'bidhigh': tick.bid, 'bidlow': tick.bid, 'ask': tick.ask,
|
||||
'askhigh': tick.ask, 'asklow': tick.bid, 'last': tick.last, 'volume_real': tick.volume_real}
|
||||
return SymbolInfo(**info)
|
||||
|
||||
def get_rates_from(self, symbol: str, timeframe: TimeFrame, date_from: datetime | float, count: int) -> np.ndarray:
|
||||
rates = self.rates[symbol][timeframe.name]
|
||||
start = int(datetime.timestamp(date_from)) if isinstance(date_from, datetime) else int(date_from)
|
||||
start = round_down(start, timeframe.time)
|
||||
start = rates.index.get_loc(start)
|
||||
end = start + count
|
||||
return rates.iloc[start:end].to_numpy()
|
||||
|
||||
def get_rates_from_pos(self, symbol: str, timeframe: TimeFrame, start_pos: int, count: int) -> np.ndarray:
|
||||
rates = self.rates[symbol][timeframe.name]
|
||||
end = -start_pos + count
|
||||
return rates.iloc[-start_pos:end].to_numpy()
|
||||
|
||||
def get_rates_range(self, symbol: str, timeframe: TimeFrame, date_from: datetime, date_to: datetime) -> np.ndarray:
|
||||
rates = self.rates[symbol][timeframe.name]
|
||||
start = int(datetime.timestamp(date_from))
|
||||
start = round_down(start, timeframe.time)
|
||||
end = round_up(int(datetime.timestamp(date_to)), timeframe.time)
|
||||
return rates.loc[start:end].to_numpy()
|
||||
|
||||
def get_ticks_from(self, symbol: str, date_from: datetime | float, count: int, flags: CopyTicks) -> DataFrame:
|
||||
ticks = self.ticks[symbol]
|
||||
start = int(datetime.timestamp(date_from)) if isinstance(date_from, datetime) else int(date_from)
|
||||
start = round_down(start, 1)
|
||||
end = start + count
|
||||
return ticks.loc[start:end]
|
||||
@@ -334,7 +334,7 @@ class SymbolInfo(Base):
|
||||
path: str
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if name := kwargs.pop('name', None):
|
||||
if name := kwargs.pop('name', None) is None:
|
||||
raise AttributeError('Symbol Object Must be initialized with a name')
|
||||
self.name = name
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from .strategies import *
|
||||
from .traders import *
|
||||
from .symbols import *
|
||||
from .backtester import *
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
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):
|
||||
self._data = data
|
||||
self.account = data['account']
|
||||
self.symbols = data['symbols']
|
||||
self.prices = data['prices']
|
||||
self.ticks = data['ticks']
|
||||
self.rates = data['rates']
|
||||
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()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -62,3 +62,10 @@ def backoff_decorator(func=None, *, max_retries: int = 3, retries: int = 0, dela
|
||||
return await wrapper(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def round_down(value: int, base: int) -> int:
|
||||
return value if value % base == 0 else value - (value % base)
|
||||
|
||||
def round_up(value: int, base: int) -> int:
|
||||
return value if value % base == 0 else value + base - (value % base)
|
||||
|
||||
Reference in New Issue
Block a user