From 2e7aa73aec229e1feccca1177b3c9471b7e3defe Mon Sep 17 00:00:00 2001 From: Ichinga Samuel Date: Fri, 15 Nov 2024 21:13:19 +0100 Subject: [PATCH] v4 --- docs/TOC.md | 83 +- docs/_utils.md | 128 ++ docs/core/backtesting/backtest_account.md | 71 +- docs/core/backtesting/backtest_controller.md | 99 +- docs/core/backtesting/backtest_engine.md | 1139 ++++++++---------- docs/core/backtesting/get_data.md | 209 ++-- docs/core/backtesting/trades_manager.md | 500 ++++---- docs/core/config.md | 143 ++- docs/core/constants.md | 59 +- docs/core/errors.md | 30 +- docs/core/exceptions.md | 30 +- docs/core/meta_backtester.md | 47 + docs/core/models.md | 160 +-- docs/lib/account.md | 7 +- docs/lib/bot.md | 20 +- docs/lib/utils.md | 66 - src/aiomql/core/backtesting/get_data.py | 6 +- src/aiomql/core/config.py | 16 +- src/aiomql/core/errors.py | 2 +- 19 files changed, 1400 insertions(+), 1415 deletions(-) create mode 100644 docs/_utils.md create mode 100644 docs/core/meta_backtester.md delete mode 100644 docs/lib/utils.md diff --git a/docs/TOC.md b/docs/TOC.md index 0198f20..e38a52d 100644 --- a/docs/TOC.md +++ b/docs/TOC.md @@ -1,30 +1,55 @@ # Table of Contents -- [MetaTrader](core/meta_trader.md) -- [Config](core/config.md) -- [Base](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/core/base.md) -- [Constants](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/core/constants.md) -- [TaskQueue](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/core/task_queue.md) -- [Models](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/core/models.md) -- [Bot_Builder](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/bot_builder.md) -- [Account](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/account.md) -- [Candle](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/candle.md) -- [Candles](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/candle.md) -- [Executor](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/executor.md) -- [History](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/history.md) -- [Order](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/order.md) -- [Positions](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/postions.md) -- [RAM](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/ram.md) -- [Records](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/records.md) -- [TradeRecords](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/trade_records.md) -- [Result](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/result.md) -- [Session](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/sessions.md) -- [Sessions](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/sessions.md) -- [Symbol](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/symbol.md) -- [Strategy](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/stategy.md) -- [Terminal](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/terminal.md) -- [Tick](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/ticks.md) -- [Ticks](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/ticks.md) -- [Trader](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/trader.md) -- [utils](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/utils.md) -- [Errors](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/core/errors.md) -- [Exceptions](https://github.com/Ichinga-Samuel/aiomql/blob/master/docs/core/exceptions.md) + +- [Core](core) + - [MetaTrader](core/meta_trader.md) + - [Config](core/config.md) + - [Base](core/base.md) + - [Constants](core/constants.md) + - [TaskQueue](core/task_queue.md) + - [Models](core/models.md) + - [Errors](core/errors.md) + - [Exceptions](core/exceptions.md) + - [MetaBackTester](core/meta_backtester.md) + + - [BackTesting](core/backtesting) + - [BackTestAccount](core/backtesting/backtest_account.md) + - [BackTestEngine](core/backtesting/backtest_engine.md) + - [GetData](core/backtesting/get_data.md) + - [TradesManager](core/backtesting/trades_manager.md) + - [BackTestController](core/backtesting/backtest_controller.md) + +- [Lib](lib) + - [Account](lib/account.md) + - [Bot](lib/bot.md) + - [Candle](lib/candle.md) + - [Candles](lib/candle.md) + - [History](lib/history.md) + - [Order](lib/order.md) + - [Positions](lib/positions.md) + - [RAM](lib/ram.md) + - [TradeRecords](lib/trade_records.md) + - [Result](lib/result.md) + - [Session](lib/sessions.md) + - [Sessions](lib/sessions.md) + - [Symbol](lib/symbol.md) + - [Strategy](lib/strategy.md) + - [Terminal](lib/terminal.md) + - [Tick](lib/ticks.md) + - [Ticks](lib/ticks.md) + - [Trader](lib/trader.md) + +- [Contrib](contrib) + - [CandlePatterns](contrib/candle_patterns) + - [Fractals](contrib/candle_patterns/fractals.md) + + - [Symbols](contrib/symbols) + - [ForexSymbol](contrib/symbols/forex_symbol.md) + + - [Utils](contrib/utils) + - [Tracker](contrib/utils/tracker.md) + + - [Traders](contrib/traders) + - [ScalpTrader](contrib/traders/scalp_trader.md) + - [SimpleTrader](contrib/traders/simple_trader.md) + +- [Utils](_utils.md) diff --git a/docs/_utils.md b/docs/_utils.md new file mode 100644 index 0000000..126e984 --- /dev/null +++ b/docs/_utils.md @@ -0,0 +1,128 @@ +# Utils +Utils is a collection of utility functions that are used throughout the codebase. It is a collection of functions. + +## Table of Contents +- [round_off](#_utiils.round_off) +- [dict_to_string](#_utils.dict_to_string) +- [round_down](#_utils.round_down) +- [round_up](#_utils.round_up) +- [async_cache](#_utils.async_cache) +- [backoff_decorator](#_utils.backoff_decorator) +- [error_handler](#_utils.error_handler) +- [error_handler_sync](#_utils.error_handler_sync) + + + +### round_off +```python +def round_off(value: float, step: float, round_down: bool = True) -> float: +``` +Rounds off a value to the nearest step. If round_down is True, it will round down, otherwise it will round up. + +#### Parameters: +| Name | Type | Description | Default | +|------------|-------|--------------------------------------------|---------| +| value | float | The value to round off. | | +| step | float | The step to round off to. | | +| round_down | bool | Whether to round down. If False, round up. | True | + +#### Returns: +| Type | Description | +|-------|------------------------| +| float | The rounded off value. | + + + +### dict_to_string +```python +def dict_to_string(data: dict, multi=True) -> str: +``` +Converts a dictionary to a string. If multi is True, it will return a multi-line string. + +#### Parameters: +| Name | Type | Description | Default | +|-------|------|----------------------------------------|---------| +| data | dict | The dictionary to convert to a string. | | +| multi | bool | Whether to return a multi-line string. | True | + +#### Returns: +| Type | Description | +|------|-----------------------------| +| str | The dictionary as a string. | + + + +### round_down +```python +def round_down(value: float, base: int) -> int: +``` +Rounds down a value to the nearest base. + +#### Parameters: +| Name | Type | Description | +|-------|-------|------------------------------------| +| value | float | The value to round down. | +| base | int | The base to round down to. | + + + +### round_up +```python +def round_up(value: float, base: int) -> int: +``` +Rounds up a value to the nearest base. + +#### Parameters: +| Name | Type | Description | +|-------|-------|----------------------------------| +| value | float | The value to round up. | +| base | int | The base to round up to. | + + + +### async_cache +```python +def async_cache(func: Callable) -> Callable: +``` +A decorator to cache the result of an async function. + + + +### backoff_decorator +```python +def backoff_decorator(func=None, *, max_retries: int = 2, retries: int = 0, error="") -> Callable: +``` +A decorator to retry a function with exponential backoff. + +#### Parameters: +| Name | Type | Description | Default | +|-------------|------|--------------------------------------------|---------| +| func | | The function to decorate. | | +| max_retries | int | The maximum number of retries. | 2 | +| retries | int | The current number of retries. | 0 | +| error | str | The error message to display on exception. | | + + + +### error_handler +```python +async def error_handler(func=None, *, msg="", exe=Exception, response=None, log_error_msg=True) -> Callable: +``` +A decorator to handle exceptions in an async function. + +#### Parameters: +| Name | Type | Description | Default | +|---------------|------|--------------------------------------------|---------| +| func | | The function to decorate. | | +| msg | str | The error message to display on exception. | | +| exe | | The exception to catch. | | +| response | | The response to return on exception. | | +| log_error_msg | bool | Whether to log the error message. | True | + + + +### error_handler_sync +```python +def error_handler_sync(func=None, *, msg="", exe=Exception, response=None, log_error_msg=True) -> Callable: +``` +A decorator to handle exceptions in a sync function. diff --git a/docs/core/backtesting/backtest_account.md b/docs/core/backtesting/backtest_account.md index 758b142..4365711 100644 --- a/docs/core/backtesting/backtest_account.md +++ b/docs/core/backtesting/backtest_account.md @@ -1,58 +1,55 @@ -# Table of Contents +# BackTestAccount -* [backtest\_account](#backtest_account) - * [BackTestAccount](#backtest_account.BackTestAccount) - * [get\_dict](#backtest_account.BackTestAccount.get_dict) - * [asdict](#backtest_account.BackTestAccount.asdict) - * [set\_attrs](#backtest_account.BackTestAccount.set_attrs) +## Table of Contents +- [BackTestAccount](#back_test_account.back_test_account) +- [get_dict](#back_test_account.back_test_account.get_dict) +- [asdict](#back_test_account.asdict) +- [set_attrs](#back_test_account.set_attrs) - - -# backtest\_account - - - -## BackTestAccount Objects +### BackTestAccount + ```python @dataclass -class BackTestAccount() +class BackTestAccount: ``` +The `BackTestAccount` class provides data structure for managing account data specifically for backtesting purposes. -Account data for backtesting +#### Attributes: +| Name | Type | Description | +|-------------|---------------|-----------------------------------------------------------| +| `balance` | `float` | The account balance for the backtest | +| `equity` | `float` | The equity value of the account during the backtest | +| `currency` | `str` | The currency type used in the backtesting account | +| `leverage` | `float` | Leverage ratio applied to the backtest account | +| `spread` | `int` | Spread value applied to simulated trades | - - -#### get\_dict + +### get_dict ```python -def get_dict(exclude: set = None, include: set = None) +def get_dict(exclude: set = None, include: set = None) -> dict ``` +Returns a dictionary representation of the account data. The `exclude` and `include` parameters allow filtering of data keys. -Returns a dictionary of the account data. Using the exclude and include arguments, you can filter the data +#### Arguments: +| Name | Type | Description | +|-----------|-------|----------------------------------------------------------| +| `exclude` | `set` | A set of attribute names to exclude from the dictionary. | +| `include` | `set` | A set of attribute names to include in the dictionary. | -**Arguments**: - -- `exclude` _set_ - A set of keys to exclude -- `include` _set_ - A set of keys to include - - - -#### asdict + +### asdict ```python -def asdict() +def asdict() -> dict ``` +Returns a dictionary of all attributes in the account data without filtering. -Returns a dictionary of the account data - - - -#### set\_attrs +### set_attrs + ```python def set_attrs(**kwargs) ``` - -Se the attributes of the account data to the instance - +Sets multiple attributes at once by passing key-value pairs as keyword arguments. diff --git a/docs/core/backtesting/backtest_controller.md b/docs/core/backtesting/backtest_controller.md index fdefb28..ba981be 100644 --- a/docs/core/backtesting/backtest_controller.md +++ b/docs/core/backtesting/backtest_controller.md @@ -1,125 +1,104 @@ -# Table of Contents +# BackTestController -* [backtest\_controller](#backtest_controller) - * [BackTestController](#backtest_controller.BackTestController) - * [backtest\_engine](#backtest_controller.BackTestController.backtest_engine) - * [add\_tasks](#backtest_controller.BackTestController.add_tasks) - * [set\_parties](#backtest_controller.BackTestController.set_parties) - * [parties](#backtest_controller.BackTestController.parties) - * [control](#backtest_controller.BackTestController.control) - * [stop\_backtesting](#backtest_controller.BackTestController.stop_backtesting) - * [wait](#backtest_controller.BackTestController.wait) - * [abort](#backtest_controller.BackTestController.abort) +## Table of Contents +- [BackTestController](#backtest_controller.back_test_controller) +- [backtest_engine](#backtest_controller.backtest_engine) +- [add_tasks](#backtest_controller.add_tasks) +- [set_parties](#backtest_controller.set_parties) +- [parties](#backtest_controller.parties) +- [control](#backtest_controller.control) +- [stop_backtesting](#backtest_controller.stop_backtesting) +- [wait](#backtest_controller.wait) +- [abort](#backtest_controller.abort) - - -# backtest\_controller - - - -## BackTestController Objects + +### BackTestController ```python -class BackTestController() +class BackTestController ``` - The controller for the backtesting engine. -It also act's as a synchronizier for running multiple strategies (tasks) using a threading.Barrier primitive. +It also acts as a synchronizer for running multiple strategies (tasks) using a threading.Barrier primitive. It handles the updating of open positions and close them when necessary. It handles the iterator for the backtesting engine and handles it movement in time by moving it to the next time step. -**Attributes**: +#### Attributes: +| Name | Type | Description | +|-------------|----------------------|----------------------------------------------| +| `_instance` | `BackTestController` | The instance of the controller | +| `config` | `Config` | The configuration for the backtesting engine | +| `tasks` | `list[Task]` | The tasks that are being run | +| `barrier` | `Barrier` | The barrier for synchronizing the tasks | -- `_instance` _Self_ - The instance of the controller -- `config` _Config_ - The configuration for the backtesting engine -- `tasks` _list[Task]_ - The tasks that are being run -- `barrier` _Barrier_ - The barrier for synchronizing the tasks - - - -#### backtest\_engine + +#### backtest_engine ```python @property def backtest_engine() ``` - Returns the backtest engine - - -#### add\_tasks + +#### add_tasks ```python def add_tasks(*tasks: Task) ``` +Adds a task to the tasks list -Adds tasks to the tasks list - - - -#### set\_parties + +#### set_parties ```python def set_parties(*, parties: int) ``` - Sets the number of parties for the barrier. The barrier will wait for the number of parties to reach the barrier. This has to be done here as it can be impossible to know the eventual number of parties to set the barrier to during initialization. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-----------|-------|---------------------------------------------| +| `parties` | `int` | The number of parties to set the barrier to | -- `parties` _int_ - The number of parties to set the barrier to - - + #### parties - ```python @property def parties() ``` - Returns the number of parties for the barrier - + #### control - ```python async def control() ``` - The backtest controller. It controls the backtesting engine and the tasks that are being run. It acts as a synchronizer for the tasks and the backtesting engine. - - -#### stop\_backtesting + +#### stop_backtesting ```python def stop_backtesting() ``` - Stop the backtester, and shutdown the executor - + #### wait - ```python def wait() ``` - Called by individual tasks to indicate completion of their cycle - + #### abort - ```python def abort() ``` - Aborts the barrier - diff --git a/docs/core/backtesting/backtest_engine.md b/docs/core/backtesting/backtest_engine.md index 632c5b5..408fc22 100644 --- a/docs/core/backtesting/backtest_engine.md +++ b/docs/core/backtesting/backtest_engine.md @@ -1,77 +1,90 @@ -# Table of Contents +# BackTestEngine -* [backtest\_engine](#backtest_engine) - * [BackTestEngine](#backtest_engine.BackTestEngine) - * [\_\_init\_\_](#backtest_engine.BackTestEngine.__init__) - * [setup\_test\_range](#backtest_engine.BackTestEngine.setup_test_range) - * [setup\_data](#backtest_engine.BackTestEngine.setup_data) - * [next](#backtest_engine.BackTestEngine.next) - * [data](#backtest_engine.BackTestEngine.data) - * [reset](#backtest_engine.BackTestEngine.reset) - * [go\_to](#backtest_engine.BackTestEngine.go_to) - * [fast\_forward](#backtest_engine.BackTestEngine.fast_forward) - * [tracker](#backtest_engine.BackTestEngine.tracker) - * [save\_result\_to\_json](#backtest_engine.BackTestEngine.save_result_to_json) - * [close\_all\_open](#backtest_engine.BackTestEngine.close_all_open) - * [wrap\_up](#backtest_engine.BackTestEngine.wrap_up) - * [preload\_ticks](#backtest_engine.BackTestEngine.preload_ticks) - * [get\_price\_tick](#backtest_engine.BackTestEngine.get_price_tick) - * [check\_order](#backtest_engine.BackTestEngine.check_order) - * [check\_account](#backtest_engine.BackTestEngine.check_account) - * [check\_position](#backtest_engine.BackTestEngine.check_position) - * [close\_position\_manually](#backtest_engine.BackTestEngine.close_position_manually) - * [close\_position](#backtest_engine.BackTestEngine.close_position) - * [modify\_stops](#backtest_engine.BackTestEngine.modify_stops) - * [update\_account](#backtest_engine.BackTestEngine.update_account) - * [deposit](#backtest_engine.BackTestEngine.deposit) - * [withdraw](#backtest_engine.BackTestEngine.withdraw) - * [setup\_account](#backtest_engine.BackTestEngine.setup_account) - * [setup\_account\_sync](#backtest_engine.BackTestEngine.setup_account_sync) - * [prices](#backtest_engine.BackTestEngine.prices) - * [ticks](#backtest_engine.BackTestEngine.ticks) - * [rates](#backtest_engine.BackTestEngine.rates) - * [symbols](#backtest_engine.BackTestEngine.symbols) - * [order\_send](#backtest_engine.BackTestEngine.order_send) - * [order\_check](#backtest_engine.BackTestEngine.order_check) - * [get\_terminal\_info](#backtest_engine.BackTestEngine.get_terminal_info) - * [get\_version](#backtest_engine.BackTestEngine.get_version) - * [get\_symbols\_total](#backtest_engine.BackTestEngine.get_symbols_total) - * [get\_symbols](#backtest_engine.BackTestEngine.get_symbols) - * [get\_account\_info](#backtest_engine.BackTestEngine.get_account_info) - * [get\_symbol\_info\_tick](#backtest_engine.BackTestEngine.get_symbol_info_tick) - * [get\_symbol\_info](#backtest_engine.BackTestEngine.get_symbol_info) - * [get\_rates\_from](#backtest_engine.BackTestEngine.get_rates_from) - * [get\_rates\_from\_pos](#backtest_engine.BackTestEngine.get_rates_from_pos) - * [get\_rates\_range](#backtest_engine.BackTestEngine.get_rates_range) - * [get\_ticks\_from](#backtest_engine.BackTestEngine.get_ticks_from) - * [get\_ticks\_range](#backtest_engine.BackTestEngine.get_ticks_range) - * [order\_calc\_margin](#backtest_engine.BackTestEngine.order_calc_margin) - * [order\_calc\_profit](#backtest_engine.BackTestEngine.order_calc_profit) - * [get\_orders\_total](#backtest_engine.BackTestEngine.get_orders_total) - * [get\_orders](#backtest_engine.BackTestEngine.get_orders) - * [get\_positions\_total](#backtest_engine.BackTestEngine.get_positions_total) - * [get\_positions](#backtest_engine.BackTestEngine.get_positions) - * [get\_history\_orders\_total](#backtest_engine.BackTestEngine.get_history_orders_total) - * [get\_history\_orders](#backtest_engine.BackTestEngine.get_history_orders) - * [get\_history\_deals\_total](#backtest_engine.BackTestEngine.get_history_deals_total) - * [get\_history\_deals](#backtest_engine.BackTestEngine.get_history_deals) +## Table of Contents - +- [BackTestEngine](#backtest_engine.back_test_engine) +- [\__init\__](#backtest_engine.__init__) +- [setup_test_range](#backtest_engine.setup_test_range) +- [setup_data](#backtest_engine.setup_data) +- [next](#backtest_engine.next) +- [data](#backtest_engine.data) +- [reset](#backtest_engine.reset) +- [go_to](#backtest_engine.go_to) +- [fast_forward](#backtest_engine.fast_forward) +- [tracker](#backtest_engine.tracker) +- [save_result_to_json](#backtest_engine.save_result_to_json) +- [close_all_open](#backtest_engine.close_all_open) +- [wrap_up](#backtest_engine.wrap_up) +- [preload_ticks](#backtest_engine.preload_ticks) +- [get_price_tick](#backtest_engine.get_price_tick) +- [check_order](#backtest_engine.check_order) +- [check_account](#backtest_engine.check_account) +- [check_position](#backtest_engine.check_position) +- [close_position_manually](#backtest_engine.close_position_manually) +- [close_position](#backtest_engine.close_position) +- [modify_stops](#backtest_engine.modify_stops) +- [update_account](#backtest_engine.update_account) +- [deposit](#backtest_engine.deposit) +- [withdraw](#backtest_engine.withdraw) +- [setup_account](#backtest_engine.setup_account) +- [setup_account_sync](#backtest_engine.setup_account_sync) +- [prices](#backtest_engine.prices) +- [ticks](#backtest_engine.ticks) +- [rates](#backtest_engine.rates) +- [symbols](#backtest_engine.symbols) +- [order_send](#backtest_engine.order_send) +- [order_check](#backtest_engine.order_check) +- [get_terminal_info](#backtest_engine.get_terminal_info) +- [get_version](#backtest_engine.get_version) +- [get_symbols_total](#backtest_engine.get_symbols_total) +- [get_symbols](#backtest_engine.get_symbols) +- [get_account_info](#backtest_engine.get_account_info) +- [get_symbol_info_tick](#backtest_engine.get_symbol_info_tick) +- [get_symbol_info](#backtest_engine.get_symbol_info) +- [get_rates_from](#backtest_engine.get_rates_from) +- [get_rates_from_pos](#backtest_engine.get_rates_from_pos) +- [get_rates_range](#backtest_engine.get_rates_range) +- [get_ticks_from](#backtest_engine.get_ticks_from) +- [get_ticks_range](#backtest_engine.get_ticks_range) +- [order_calc_margin](#backtest_engine.order_calc_margin) +- [order_calc_profit](#backtest_engine.order_calc_profit) +- [get_orders_total](#backtest_engine.get_orders_total) +- [get_orders](#backtest_engine.get_orders) +- [get_positions_total](#backtest_engine.get_positions_total) +- [get_positions](#backtest_engine.get_positions) +- [get_history_orders_total](#backtest_engine.get_history_orders_total) +- [get_history_orders](#backtest_engine.get_history_orders) +- [get_history_deals_total](#backtest_engine.get_history_deals_total) +- [get_history_deals](#backtest_engine.get_history_deals) -# backtest\_engine - - - -## BackTestEngine Objects + +#### BackTestEngine ```python -class BackTestEngine() +class BackTestEngine ``` +The BackTestEngine class is used to simulate trading strategies on historical data that is either preloaded or provided +at runtime during the test. - +#### Attributes: +| Name | Type | Description | +|--------------------------------|----------------|-----------------------------------------------------------------------------------------------------| +| `_data` | `BackTestData` | The data used for backtesting. This is the data that is saved to disk when the backtest is stopped. | +| `mt5` | `MetaTrader` | The MetaTrader instance for the backtest engine. | +| `config` | `Config` | The global configuration instance. | +| `name` | `str` | The name of the backtest. | +| `stop_testing` | `bool` | Whether to stop the backtest. | +| `use_terminal` | `bool` | Whether to use the terminal for backtesting. | +| `close_open_positions_on_exit` | `bool` | Whether to close all open positions when the backtest is stopped. | +| `stop_time` | `int` | The time to stop the backtest. | +| `preload` | `bool` | Whether to preload the ticks for the backtest. | +| `preloaded_ticks` | `dict` | A dictionary of preloaded ticks for the backtest. | +| `account_lock` | `RLock` | A reentrant lock for the account data. | +| `account_info` | `dict` | A dictionary of account information for the backtest. | -#### \_\_init\_\_ + +#### \__init\__ ```python def __init__(*, data: BackTestData = None, @@ -87,7 +100,6 @@ def __init__(*, assign_to_config: bool = True, account_info: dict = None) ``` - The BackTestEngine class is used to simulate trading strategies on historical data. It can accept already saved data or create new data for backtesting on the fly. Ideally only one instance of this class should be created per session. By default it is automatically assigned to the global config instance @@ -95,75 +107,26 @@ during instantiation, replacing any existing backtest engine instance. But this The start and end time can still be specified even when test data is provided. In that case it will be used to set the range of the backtest. -**Arguments**: -- `data` _BackTestData, optional_ - The data to use for backtesting. Defaults to None. - -- `speed` _int, optional_ - The speed of the backtest. Defaults to 60 seconds. - -- `start` _float | datetime, optional_ - The start time of the backtest. Defaults to 0. If a float is passed, - it is assumed to be a timestamp. - -- `end` _float | datetime, optional_ - The end time of the backtest. Defaults to 0. If a float is passed, - it is assumed to be a timestamp. - -- `restart` _bool, optional_ - Whether to restart the backtest from the beginning. Defaults to True. - This is useful when resuming a backtest using a saved BackTestData instance. - -- `use_terminal` _bool, optional_ - Whether to use the terminal for backtesting. Defaults to None. If None, - it uses the global config setting. If use terminal is true, the backtest engine will use the terminal to - get price data, compute margins, profit and check order viability. If false, it will use the data - provided in the BackTestData instance and default algorithm for the calculations - -- `name` _str, optional_ - The name of the backtest. Defaults to "". If not provided, - it is generated from the start and end times. - -- `stop_time` _float | datetime, optional_ - The time to stop the backtest. Defaults to None. - If a float is passed, it is assumed to be a timestamp. If not given it is assumed to be the end of the backtest range. - -- `close_open_positions_on_exit` _bool, optional_ - Whether to close all open positions when the backtest - is stopped. Defaults to True. - -- `preload` _bool, optional_ - Whether to preload the ticks for the backtest. Defaults to True. - -- `assign_to_config` _bool, optional_ - Whether to assign the backtest engine to the global config instance. - Defaults to True. - -- `account_info` _dict, optional_ - A dictionary of account information to use for the backtest. Defaults to None. Use this to set - the account information for the backtest. - +#### Parameters: +| Name | Type | Description | +|--------------------------------|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `data` | `BackTestData` | The data to use for backtesting. Defaults to None. | +| `speed` | `int` | The speed of the backtest. Defaults to 60 seconds. | +| `start` | `float \| datetime` | The start time of the backtest. Defaults to 0. If a float is passed, it is assumed to be a timestamp. | +| `end` | `float \| datetime` | The end time of the backtest. Defaults to 0. If a float is passed, it is assumed to be a timestamp. | +| `restart` | `bool` | Whether to restart the backtest from the beginning. Defaults to True. This is useful when resuming a backtest using a saved BackTestData instance. | +| `use_terminal` | `bool` | Whether to use the terminal for backtesting. Defaults to None. If None, it uses the global config setting. If use terminal is true, the backtest engine will use the terminal to get price data, compute margins, profit and check order viability. If false, it will use the data provided in the BackTestData instance and default algorithm for the calculations | +| `name` | `str` | The name of the backtest. Defaults to "". If not provided, it is generated from the start and end times. | +| `stop_time` | `float \| datetime` | The time to stop the backtest. Defaults to None. If a float is passed, it is assumed to be a timestamp. If not given it is assumed to be the end of the backtest range. | +| `close_open_positions_on_exit` | `bool` | Whether to close all open positions when the backtest is stopped. Defaults to True. | +| `preload` | `bool` | Whether to preload the ticks for the backtest. Defaults to True. | +| `assign_to_config` | `bool` | Whether to assign the backtest engine to the global config instance. Defaults to True. | +| `account_info` | `dict` | A dictionary of account information to use for the backtest. Defaults to None. Use this to set the account information for the backtest. | -**Attributes**: - -- `_data` _BackTestData_ - The data used for backtesting. This is the data that is saved to disk when the - backtest is stopped. - -- `mt5` _MetaTrader_ - The MetaTrader instance for the backtest engine. - -- `config` _Config_ - The global configuration instance. - -- `name` _str_ - The name of the backtest. - -- `stop_testing` _bool_ - Whether to stop the backtest. - -- `use_terminal` _bool_ - Whether to use the terminal for backtesting. - -- `close_open_positions_on_exit` _bool_ - Whether to close all open positions when the backtest is stopped. - -- `stop_time` _int_ - The time to stop the backtest. - -- `preload` _bool_ - Whether to preload the ticks for the backtest. - -- `preloaded_ticks` _dict_ - A dictionary of preloaded ticks for the backtest. - -- `account_lock` _RLock_ - A reentrant lock for the account data. - -- `account_info` _dict_ - A dictionary of account information for the backtest. - - - -#### setup\_test\_range + +#### setup_test_range ```python def setup_test_range(*, start: float | datetime = None, @@ -171,334 +134,285 @@ def setup_test_range(*, speed: int = 60, restart: bool = True) ``` - Setup the test range for the backtest engine. This is used to set the range of the backtest and the speed at which it runs. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-----------|---------------------|------------------------------------------------------------------------------------------------------------------------| +| `start` | `float \| datetime` | The start time of the backtest. Defaults to None. If a float is passed, it is assumed to be a timestamp. | +| `end` | `float \| datetime` | The end time of the backtest. Defaults to None. If a float is passed, it is assumed to be a timestamp. | +| `speed` | `int` | The speed of the backtest. Defaults to 60 seconds. | +| `restart` | `bool` | Whether to restart the backtest. Defaults to True. This is useful when resuming a backtest using a saved BackTestData. | -- `start` _float | datetime, optional_ - The start time of the backtest. Defaults to None. If a float is passed, - it is assumed to be a timestamp. - -- `end` _float | datetime, optional_ - The end time of the backtest. Defaults to None. If a float is passed, - it is assumed to be a timestamp. - -- `speed` _int, optional_ - The speed of the backtest. Defaults to 60. - -- `restart` _bool, optional_ - Whether to restart the backtest. Defaults to True. - This is useful when resuming a backtest using a saved BackTestData. - - - -#### setup\_data + +#### setup_data ```python def setup_data(*, restart: bool = True) ``` - Sets up the data for the backtest engine. This includes the orders, positions, deals and account information. This data is handled by specialized classes such as the BackTestAccount and the TradeManager classes. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-----------|--------|------------------------------------------------| +| `restart` | `bool` | Whether to restart the data. Defaults to True. | -- `restart` _bool, optional_ - Whether to restart the data. Defaults to True. - - + #### next - ```python def next() -> Cursor ``` - Move the cursor to the next time step in the backtest range. - + #### data - ```python @property def data() ``` - The BackTestData instance used for the backtest. If not provided, a new instance is created, and the data is made persistent when the backtest is stopped. - + #### reset - ```python def reset(clear_data: bool = False) ``` +Reset the backtest engine. This is useful when restarting the backtest from the beginning. Clear trade data if any +when the `clear_data` parameter is true -Reset the backtest engine. This is useful when restarting the backtest from the beginning. - - - -#### go\_to + +#### go_to ```python def go_to(*, time: datetime | float) ``` - Move the cursor to a specific time in the backtest range. You can pass a datetime object or a timestamp. You can't go back in time or beyond the limits of the range. - - -#### fast\_forward + +#### fast_forward ```python def fast_forward(*, steps: int) ``` - Fast-forward the backtester by the given steps. - + #### tracker - ```python async def tracker() ``` - The tracker monitors and updates open positions on every iteration. It is called by the controller. - - -#### save\_result\_to\_json + +#### save_result_to_json ```python @error_handler_sync def save_result_to_json() ``` - Saves the result to a json file at the end of testing. - - -#### close\_all\_open + +#### close_all_open ```python async def close_all_open() ``` - Closes all open position at the end of testing - - -#### wrap\_up - + +#### wrap_up ```python @error_handler async def wrap_up() ``` +Wraps up the backtest. This is called at the end of testing to save the results and close all open positions. -Wraps up the backtest. This is called at the end of testing to save the results and close all open -positions. - - - -#### preload\_ticks + +#### preload_ticks ```python async def preload_ticks(*, symbol: str) ``` - Pull a month data on ticks from the terminal. Starting from the current time. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|----------------------------------| +| `symbol` | `str` | The symbol to preload ticks for. | -- `symbol` _str_ - The symbol to preload ticks for. - - - -#### get\_price\_tick + +#### get_price_tick ```python @async_cache async def get_price_tick(*, symbol: str, time: int) -> Tick | None ``` - Get the price tick for a symbol at a given time. If the preload option is set to True, it will use the preloaded ticks when available. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|---------------------------------------| +| `symbol` | `str` | The symbol to get the price tick for. | +| `time` | `int` | The time to get the price tick. | -- `symbol` _str_ - The symbol to get the price tick for. -- `time` _int_ - The time to get the price tick. - - - -#### check\_order + +#### check_order ```python @error_handler async def check_order(*, ticket: int) ``` - -" Check if the order has reached its take profit or stop loss levels and close the order if it has. -Checks only **OrderType.BUY** and **OrderType.SELL** orders that have reached their take profit or stop loss levels. +Checks only `OrderType.BUY` and `OrderType.SELL` orders that have reached their take profit or stop loss levels. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|--------------| +| `ticket` | `int` | Order ticket | -- `ticket` _int_ - Order ticket - - - -#### check\_account + +#### check_account ```python def check_account() ``` - Checks an account status. This method is called at each iteration to check if the account has burned out. - - -#### check\_position + +#### check_position ```python async def check_position(*, ticket: int) ``` - Update the profit of an open position based on the current price of the symbol. It is called by the tracker to update the profit of open positions. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|------------------| +| `ticket` | `int` | Position ticket | -- `ticket` _int_ - Position ticket - - - -#### close\_position\_manually + +#### close_position_manually ```python @error_handler_sync async def close_position_manually(*, ticket: int) ``` - Close a position manually without. Usually at the end of testing. - - -#### close\_position + +#### close_position ```python async def close_position(*, ticket: int) -> bool ``` - Close an open position for the trading account using the position ticket. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|------------------| +| `ticket` | `int` | Position ticket | -- `ticket` - Position ticket - +#### Returns: +| Type | Description | +|--------|--------------------------------------------------------------| +| `bool` | True if the position is closed successfully, False otherwise | -**Returns**: - -- `bool` - True if the position is closed successfully, False otherwise - - - -#### modify\_stops + +#### modify_stops ```python @error_handler(response=False) def modify_stops(*, ticket: int, sl: int, tp: int) -> bool ``` - Modify the stop loss and take profit levels of an open position. +#### Parameters: +| Name | Type | Description | +|----------|-------|------------------| +| `ticket` | `int` | Position ticket | +| `sl` | `int` | stop loss level | -**Arguments**: +#### Returns: +| Type | Description | +|--------|--------------------------------------------------------------| +| `bool` | True if the stops are modified successfully, False otherwise | -- `ticket` _int_ - Position ticket -- `sl` _int_ - stop loss level -- `tp` _int_ - Take profit level - - -**Returns**: - -- `bool` - True if the stops are modified successfully, False otherwise - - - -#### update\_account + +#### update_account ```python def update_account(*, profit: float = None, margin: float = 0, gain: float = 0) ``` - Update the account. This method is protected by thread lock. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|---------|--------------------------------------------------------------------------------| +| `profit` | `float` | The current profit of one or more open positions. Can be positive or negative. | +| `margin` | `float` | The margin set aside for a trade. It is released when the trade is closed. | +| `gain` | `gain` | The gain realized when the trade is closed. | -- `profit` _float_ - The current profit of one or more open positions. Can be positive or negative. -- `margin` _float_ - The margin set aside for a trade. It is released when the trade is closed. -- `gain` _gain_ - The gain realized when the trade is closed. - - + #### deposit - ```python def deposit(*, amount: float) ``` - Make deposit to the trading account - + #### withdraw - ```python def withdraw(*, amount: float) ``` - Make a withdrawal from the trading account. You can not withdraw more than what you have - - -#### setup\_account + +#### setup_account ```python @error_handler async def setup_account(**kwargs) ``` +Set up the trading account before the beginning of a backtesting session. -Setup the trading account before the begining of a backtesting session. +#### Parameters: +| Name | Type | Description | +|----------|------|-------------------------------------------------------------| +| `kwargs` | dict | Attributes for the backtest account object can be set here. | -**Arguments**: - - (**kwargs, Any): Attributes for the backetest account object can be set here. - - - -#### setup\_account\_sync + +#### setup_account_sync ```python @error_handler_sync def setup_account_sync(**kwargs) ``` - Set up the backtesting account in sync mode - + #### prices - ```python @cached_property def prices() -> dict[str, DataFrame] ``` - Get the prices for instruments used in the backtesting. This class is called when the use_terminal option is set to False and trading data is provided in the data attribute. It makes sure that there is a price for each symbol for every second covered in the backtesting range, by reindexing the price ticks using the backtesting @@ -506,597 +420,538 @@ time span and filling up missing data using the nearest method. This method returns a dictionaries of dataframe containing the prices for each symbol. It's cached and there computed only once per backtesting session. -**Returns**: +#### Returns: +| Type | Description | +|--------|--------------------------------------------------------------| +| `dict` | A dictionary mapping dataframe of prices to symbols. | - dict[str, DataFrame]: A dictionary mapping dataframe of prices to symbols. - - + #### ticks - ```python @cached_property def ticks() -> dict[str, DataFrame] ``` - Similar to prices above, but returns prices exactly as they are without reindexing and filling up. -**Returns**: +#### Returns: +| Type | Description | +|--------|--------------------------------------------------------------| +| `dict` | A dictionary mapping dataframe of prices to symbols. | - dict[str, DataFrame]: A dictionary mapping symbols to dataframes of ticks. - - + #### rates - ```python @cached_property def rates() -> dict[str, dict[int, DataFrame]] ``` - This property is useful when backtesting with the use_terminal option set to false. It returns a nested dict that maps symbols to a dict mapping timeframes to rates. The timeframes are mapped using their integer values. -**Returns**: +#### Returns: +| Type | Description | +|-----------------------------------|-------------------------------------------| +| `dict[str, dict[int, DataFrame]]` | A dictionary containing the symbol rates. | - dict[str, dict[int, DataFrame]]: A dictionary containing the symbol rates. - - + #### symbols - ```python @cached_property def symbols() -> dict[str, SymbolInfo] ``` - A dictionary of symbols and SymbolInfo object. Used when use_terminal is set to false. +#### Returns: +| Type | Description | +|-------------------------|------------------------------------------------| +| `dict[str, SymbolInfo]` | A dictionary of symbols and SymbolInfo object. | -**Returns**: - - dict[str, SymbolInfo] - - - -#### order\_send - + + +#### order_send ```python @error_handler async def order_send(*, request: dict, use_terminal=False) -> OrderSendResult ``` - Simulates the sending of an order to the broker. An OrderSendResult is object is created at the end of this operation as would be created if it was done in live trading. When an order is successful a positions object is -created, an order and deal object is created as well. When use_terminal is set to true the margin and profit -are calculated by sending to the broker. This increases accuracy but slows down the backtester. Check order is +created, an order and deal object is created as well. The margin and profit are calculated by sending to the broker +if `use_terminal` is true. This increases accuracy but slows down the backtester. The `check_order` method is called to make sure the order is valid and would go through if it was a live trade. -**Arguments**: +#### Parameters: -- `request` _dict_ - The order request as a dict. -- `use_terminal` _bool_ - A flag to override the use_terminal attribute. If true, the terminal will - be used even if the use_terminal attribute is True. - +| Name | Type | Description | +|----------------|------|-------------------------------------------------------------------------------------------------------------------------------| +| `request` | dict | The order request as a dict. | +| `use_terminal` | bool | A flag to override the use_terminal attribute. If true, the terminal will be used even if the use_terminal attribute is True. | -**Returns**: -- `OrderSendResult` - An object containing the result of the order send operation. +#### Returns: +| Type | Description | +|-------------------|--------------------------------------------------------------| +| `OrderSendResult` | An object containing the result of the order send operation. | - - -#### order\_check + +#### order_check ```python @error_handler -async def order_check(*, - request: dict, - use_terminal: bool = False) -> OrderCheckResult +async def order_check(*, request: dict, use_terminal: bool = False) -> OrderCheckResult ``` +Checks the order before placing it. If `use_terminal` is true, the order is checked with the broker, +but the entire result is not used. Details such as balance, profit, equity, margin, and margin level are calculated +by the backtester. -Checks the order before placing it. If use_terminal, the order is checked with the broker, but the entire result -is not used. Details such as balance, profit, equity, margin, and margin level are calculated by the backtester. +#### Parameters: +| Name | Type | Description | +|----------------|------|---------------------------------------------------------------------------------| +| `request` | dict | The order request as a dict. | +| `use_terminal` | bool | A flag to override the use_terminal attribute. If true, the terminal will used. | + -**Arguments**: +#### Returns: +| Type | Description | +|--------------------|--------------------------------| +| `OrderCheckResult` | The result of the order check. | -- `request` _dict_ - The order request as a dict. -- `use_terminal` _bool_ - A flag to override the use_terminal attribute. If true, the terminal will used. - - -**Returns**: - -- `OrderCheckResult` - The result of the order check. - - - -#### get\_terminal\_info + +#### get_terminal_info ```python @error_handler async def get_terminal_info() -> TerminalInfo ``` - Get the terminal information -**Returns**: +#### Returns: +| Type | Description | +|----------------|--------------------------| +| `TerminalInfo` | The terminal information | -- `TerminalInfo` - The terminal information - - - -#### get\_version + +#### get_version ```python @error_handler async def get_version() -> tuple[int, int, str] ``` - Get the version of the terminal. -**Returns**: - - tuple[int, int, str]: The version of the terminal - - - -#### get\_symbols\_total +#### Returns: +| Type | Description | +|------------------------|-----------------------------| +| `tuple[int, int, str]` | The version of the terminal | + + +#### get_symbols_total ```python @error_handler async def get_symbols_total() -> int ``` - Get the total number of symbols available in the terminal. -**Returns**: +#### Returns: +| Type | Description | +|------|------------------------------------------------| +| `int` | The total number of symbols available. | -- `int` - The total number of symbols available. - - - -#### get\_symbols + +#### get_symbols ```python @error_handler async def get_symbols(*, group: str = "") -> tuple[SymbolInfo, ...] ``` - Get the symbols available in the terminal. Filter by group if provided. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|------|------------------------------------------------| +| `group` | str | The group to filter by (default is "") | -- `group` _str_ - The group to filter by (default is "") - -**Returns**: +#### Returns: +| Type | Description | +|--------------------------|-------------------------------| +| `tuple[SymbolInfo, ...]` | A tuple of symbol information | - tuple[SymbolInfo, ...]: A tuple of symbol information - - - -#### get\_account\_info + +#### get_account_info ```python @error_handler_sync def get_account_info() -> AccountInfo ``` - Get the account information -**Returns**: +#### Returns: +| Type | Description | +|---------------|-------------------------| +| `AccountInfo` | The account information | -- `AccountInfo` - The account information - - - -#### get\_symbol\_info\_tick + +#### get_symbol_info_tick ```python @error_handler async def get_symbol_info_tick(*, symbol: str) -> Tick ``` - Get the price tick for a symbol at the current time -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|------|---------------------------------------| +| `symbol` | str | The symbol to get the price tick for. | -- `symbol` _str_ - The symbol +#### Returns: +| Type | Description | +|--------|----------------| +| `Tick` | The price tick | -**Returns**: - -- `Tick` - The price tick - - - -#### get\_symbol\_info + +#### get_symbol_info ```python @error_handler async def get_symbol_info(*, symbol: str) -> SymbolInfo ``` - Get the symbol information -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|------|---------------------------------------| +| `symbol` | str | The symbol to get information for | -- `symbol` _str_ - The symbol to get information for - -**Returns**: +#### Returns: +| Type | Description | +|--------------|------------------------| +| `SymbolInfo` | The symbol information | -- `SymbolInfo` - The symbol information - - - -#### get\_rates\_from + +#### get_rates_from ```python @error_handler -async def get_rates_from(*, symbol: str, timeframe: TimeFrame, - date_from: datetime | float, - count: int) -> np.ndarray +async def get_rates_from(*, symbol: str, timeframe: TimeFrame, date_from: datetime | float, count: int) -> np.ndarray ``` - Get rates from a specific date to the current date. Used by the backtester to get rates for a symbol -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|--------------------------------------| +| `symbol` | `str` | The symbol to get rates for | +| `timeframe` | `TimeFrame` | The timeframe of the rates | +| `date_from` | `datetime \| float` | The date from which to get the rates | +| `count` | `int` | The number of rates to get | -- `symbol` _str_ - The symbol to get rates for -- `timeframe` _TimeFrame_ - The timeframe of the rates -- `date_from` _datetime | float_ - The date from which to get the rates -- `count` _int_ - The number of rates to get - -**Returns**: +#### Returns: +| Type | Description | +|--------------|------------------------| +| `np.ndarray` | An array of rates | -- `np.ndarray` - An array of rates - - - -#### get\_rates\_from\_pos + +#### get_rates_from_pos ```python @error_handler -async def get_rates_from_pos(*, symbol: str, timeframe: TimeFrame, - start_pos: int, count: int) -> np.ndarray +async def get_rates_from_pos(*, symbol: str, timeframe: TimeFrame, start_pos: int, count: int) -> np.ndarray ``` - Get a number of rates counting from a specific position. With position zero being the current time. +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|--------------------------------------| +| `symbol` | `str` | The symbol to get rates for | +| `timeframe` | `TimeFrame` | The timeframe of the rates | +| `start_pos` | `int` | The position to start from | +| `count` | `int` | The number of rates to get | -**Arguments**: +#### Returns: +| Type | Description | +|--------------|------------------------| +| `np.ndarray` | An array of rates | -- `symbol` _str_ - The symbol to get rates for -- `timeframe` _TimeFrame_ - The timeframe of the rates -- `start_pos` _int_ - The position to start from -- `count` _int_ - The number of rates to get - - -**Returns**: - -- `np.ndarray` - An array of rates - - - -#### get\_rates\_range + +#### get_rates_range ```python @error_handler -async def get_rates_range(*, symbol: str, timeframe: TimeFrame, - date_from: datetime | float, +async def get_rates_range(*, symbol: str, timeframe: TimeFrame, date_from: datetime | float, date_to: datetime | float) -> np.ndarray ``` - Get rates within a specific date range. Used by the backtester to get rates for a symbol -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|--------------------------------------| +| `symbol` | `str` | The symbol to get rates for | +| `timeframe` | `TimeFrame` | The timeframe of the rates | +| `date_from` | `datetime \| float` | The date from which to get the rates | +| `date_to` | `datetime \| float` | The date to which to get the rates | -- `symbol` _str_ - The symbol to get rates for -- `timeframe` _TimeFrame_ - The timeframe of the rates -- `date_from` _datetime | float_ - The date from which to get the rates -- `date_to` _datetime | float_ - The date to which to get the rates - -**Returns**: +#### Returns: +| Type | Description | +|--------------|------------------------| +| `np.ndarray` | An array of rates | -- `np.ndarray` - An array of rates - - - -#### get\_ticks\_from + +#### get_ticks_from ```python @error_handler -async def get_ticks_from(*, - symbol: str, - date_from: datetime | float, - count: int, +async def get_ticks_from(*, symbol: str, date_from: datetime | float, count: int, flags: CopyTicks = CopyTicks.ALL) -> np.ndarray ``` - Get a specified number of ticks counting from a specific date. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|--------------------------------------| +| `symbol` | `str` | The symbol to get ticks for | +| `date_from` | `datetime \| float` | The date from which to get the ticks | +| `count` | `int` | The number of ticks to get | +| `flags` | `CopyTicks` | The flags to use when getting ticks | -- `symbol` _str_ - The symbol to get ticks for -- `date_from` _datetime | float_ - The date from which to get the ticks -- `count` _int_ - The number of ticks to get -- `flags` _CopyTicks_ - The flags to use when getting the ticks - +#### Returns: +| Type | Description | +|--------------|------------------------| +| `np.ndarray` | An array of ticks | -**Returns**: - -- `np.ndarray` - An array of ticks - - - -#### get\_ticks\_range + +#### get_ticks_range ```python @error_handler -async def get_ticks_range(*, - symbol: str, - date_from: datetime | float, - date_to: datetime | float, +async def get_ticks_range(*, symbol: str, date_from: datetime | float, date_to: datetime | float, flags: CopyTicks = CopyTicks.ALL) -> np.ndarray ``` - Get ticks within a specific date range. +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|--------------------------------------| +| `symbol` | `str` | The symbol to get ticks for | +| `date_from` | `datetime \| float` | The date from which to get the ticks | +| `date_to` | `datetime \| float` | The date to which to get the ticks | +| `flags` | `CopyTicks` | The flags to use when getting ticks | -**Arguments**: -- `symbol` _str_ - The symbol to get ticks for -- `date_from` _datetime | float_ - The date from which to get the ticks -- `date_to` _datetime | float_ - The date to which to get the ticks -- `flags` _CopyTicks_ - The flags to use when getting the ticks - +#### Returns: +| Type | Description | +|--------------|------------------------| +| `np.ndarray` | An array of ticks | -**Returns**: - -- `np.ndarray` - An array of ticks - - - -#### order\_calc\_margin + +#### order_calc_margin ```python @error_handler -async def order_calc_margin(*, - action: Literal[OrderType.BUY, OrderType.SELL], - symbol: str, - volume: float, - price: float, - use_terminal: bool = None) +async def order_calc_margin(*, action: Literal[OrderType.BUY, OrderType.SELL], symbol: str, volume: float, + price: float, use_terminal: bool = None) ``` - Calculate the margin required for a trade. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------------|------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------| +| `action` | `Literal[OrderType.BUY, OrderType.SELL]` | Type of order | +| `symbol` | `str` | Symbol name | +| `volume` | `float` | Volume of the trade | +| `price` | `float` | The price at which the trade is opened | +| `use_terminal` | `bool` | A flag to override the use_terminal attribute. If true, the terminal will be used even if the use_terminal attribute is True. | -- `action` _Literal[OrderType.BUY, OrderType.SELL]_ - Type of order -- `symbol` _str_ - Symbol name -- `volume` _float_ - Volume of the trade -- `price` _float_ - The price at which the trade is opened -- `use_terminal` _bool_ - A flag to override the use_terminal attribute. If true, the terminal will be used - even if the use_terminal attribute is True. - -**Returns**: +#### Returns: +| Type | Description | +|--------|------------------------------------| +| `float` | The margin required for the trade | -- `float` - The margin required for the trade - - - -#### order\_calc\_profit + +#### order_calc_profit ```python @error_handler -async def order_calc_profit(*, - action: Literal[OrderType.BUY, OrderType.SELL], - symbol: str, - volume: float, - price_open: float, - price_close: float, - use_terminal=None) +async def order_calc_profit(*, action: Literal[OrderType.BUY, OrderType.SELL], symbol: str, volume: float, + price_open: float, price_close: float, use_terminal=None) ``` - Calculate the profit for a trade. +#### Parameters: +| Name | Type | Description | +|----------------|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| +| `action` | `Literal[OrderType.BUY, OrderType.SELL]` | Type of order | +| `symbol` | `str` | Symbol name | +| `volume` | `float` | Volume of the trade | +| `price_open` | `float` | The price at which the trade is opened | +| `price_close` | `float` | The price at which the trade is closed | +| `use_terminal` | `bool` | A flag to override the use_terminal attribute. If true, the terminal will be used even if the `use_terminal` attribute is True. | -**Arguments**: +#### Returns: +| Type | Description | +|---------|-------------------------| +| `float` | The profit of the trade | -- `action` _Literal[OrderType.BUY, OrderType.SELL]_ - Type of order -- `symbol` _str_ - Symbol name -- `volume` _float_ - Volume of the trade -- `price_open` _float_ - The price at which the trade is opened -- `price_close` _float_ - The price at which the trade is closed -- `use_terminal` _bool_ - A flag to override the use_terminal attribute. If true, the terminal will be used - even if the use_terminal attribute is True. - - -**Returns**: - -- `float` - The profit of the trade - - - -#### get\_orders\_total + +#### get_orders_total ```python @error_handler_sync def get_orders_total() -> int ``` - Get the total number of pending orders. -**Returns**: +#### Returns: +| Type | Description | +|-------|--------------------------------| +| `int` | Total number of pending orders | -- `int` - Total number of pending orders - - - -#### get\_orders + +#### get_orders ```python @error_handler_sync -def get_orders(*, - symbol: str = "", - group: str = "", - ticket: int = None) -> tuple[TradeOrder, ...] +def get_orders(*, symbol: str = "", group: str = "", ticket: int = None) -> tuple[TradeOrder, ...] ``` - Get pending orders from the terminal history. This has to do with pending orders, which this backtester doesn't support yet. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|--------------| +| `symbol` | `str` | Symbol name | +| `group` | `str` | Group name | +| `ticket` | `int` | Order ticket | -- `symbol` - Symbol name -- `group` - Group name -- `ticket` - Order ticket - +#### Returns: +| Type | Description | +|--------------------------|----------------| +| `tuple[TradeOrder, ...]` | Pending orders | -**Returns**: - - tuple[TradeOrder, ...]: Pending orders - - - -#### get\_positions\_total + +#### get_positions_total ```python @error_handler_sync def get_positions_total() -> int ``` - Get the total number of open positions. -**Returns**: +#### Returns: +| Type | Description | +|-------|--------------------------------| +| `int` | Total number of open positions | -- `int` - Total number of open positions - - - -#### get\_positions + +#### get_positions ```python @error_handler_sync -def get_positions(*, - symbol: str = None, - group: str = None, - ticket: int = None) -> tuple[TradePosition, ...] +def get_positions(*, symbol: str = None, group: str = None, ticket: int = None) -> tuple[TradePosition, ...] ``` - Get open positions from the terminal history. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|-----------------| +| `symbol` | `str` | Symbol name | +| `group` | `str` | Group name | +| `ticket` | `int` | Position ticket | -- `symbol` - The symbol name -- `group` - Group argument to filter by -- `ticket` - Position ticket - +#### Returns: +| Type | Description | +|--------------------------|----------------| +| `tuple[TradePosition, ...]` | Open positions | -**Returns**: - - tuple[TradePosition, ...]: Open positions - - - -#### get\_history\_orders\_total + +#### get_history_orders_total ```python @error_handler_sync -def get_history_orders_total(*, date_from: datetime | float, - date_to: datetime | float) -> int +def get_history_orders_total(*, date_from: datetime | float, date_to: datetime | float) -> int ``` - Get the total number of orders in the terminal history. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|---------------------------------------| +| `date_from` | `datetime \| float` | The start date of the history | +| `date_to` | `datetime \| float` | The end date of the history | -- `date_from` - The start date of the history - -- `date_to` - The end date of the history - +#### Returns: +| Type | Description | +|-------|--------------------------------| +| `int` | Total number of orders in the history | -**Returns**: - -- `int` - Total number of orders in the history - - - -#### get\_history\_orders + +#### get_history_orders ```python @error_handler_sync -def get_history_orders(*, - date_from: datetime | float = None, - date_to: datetime | float = None, - group: str = "", - ticket: int = None, - position: int = None) -> tuple[TradeOrder, ...] +def get_history_orders(*, date_from: datetime | float = None, date_to: datetime | float = None, group: str = "", + ticket: int = None, position: int = None) -> tuple[TradeOrder, ...] ``` - Get orders from the terminal history. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|---------------------------------------| +| `date_from` | `datetime \| float` | Date from which to start the history | +| `date_to` | `datetime \| float` | Date to which to end the history | +| `group` | `str` | group keyword to filter by | +| `ticket` | `int` | ticket id to filter by | +| `position` | `int` | position id to filter by | -- `date_from` - Date from which to start the history -- `date_to` - Date to which to end the history -- `group` - group keyword to filter by -- `ticket` - ticket id to filter by -- `position` - position id to filter by - -**Returns**: +#### Returns: +| Type | Description | +|--------------------------|-----------------------| +| `tuple[TradeOrder, ...]` | Orders in the history | - tuple[TradeOrder, ...]: Orders in the history - - - -#### get\_history\_deals\_total + +#### get_history_deals_total ```python @error_handler_sync -def get_history_deals_total(*, date_from: datetime | float, - date_to: datetime | float) -> int +def get_history_deals_total(*, date_from: datetime | float, date_to: datetime | float) -> int ``` - Get the total number of deals in the terminal history. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|--------------------------------------| +| `date_from` | `datetime \| float` | Date from which to start the history | +| `date_to` | `datetime \| float` | Date to which to end the history | -- `date_from` - Date from which to start the history -- `date_to` - Date to which to end the history - -**Returns**: +#### Returns: +| Type | Description | +|-------|--------------------------------------| +| `int` | Total number of deals in the history | -- `int` - Total number of deals in the history - - - -#### get\_history\_deals + +#### get_history_deals ```python @error_handler_sync -def get_history_deals(*, - date_from: datetime | float = None, - date_to: datetime | float = None, - group: str = None, - position: int = None, - ticket: int = None) -> tuple[TradeDeal, ...] +def get_history_deals(*, date_from: datetime | float = None, date_to: datetime | float = None, group: str = None, + position: int = None, ticket: int = None) -> tuple[TradeDeal, ...] ``` - Get deals from the terminal history. -**Arguments**: - -- `date_from` - Date from which to start the history -- `date_to` - Date to which to end the history -- `group` - group keyword to filter by -- `position` - position id to filter by -- `ticket` - ticket id to filter by - - -**Returns**: - - tuple[TradeDeal, ...]: Deals in the history +#### Parameters: +| Name | Type | Description | +|-------------|---------------------|---------------------------------------| +| `date_from` | `datetime \| float` | Date from which to start the history | +| `date_to` | `datetime \| float` | Date to which to end the history | +| `group` | `str` | group keyword to filter by | +| `position` | `int` | position id to filter by | +| `ticket` | `int` | ticket id to filter by | +#### Returns: +| Type | Description | +|-------------------------|----------------------| +| `tuple[TradeDeal, ...]` | Deals in the history | diff --git a/docs/core/backtesting/get_data.md b/docs/core/backtesting/get_data.md index 11f6d3b..89a2748 100644 --- a/docs/core/backtesting/get_data.md +++ b/docs/core/backtesting/get_data.md @@ -1,185 +1,162 @@ -# Table of Contents +# Get Data -* [get\_data](#get_data) - * [Cursor](#get_data.Cursor) - * [BackTestData](#get_data.BackTestData) - * [set\_attrs](#get_data.BackTestData.set_attrs) - * [fields](#get_data.BackTestData.fields) - * [GetData](#get_data.GetData) - * [\_\_init\_\_](#get_data.GetData.__init__) - * [pickle\_data](#get_data.GetData.pickle_data) - * [load\_data](#get_data.GetData.load_data) - * [save\_data](#get_data.GetData.save_data) - * [get\_data](#get_data.GetData.get_data) +## Table of Contents - +- [Cursor](#get_data.cursor) +- [BackTestData](#get_data.back_test_data) + - [set_attrs](#get_data.back_test_data.set_attrs) + - [fields](#get_data.back_test_data.fields) +- [GetData](#get_data.getdata) + - [\__init\__](#get_data.get_data.__init__) + - [pickle_data](#get_data.pickle_data) + - [load_data](#get_data.load_data) + - [save_data](#get_data.save_data) + - [get_data](#get_data.get_data) -# get\_data - - - -## Cursor Objects + +### Cursor ```python class Cursor(NamedTuple) ``` +A cursor to iterate over the data. Marks the current position in time. -A cursor to iterate over the data. Marks the current position. - - - -## BackTestData Objects + +### BackTestData ```python @dataclass -class BackTestData() +class BackTestData ``` - The data class to store the backtesting data. -**Attributes**: +#### Attributes: +| Name | Type | Description | +|------------------|----------|------------------------------------------------| +| `name` | `str` | The name of the backtest data | +| `terminal` | `dict` | The terminal information | +| `version` | `tuple` | The version of the terminal | +| `account` | `dict` | The account information | +| `symbols` | `dict` | The symbols information | +| `ticks` | `dict` | The ticks data | +| `rates` | `dict` | The rates data | +| `span` | `range` | The range of the data | +| `range` | `range` | The range of the data | +| `orders` | `dict` | The orders data | +| `deals` | `dict` | The deals data | +| `positions` | `dict` | The positions data | +| `open_positions` | `set` | The open positions | +| `cursor` | `Cursor` | The cursor to iterate over the data | +| `margins` | `dict` | The margins data | +| `fully_loaded` | `bool` | A flag to indicate if the data is fully loaded | -- `name` _str_ - The name of the backtest data. -- `terminal` _dict_ - The terminal information. -- `version` _tuple_ - The version of the terminal. -- `account` _dict_ - The account information. -- `symbols` _dict_ - The symbols information. -- `ticks` _dict_ - The ticks data. -- `rates` _dict_ - The rates data. -- `span` _range_ - The range of the data. -- `range` _range_ - The range of the data. -- `orders` _dict_ - The orders data. -- `deals` _dict_ - The deals data. -- `positions` _dict_ - The positions data. -- `open_positions` _set_ - The open positions. -- `cursor` _Cursor_ - The cursor to iterate over the data. -- `margins` _dict_ - The margins data. -- `fully_loaded` _bool_ - A flag to indicate if the data is fully loaded - - - -#### set\_attrs + +#### set_attrs ```python def set_attrs(**kwargs) ``` - Set the attributes of the class on the instance. - + #### fields - ```python @property def fields() ``` - A list of the fields of the class. - - -## GetData Objects + +### GetData ```python -class GetData() +class GetData ``` - A class to get the backtesting data from the MetaTrader5 terminal. -**Attributes**: +#### Attributes: +| Name | Type | Description | +|--------------|-----------------------|---------------------------------------| +| `start` | `datetime` | The start date of the data | +| `end` | `datetime` | The end date of the data | +| `symbols` | `Iterable[str]` | The symbols to get the data for | +| `timeframes` | `Iterable[TimeFrame]` | The timeframes to get the data for | +| `name` | `str` | The name of the backtest data | +| `range` | `range` | The range of the data | +| `span` | `range` | The span of the data | +| `data` | `BackTestData` | The backtesting data | +| `mt5` | `MetaTrader` | The MetaTrader5 instance | +| `task_queue` | `TaskQueue` | The task queue to handle the requests | -- `start` _datetime_ - The start date of the data. -- `end` _datetime_ - The end date of the data. -- `symbols` _Sequence[str]_ - The symbols to get the data for. -- `timeframes` _Sequence[TimeFrame]_ - The timeframes to get the data for. -- `name` _str_ - The name of the backtest data. -- `range` _range_ - The range of the data. -- `span` _range_ - The span of the data. -- `data` _BackTestData_ - The backtesting data. -- `mt5` _MetaTrader_ - The MetaTrader5 instance. -- `task_queue` _TaskQueue_ - The task queue to handle the requests. - - - -#### \_\_init\_\_ + +#### \__init\__ ```python -def __init__(*, - start: datetime, - end: datetime, - symbols: Sequence[str], - timeframes: Sequence[TimeFrame], - name: str = "") +def __init__(*, start: datetime, end: datetime, symbols: Sequence[str], + timeframes: Sequence[TimeFrame], name: str = "") ``` - Get the backtesting data from the MetaTrader5 terminal. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|--------------|-----------------------|------------------------------------------------| +| `start` | `datetime` | The start date of the data | +| `end` | `datetime` | The end date of the data | +| `symbols` | `Sequence[str]` | The symbols to get the data for | +| `timeframes` | `Sequence[TimeFrame]` | The timeframes to get the data for | +| `name` | `str` | The name of the backtest data | -- `start` _datetime_ - The start date of the data. -- `end` _datetime_ - The end date of the data. -- `symbols` _Sequence[str]_ - The symbols to get the data for. -- `timeframes` _Sequence[TimeFrame]_ - The timeframes to get the data for. -- `name` _str_ - The name of the backtest data. - - - -#### pickle\_data + +#### pickle_data ```python @classmethod def pickle_data(cls, *, data: BackTestData, name: str | Path) ``` - Pickle the data to a file. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|--------|-------------------------|----------------------| +| `data` | `BackTestData` | The data to pickle | +| `name` | `str \| Path` | The name of the file | -- `data` _BackTestData_ - The data to pickle. -- `name` _str | Path_ - The name of the file to pickle the data to. - - - -#### load\_data + +#### load_data ```python @classmethod def load_data(cls, *, name: str | Path) -> BackTestData ``` - Load the data from a file. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|--------|-------------------------|----------------------| +| `name` | `str \| Path` | The name of the file | -- `name` _str | Path_ - The name of the file to load the data from. - - - -#### save\_data + +#### save_data ```python def save_data(*, name: str | Path = "") ``` - Save the data to a file. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|--------|-------------------------|----------------------| +| `name` | `str \| Path` | The name of the file | -- `name` _str | Path_ - The name of the file to save the data to. If not provided, the name of the data is used. - - - -#### get\_data + +#### get_data ```python async def get_data(workers: int = None) ``` - Use the task queue to get the data from the MetaTrader5 terminal. - -**Arguments**: - -- `workers` _int_ - The number of workers to use in the task queue. If not provided, the default number of workers - is used. - +#### Parameters: +| Name | Type | Description | +|-----------|-------|------------------------------------------------| +| `workers` | `int` | The number of workers to use in the task queue | diff --git a/docs/core/backtesting/trades_manager.md b/docs/core/backtesting/trades_manager.md index 46b8e1f..a0b903f 100644 --- a/docs/core/backtesting/trades_manager.md +++ b/docs/core/backtesting/trades_manager.md @@ -1,410 +1,374 @@ -# Table of Contents +# TradesManager -* [trades\_manager](#trades_manager) - * [TradeManager](#trades_manager.TradeManager) - * [update](#trades_manager.TradeManager.update) - * [values](#trades_manager.TradeManager.values) - * [keys](#trades_manager.TradeManager.keys) - * [items](#trades_manager.TradeManager.items) - * [to\_dict](#trades_manager.TradeManager.to_dict) - * [PositionsManager](#trades_manager.PositionsManager) - * [\_\_init\_\_](#trades_manager.PositionsManager.__init__) - * [margin](#trades_manager.PositionsManager.margin) - * [close](#trades_manager.PositionsManager.close) - * [get\_margin](#trades_manager.PositionsManager.get_margin) - * [delete\_margin](#trades_manager.PositionsManager.delete_margin) - * [set\_margin](#trades_manager.PositionsManager.set_margin) - * [positions\_get](#trades_manager.PositionsManager.positions_get) - * [positions\_total](#trades_manager.PositionsManager.positions_total) - * [open\_positions](#trades_manager.PositionsManager.open_positions) - * [OrdersManager](#trades_manager.OrdersManager) - * [get\_orders\_range](#trades_manager.OrdersManager.get_orders_range) - * [history\_orders\_get](#trades_manager.OrdersManager.history_orders_get) - * [history\_orders\_total](#trades_manager.OrdersManager.history_orders_total) - * [DealsManager](#trades_manager.DealsManager) - * [get\_deals\_range](#trades_manager.DealsManager.get_deals_range) - * [history\_deals\_get](#trades_manager.DealsManager.history_deals_get) - * [history\_deals\_total](#trades_manager.DealsManager.history_deals_total) +## Table of Contents +- [trades_manager](#trades_manager.trades_manager) + - [TradesManager](#trades_manager.trades_manager) + - [update](#trades_manager.trade_manager.update) + - [values](#trades_manager.trade_manager.values) + - [keys](#trades_manager.trade_manager.keys) + - [items](#trades_manager.trade_manager.items) + - [to_dict](#trades_manager.trade_manager.to_dict) + - [PositionsManager](#trades_manager.positions_manager) + - [\__init\__](#positions_manager.__init__) + - [margin](#positions_manager.margin) + - [close](#positions_manager.close) + - [get_margin](#positions_manager.get_margin) + - [delete_margin](#positions_manager.delete_margin) + - [set_margin](#positions_manager.set_margin) + - [positions_get](#positions_manager.positions_get) + - [positions_total](#positions_manager.positions_total) + - [open_positions](#positions_manager.open_positions) + - [OrdersManager](#trades_manager.orders_manager) + - [get_orders_range](#orders_manager.get_orders_range) + - [history_orders_get](#orders_manager.history_orders_get) + - [history_orders_total](#orders_manager.history_orders_total) + - [DealsManager](#trades_manager.deals_manager) + - [get_deals_range](#deals_manager.get_deals_range) + - [history_deals_get](#deals_manager.history_deals_get) + - [history_deals_total](#deals_manager.history_deals_total) - - -# trades\_manager - - - -## TradeManager Objects + +### TradesManager ```python class TradeManager(Generic[TradeData]) ``` - A generic class to manage trades data during a backtest. It is the parent class of the PositionsManager, OrdersManager, and DealsManager. It implements some dict-like methods to manage the data. It has a private attribute _data to store the data. It exposes the data through the values, keys, and items methods. -It also has a to_dict method to convert the data to a dictionary. +It also has a `to_dict` method to convert the data to a dictionary. -**Attributes**: +#### Parameters: +| Name | Type | Description | +|---------|------------------------|------------------------------| +| `_data` | `dict[int, TradeData]` | The data to store the trades | -- `_data` _dict[int, TradeData]_ - The data to store the trades. + +#### Examples: +```python +>>> manager = TradeManager() +>>> manager[123456] = TradePosition(ticket=123456, symbol="EURUSD", volume=0.1) +>>> manager.update(ticket=123456, symbol="EURUSD", volume=0.1) +>>> manager[123456] +TradePosition(ticket=123456, symbol='EURUSD', volume=0.1) +>>> manager.values() +(TradePosition(ticket=123456, symbol='EURUSD', volume=0.1),) +>>> manager.keys() +(123456,) +>>> manager.items() +((123456, TradePosition(ticket=123456, symbol='EURUSD', volume=0.1)),) +>>> manager.to_dict() +{'123456' - {'ticket': 123456, 'symbol': 'EURUSD', 'volume': 0.1}} +>>> pos = manager.get(123456) +>>> pos +TradePosition(ticket=123456, symbol='EURUSD', volume=0.1) +>>> pos in manager +True +>>> len(manager) +1 +>>> pos in manager +False +``` - -**Examples**: - - >>> manager = TradeManager() - >>> manager[123456] = TradePosition(ticket=123456, symbol="EURUSD", volume=0.1) - >>> manager.update(ticket=123456, symbol="EURUSD", volume=0.1) - >>> manager[123456] - TradePosition(ticket=123456, symbol='EURUSD', volume=0.1) - >>> manager.values() - (TradePosition(ticket=123456, symbol='EURUSD', volume=0.1),) - >>> manager.keys() - (123456,) - >>> manager.items() - ((123456, TradePosition(ticket=123456, symbol='EURUSD', volume=0.1)),) - >>> manager.to_dict() -- `{123456` - {'ticket': 123456, 'symbol': 'EURUSD', 'volume': 0.1}} - >>> pos = manager.get(123456) - >>> pos - TradePosition(ticket=123456, symbol='EURUSD', volume=0.1) - >>> pos in manager - True - >>> len(manager) - 1 - >>> pos in manager - False - - - + #### update - ```python def update(*, ticket: int, **kwargs) ``` - Update the data of a trade. Given the ticket of the trade and the new data to update. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|------------|-------|------------------------------------| +| `ticket` | `int` | The ticket of the trade to update. | +| `**kwargs` | | The new data to update. | -- `ticket` _int_ - The ticket of the trade to update. -- `**kwargs` - The new data to update. - - - -#### values + +### values ```python def values() -> tuple[TradeData, ...] ``` - Returns the values of the data. - - -#### keys + +### keys ```python def keys() -> tuple[int, ...] ``` - Returns the keys of the data. - - -#### items + +### items ```python def items() -> tuple[tuple[int, TradeData], ...] ``` - Returns the items of the data. - - -#### to\_dict + +### to_dict ```python def to_dict() ``` - Convert the data to a dictionary. - - -## PositionsManager Objects + ```python class PositionsManager(TradeManager) ``` - -A class to manage the open positions during a backtest. It is a subclass of TradeManager. It has an additional +A class to manage the open positions during a backtest. It is a subclass of It has an additional attribute _open_positions to store the open positions. It also has a margins attribute to store the margins of the open positions. It overrides some methods of the TradeManager class to manage the open positions. -**Attributes**: - -- `_open_positions` _set[int]_ - The open positions. -- `margins` _dict[int, float]_ - The margins of the open positions. - - - -#### \_\_init\_\_ +#### Attributes: +| Name | Type | Description | +|------------------|--------------------|--------------------------------------------------------------------------------------------------------------------------| +| `data` | `dict` | The data to store the trades. This used for continuation of the backtesting, if it was stopped with some open positions. | +| `open_positions` | `set[int]` | The open positions. | +| `margins` | `dict[int, float]` | The margins of the open positions. | + + +#### \__init\__ ```python -def __init__(*, - data: dict = None, - open_positions: set[int] = None, - margins: dict = None) +def __init__(*, data: dict = None, open_positions: set[int] = None, margins: dict = None) ``` - -Positions manager manages the open positions during a backtest. It is a subclass of TradeManager. It has an +Positions manager manages the open positions during a backtest. It is a subclass of It has an additional attribute _open_positions to store the open positions. It also has a margins attribute to store the margins of the open positions. It overrides some methods of the TradeManager class to manage the open positions. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|------------------|--------------------|--------------------------------------------------------------------------------------------------------------------------| +| `data` | `dict` | The data to store the trades. This used for continuation of the backtesting, if it was stopped with some open positions. | +| `open_positions` | `set[int]` | The open positions. | +| `margins` | `dict[int, float]` | The margins of the open positions. | -- `data` _dict, optional_ - The data to store the trades. This used for continuation of the backtesting, if it - was stopped with some open positions. - -- `open_positions` _set, optional_ - The open positions. Defaults to None. - -- `margins` _dict, optional_ - The margins of the open positions. Defaults to None. - - - -#### margin + +### margin ```python @property def margin() ``` - Returns the total margin of all open positions - - -#### close + +### close ```python def close(*, ticket: int) -> bool ``` - Close a position. Given the ticket of the position to close. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|--------------------------------------| +| `ticket` | `int` | The ticket of the position to close. | -- `ticket` _int_ - The ticket of the position to close. - - - -#### get\_margin + +#### get_margin ```python def get_margin(*, ticket: int) -> float ``` - Get the margin of a position. Given the ticket of the position. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|-----------------------------| +| `ticket` | `int` | The ticket of the position. | -- `ticket` _int_ - The ticket of the position. - -**Returns**: +#### Returns: +| Type | Description | +|---------|-----------------------------| +| `float` | The margin of the position. | -- `float` - The margin of the position. - - - -#### delete\_margin + +### delete_margin ```python def delete_margin(*, ticket: int) ``` - Delete the margin of a position. Given the ticket of the position. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|-----------------------------| +| `ticket` | `int` | The ticket of the position. | -- `ticket` _int_ - The ticket of the position. - - - -#### set\_margin + +### set_margin ```python def set_margin(*, ticket: int, margin: float) ``` - Set the margin of a position. Given the ticket of the position and the margin. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|---------|-----------------------------| +| `ticket` | `int` | The ticket of the position. | +| `margin` | `float` | The margin of the position. | -- `ticket` _int_ - The ticket of the position. -- `margin` _float_ - The margin of the position - - - -#### positions\_get + +### positions_get ```python -def positions_get(*, - ticket: int = None, - symbol: str = None, - group: None = None) -> tuple[TradePosition, ...] +def positions_get(*, ticket: int = None, symbol: str = None, group: None = None) -> tuple[TradePosition, ...] ``` - Get positions. Given the ticket, symbol, or group of the positions. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|-----------------------------| +| `ticket` | `int` | The ticket of the position. | +| `symbol` | `str` | The symbol of the position. | +| `group` | `str` | The group of the position. | -- `ticket` _int_ - The ticket of the position. -- `symbol` _str_ - The symbol of the position. -- `group` _str_ - The group - +#### Returns: +| Type | Description | +|------------------------|-----------------------------| +| `tuple[TradePosition]` | The positions. | -**Returns**: +#### Returns: +| Type | Description | +|-----------------------------|-----------------------------| +| `tuple[TradePosition, ...]` | The positions. | - tuple[TradePosition, ...]: The positions - - - -#### positions\_total + +### positions_total ```python def positions_total() -> int ``` - Get the total number of open positions. -**Returns**: +#### Returns: +| Type | Description | +|-------|-------------------------------------| +| `int` | The total number of open positions. | -- `int` - The total number of open positions. - - - -#### open\_positions + +#### open_positions ```python @property def open_positions() -> tuple[TradePosition, ...] ``` - Returns the open positions. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|----------|-------|-----------------------------| +| `ticket` | `int` | The ticket of the position. | - tuple[TradePosition, ...]: The open positions. - - - -## OrdersManager Objects + +### OrdersManager ```python class OrdersManager(TradeManager) ``` - -Managers orders data during a backtest. It is a subclass of TradeManager. It manages access to the historical +Managers orders data during a backtest. It is a subclass of It manages access to the historical orders data - - -#### get\_orders\_range + +#### get_orders_range ```python -def get_orders_range(*, date_from: float, - date_to: float) -> tuple[TradeData, ...] +def get_orders_range(*, date_from: float, date_to: float) -> tuple[TradeData, ...] ``` - Get orders within a date range. Given the start and end date of the range. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------|------------------------------| +| `date_from` | `float` | The start date of the range. | +| `date_to` | `float` | The end date of the range. | -- `date_from` _float_ - The start date of the range. -- `date_to` _float_ - The end date of the range. - +#### Returns: +| Type | Description | +|--------------------|-----------------------------------| +| `tuple[TradeData]` | The orders within the date range. | + -**Returns**: +#### Returns: +| Type | Description | +|--------------------|-----------------------------------| +| `tuple[TradeData]` | The orders within the date range. | - tuple[TradeData, ...]: The orders within the date range. - - - -#### history\_orders\_get + +#### history_orders_get ```python -def history_orders_get(*, - date_from: float | datetime = None, - date_to: float | datetime = None, - group: str = "", - ticket: int = None, - position: int = None) -> tuple[TradeOrder, ...] +def history_orders_get(*, date_from: float | datetime = None, date_to: float | datetime = None, + group: str = "", ticket: int = None, position: int = None) -> tuple[TradeOrder, ...] ``` - Get historical orders. Given the start and end date of the range, the group, ticket, or position of the orders. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------|------------------------------| +| `date_from` | `float` | The start date of the range. | +| `date_to` | `float` | The end date of the range. | +| `group` | `str` | The group of the orders. | +| `ticket` | `int` | The ticket of the order. | +| `position` | `int` | The position of the order. | -- `date_from` _float, datetime_ - The start date of the range. -- `date_to` _float, datetime_ - The end date of the range. -- `group` _str_ - The group of the orders. -- `ticket` _int_ - The ticket of the order. -- `position` _int_ - The position of the order. - +#### Returns: +| Type | Description | +|---------------------|------------------------| +| `tuple[TradeOrder]` | The historical orders. | -**Returns**: - - tuple[TradeOrder, ...]: The historical orders. - - - -#### history\_orders\_total + +### history_orders_total ```python def history_orders_total(*, date_from: datetime | float, date_to: datetime | float) -> int ``` - Get the total number of historical orders. Given the start and end date of the range. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------|------------------------------| +| `date_from` | `float` | The start date of the range. | +| `date_to` | `float` | The end date of the range. | -- `date_from` _datetime, float_ - The start date of the range. -- `date_to` _datetime, float_ - The end date of the range. - - - -## DealsManager Objects + +### DealsManager ```python class DealsManager(TradeManager) ``` - - -#### get\_deals\_range - + +#### get_deals_range ```python -def get_deals_range(*, date_from: float, - date_to: float) -> tuple[TradeData, ...] +def get_deals_range(*, date_from: float, date_to: float) -> tuple[TradeData, ...] ``` - Get deals within a date range. Given the start and end date of the range. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------|------------------------------| +| `date_from` | `float` | The start date of the range. | +| `date_to` | `float` | The end date of the range. | -- `date_from` _float_ - The start date of the range. -- `date_to` _float_ - The end date of the range. - +#### Returns: +| Type | Description | +|--------------------|-----------------------------------| +| `tuple[TradeData]` | The deals within the date range. | -**Returns**: - - tuple[TradeData, ...]: The deals within the date range. - - - -#### history\_deals\_get + +### history_deals_get ```python def history_deals_get(*, date_from: float | datetime = None, @@ -413,35 +377,33 @@ def history_deals_get(*, ticket: int = None, position: int = None) -> tuple[TradeDeal, ...] ``` - History deals get. Given the start and end date of the range, the group, ticket, or position of the deals. -**Arguments**: +#### Parameters: +| Name | Type | Description | +|-------------|---------|------------------------------| +| `date_from` | `float` | The start date of the range. | +| `date_to` | `float` | The end date of the range. | +| `group` | `str` | The group of the deals. | +| `ticket` | `int` | The ticket of the deal. | +| `position` | `int` | The position of the deal. | -- `date_from` _float, datetime_ - The start date of the range. -- `date_to` _float, datetime_ - The end date of the range. -- `group` _str_ - The group of the deals. -- `ticket` _int_ - The ticket of the deal. -- `position` _int_ - The position of the deal. - - - -#### history\_deals\_total + +#### history_deals_total ```python def history_deals_total(*, date_from: datetime | float, date_to: datetime | float) -> int ``` - Get the total number of historical deals. Given the start and end date of the range -**Arguments**: - -- `date_from` _datetime, float_ - The start date of the range. -- `date_to` _datetime, float_ - The end date of the range. - - -**Returns**: - -- `int` - The total number of historical deals. +#### Parameters: +| Name | Type | Description | +|-------------|---------|------------------------------| +| `date_from` | `float` | The start date of the range. | +| `date_to` | `float` | The end date of the range. | +#### Returns: +| Type | Description | +|-------|---------------------------------------| +| `int` | The total number of historical deals. | diff --git a/docs/core/config.md b/docs/core/config.md index 6b40cc3..3b85f7c 100644 --- a/docs/core/config.md +++ b/docs/core/config.md @@ -1,72 +1,111 @@ # Config ## Table of Contents -- [Config](#config.Config) -- [account\_info](#config.account_info) -- [load\_config](#config.load_config) -- [create\_records\_dir](#config.create_records_dir) +- [Config](#config.config) +- [account_info](#config.account_info) +- [backtest_engine](#config.backtest_engine) +- [set_attributes](#config.set_attributes) +- [load_config](#config.load_config) - + ```python class Config ``` -A class for handling configuration settings for the aiomql package. A single instance of this class is created and used -per bot instance. -### Class Attributes -| Name | Type | Description | Default | -|------------------|--------------|-----------------------------------------------------|-----------------------------------------------------| -| `record\_trades` | `bool` | Whether to keep record of trades or not. | True | -| `filename` | `str` | Name of the config file | aiomql.json | -| `records\_dir` | `str\| Path` | Path to the directory where trade records are saved | Should be relative to the project root | -| `login` | `str` | Trading account number | | -| `password` | `str` | Trading account password | | -| `server` | `str` | Broker server | | -| `path` | `str\|Path` | Path to terminal file | Absolute | -| `timeout` | `int` | Timeout for terminal connection | | -| `config_dir` | `str` | Directory where the config file is located | Optional. Should be relative to the root directory | -| `state` | `dict` | A global state object | | -| `task_queue` | `Queue` | A global queue for handling tasks | | -| `bot` | `Bot` | The bot instance | Added to the config object after bot initialization | -| `root_dir` | `str` | Root directory of the project | | +The global config object. It is a singleton class for handling configuration settings for the aiomql package. +A single instance of this class is created and used per bot instance. + +#### Attributes: +| Name | Type | Description | +|--------------------------------|-------------------------------|-------------------------------------------------------------------------| +| `login` | `int` | The account login number | +| `trade_record_mode` | `Literal["csv", "json"]` | The mode for recording trades | +| `password` | `str` | The account password | +| `server` | `str` | The account server | +| `path` | `str \| Path` | The path to the terminal | +| `timeout` | `int` | The timeout argument for the terminal | +| `filename` | `str` | The filename of the config file | +| `state` | `dict` | The state of the configuration | +| `root` | `Path` | The root directory of the project | +| `record_trades` | `bool` | To record trades or not. Default is True | +| `records_dir` | `Path` | The directory to store trade records, relative to the root directory | +| `records_dir_name` | `str` | The name of the trade records directory | +| `backtest_dir` | `Path` | The directory to store backtest results, relative to the root directory | +| `backtest_dir_name` | `str` | The name of the backtest directory | +| `task_queue` | `TaskQueue` | The TaskQueue object for handling background tasks | +| `_backtest_engine` | `BackTestEngine` | The backtest engine object | +| `bot` | `Bot` | The bot object | +| `_instance` | `Self` | The instance of the Config class | +| `mode` | `Literal["backtest", "live"]` | The trading mode, either backtest or live, default is live | +| `use_terminal_for_backtesting` | `bool` | Use the terminal for backtesting, default is True | +| `shutdown` | `bool` | A signal to shut down the terminal, default is False | +| `force_shutdown` | `bool` | A signal to force shut down the terminal, default is False | + +#### Notes: +By default, the config class looks for a file named aiomql.json. This can be changed by setting the filename +attribute to the desired file name. The root directory of the project can be set by passing the root argument +to the load_config method or during object instantiation. If not provided it is assumed to be the current working +directory. All directories and files are assumed to be relative to the root directory except when an absolute path +is provided, this includes the config file, the records_dir and the backtest_dir attributes. +The root directory is used to locate the config file and to set the records_dir and backtest_dir attributes. -#### Notes -By default, the config class looks for a file named aiomql.json. -You can change this by passing the filename keyword argument to the constructor. -By passing reload=True to the load_config method, you can reload and search again for the config file. -### account\_info +### account_info ```python def account_info() -> dict['login', 'password', 'server'] ``` Returns Account login details as found in the config object if available -#### Returns -| Type | Description | -|--------|-------------------------------------------------------| -| `dict` | A dictionary with login, password, and server details | + +#### Returns: +| Type | Description | +|---------------------------------------|-------------------------------------------------------| +| `dict['login', 'password', 'server']` | A dictionary with login, password, and server details | + + +### backtest_engine +```python +@property +def backtest_engine(self) +``` +Returns the backtest engine object. + +#### Returns: +| Type | Description | +|-----------------|------------------------| +| `BackTestEngine` | The backtest engine object | + + + +```python +@backtest_engine.setter +def backtest_engine(self, value: BackTestEngine) +``` +Sets the backtest engine object. + +#### Parameters: +| Name | Type | Description | +|---------|------------------|----------------------------| +| `value` | `BackTestEngine` | The backtest engine object | + + +### set_attributes +```python +def set_attributes(self, **kwargs) +``` +Set attributes on the config object. The root folder attribute can't be set here. -### load\_config +### load_config ```python -def load_config(self, *, file: str = None, reload: bool = True, filename: str = None, config_dir: str = '') +def load_config(*, file: str | Path = None, filename: str = None, root: str | Path = None, **kwargs) -> Config ``` -Load configuration settings from a file. -#### Parameters -| Name | Type | Description | -|--------------|--------|-------------------------------------------------------------------------------------------------------------| -| `file` | `str` | The file to load the configuration settings from. If not provided, the default file is used. | -| `reload` | `bool` | Whether to reload the configuration settings or not. | -| `filename` | `str` | The name of the file to load the configuration settings from. If not provided, the default filename is used | -| `config_dir` | `str` | The directory where the configuration file is located. Default is the root directory | +Load configuration settings from a file and reset the config object. - -### create_records_dir -```python -def create_records_dir(self, *, records_dir: str | Path = 'records'): -``` -Create a directory for saving trade records. -#### Parameters -| Name | Type | Description | -|----------------|-------------|-------------------------------------------------------------------| -| `records\_dir` | `str\|Path` | The directory where trade records are saved. Default is 'records' | +#### Parameters: +| Name | Type | Description | +|------------|---------------|----------------------------------------------------------------------------------------------------| +| `file` | `str \| Path` | The absolute path to the config file. | +| `filename` | `str` | The name of the file to load if file path is not specified. If not provided `aiomql.json` is used. | +| `root` | `str` | The root directory of the project. | +| `**kwargs` | `dict` | Additional keyword arguments to be set on the config object. | diff --git a/docs/core/constants.md b/docs/core/constants.md index 98e516a..6155c93 100644 --- a/docs/core/constants.md +++ b/docs/core/constants.md @@ -9,8 +9,9 @@ MetaTrader 5 constants defined as Enums. - [opposite](#ordertype.opposite) - [BookType](#BookType) - [TimeFrame](#TimeFrame) - - [time](#timeframe.time) - - [get](#timeframe.get) + - [get_timeframe](#timeframe.get_timeframe) + - [seconds](#timeframe.seconds) + - [all](#timeframe.all) - [CopyTicks](#CopyTicks) - [PositionType](#PositionType) - [PositionReason](#PositionReason) @@ -156,41 +157,43 @@ TIMEFRAME Enum. | `W1` | 604800 | One Week | | `MN1` | 2592000 | One Month | - -### get -```python -@classmethod - def get(cls, time: int) -> 'TimeFrame': -``` -Gets the TIMEFRAME enum value from a time in seconds -#### Parameters -| Name | Type | Description | -|-------|------|----------------------| -| time | int | The time in seconds | -#### Returns -| Type | Description | -|------------|--------------------------------------| -| TimeFrame | The TIMEFRAME enum value | - -### time + +### seconds ```python @property -def time() +def seconds() -> int ``` The number of seconds in a TIMEFRAME -#### Returns -| Type | Description | -|------|--------------------------------------| -| int | The number of seconds in a TIMEFRAME | - -### Example + +#### get_timeframe ```python -t = TimeFrame.H1 -print(t.seconds) # 3600 +@property +def get_timeframe() ``` +Get a timeframe object from a time value in seconds + +#### Returns: +| Type | Description | +|-----------|-----------------------------| +| TimeFrame | The corresponding timeframe | + + + +#### all +```python +@classmethod +def all() +``` +Get all the timeframes + +#### Returns: +| Type | Description | +|-----------------------|-----------------------------| +| tuple[TimeFrame, ...] | All the timeframes | + ## CopyTicks diff --git a/docs/core/errors.md b/docs/core/errors.md index 0c8872b..ec4f9e3 100644 --- a/docs/core/errors.md +++ b/docs/core/errors.md @@ -1,21 +1,24 @@ # Errors ## Tabel of contents -- [Error](#errors.Error) +- [Error](#errors.error) - [is_connection_error](#errors.is_connection_error) - + + ## Error ```python -class Error() +class Error ``` -Error class for handling errors from MetaTrader 5. -#### Attributes -| Name | Type | Description | -|----------------|--------|----------------------------------------------| -| `code` | `int` | Error code | -| `description` | `str` | Error description | -| `descriptions` | `dict` | A dictionary of error codes and descriptions | +Error class for handling errors. + +#### Attributes: +| Name | Type | Description | +|----------------|--------------|----------------------------------------------| +| `code` | `int` | Error code | +| `description` | `str` | Error description | +| `descriptions` | `dict` | A dictionary of error codes and descriptions | +| `conn_errors` | `tuple[int]` | A tuple of connection errors | @@ -23,8 +26,9 @@ Error class for handling errors from MetaTrader 5. ```python def is_connection_error(self) -> bool ``` -Check if error is a connection error. -#### Returns +Check if an error is a connection error. + +#### Returns: | Type | Description | |--------|------------------------------------------------------| -| `bool` | True if error is a connection error, False otherwise | \ No newline at end of file +| `bool` | True if error is a connection error, False otherwise | diff --git a/docs/core/exceptions.md b/docs/core/exceptions.md index f62e14a..f3d6ea1 100644 --- a/docs/core/exceptions.md +++ b/docs/core/exceptions.md @@ -2,36 +2,48 @@ Exceptions for the aiomql package. ## Table of Contents -- [LoginError](#exceptions.LoginError) -- [VolumeError](#exceptions.VolumeError) -- [SymbolError](#exceptions.SymbolError) -- [OrderError](#exceptions.OrderError) +- [LoginError](#exceptions.login_error) +- [VolumeError](#exceptions.volume_error) +- [SymbolError](#exceptions.symbol_error) +- [OrderError](#exceptions.order_error) +- [StopTradingError](#exceptions.stop_trading_error) - + ### LoginError ```python class LoginError(Exception) ``` Raised when an error occurs when logging in. - + + ### VolumeError ```python class VolumeError(Exception) ``` Raised when a volume is not valid or out of range for a symbol. - + + ### SymbolError ```python class SymbolError(Exception) ``` Raised when a symbol is not provided where required or not available in the Market Watch. - + + ### OrderError ```python class OrderError(Exception) ``` -Raised when an error occurs when working with the order class. \ No newline at end of file +Raised when an error occurs when working with the order class. + + + +### StopTradingError +```python +class StopTradingError(Exception) +``` +Raised when an error occurs when trying to stop trading. diff --git a/docs/core/meta_backtester.md b/docs/core/meta_backtester.md new file mode 100644 index 0000000..7a009e1 --- /dev/null +++ b/docs/core/meta_backtester.md @@ -0,0 +1,47 @@ +# MetaBackTester + +## Table of Contents +- [MetaBackTester](#metabacktester) +- [\__init\__](#metabacktester.__init__) +- [backtest_engine](#metabacktester.backtest_engine) +- [backtest_engine.setter](#metabacktester.backtest_engine.setter) + + + +### MetaBackTester +```python +class MetaBackTester(MetaTrader) +``` +A class for testing trading strategies in the MetaTrader 5 terminal. A subclass of MetaTrader. + +#### Attributes: +| Name | Type | Description | +|-------------------|------------------|---------------------------------------------------------------| +| `backtest_engine` | `BackTestEngine` | The backtesting engine to use for testing trading strategies. | + + + +### \__init\__ +```python +def __init__(self, *, backtest_engine: BackTestEngine = None) +``` + +#### Parameters: +| Name | Type | Description | +|-------------------|------------------|--------------------------------------------------| +| `backtest_engine` | `BackTestEngine` | The backtesting engine to use for testing trades | + + +```python +@property +def backtest_engine(self) -> BackTestEngine +``` +Returns the backtest engine object. + + + +```python +@backtest_engine.setter +def backtest_engine(self, value: BackTestEngine): +``` +Sets the backtest engine object. diff --git a/docs/core/models.md b/docs/core/models.md index bf14070..64fbd94 100644 --- a/docs/core/models.md +++ b/docs/core/models.md @@ -1,68 +1,71 @@ # Models -This module contains the models used in the aiomql package. These models are used to represent the data returned from the MetaTrader 5 terminal. -They are all subclasses of the `Base` class. + +This module contains the models used in the aiomql package. These models are used to represent the data returned from +the MetaTrader 5 terminal. They are all subclasses of the `Base` class. ## Table of Contents -- [AccountInfo](#AccountInfo) -- [TerminalInfo](#TerminalInfo) -- [SymbolInfo](#SymbolInfo) -- [BookInfo](#BookInfo) -- [TradeOrder](#TradeOrder) -- [TradeRequest](#TradeRequest) -- [OrderCheckResult](#OrderCheckResult) -- [OrderSendResult](#OrderSendResult) -- [TradePosition](#TradePosition) -- [TradeDeal](#TradeDeal) +- [AccountInfo](#models.account_info) +- [TerminalInfo](#models.terminal_info) +- [SymbolInfo](#models.symbol.info) +- [BookInfo](#models.book_info) +- [TradeOrder](#models.trade_order) +- [TradeRequest](#models_trade_request) +- [OrderCheckResult](#models.order_check_result) +- [OrderSendResult](#models.order_send_result) +- [TradePosition](#models.trade_position) +- [TradeDeal](#models.trade_deal) - -## AccountInfo + + +### AccountInfo ```python class AccountInfo(Base) ``` Account Information Class. -#### Attributes -| Name | Type | Description | Default | -|----------------------|--------------------|------------------------------------------|---------| -| `login` | `int` | Account number | | -| `password` | `str` | Account password | | -| `server` | `str` | Trade server name | | -| `trade_mode` | AccountTradeMode | Trade mode | | -| `balance` | `float` | Account balance | | -| `leverage` | `float` | Account leverage | | -| `profit` | `float` | Account profit | | -| `point` | `float` | Point size | | -| `amount` | `float` | Account amount | 0 | -| `equity` | `float` | Account equity | | -| `credit` | `float` | Account credit | | -| `margin` | `float` | Account margin | | -| `margin_level` | `float` | Margin level | | -| `margin_free` | `float` | Free margin | | -| `margin_mode` | AccountMarginMode | Margin calculation mode | | -| `margin_so_mode` | AccountStopoutMode | Stop out mode | | -| `margin_so_call` | `float` | Margin call level | | -| `margin_so_so` | `float` | Stop out level | | -| `margin_initial` | `float` | Initial margin | | -| `margin_maintenance` | `float` | Maintenance margin | | -| `fifo_close` | `bool` | FIFO close flag | | -| `limit_orders` | `float` | Limit orders | | -| `currency` | `str` | Account currency | "USD" | -| `trade_allowed` | `bool` | Trade allowed flag | True | -| `trade_expert` | `bool` | Trade expert flag | True | -| `currency_digits` | `int` | Number of digits after the decimal point | | -| `assets` | `float` | Assets | | -| `liabilities` | `float` | Liabilities | | -| `commission_blocked` | `float` | Blocked commission | | -| `name` | `str` | Account name | | -| `company` | `str` | Company name | | +#### Attributes: +| Name | Type | Description | Default | +|----------------------|----------------------|------------------------------------------|---------| +| `login` | `int` | Account number | | +| `password` | `str` | Account password | | +| `server` | `str` | Trade server name | | +| `trade_mode` | AccountTradeMode | Trade mode | | +| `balance` | `float` | Account balance | | +| `leverage` | `float` | Account leverage | | +| `profit` | `float` | Account profit | | +| `point` | `float` | Point size | | +| `amount` | `float` | Account amount | 0 | +| `equity` | `float` | Account equity | | +| `credit` | `float` | Account credit | | +| `margin` | `float` | Account margin | | +| `margin_level` | `float` | Margin level | | +| `margin_free` | `float` | Free margin | | +| `margin_mode` | `AccountMarginMode` | Margin calculation mode | | +| `margin_so_mode` | `AccountStopoutMode` | Stop out mode | | +| `margin_so_call` | `float` | Margin call level | | +| `margin_so_so` | `float` | Stop out level | | +| `margin_initial` | `float` | Initial margin | | +| `margin_maintenance` | `float` | Maintenance margin | | +| `fifo_close` | `bool` | FIFO close flag | | +| `limit_orders` | `float` | Limit orders | | +| `currency` | `str` | Account currency | "USD" | +| `trade_allowed` | `bool` | Trade allowed flag | True | +| `trade_expert` | `bool` | Trade expert flag | True | +| `currency_digits` | `int` | Number of digits after the decimal point | | +| `assets` | `float` | Assets | | +| `liabilities` | `float` | Liabilities | | +| `commission_blocked` | `float` | Blocked commission | | +| `name` | `str` | Account name | | +| `company` | `str` | Company name | | - -## TerminalInfo + + +### TerminalInfo ```python class TerminalInfo(Base) ``` Terminal information class. Holds information about the terminal. -#### Attributes +#### Attributes: | Name | Type | Description | Default | |-------------------------|---------|----------------------------|---------| | `community_account` | `bool` | Community account flag | | @@ -88,13 +91,14 @@ Terminal information class. Holds information about the terminal. | `data_path` | `str` | Data path | | | `commondata_path` | `str` | Common data path | | - -## SymbolInfo + + +### SymbolInfo ```python class SymbolInfo(Base) ``` Symbol Information Class. Symbols are financial instruments available for trading in the MetaTrader 5 terminal. -#### Attributes +#### Attributes: | Name | Type | Description | Default | |------------------------------|------------------------|----------------------------|---------| | `name` | `str` | Symbol name | | @@ -195,13 +199,14 @@ Symbol Information Class. Symbols are financial instruments available for tradin | `page` | `str` | Page | | | `path` | `str` | Path | | - -## BookInfo + + +### BookInfo ```python class BookInfo(Base) ``` Book Information Class. -#### Attributes +#### Attributes: | Name | Type | Description | Default | |--------------|------------|-------------|---------| | `symbol` | `str` | Symbol | | @@ -210,13 +215,15 @@ Book Information Class. | `volume` | `float` | Volume | | | `volume_dbl` | `float` | Volume dbl | | - -## TradeOrder + + +#### TradeOrder ```python class TradeOrder(Base) ``` Trade Order Class. -#### Attributes + +#### Attributes: | Name | Type | Description | Default | |-------------------|----------------|-----------------|---------| | `ticket` | `int` | Ticket | | @@ -244,13 +251,14 @@ Trade Order Class. | `comment` | `str` | Comment | | | `external_id` | `str` | External id | | - + + ## TradeRequest ```python class TradeRequest(Base) ``` Trade Request Class. -#### Attributes +#### Attributes: | Name | Type | Description | Default | |----------------|--------------|--------------|---------| | `action` | TradeAction | Action | | @@ -272,13 +280,14 @@ Trade Request Class. | `magic` | `int` | Magic | | | `deviation` | `int` | Deviation | | - -## OrderCheckResult + + +### OrderCheckResult ```python class OrderCheckResult(Base) ``` Order Check Result -#### Attributes +#### Attributes: | Name | Type | Description | Default | |----------------|----------------|--------------|---------| | `retcode` | `int` | Retcode | | @@ -291,14 +300,15 @@ Order Check Result | `comment` | `str` | Comment | | | `request` | `TradeRequest` | Request | | - -## OrderSendResult + + +### OrderSendResult ```python class OrderSendResult(Base) ``` Order Send Result -#### Attributes +#### Attributes: | Name | Type | Description | Default | |--------------------|----------------|------------------|---------| | `retcode` | `int` | Retcode | | @@ -314,13 +324,14 @@ Order Send Result | `retcode_external` | `int` | Retcode external | | | `profit` | `float` | Profit | | - -## TradePosition + + +### TradePosition ```python class TradePosition(Base) ``` Trade Position -#### Attributes +#### Attributes: | Name | Type | Description | Default | |-------------------|------------------|-----------------|---------| | `ticket` | `int` | Ticket | | @@ -343,13 +354,14 @@ Trade Position | `comment` | `str` | Comment | | | `external_id` | `str` | External id | | - -## TradeDeal + + +### TradeDeal ```python class TradeDeal(Base) ``` Trade Deal -#### Attributes +#### Attributes: | Name | Type | Description | Default | |---------------|--------------|-------------|---------| | `ticket` | `int` | Ticket | | diff --git a/docs/lib/account.md b/docs/lib/account.md index 5e0a11b..9ba4c5f 100644 --- a/docs/lib/account.md +++ b/docs/lib/account.md @@ -1,11 +1,11 @@ # Account ## Table of Contents -- [Account](#account.Account) +- [Account](#account.account) - [refresh](#account.refresh) - + ### Account ```python class Account(_Base, AccountInfo) @@ -13,11 +13,12 @@ class Account(_Base, AccountInfo) A singleton class for managing a trading account. A subclass of _Base and AccountInfo. It supports asynchronous context management protocol. -#### Attributes +#### Attributes: | Name | Type | Description | Default | |-------------|-------------------|------------------------------------------------------|---------| | `connected` | `bool` | Status of connection to MetaTrader 5 Terminal | False | + ### refresh ```python diff --git a/docs/lib/bot.md b/docs/lib/bot.md index 8415289..da2c839 100644 --- a/docs/lib/bot.md +++ b/docs/lib/bot.md @@ -1,7 +1,7 @@ # Bot ## Table of Contents -- [Bot](#bot.Bot) +- [Bot](#bot.bot) - [\_\_init\_\_](#bot.init) - [initialize](#bot.initialize) - [execute](#bot.execute) @@ -13,14 +13,14 @@ - [add_strategy_all](#bot.add_strategy_all) - [process_pool](#bot.run_bots) - + ### Bot ```python class Bot ``` """The bot class. Create a bot instance to run strategies. -#### Attributes. +#### Attributes: | Name | Type | Description | Default | |--------------|--------------------|--------------------------------------------|--------------| | `account` | `Account` | Account Object. | None | @@ -30,12 +30,13 @@ class Bot | `config` | `Config` | A Config instance | Config() | -### \_\_init\_\_ +### \__init\__ ```python def __init__() ``` Initializes the Bot class. + ### initialize ```python @@ -52,7 +53,6 @@ Note: *initialize_sync* is a synchronous version of this method. | `SystemExit` | If sign in was not successful | - ### execute ```python @@ -61,6 +61,7 @@ def execute() Executes the bot. Use this method to run the bot in a synchronous manner. This method is blocking and will not return until the bot is done running. + ### start ```python @@ -68,13 +69,14 @@ async def start() ``` Initialize the bot and execute it. Similar to calling **execute** method but is asynchronous. + ### add_coroutine ```python def add_coroutine(self, coroutine: Coroutine, on_separate_thread=False, **kwargs) ``` Add a coroutine to the executor. By default, all coroutines added to the executor run on this same thread, -using _asyncio.gather_, but if _on_separate_thread_ is true then the coroutine is given it's own thread. +using `asyncio.gather`, but if `on_separate_thread` is true then the coroutine is given it's own thread. #### Parameters: | Name | Type | Description | @@ -83,6 +85,7 @@ using _asyncio.gather_, but if _on_separate_thread_ is true then the coroutine i | `on_separate_thread` | `bool` | Run coroutine on a separate thread in the executor | | `kwargs` | `Any` | Keyword arguments to pass to the coroutine | + ### add_function ```python @@ -95,6 +98,7 @@ Add a function to the executor. | `function` | `Callable` | A function to run in the executor | | `kwargs` | `Any` | Keyword arguments to pass to the function | + ### add_strategy ```python @@ -107,23 +111,27 @@ Add a strategy to the list of strategies. |------------|------------|-----------------------------------| | `strategy` | `Strategy` | A Strategy instance to run on bot | + ### add_strategies ```python def add_strategies(strategies: Iterable[Strategy]) ``` Add multiple strategies at the same time + #### Parameters: | Name | Type | Description | |--------------|----------------------|-----------------------------------| | `strategies` | `Iterable[Strategy]` | An iterable of Strategy instances | + ### add_strategy_all ```python def add_strategy_all(*, strategy: Type[Strategy], params: dict | None = None, symbols: list[Symbol] = None, **kwargs) ``` Use this to run a single strategy on multiple symbols with the same parameters and keyword arguments. + #### Parameters: | Name | Type | Description | |------------|------------------|---------------------------------------------| diff --git a/docs/lib/utils.md b/docs/lib/utils.md deleted file mode 100644 index af921db..0000000 --- a/docs/lib/utils.md +++ /dev/null @@ -1,66 +0,0 @@ -# Utils -Utils is a collection of utility functions that are used throughout the codebase. It is a collection of functions. - -## Table of Contents -- [round_off](#round_off) -- [find_bearish_fractal](#find_bearish_fractal) -- [find_bullish_fractal](#find_bullish_fractal) -- [dict_to_string](#dict_to_string) - - -```python -def round_off(value: float, step: float, round_down: bool = True) -> float: -``` -Rounds off a value to the nearest step. If round_down is True, it will round down, otherwise it will round up. -#### Parameters -| Name | Type | Description | Default | -|------------|-------|--------------------------------------------|---------| -| value | float | The value to round off. | | -| step | float | The step to round off to. | | -| round_down | bool | Whether to round down. If False, round up. | True | -#### Returns -| Type | Description | -|-------|------------------------| -| float | The rounded off value. | - -```python -def find_bearish_fractal(candles: Candles) -> Candle | None: -``` -Finds the most recent bearish fractal in the candles. -#### Parameters -| Name | Type | Description | Default | -|---------|---------|----------------------------------|---------| -| candles | Candles | The candles to search for. | | -#### Returns -| Type | Description | -|--------|----------------------------------| -| Candle | The most recent bearish fractal. | - -```python -def find_bullish_fractal(candles: Candles) -> Candle | None: -``` -Finds the most recent bullish fractal in the candles. -#### Parameters -| Name | Type | Description | Default | -|---------|---------|----------------------------------|---------| -| candles | Candles | The candles to search for. | | -#### Returns -| Type | Description | -|--------|----------------------------------| -| Candle | The most recent bullish fractal. | - - -```python -def dict_to_string(data: dict, multi=True) -> str: -``` -Converts a dictionary to a string. If multi is True, it will return a multi-line string. -#### Parameters -| Name | Type | Description | Default | -|-------|------|----------------------------------------|---------| -| data | dict | The dictionary to convert to a string. | | -| multi | bool | Whether to return a multi-line string. | True | - -#### Returns -| Type | Description | -|------|-----------------------------| -| str | The dictionary as a string. | diff --git a/src/aiomql/core/backtesting/get_data.py b/src/aiomql/core/backtesting/get_data.py index da30d2a..61ff7ff 100644 --- a/src/aiomql/core/backtesting/get_data.py +++ b/src/aiomql/core/backtesting/get_data.py @@ -3,7 +3,7 @@ import pickle from pathlib import Path from datetime import datetime, UTC from logging import getLogger -from typing import Sequence, NamedTuple +from typing import NamedTuple, Iterable import MetaTrader5 from numpy import ndarray @@ -95,8 +95,8 @@ class GetData: """ data: BackTestData - def __init__(self, *, start: datetime, end: datetime, symbols: Sequence[str], - timeframes: Sequence[TimeFrame], name: str = ""): + def __init__(self, *, start: datetime, end: datetime, symbols: Iterable[str], + timeframes: Iterable[TimeFrame], name: str = ""): """ Get the backtesting data from the MetaTrader5 terminal. diff --git a/src/aiomql/core/config.py b/src/aiomql/core/config.py index de44b87..9429712 100644 --- a/src/aiomql/core/config.py +++ b/src/aiomql/core/config.py @@ -39,10 +39,12 @@ class Config: force_shutdown (bool): A signal to force shut down the terminal, default is False Notes: - By default, the config class looks for a file named aiomql.json. - You can change this by passing the filename and/or the config_dir keyword argument(s) to the constructor - or the load_config method. - By passing reload=True to the load_config method, you can reload and search again for the config file. + By default, the config class looks for a file named aiomql.json. This can be changed by setting the filename + attribute to the desired file name. The root directory of the project can be set by passing the root argument + to the load_config method or during object instantiation. If not provided it is assumed to be the current working + directory. All directories and files are assumed to be relative to the root directory except when an absolute path + is provided, this includes the config file, the records_dir and the backtest_dir attributes. + The root directory is used to locate the config file and to set the records_dir and backtest_dir attributes. """ login: int trade_record_mode: Literal["csv", "json"] @@ -113,13 +115,13 @@ class Config: self._backtest_engine = value def set_attributes(self, **kwargs): - """Set keyword arguments as object attributes, The root folder attribute can't be set here. + """Set keyword arguments as object attributes. The root folder attribute can't be set here. Args: **kwargs: Object attributes and values as keyword arguments """ if kwargs.pop("root", None) is not None: - logger.warning("Tried setting root from set_attributes. Use load_config to change project root") + logger.debug("Tried setting root from set_attributes. Use load_config to change project root") [setattr(self, key, value) for key, value in kwargs.items()] @staticmethod @@ -149,7 +151,7 @@ class Config: return def load_config(self, *, file: str | Path = None, filename: str = None, root: str | Path = None, **kwargs) -> Self: - """Load configuration settings from a file. + """Load configuration settings from a file and reset the config object. Args: file (str | Path): The absolute path to the config file. diff --git a/src/aiomql/core/errors.py b/src/aiomql/core/errors.py index 56d0116..5e868e1 100644 --- a/src/aiomql/core/errors.py +++ b/src/aiomql/core/errors.py @@ -1,5 +1,5 @@ class Error: - """Error class for handling errors from MetaTrader 5.""" + """Error class for handling errors""" descriptions = { # common errors