mirror of
https://github.com/Ichinga-Samuel/aiomql.git
synced 2026-08-16 13:28:08 +00:00
testdata
This commit is contained in:
@@ -6,24 +6,21 @@ from logging import getLogger
|
||||
import asyncio
|
||||
|
||||
import pytz
|
||||
from MetaTrader5 import Tick, SymbolInfo
|
||||
import pandas as pd
|
||||
from pandas import DataFrame
|
||||
|
||||
from ...core.meta_trader import MetaTrader
|
||||
from ...core.config import Config
|
||||
from ...core.errors import Error
|
||||
from ...core.constants import TimeFrame, CopyTicks, OrderType
|
||||
from ...core.models import (AccountInfo, SymbolInfo, BookInfo, TradeOrder, OrderCheckResult, OrderSendResult,
|
||||
TradePosition, TradeDeal, TickInfo)
|
||||
from ...core.constants import TimeFrame, CopyTicks
|
||||
|
||||
from ...utils import backoff_decorator
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class Data(TypedDict):
|
||||
account: AccountInfo
|
||||
symbols: dict[str, SymbolInfo]
|
||||
account: dict
|
||||
symbols: dict[str, dict]
|
||||
prices: dict[str, DataFrame]
|
||||
ticks: dict[str, DataFrame]
|
||||
rates: dict[str, dict[str, DataFrame]]
|
||||
@@ -93,11 +90,11 @@ class GetData:
|
||||
|
||||
return data
|
||||
|
||||
async def get_symbols_info(self) -> dict[str, SymbolInfo]:
|
||||
async def get_symbols_info(self) -> dict[str, dict]:
|
||||
""""""
|
||||
tasks = [self.get_symbol_info(symbol) for symbol in self.symbols]
|
||||
res = await asyncio.gather(*tasks)
|
||||
return {symbol: SymbolInfo(**info) for symbol, info in res}
|
||||
return {symbol: info for symbol, info in res}
|
||||
|
||||
async def get_symbols_ticks(self) -> dict[str, DataFrame]:
|
||||
""""""
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from datetime import datetime, tzinfo
|
||||
from typing import Literal
|
||||
|
||||
import pytz
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from pandas import DataFrame
|
||||
from MetaTrader5 import Tick, SymbolInfo, AccountInfo, TradeOrder, TradePosition, TradeDeal
|
||||
import MetaTrader5
|
||||
from MetaTrader5 import (Tick, SymbolInfo, AccountInfo, TradeOrder, TradePosition, TradeDeal,
|
||||
ORDER_TYPE_BUY, ORDER_TYPE_SELL)
|
||||
|
||||
from ..constants import TimeFrame, CopyTicks
|
||||
from .get_data import Data, GetData
|
||||
@@ -20,8 +21,8 @@ class TestData:
|
||||
|
||||
def __init__(self, data: Data):
|
||||
self._data = data
|
||||
self.account = data['account']
|
||||
self.symbols = data['symbols']
|
||||
self.account = AccountInfo(**data['account'])
|
||||
self.symbols = {symbol: SymbolInfo(**info) for symbol, info in data['symbols'].items()}
|
||||
self.prices = data['prices']
|
||||
self.ticks = data['ticks']
|
||||
self.rates = data['rates']
|
||||
@@ -31,8 +32,7 @@ class TestData:
|
||||
self.orders: dict[str, dict[int, TradeOrder]] = {}
|
||||
self.open_orders: dict[int, TradeOrder] = {}
|
||||
self.positions: dict[str, dict[int, TradePosition]] = {}
|
||||
self.open_positions = dict[int, TradePosition] = {}
|
||||
self.history_deals = dict[str, dict[int, TradeDeal]] = {}
|
||||
self.open_positions: dict[int, TradePosition] = {}
|
||||
|
||||
def __next__(self):
|
||||
self.cursor = next(self.iter)
|
||||
@@ -49,7 +49,7 @@ class TestData:
|
||||
return list(self.symbols.keys())
|
||||
|
||||
def get_account_info(self) -> AccountInfo:
|
||||
return AccountInfo(**self.account.dict)
|
||||
return AccountInfo(**self.account._asdict())
|
||||
|
||||
def get_symbol_info_tick(self, symbol: str) -> Tick:
|
||||
tick = self.prices[symbol].iloc[self.cursor]
|
||||
@@ -58,7 +58,7 @@ class TestData:
|
||||
def get_symbol_info(self, symbol: str) -> SymbolInfo:
|
||||
info = self.symbols[symbol]
|
||||
tick = self.get_symbol_info_tick(symbol)
|
||||
info = info.dict
|
||||
info = info._asdict()
|
||||
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)
|
||||
@@ -103,26 +103,103 @@ class TestData:
|
||||
end = int(datetime.timestamp(date_to)) if isinstance(date_to, datetime) else int(date_to)
|
||||
end = ticks[ticks.index >= end].iloc[-1].index
|
||||
return ticks.loc[start:end].to_numpy()
|
||||
|
||||
def order_calc_margin(self, action: Literal[0, 1], symbol: str, volume: float, price: float):
|
||||
symbol_info = self.get_symbol_info(symbol)
|
||||
margin_rate = symbol_info.margin_rate
|
||||
margin = volume * price / margin_rate
|
||||
return margin
|
||||
|
||||
def order_send(self, request: dict) -> dict:
|
||||
...
|
||||
|
||||
def order_check(self, request: dict) -> dict:
|
||||
...
|
||||
|
||||
def get_orders_total(self) -> int:
|
||||
return len(self.live_orders)
|
||||
return len(self.open_orders)
|
||||
|
||||
def get_orders(self, symbol: str = '', group: str = '', ticket: int = None) -> tuple[TradeOrder, ...]:
|
||||
if ticket:
|
||||
return self.live_orders.get(ticket, ())
|
||||
order = self.open_orders.get(ticket)
|
||||
return (order,) if order else ()
|
||||
|
||||
elif symbol:
|
||||
return tuple(order for order in self.orders.get(symbol, ()) if order.ticket in self.live_orders)
|
||||
return tuple(order for order in self.orders.get(symbol, ()) if order.ticket in self.open_orders)
|
||||
|
||||
elif group:
|
||||
return tuple(self.live_orders.values())
|
||||
return tuple(order for order in self.open_orders.values())
|
||||
|
||||
else:
|
||||
return tuple(self.live_orders.values())
|
||||
return tuple(order for order in self.open_orders.values())
|
||||
|
||||
def get_positions_total(self):
|
||||
return len(self.open_positions)
|
||||
|
||||
def get_positions(self, symbol: str = '', group: str = '', ticket: int = None) -> tuple[TradePosition, ...]:
|
||||
if ticket:
|
||||
position = self.open_positions.get(ticket)
|
||||
return (position,) if position else ()
|
||||
|
||||
elif symbol:
|
||||
return tuple(position for position in self.positions.get(symbol, ()) if position.ticket in self.open_positions)
|
||||
|
||||
elif group:
|
||||
return tuple(position for position in self.open_positions.values())
|
||||
|
||||
else:
|
||||
return tuple(position for position in self.open_positions.values())
|
||||
|
||||
def history_orders_total(self, date_from: datetime | float, date_to: datetime | float):
|
||||
start =
|
||||
def history_orders_total(self, date_from: datetime | float, date_to: datetime | float) -> int:
|
||||
start = int(date_from.timestamp()) if isinstance(date_from, datetime) else int(date_from)
|
||||
end = int(date_to.timestamp()) if isinstance(date_to, datetime) else int(date_to)
|
||||
start = self.history_orders[self.history_orders.index >= start].iloc[0].name
|
||||
end = self.history_orders[self.history_orders.index <= end].iloc[-1].name
|
||||
return self.history_orders.loc[start:end].shape[0]
|
||||
|
||||
def history_orders_get(self, date_from: datetime | float, date_to: datetime | float, group: str = '',
|
||||
ticket: int = None, position: int = None) -> tuple[TradeOrder, ...]:
|
||||
start = int(date_from.timestamp()) if isinstance(date_from, datetime) else int(date_from)
|
||||
end = int(date_to.timestamp()) if isinstance(date_to, datetime) else int(date_to)
|
||||
start = self.history_orders[self.history_orders.index >= start].iloc[0].name
|
||||
end = self.history_orders[self.history_orders.index <= end].iloc[-1].name
|
||||
orders = self.history_orders.loc[start:end]
|
||||
|
||||
if ticket:
|
||||
orders = orders[orders.ticket == ticket]
|
||||
|
||||
elif position:
|
||||
orders = orders[orders.position == position]
|
||||
|
||||
elif group:
|
||||
...
|
||||
|
||||
orders.drop(columns=['symbol'], inplace=True)
|
||||
return tuple(TradeOrder(**order) for order in orders.to_dict(orient='records'))
|
||||
|
||||
def get_history_deals_total(self, date_from: datetime | float, date_to: datetime | float) -> int:
|
||||
start = int(date_from.timestamp()) if isinstance(date_from, datetime) else int(date_from)
|
||||
end = int(date_to.timestamp()) if isinstance(date_to, datetime) else int(date_to)
|
||||
start = self.history_deals[self.history_deals.index >= start].iloc[0].name
|
||||
end = self.history_deals[self.history_deals.index <= end].iloc[-1].name
|
||||
return self.history_deals.loc[start:end].shape[0]
|
||||
|
||||
def get_history_deals(self, date_from: datetime | float, date_to: datetime | float, group: str = '',
|
||||
position: int = None, ticket: int = None) -> tuple[TradeDeal, ...]:
|
||||
start = int(date_from.timestamp()) if isinstance(date_from, datetime) else int(date_from)
|
||||
end = int(date_to.timestamp()) if isinstance(date_to, datetime) else int(date_to)
|
||||
start = self.history_deals[self.history_deals.index >= start].iloc[0].name
|
||||
end = self.history_deals[self.history_deals.index <= end].iloc[-1].name
|
||||
deals = self.history_deals.loc[start:end]
|
||||
|
||||
if ticket:
|
||||
deals = deals[deals.ticket == ticket]
|
||||
|
||||
elif position:
|
||||
deals = deals[deals.position == position]
|
||||
|
||||
elif group:
|
||||
...
|
||||
|
||||
deals.drop(columns=['symbol'], inplace=True)
|
||||
return tuple(TradeDeal(**deal) for deal in deals.to_dict(orient='records'))
|
||||
|
||||
@@ -334,9 +334,9 @@ class SymbolInfo(Base):
|
||||
path: str
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if name := kwargs.pop('name', None) is None:
|
||||
if (name := kwargs.pop('name', None)) is None:
|
||||
raise AttributeError('Symbol Object Must be initialized with a name')
|
||||
self.name = name
|
||||
self.name = name # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -48,7 +48,7 @@ class Symbol(SymbolInfo):
|
||||
"""
|
||||
return self.point * 10
|
||||
|
||||
async def info_tick(self, *, name: str = "", retries=3) -> Tick:
|
||||
async def info_tick(self, *, name: str = "") -> Tick:
|
||||
"""Get the current price tick of a financial instrument.
|
||||
|
||||
Args:
|
||||
@@ -60,16 +60,11 @@ class Symbol(SymbolInfo):
|
||||
Raises:
|
||||
ValueError: If request was unsuccessful and None was returned
|
||||
"""
|
||||
if retries < 1:
|
||||
raise ValueError(f'Could not get tick for {name or self.name}. {self.mt5.error}')
|
||||
tick = await self.mt5.symbol_info_tick(name or self.name)
|
||||
if tick is not None:
|
||||
tick = Tick(**tick._asdict())
|
||||
setattr(self, 'tick', tick) if not name else ...
|
||||
return tick
|
||||
if self.mt5.error.is_connection_error():
|
||||
await asyncio.sleep(retries)
|
||||
return await self.info_tick(name=name, retries=retries - 1)
|
||||
raise ValueError(f'Could not get tick for {name or self.name}. {self.mt5.error}')
|
||||
|
||||
async def symbol_select(self, *, enable: bool = True) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user