bbstrader 2.0.3__cp312-cp312-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bbstrader/__init__.py +27 -0
- bbstrader/__main__.py +92 -0
- bbstrader/api/__init__.py +96 -0
- bbstrader/api/handlers.py +245 -0
- bbstrader/api/metatrader_client.cpython-312-darwin.so +0 -0
- bbstrader/api/metatrader_client.pyi +624 -0
- bbstrader/assets/bbs_.png +0 -0
- bbstrader/assets/bbstrader.ico +0 -0
- bbstrader/assets/bbstrader.png +0 -0
- bbstrader/assets/qs_metrics_1.png +0 -0
- bbstrader/btengine/__init__.py +54 -0
- bbstrader/btengine/backtest.py +358 -0
- bbstrader/btengine/data.py +737 -0
- bbstrader/btengine/event.py +229 -0
- bbstrader/btengine/execution.py +287 -0
- bbstrader/btengine/performance.py +408 -0
- bbstrader/btengine/portfolio.py +393 -0
- bbstrader/btengine/strategy.py +588 -0
- bbstrader/compat.py +28 -0
- bbstrader/config.py +100 -0
- bbstrader/core/__init__.py +27 -0
- bbstrader/core/data.py +628 -0
- bbstrader/core/strategy.py +466 -0
- bbstrader/metatrader/__init__.py +48 -0
- bbstrader/metatrader/_copier.py +720 -0
- bbstrader/metatrader/account.py +865 -0
- bbstrader/metatrader/broker.py +418 -0
- bbstrader/metatrader/copier.py +1487 -0
- bbstrader/metatrader/rates.py +495 -0
- bbstrader/metatrader/risk.py +667 -0
- bbstrader/metatrader/trade.py +1692 -0
- bbstrader/metatrader/utils.py +402 -0
- bbstrader/models/__init__.py +39 -0
- bbstrader/models/nlp.py +932 -0
- bbstrader/models/optimization.py +182 -0
- bbstrader/scripts.py +665 -0
- bbstrader/trading/__init__.py +33 -0
- bbstrader/trading/execution.py +1159 -0
- bbstrader/trading/strategy.py +362 -0
- bbstrader/trading/utils.py +69 -0
- bbstrader-2.0.3.dist-info/METADATA +396 -0
- bbstrader-2.0.3.dist-info/RECORD +45 -0
- bbstrader-2.0.3.dist-info/WHEEL +5 -0
- bbstrader-2.0.3.dist-info/entry_points.txt +3 -0
- bbstrader-2.0.3.dist-info/licenses/LICENSE +21 -0
bbstrader/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simplified Investment & Trading Toolkit with Python & C++
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__author__ = "Bertin Balouki SIMYELI"
|
|
7
|
+
__copyright__ = "2023-2026 Bertin Balouki SIMYELI"
|
|
8
|
+
__email__ = "bertin@bbs-trading.com"
|
|
9
|
+
__license__ = "MIT"
|
|
10
|
+
|
|
11
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
__version__ = version("bbstrader")
|
|
15
|
+
except PackageNotFoundError:
|
|
16
|
+
__version__ = "unknown"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
from bbstrader import compat # noqa: F401
|
|
20
|
+
from bbstrader import core # noqa: F401
|
|
21
|
+
from bbstrader import btengine # noqa: F401
|
|
22
|
+
from bbstrader import metatrader # noqa: F401
|
|
23
|
+
from bbstrader import models # noqa: F401
|
|
24
|
+
from bbstrader import trading # noqa: F401
|
|
25
|
+
from bbstrader.config import config_logger # noqa: F401
|
|
26
|
+
|
|
27
|
+
version = __version__
|
bbstrader/__main__.py
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import multiprocessing
|
|
3
|
+
import sys
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
import pyfiglet
|
|
7
|
+
from colorama import Fore
|
|
8
|
+
from loguru import logger
|
|
9
|
+
|
|
10
|
+
from bbstrader.scripts import backtest, copy_trades, execute_strategy, send_news_feed
|
|
11
|
+
|
|
12
|
+
from . import __author__, __version__
|
|
13
|
+
|
|
14
|
+
logger.remove()
|
|
15
|
+
|
|
16
|
+
custom_format = "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | <white>{message}</white>"
|
|
17
|
+
|
|
18
|
+
logger.add(sys.stdout, level="DEBUG", format=custom_format, colorize=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class _Module(Enum):
|
|
22
|
+
COPIER = "copier"
|
|
23
|
+
BACKTEST = "backtest"
|
|
24
|
+
EXECUTION = "execution"
|
|
25
|
+
NEWS_FEED = "news_feed"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
FONT = pyfiglet.figlet_format("BBSTRADER", font="big")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def main() -> None:
|
|
32
|
+
DESCRIPTION = "BBSTRADER"
|
|
33
|
+
USAGE_TEXT = """
|
|
34
|
+
Usage:
|
|
35
|
+
python -m bbstrader --run <module> [options]
|
|
36
|
+
|
|
37
|
+
Modules:
|
|
38
|
+
copier: Copy trades from one MetaTrader account to another or multiple accounts
|
|
39
|
+
backtest: Backtest a strategy, see bbstrader.btengine.backtest.run_backtest
|
|
40
|
+
execution: Execute a strategy, see bbstrader.trading.execution.Mt5ExecutionEngine
|
|
41
|
+
news_feed: Send news feed from Coindesk to Telegram channel
|
|
42
|
+
|
|
43
|
+
python -m bbstrader --run <module> --help for more information on the module
|
|
44
|
+
"""
|
|
45
|
+
print(Fore.BLUE + FONT)
|
|
46
|
+
print(Fore.WHITE + "")
|
|
47
|
+
parser = argparse.ArgumentParser(
|
|
48
|
+
prog="BBSTRADER",
|
|
49
|
+
usage=USAGE_TEXT,
|
|
50
|
+
description=DESCRIPTION,
|
|
51
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
52
|
+
add_help=False,
|
|
53
|
+
)
|
|
54
|
+
parser.add_argument("--run", type=str, nargs="?", default=None, help="Run a module")
|
|
55
|
+
args, unknown = parser.parse_known_args()
|
|
56
|
+
if ("-h" in sys.argv or "--help" in sys.argv) and args.run is None:
|
|
57
|
+
print(Fore.WHITE + USAGE_TEXT)
|
|
58
|
+
sys.exit(0)
|
|
59
|
+
if "-v" in sys.argv or "--version" in sys.argv:
|
|
60
|
+
print(Fore.GREEN + f"bbstrader version {__version__}")
|
|
61
|
+
print(Fore.WHITE + f"bbstrader maintained and supported by {__author__}")
|
|
62
|
+
sys.exit(0)
|
|
63
|
+
try:
|
|
64
|
+
match args.run:
|
|
65
|
+
case _Module.COPIER.value:
|
|
66
|
+
copy_trades(unknown)
|
|
67
|
+
case _Module.BACKTEST.value:
|
|
68
|
+
backtest(unknown)
|
|
69
|
+
case _Module.EXECUTION.value:
|
|
70
|
+
execute_strategy(unknown)
|
|
71
|
+
case _Module.NEWS_FEED.value:
|
|
72
|
+
send_news_feed(unknown)
|
|
73
|
+
case _:
|
|
74
|
+
print(Fore.RED + f"Unknown module: {args.run}")
|
|
75
|
+
sys.exit(1)
|
|
76
|
+
except KeyboardInterrupt:
|
|
77
|
+
sys.exit(0)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print(Fore.RED + f"Error: {e}")
|
|
80
|
+
sys.exit(1)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
multiprocessing.freeze_support()
|
|
85
|
+
try:
|
|
86
|
+
main()
|
|
87
|
+
except KeyboardInterrupt:
|
|
88
|
+
print(Fore.RED + "\nExecution interrupted by user")
|
|
89
|
+
sys.exit(0)
|
|
90
|
+
except Exception as e:
|
|
91
|
+
print(Fore.RED + f"Error: {e}")
|
|
92
|
+
sys.exit(1)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Overview
|
|
3
|
+
========
|
|
4
|
+
|
|
5
|
+
The API Module provides a high-level client for interacting with the MetaTrader 5 platform.
|
|
6
|
+
It serves as the primary interface for connecting to, retrieving data from, and sending commands
|
|
7
|
+
to a MetaTrader 5 terminal from a Python application. The module is designed to simplify
|
|
8
|
+
interactions and provide convenient data handling.
|
|
9
|
+
|
|
10
|
+
Features
|
|
11
|
+
========
|
|
12
|
+
|
|
13
|
+
- **High-Level MT5 Client**: A simplified client (`Mt5client`) for easy access to MetaTrader 5 functionalities.
|
|
14
|
+
- **Dynamic Object Representation**: Automatically patches MetaTrader 5 data objects for better string representation, making debugging easier.
|
|
15
|
+
- **DataFrame Conversion**: Includes a utility function (`trade_object_to_df`) to quickly convert lists of MT5 trade objects (like deals, orders, positions) into pandas DataFrames for analysis.
|
|
16
|
+
- **Handler-Based Architecture**: Uses a handler class (`Mt5Handlers`) to manage the underlying MetaTrader 5 API calls, promoting modularity.
|
|
17
|
+
|
|
18
|
+
Components
|
|
19
|
+
==========
|
|
20
|
+
|
|
21
|
+
- **Mt5client**: The main client instance used to interact with the MetaTrader 5 terminal.
|
|
22
|
+
- **Mt5Handlers**: A class that encapsulates the direct calls to the MetaTrader 5 API.
|
|
23
|
+
- **Helper Functions**:
|
|
24
|
+
- `trade_object_to_df`: Converts lists of trade-related objects to pandas DataFrames.
|
|
25
|
+
- Dynamic patching of `__str__` and `__repr__` for improved object inspection.
|
|
26
|
+
|
|
27
|
+
Notes
|
|
28
|
+
=====
|
|
29
|
+
|
|
30
|
+
This module requires a running MetaTrader 5 terminal and the `MetaTrader5` Python package to be installed.
|
|
31
|
+
The connection is managed by the `Mt5client`.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from operator import attrgetter
|
|
35
|
+
|
|
36
|
+
import pandas as pd
|
|
37
|
+
|
|
38
|
+
from bbstrader.api.handlers import Mt5Handlers
|
|
39
|
+
from bbstrader.api.metatrader_client import * # type: ignore # noqa: F403
|
|
40
|
+
|
|
41
|
+
# ruff: noqa: F405
|
|
42
|
+
classes_to_patch = [
|
|
43
|
+
AccountInfo,
|
|
44
|
+
BookInfo,
|
|
45
|
+
OrderCheckResult,
|
|
46
|
+
OrderSentResult,
|
|
47
|
+
RateInfo,
|
|
48
|
+
SymbolInfo,
|
|
49
|
+
TerminalInfo,
|
|
50
|
+
TickInfo,
|
|
51
|
+
TradeDeal,
|
|
52
|
+
TradeOrder,
|
|
53
|
+
TradePosition,
|
|
54
|
+
TradeRequest,
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def dynamic_str(self):
|
|
59
|
+
fields = set()
|
|
60
|
+
for name in dir(self):
|
|
61
|
+
if name.startswith("_"):
|
|
62
|
+
continue
|
|
63
|
+
try:
|
|
64
|
+
value = getattr(self, name)
|
|
65
|
+
if not callable(value):
|
|
66
|
+
fields.add(f"{name}={value!r}")
|
|
67
|
+
except Exception:
|
|
68
|
+
pass
|
|
69
|
+
return f"{type(self).__name__}({', '.join(fields)})"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
for cls in classes_to_patch:
|
|
73
|
+
cls.__str__ = dynamic_str
|
|
74
|
+
cls.__repr__ = dynamic_str
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def trade_object_to_df(obj_list):
|
|
78
|
+
"""
|
|
79
|
+
Fast conversion of a list of C++ bound objects to a pandas DataFrame.
|
|
80
|
+
"""
|
|
81
|
+
if not obj_list:
|
|
82
|
+
return pd.DataFrame()
|
|
83
|
+
|
|
84
|
+
first_obj = obj_list[0]
|
|
85
|
+
columns = [
|
|
86
|
+
name
|
|
87
|
+
for name in dir(first_obj)
|
|
88
|
+
if not name.startswith("_") and not callable(getattr(first_obj, name))
|
|
89
|
+
]
|
|
90
|
+
fetcher = attrgetter(*columns)
|
|
91
|
+
data = [fetcher(obj) for obj in obj_list]
|
|
92
|
+
df = pd.DataFrame(data, columns=columns)
|
|
93
|
+
return df
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
Mt5client = MetaTraderClient(Mt5Handlers)
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
import pytz
|
|
4
|
+
|
|
5
|
+
from bbstrader.api.metatrader_client import ( # type: ignore
|
|
6
|
+
AccountInfo,
|
|
7
|
+
BookInfo,
|
|
8
|
+
MetaTraderHandlers,
|
|
9
|
+
OrderCheckResult,
|
|
10
|
+
OrderSentResult,
|
|
11
|
+
SymbolInfo,
|
|
12
|
+
TerminalInfo,
|
|
13
|
+
TickInfo,
|
|
14
|
+
TradeDeal,
|
|
15
|
+
TradeOrder,
|
|
16
|
+
TradePosition,
|
|
17
|
+
TradeRequest,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
import MetaTrader5 as mt5
|
|
22
|
+
except ImportError:
|
|
23
|
+
import bbstrader.compat # noqa: F401
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _convert_obj(obj, obj_type):
|
|
27
|
+
"""Converts a single MT5 object to the target C++ class instance."""
|
|
28
|
+
if obj is None:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
if hasattr(obj, "_asdict"):
|
|
32
|
+
field_data: dict = obj._asdict()
|
|
33
|
+
instance = obj_type()
|
|
34
|
+
|
|
35
|
+
for k, v in field_data.items():
|
|
36
|
+
if not hasattr(instance, k):
|
|
37
|
+
continue
|
|
38
|
+
if (
|
|
39
|
+
k == "request"
|
|
40
|
+
and hasattr(v, "_asdict")
|
|
41
|
+
and obj_type in (OrderCheckResult, OrderSentResult)
|
|
42
|
+
):
|
|
43
|
+
setattr(instance, k, v._asdict())
|
|
44
|
+
else:
|
|
45
|
+
setattr(instance, k, v)
|
|
46
|
+
|
|
47
|
+
return instance
|
|
48
|
+
else:
|
|
49
|
+
raise TypeError(f"Expected MT5 namedtuple, got {type(obj)}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _convert_list(obj_list, obj_type):
|
|
53
|
+
if obj_list is None:
|
|
54
|
+
return None
|
|
55
|
+
return [_convert_obj(obj, obj_type) for obj in obj_list]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _build_request(req: TradeRequest | dict) -> dict:
|
|
59
|
+
if isinstance(req, dict):
|
|
60
|
+
return req
|
|
61
|
+
|
|
62
|
+
request = {}
|
|
63
|
+
attrs = [
|
|
64
|
+
"action",
|
|
65
|
+
"magic",
|
|
66
|
+
"order",
|
|
67
|
+
"symbol",
|
|
68
|
+
"volume",
|
|
69
|
+
"price",
|
|
70
|
+
"stoplimit",
|
|
71
|
+
"sl",
|
|
72
|
+
"tp",
|
|
73
|
+
"deviation",
|
|
74
|
+
"type",
|
|
75
|
+
"type_filling",
|
|
76
|
+
"type_time",
|
|
77
|
+
"expiration",
|
|
78
|
+
"comment",
|
|
79
|
+
"position",
|
|
80
|
+
"position_by",
|
|
81
|
+
]
|
|
82
|
+
enum_types = {"action", "type", "type_time", "type_filling"}
|
|
83
|
+
for attr in attrs:
|
|
84
|
+
val = getattr(req, attr)
|
|
85
|
+
if attr in enum_types or (val != 0 and val != ""):
|
|
86
|
+
request[attr] = val
|
|
87
|
+
return request
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def check_order(request: TradeRequest) -> OrderCheckResult:
|
|
91
|
+
return mt5.order_check(_build_request(request))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def send_order(request: TradeRequest) -> OrderSentResult:
|
|
95
|
+
return mt5.order_send(_build_request(request))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_time(ts):
|
|
99
|
+
timezone = pytz.timezone("UTC")
|
|
100
|
+
if isinstance(ts, datetime):
|
|
101
|
+
return ts
|
|
102
|
+
elif isinstance(ts, int):
|
|
103
|
+
return datetime.fromtimestamp(ts, tz=timezone)
|
|
104
|
+
else:
|
|
105
|
+
raise ValueError(f"Invalide Time format {type(ts)} must be and int or datetime")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_mt5_handlers():
|
|
109
|
+
"""
|
|
110
|
+
Exhaustively maps all MetaTrader 5 Python functions to the C++ Handlers struct,
|
|
111
|
+
converting return values to the appropriate types.
|
|
112
|
+
"""
|
|
113
|
+
h = MetaTraderHandlers()
|
|
114
|
+
|
|
115
|
+
# 1. System & Session Management (Functions returning structs are wrapped)
|
|
116
|
+
h.init_auto = lambda: mt5.initialize()
|
|
117
|
+
h.init_path = lambda path: mt5.initialize(path)
|
|
118
|
+
h.init_full = (
|
|
119
|
+
lambda path, login, password, server, timeout, portable: mt5.initialize(
|
|
120
|
+
path=path,
|
|
121
|
+
login=login,
|
|
122
|
+
password=password,
|
|
123
|
+
server=server,
|
|
124
|
+
timeout=timeout,
|
|
125
|
+
portable=portable,
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
h.login = lambda login, password, server, timeout: mt5.login(
|
|
129
|
+
login=login, password=password, server=server, timeout=timeout
|
|
130
|
+
)
|
|
131
|
+
h.shutdown = mt5.shutdown
|
|
132
|
+
h.get_version = mt5.version
|
|
133
|
+
h.get_last_error = mt5.last_error
|
|
134
|
+
h.get_terminal_info = lambda: _convert_obj(mt5.terminal_info(), TerminalInfo)
|
|
135
|
+
h.get_account_info = lambda: _convert_obj(mt5.account_info(), AccountInfo)
|
|
136
|
+
|
|
137
|
+
# 2. Symbols & Market Depth (Level 2)
|
|
138
|
+
h.get_total_symbols = mt5.symbols_total
|
|
139
|
+
h.get_symbols_all = lambda: _convert_list(mt5.symbols_get(), SymbolInfo)
|
|
140
|
+
h.get_symbol_info = lambda symbol: _convert_obj(mt5.symbol_info(symbol), SymbolInfo)
|
|
141
|
+
h.select_symbol = mt5.symbol_select
|
|
142
|
+
h.get_symbols_by_group = lambda group: _convert_list(
|
|
143
|
+
mt5.symbols_get(group), SymbolInfo
|
|
144
|
+
)
|
|
145
|
+
h.subscribe_book = mt5.market_book_add
|
|
146
|
+
h.unsubscribe_book = mt5.market_book_release
|
|
147
|
+
h.get_book_info = lambda symbol: _convert_list(
|
|
148
|
+
mt5.market_book_get(symbol), BookInfo
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# 3. Market Data (Rates & Ticks)
|
|
152
|
+
h.get_rates_by_date = (
|
|
153
|
+
lambda symbol, timeframe, date_from, count: mt5.copy_rates_from(
|
|
154
|
+
symbol, timeframe, get_time(date_from), count
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
h.get_rates_by_pos = (
|
|
158
|
+
lambda symbol, timeframe, start_pos, count: mt5.copy_rates_from_pos(
|
|
159
|
+
symbol, timeframe, start_pos, count
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
h.get_rates_by_range = (
|
|
163
|
+
lambda symbol, timeframe, date_from, date_to: mt5.copy_rates_range(
|
|
164
|
+
symbol, timeframe, get_time(date_from), get_time(date_to)
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
h.get_ticks_by_date = lambda symbol, date_from, count, flags: mt5.copy_ticks_from(
|
|
168
|
+
symbol, get_time(date_from), count, flags
|
|
169
|
+
)
|
|
170
|
+
h.get_ticks_by_range = (
|
|
171
|
+
lambda symbol, date_from, date_to, flags: mt5.copy_ticks_range(
|
|
172
|
+
symbol, get_time(date_from), get_time(date_to), flags
|
|
173
|
+
)
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
h.get_tick_info = lambda symbol: _convert_obj(
|
|
177
|
+
mt5.symbol_info_tick(symbol), TickInfo
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# 4. Trading Operations
|
|
181
|
+
h.check_order = lambda request: _convert_obj(check_order(request), OrderCheckResult)
|
|
182
|
+
h.send_order = lambda request: _convert_obj(send_order(request), OrderSentResult)
|
|
183
|
+
h.calc_margin = mt5.order_calc_margin
|
|
184
|
+
h.calc_profit = mt5.order_calc_profit
|
|
185
|
+
|
|
186
|
+
# 5. Active Orders & Positions
|
|
187
|
+
h.get_orders_all = lambda: _convert_list(mt5.orders_get(), TradeOrder)
|
|
188
|
+
h.get_orders_by_symbol = lambda symbol: _convert_list(
|
|
189
|
+
mt5.orders_get(symbol=symbol), TradeOrder
|
|
190
|
+
)
|
|
191
|
+
h.get_orders_by_group = lambda group: _convert_list(
|
|
192
|
+
mt5.orders_get(group=group), TradeOrder
|
|
193
|
+
)
|
|
194
|
+
h.get_order_by_ticket = lambda ticket: _convert_obj(
|
|
195
|
+
(mt5.orders_get(ticket=ticket) or [None])[0], TradeOrder
|
|
196
|
+
)
|
|
197
|
+
h.get_total_orders = mt5.orders_total
|
|
198
|
+
h.get_positions_all = lambda: _convert_list(mt5.positions_get(), TradePosition)
|
|
199
|
+
h.get_positions_symbol = lambda symbol: _convert_list(
|
|
200
|
+
mt5.positions_get(symbol=symbol), TradePosition
|
|
201
|
+
)
|
|
202
|
+
h.get_positions_group = lambda group: _convert_list(
|
|
203
|
+
mt5.positions_get(group=group), TradePosition
|
|
204
|
+
)
|
|
205
|
+
h.get_position_ticket = lambda ticket: _convert_obj(
|
|
206
|
+
(mt5.positions_get(ticket=ticket) or [None])[0], TradePosition
|
|
207
|
+
)
|
|
208
|
+
h.get_total_positions = mt5.positions_total
|
|
209
|
+
|
|
210
|
+
# 6. Trade History (Orders & Deals)
|
|
211
|
+
h.get_hist_orders_group = lambda date_from, date_to, group: _convert_list(
|
|
212
|
+
mt5.history_orders_get(get_time(date_from), get_time(date_to), group=group),
|
|
213
|
+
TradeOrder,
|
|
214
|
+
)
|
|
215
|
+
h.get_hist_orders_range = lambda date_from, date_to: _convert_list(
|
|
216
|
+
mt5.history_orders_get(get_time(date_from), get_time(date_to)),
|
|
217
|
+
TradeOrder,
|
|
218
|
+
)
|
|
219
|
+
h.get_hist_order_ticket = lambda ticket: _convert_obj(
|
|
220
|
+
mt5.history_orders_get(ticket=ticket), TradeOrder
|
|
221
|
+
)
|
|
222
|
+
h.get_hist_orders_pos = lambda position: _convert_list(
|
|
223
|
+
mt5.history_orders_get(position=position), TradeOrder
|
|
224
|
+
)
|
|
225
|
+
h.get_hist_orders_total = mt5.history_orders_total
|
|
226
|
+
h.get_hist_deals_group = lambda date_from, date_to, group: _convert_list(
|
|
227
|
+
mt5.history_deals_get(get_time(date_from), get_time(date_to), group=group),
|
|
228
|
+
TradeDeal,
|
|
229
|
+
)
|
|
230
|
+
h.get_hist_deals_range = lambda date_from, date_to: _convert_list(
|
|
231
|
+
mt5.history_deals_get(get_time(date_from), get_time(date_to)), TradeDeal
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
h.get_hist_deals_ticket = lambda ticket: _convert_obj(
|
|
235
|
+
mt5.history_deals_get(ticket=ticket), TradeDeal
|
|
236
|
+
)
|
|
237
|
+
h.get_hist_deals_pos = lambda position: _convert_list(
|
|
238
|
+
mt5.history_deals_get(position=position), TradeDeal
|
|
239
|
+
)
|
|
240
|
+
h.get_hist_deals_total = mt5.history_deals_total
|
|
241
|
+
|
|
242
|
+
return h
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
Mt5Handlers = get_mt5_handlers()
|
|
Binary file
|