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
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import collections.abc
|
|
2
|
+
import datetime
|
|
3
|
+
import typing
|
|
4
|
+
from typing import overload
|
|
5
|
+
|
|
6
|
+
import numpy.typing
|
|
7
|
+
|
|
8
|
+
class AccountInfo:
|
|
9
|
+
assets: float
|
|
10
|
+
balance: float
|
|
11
|
+
commission_blocked: float
|
|
12
|
+
company: str
|
|
13
|
+
credit: float
|
|
14
|
+
currency: str
|
|
15
|
+
currency_digits: int
|
|
16
|
+
equity: float
|
|
17
|
+
fifo_close: bool
|
|
18
|
+
leverage: int
|
|
19
|
+
liabilities: float
|
|
20
|
+
limit_orders: int
|
|
21
|
+
login: int
|
|
22
|
+
margin: float
|
|
23
|
+
margin_free: float
|
|
24
|
+
margin_initial: float
|
|
25
|
+
margin_level: float
|
|
26
|
+
margin_maintenance: float
|
|
27
|
+
margin_mode: int
|
|
28
|
+
margin_so_call: float
|
|
29
|
+
margin_so_mode: int
|
|
30
|
+
margin_so_so: float
|
|
31
|
+
name: str
|
|
32
|
+
profit: float
|
|
33
|
+
server: str
|
|
34
|
+
trade_allowed: bool
|
|
35
|
+
trade_expert: bool
|
|
36
|
+
trade_mode: int
|
|
37
|
+
def __init__(self) -> None: ...
|
|
38
|
+
|
|
39
|
+
class BookInfo:
|
|
40
|
+
price: float
|
|
41
|
+
type: int
|
|
42
|
+
volume: int
|
|
43
|
+
volume_real: float
|
|
44
|
+
def __init__(self) -> None: ...
|
|
45
|
+
|
|
46
|
+
class MetaTraderClient:
|
|
47
|
+
def __init__(self, handlers: MetaTraderHandlers) -> None: ...
|
|
48
|
+
def account_info(self) -> AccountInfo | None: ...
|
|
49
|
+
@overload
|
|
50
|
+
def copy_rates_from(
|
|
51
|
+
self,
|
|
52
|
+
symbol: str,
|
|
53
|
+
timeframe: typing.SupportsInt,
|
|
54
|
+
date_from: typing.SupportsInt,
|
|
55
|
+
count: typing.SupportsInt,
|
|
56
|
+
) -> numpy.typing.NDArray | None: ...
|
|
57
|
+
@overload
|
|
58
|
+
def copy_rates_from(
|
|
59
|
+
self,
|
|
60
|
+
symbol: str,
|
|
61
|
+
timeframe: typing.SupportsInt,
|
|
62
|
+
date_from: datetime.datetime,
|
|
63
|
+
count: typing.SupportsInt,
|
|
64
|
+
) -> numpy.typing.NDArray | None: ...
|
|
65
|
+
def copy_rates_from_pos(
|
|
66
|
+
self,
|
|
67
|
+
symbol: str,
|
|
68
|
+
timeframe: typing.SupportsInt,
|
|
69
|
+
start_pos: typing.SupportsInt,
|
|
70
|
+
count: typing.SupportsInt,
|
|
71
|
+
) -> numpy.typing.NDArray | None: ...
|
|
72
|
+
@overload
|
|
73
|
+
def copy_rates_range(
|
|
74
|
+
self,
|
|
75
|
+
symbol: str,
|
|
76
|
+
timeframe: typing.SupportsInt,
|
|
77
|
+
date_from: typing.SupportsInt,
|
|
78
|
+
date_to: typing.SupportsInt,
|
|
79
|
+
) -> numpy.typing.NDArray | None: ...
|
|
80
|
+
@overload
|
|
81
|
+
def copy_rates_range(
|
|
82
|
+
self,
|
|
83
|
+
symbol: str,
|
|
84
|
+
timeframe: typing.SupportsInt,
|
|
85
|
+
date_from: datetime.datetime,
|
|
86
|
+
date_to: datetime.datetime,
|
|
87
|
+
) -> numpy.typing.NDArray | None: ...
|
|
88
|
+
@overload
|
|
89
|
+
def copy_ticks_from(
|
|
90
|
+
self,
|
|
91
|
+
symbol: str,
|
|
92
|
+
date_from: typing.SupportsInt,
|
|
93
|
+
count: typing.SupportsInt,
|
|
94
|
+
flags: typing.SupportsInt,
|
|
95
|
+
) -> numpy.typing.NDArray | None: ...
|
|
96
|
+
@overload
|
|
97
|
+
def copy_ticks_from(
|
|
98
|
+
self,
|
|
99
|
+
symbol: str,
|
|
100
|
+
date_from: datetime.datetime,
|
|
101
|
+
count: typing.SupportsInt,
|
|
102
|
+
flags: typing.SupportsInt,
|
|
103
|
+
) -> numpy.typing.NDArray | None: ...
|
|
104
|
+
@overload
|
|
105
|
+
def copy_ticks_range(
|
|
106
|
+
self,
|
|
107
|
+
symbol: str,
|
|
108
|
+
date_from: typing.SupportsInt,
|
|
109
|
+
date_to: typing.SupportsInt,
|
|
110
|
+
flags: typing.SupportsInt,
|
|
111
|
+
) -> numpy.typing.NDArray | None: ...
|
|
112
|
+
@overload
|
|
113
|
+
def copy_ticks_range(
|
|
114
|
+
self,
|
|
115
|
+
symbol: str,
|
|
116
|
+
date_from: datetime.datetime,
|
|
117
|
+
date_to: datetime.datetime,
|
|
118
|
+
flags: typing.SupportsInt,
|
|
119
|
+
) -> numpy.typing.NDArray | None: ...
|
|
120
|
+
@overload
|
|
121
|
+
def history_deals_get(
|
|
122
|
+
self, date_from: typing.SupportsInt, date_to: typing.SupportsInt, group: str
|
|
123
|
+
) -> list[TradeDeal] | None: ...
|
|
124
|
+
@overload
|
|
125
|
+
def history_deals_get(
|
|
126
|
+
self, date_from: datetime.datetime, date_to: datetime.datetime, group: str
|
|
127
|
+
) -> list[TradeDeal] | None: ...
|
|
128
|
+
@overload
|
|
129
|
+
def history_deals_get(
|
|
130
|
+
self, date_from: typing.SupportsInt, date_to: typing.SupportsInt
|
|
131
|
+
) -> list[TradeDeal] | None: ...
|
|
132
|
+
@overload
|
|
133
|
+
def history_deals_get(
|
|
134
|
+
self, date_from: datetime.datetime, date_to: datetime.datetime
|
|
135
|
+
) -> list[TradeDeal] | None: ...
|
|
136
|
+
@overload
|
|
137
|
+
def history_deals_get(
|
|
138
|
+
self, ticket: typing.SupportsInt
|
|
139
|
+
) -> list[TradeDeal] | None: ...
|
|
140
|
+
def history_deals_get_by_pos(
|
|
141
|
+
self, position_id: typing.SupportsInt
|
|
142
|
+
) -> list[TradeDeal] | None: ...
|
|
143
|
+
@overload
|
|
144
|
+
def history_deals_total(
|
|
145
|
+
self, date_from: typing.SupportsInt, date_to: typing.SupportsInt
|
|
146
|
+
) -> int | None: ...
|
|
147
|
+
@overload
|
|
148
|
+
def history_deals_total(
|
|
149
|
+
self, date_from: datetime.datetime, date_to: datetime.datetime
|
|
150
|
+
) -> int | None: ...
|
|
151
|
+
@overload
|
|
152
|
+
def history_orders_get(
|
|
153
|
+
self, date_from: typing.SupportsInt, date_to: typing.SupportsInt, group: str
|
|
154
|
+
) -> list[TradeOrder] | None: ...
|
|
155
|
+
@overload
|
|
156
|
+
def history_orders_get(
|
|
157
|
+
self, date_from: datetime.datetime, date_to: datetime.datetime, group: str
|
|
158
|
+
) -> list[TradeOrder] | None: ...
|
|
159
|
+
@overload
|
|
160
|
+
def history_orders_get(
|
|
161
|
+
self, date_from: typing.SupportsInt, date_to: typing.SupportsInt
|
|
162
|
+
) -> list[TradeOrder] | None: ...
|
|
163
|
+
@overload
|
|
164
|
+
def history_orders_get(
|
|
165
|
+
self, date_from: datetime.datetime, date_to: datetime.datetime
|
|
166
|
+
) -> list[TradeOrder] | None: ...
|
|
167
|
+
@overload
|
|
168
|
+
def history_orders_get(self, ticket: typing.SupportsInt) -> TradeOrder | None: ...
|
|
169
|
+
def history_orders_get_by_pos(
|
|
170
|
+
self, position_id: typing.SupportsInt
|
|
171
|
+
) -> list[TradeOrder] | None: ...
|
|
172
|
+
@overload
|
|
173
|
+
def history_orders_total(
|
|
174
|
+
self, date_from: typing.SupportsInt, date_to: typing.SupportsInt
|
|
175
|
+
) -> int | None: ...
|
|
176
|
+
@overload
|
|
177
|
+
def history_orders_total(
|
|
178
|
+
self, date_from: datetime.datetime, date_to: datetime.datetime
|
|
179
|
+
) -> int | None: ...
|
|
180
|
+
@overload
|
|
181
|
+
def initialize(self) -> bool: ...
|
|
182
|
+
@overload
|
|
183
|
+
def initialize(self, path: str) -> bool: ...
|
|
184
|
+
@overload
|
|
185
|
+
def initialize(
|
|
186
|
+
self,
|
|
187
|
+
path: str,
|
|
188
|
+
login: typing.SupportsInt,
|
|
189
|
+
password: str,
|
|
190
|
+
server: str,
|
|
191
|
+
timeout: typing.SupportsInt,
|
|
192
|
+
portable: bool,
|
|
193
|
+
) -> bool: ...
|
|
194
|
+
def last_error(self) -> tuple[int, str] | None: ...
|
|
195
|
+
def login(
|
|
196
|
+
self,
|
|
197
|
+
login: typing.SupportsInt,
|
|
198
|
+
password: str,
|
|
199
|
+
server: str,
|
|
200
|
+
timeout: typing.SupportsInt,
|
|
201
|
+
) -> bool: ...
|
|
202
|
+
def market_book_add(self, symbol: str) -> bool: ...
|
|
203
|
+
def market_book_get(self, symbol: str) -> list[BookInfo] | None: ...
|
|
204
|
+
def market_book_release(self, symbol: str) -> bool: ...
|
|
205
|
+
def order_calc_margin(
|
|
206
|
+
self,
|
|
207
|
+
action: typing.SupportsInt,
|
|
208
|
+
symbol: str,
|
|
209
|
+
volume: typing.SupportsFloat,
|
|
210
|
+
price: typing.SupportsFloat,
|
|
211
|
+
) -> float | None: ...
|
|
212
|
+
def order_calc_profit(
|
|
213
|
+
self,
|
|
214
|
+
action: typing.SupportsInt,
|
|
215
|
+
symbol: str,
|
|
216
|
+
volume: typing.SupportsFloat,
|
|
217
|
+
price_open: typing.SupportsFloat,
|
|
218
|
+
price_close: typing.SupportsFloat,
|
|
219
|
+
) -> float | None: ...
|
|
220
|
+
@overload
|
|
221
|
+
def order_check(self, request: TradeRequest) -> OrderCheckResult | None: ...
|
|
222
|
+
@overload
|
|
223
|
+
def order_check(self, request: dict) -> OrderCheckResult | None: ...
|
|
224
|
+
def order_get_by_ticket(self, ticket: typing.SupportsInt) -> TradeOrder | None: ...
|
|
225
|
+
@overload
|
|
226
|
+
def order_send(self, request: TradeRequest) -> OrderSentResult | None: ...
|
|
227
|
+
@overload
|
|
228
|
+
def order_send(self, request: dict) -> OrderSentResult | None: ...
|
|
229
|
+
@overload
|
|
230
|
+
def orders_get(self) -> list[TradeOrder] | None: ...
|
|
231
|
+
@overload
|
|
232
|
+
def orders_get(self, symbol: str) -> list[TradeOrder] | None: ...
|
|
233
|
+
def orders_get_by_group(self, group: str) -> list[TradeOrder] | None: ...
|
|
234
|
+
def orders_total(self) -> int | None: ...
|
|
235
|
+
def position_get_by_ticket(
|
|
236
|
+
self, ticket: typing.SupportsInt
|
|
237
|
+
) -> TradePosition | None: ...
|
|
238
|
+
@overload
|
|
239
|
+
def positions_get(self) -> list[TradePosition] | None: ...
|
|
240
|
+
@overload
|
|
241
|
+
def positions_get(self, symbol: str) -> list[TradePosition] | None: ...
|
|
242
|
+
def positions_get_by_group(self, group: str) -> list[TradePosition] | None: ...
|
|
243
|
+
def positions_total(self) -> int | None: ...
|
|
244
|
+
def shutdown(self) -> None: ...
|
|
245
|
+
def symbol_info(self, symbol: str) -> SymbolInfo | None: ...
|
|
246
|
+
def symbol_info_tick(self, symbol: str) -> TickInfo | None: ...
|
|
247
|
+
def symbol_select(self, symbol: str, enable: bool) -> bool: ...
|
|
248
|
+
@overload
|
|
249
|
+
def symbols_get(self) -> list[SymbolInfo] | None: ...
|
|
250
|
+
@overload
|
|
251
|
+
def symbols_get(self, group: str) -> list[SymbolInfo] | None: ...
|
|
252
|
+
def symbols_total(self) -> int | None: ...
|
|
253
|
+
def terminal_info(self) -> TerminalInfo | None: ...
|
|
254
|
+
def version(self) -> tuple[int, int, str] | None: ...
|
|
255
|
+
|
|
256
|
+
class MetaTraderHandlers:
|
|
257
|
+
calc_margin: collections.abc.Callable[
|
|
258
|
+
[typing.SupportsInt, str, typing.SupportsFloat, typing.SupportsFloat],
|
|
259
|
+
float | None,
|
|
260
|
+
]
|
|
261
|
+
calc_profit: collections.abc.Callable[
|
|
262
|
+
[
|
|
263
|
+
typing.SupportsInt,
|
|
264
|
+
str,
|
|
265
|
+
typing.SupportsFloat,
|
|
266
|
+
typing.SupportsFloat,
|
|
267
|
+
typing.SupportsFloat,
|
|
268
|
+
],
|
|
269
|
+
float | None,
|
|
270
|
+
]
|
|
271
|
+
check_order: collections.abc.Callable[[TradeRequest], OrderCheckResult | None]
|
|
272
|
+
get_account_info: collections.abc.Callable[[], AccountInfo | None]
|
|
273
|
+
get_book_info: collections.abc.Callable[[str], list[BookInfo] | None]
|
|
274
|
+
get_hist_deals_group: collections.abc.Callable[
|
|
275
|
+
[typing.SupportsInt, typing.SupportsInt, str], list[TradeDeal] | None
|
|
276
|
+
]
|
|
277
|
+
get_hist_deals_pos: collections.abc.Callable[
|
|
278
|
+
[typing.SupportsInt], list[TradeDeal] | None
|
|
279
|
+
]
|
|
280
|
+
get_hist_deals_range: collections.abc.Callable[
|
|
281
|
+
[typing.SupportsInt, typing.SupportsInt], list[TradeDeal] | None
|
|
282
|
+
]
|
|
283
|
+
get_hist_deals_ticket: collections.abc.Callable[
|
|
284
|
+
[typing.SupportsInt], list[TradeDeal] | None
|
|
285
|
+
]
|
|
286
|
+
get_hist_deals_total: collections.abc.Callable[
|
|
287
|
+
[typing.SupportsInt, typing.SupportsInt], int | None
|
|
288
|
+
]
|
|
289
|
+
get_hist_order_ticket: collections.abc.Callable[
|
|
290
|
+
[typing.SupportsInt], TradeOrder | None
|
|
291
|
+
]
|
|
292
|
+
get_hist_orders_group: collections.abc.Callable[
|
|
293
|
+
[typing.SupportsInt, typing.SupportsInt, str], list[TradeOrder] | None
|
|
294
|
+
]
|
|
295
|
+
get_hist_orders_pos: collections.abc.Callable[
|
|
296
|
+
[typing.SupportsInt], list[TradeOrder] | None
|
|
297
|
+
]
|
|
298
|
+
get_hist_orders_range: collections.abc.Callable[
|
|
299
|
+
[typing.SupportsInt, typing.SupportsInt], list[TradeOrder] | None
|
|
300
|
+
]
|
|
301
|
+
get_hist_orders_total: collections.abc.Callable[
|
|
302
|
+
[typing.SupportsInt, typing.SupportsInt], int | None
|
|
303
|
+
]
|
|
304
|
+
get_last_error: collections.abc.Callable[[], tuple[int, str] | None]
|
|
305
|
+
get_order_by_ticket: collections.abc.Callable[
|
|
306
|
+
[typing.SupportsInt], TradeOrder | None
|
|
307
|
+
]
|
|
308
|
+
get_orders_all: collections.abc.Callable[[], list[TradeOrder] | None]
|
|
309
|
+
get_orders_by_group: collections.abc.Callable[[str], list[TradeOrder] | None]
|
|
310
|
+
get_orders_by_symbol: collections.abc.Callable[[str], list[TradeOrder] | None]
|
|
311
|
+
get_position_ticket: collections.abc.Callable[
|
|
312
|
+
[typing.SupportsInt], TradePosition | None
|
|
313
|
+
]
|
|
314
|
+
get_positions_all: collections.abc.Callable[[], list[TradePosition] | None]
|
|
315
|
+
get_positions_group: collections.abc.Callable[[str], list[TradePosition] | None]
|
|
316
|
+
get_positions_symbol: collections.abc.Callable[[str], list[TradePosition] | None]
|
|
317
|
+
get_rates_by_date: collections.abc.Callable[
|
|
318
|
+
[str, typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
319
|
+
numpy.typing.NDArray | None,
|
|
320
|
+
]
|
|
321
|
+
get_rates_by_pos: collections.abc.Callable[
|
|
322
|
+
[str, typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
323
|
+
numpy.typing.NDArray | None,
|
|
324
|
+
]
|
|
325
|
+
get_rates_by_range: collections.abc.Callable[
|
|
326
|
+
[str, typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
327
|
+
numpy.typing.NDArray | None,
|
|
328
|
+
]
|
|
329
|
+
get_symbol_info: collections.abc.Callable[[str], SymbolInfo | None]
|
|
330
|
+
get_symbols_all: collections.abc.Callable[[], list[SymbolInfo] | None]
|
|
331
|
+
get_symbols_by_group: collections.abc.Callable[[str], list[SymbolInfo] | None]
|
|
332
|
+
get_terminal_info: collections.abc.Callable[[], TerminalInfo | None]
|
|
333
|
+
get_tick_info: collections.abc.Callable[[str], TickInfo | None]
|
|
334
|
+
get_ticks_by_date: collections.abc.Callable[
|
|
335
|
+
[str, typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
336
|
+
numpy.typing.NDArray | None,
|
|
337
|
+
]
|
|
338
|
+
get_ticks_by_range: collections.abc.Callable[
|
|
339
|
+
[str, typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
340
|
+
numpy.typing.NDArray | None,
|
|
341
|
+
]
|
|
342
|
+
get_total_orders: collections.abc.Callable[[], int | None]
|
|
343
|
+
get_total_positions: collections.abc.Callable[[], int | None]
|
|
344
|
+
get_total_symbols: collections.abc.Callable[[], int | None]
|
|
345
|
+
get_version: collections.abc.Callable[[], tuple[int, int, str] | None]
|
|
346
|
+
init_auto: collections.abc.Callable[[], bool]
|
|
347
|
+
init_full: collections.abc.Callable[
|
|
348
|
+
[str, typing.SupportsInt, str, str, typing.SupportsInt, bool], bool
|
|
349
|
+
]
|
|
350
|
+
init_path: collections.abc.Callable[[str], bool]
|
|
351
|
+
login: collections.abc.Callable[
|
|
352
|
+
[typing.SupportsInt, str, str, typing.SupportsInt], bool
|
|
353
|
+
]
|
|
354
|
+
select_symbol: collections.abc.Callable[[str, bool], bool]
|
|
355
|
+
send_order: collections.abc.Callable[[TradeRequest], OrderSentResult | None]
|
|
356
|
+
shutdown: collections.abc.Callable[[], None]
|
|
357
|
+
subscribe_book: collections.abc.Callable[[str], bool]
|
|
358
|
+
unsubscribe_book: collections.abc.Callable[[str], bool]
|
|
359
|
+
def __init__(self) -> None: ...
|
|
360
|
+
|
|
361
|
+
class OrderCheckResult:
|
|
362
|
+
balance: float
|
|
363
|
+
comment: str
|
|
364
|
+
equity: float
|
|
365
|
+
margin: float
|
|
366
|
+
margin_free: float
|
|
367
|
+
margin_level: float
|
|
368
|
+
profit: float
|
|
369
|
+
request: TradeRequest
|
|
370
|
+
retcode: int
|
|
371
|
+
def __init__(self) -> None: ...
|
|
372
|
+
|
|
373
|
+
class OrderSentResult:
|
|
374
|
+
ask: float
|
|
375
|
+
bid: float
|
|
376
|
+
comment: str
|
|
377
|
+
deal: int
|
|
378
|
+
order: int
|
|
379
|
+
price: float
|
|
380
|
+
request: TradeRequest
|
|
381
|
+
request_id: int
|
|
382
|
+
retcode: int
|
|
383
|
+
retcode_external: int
|
|
384
|
+
volume: float
|
|
385
|
+
def __init__(self) -> None: ...
|
|
386
|
+
|
|
387
|
+
class RateInfo:
|
|
388
|
+
close: float
|
|
389
|
+
high: float
|
|
390
|
+
low: float
|
|
391
|
+
open: float
|
|
392
|
+
real_volume: int
|
|
393
|
+
spread: int
|
|
394
|
+
tick_volume: int
|
|
395
|
+
time: int
|
|
396
|
+
def __init__(self) -> None: ...
|
|
397
|
+
|
|
398
|
+
class SymbolInfo:
|
|
399
|
+
ask: float
|
|
400
|
+
askhigh: float
|
|
401
|
+
asklow: float
|
|
402
|
+
bank: str
|
|
403
|
+
basis: str
|
|
404
|
+
bid: float
|
|
405
|
+
bidhigh: float
|
|
406
|
+
bidlow: float
|
|
407
|
+
category: str
|
|
408
|
+
chart_mode: int
|
|
409
|
+
currency_base: str
|
|
410
|
+
currency_margin: str
|
|
411
|
+
currency_profit: str
|
|
412
|
+
custom: bool
|
|
413
|
+
description: str
|
|
414
|
+
digits: int
|
|
415
|
+
exchange: str
|
|
416
|
+
expiration_mode: int
|
|
417
|
+
expiration_time: int
|
|
418
|
+
filling_mode: int
|
|
419
|
+
formula: str
|
|
420
|
+
isin: str
|
|
421
|
+
last: float
|
|
422
|
+
lasthigh: float
|
|
423
|
+
lastlow: float
|
|
424
|
+
margin_hedged: float
|
|
425
|
+
margin_hedged_use_leg: bool
|
|
426
|
+
margin_initial: float
|
|
427
|
+
margin_maintenance: float
|
|
428
|
+
name: str
|
|
429
|
+
option_mode: int
|
|
430
|
+
option_right: int
|
|
431
|
+
option_strike: float
|
|
432
|
+
order_gtc_mode: int
|
|
433
|
+
order_mode: int
|
|
434
|
+
page: str
|
|
435
|
+
path: str
|
|
436
|
+
point: float
|
|
437
|
+
price_change: float
|
|
438
|
+
price_greeks_delta: float
|
|
439
|
+
price_greeks_gamma: float
|
|
440
|
+
price_greeks_omega: float
|
|
441
|
+
price_greeks_rho: float
|
|
442
|
+
price_greeks_theta: float
|
|
443
|
+
price_greeks_vega: float
|
|
444
|
+
price_sensitivity: float
|
|
445
|
+
price_theoretical: float
|
|
446
|
+
price_volatility: float
|
|
447
|
+
select: bool
|
|
448
|
+
session_aw: float
|
|
449
|
+
session_buy_orders: int
|
|
450
|
+
session_buy_orders_volume: float
|
|
451
|
+
session_close: float
|
|
452
|
+
session_deals: int
|
|
453
|
+
session_interest: float
|
|
454
|
+
session_open: float
|
|
455
|
+
session_price_limit_max: float
|
|
456
|
+
session_price_limit_min: float
|
|
457
|
+
session_price_settlement: float
|
|
458
|
+
session_sell_orders: int
|
|
459
|
+
session_sell_orders_volume: float
|
|
460
|
+
session_turnover: float
|
|
461
|
+
session_volume: float
|
|
462
|
+
spread: int
|
|
463
|
+
spread_float: bool
|
|
464
|
+
start_time: int
|
|
465
|
+
swap_long: float
|
|
466
|
+
swap_mode: int
|
|
467
|
+
swap_rollover3days: int
|
|
468
|
+
swap_short: float
|
|
469
|
+
ticks_bookdepth: int
|
|
470
|
+
time: int
|
|
471
|
+
trade_accrued_interest: float
|
|
472
|
+
trade_calc_mode: int
|
|
473
|
+
trade_contract_size: float
|
|
474
|
+
trade_exemode: int
|
|
475
|
+
trade_face_value: float
|
|
476
|
+
trade_freeze_level: int
|
|
477
|
+
trade_liquidity_rate: float
|
|
478
|
+
trade_mode: int
|
|
479
|
+
trade_stops_level: int
|
|
480
|
+
trade_tick_size: float
|
|
481
|
+
trade_tick_value: float
|
|
482
|
+
trade_tick_value_loss: float
|
|
483
|
+
trade_tick_value_profit: float
|
|
484
|
+
visible: bool
|
|
485
|
+
volume: int
|
|
486
|
+
volume_limit: float
|
|
487
|
+
volume_max: float
|
|
488
|
+
volume_min: float
|
|
489
|
+
volume_real: float
|
|
490
|
+
volume_step: float
|
|
491
|
+
volumehigh: int
|
|
492
|
+
volumehigh_real: float
|
|
493
|
+
volumelow: int
|
|
494
|
+
volumelow_real: float
|
|
495
|
+
def __init__(self) -> None: ...
|
|
496
|
+
|
|
497
|
+
class TerminalInfo:
|
|
498
|
+
build: int
|
|
499
|
+
codepage: int
|
|
500
|
+
commondata_path: str
|
|
501
|
+
community_account: bool
|
|
502
|
+
community_balance: float
|
|
503
|
+
community_connection: bool
|
|
504
|
+
company: str
|
|
505
|
+
connected: bool
|
|
506
|
+
data_path: str
|
|
507
|
+
dlls_allowed: bool
|
|
508
|
+
email_enabled: bool
|
|
509
|
+
ftp_enabled: bool
|
|
510
|
+
language: str
|
|
511
|
+
maxbars: int
|
|
512
|
+
mqid: bool
|
|
513
|
+
name: str
|
|
514
|
+
notifications_enabled: bool
|
|
515
|
+
path: str
|
|
516
|
+
ping_last: int
|
|
517
|
+
retransmission: float
|
|
518
|
+
trade_allowed: bool
|
|
519
|
+
tradeapi_disabled: bool
|
|
520
|
+
def __init__(self) -> None: ...
|
|
521
|
+
|
|
522
|
+
class TickInfo:
|
|
523
|
+
ask: float
|
|
524
|
+
bid: float
|
|
525
|
+
flags: int
|
|
526
|
+
last: float
|
|
527
|
+
time: int
|
|
528
|
+
time_msc: int
|
|
529
|
+
volume: int
|
|
530
|
+
volume_real: float
|
|
531
|
+
def __init__(self) -> None: ...
|
|
532
|
+
|
|
533
|
+
class TradeDeal:
|
|
534
|
+
comment: str
|
|
535
|
+
commission: float
|
|
536
|
+
entry: int
|
|
537
|
+
external_id: str
|
|
538
|
+
fee: float
|
|
539
|
+
magic: int
|
|
540
|
+
order: int
|
|
541
|
+
position_id: int
|
|
542
|
+
price: float
|
|
543
|
+
profit: float
|
|
544
|
+
reason: int
|
|
545
|
+
swap: float
|
|
546
|
+
symbol: str
|
|
547
|
+
ticket: int
|
|
548
|
+
time: int
|
|
549
|
+
time_msc: int
|
|
550
|
+
type: int
|
|
551
|
+
volume: float
|
|
552
|
+
def __init__(self) -> None: ...
|
|
553
|
+
|
|
554
|
+
class TradeOrder:
|
|
555
|
+
comment: str
|
|
556
|
+
external_id: str
|
|
557
|
+
magic: int
|
|
558
|
+
position_by_id: int
|
|
559
|
+
position_id: int
|
|
560
|
+
price_current: float
|
|
561
|
+
price_open: float
|
|
562
|
+
price_stoplimit: float
|
|
563
|
+
reason: int
|
|
564
|
+
sl: float
|
|
565
|
+
state: int
|
|
566
|
+
symbol: str
|
|
567
|
+
ticket: int
|
|
568
|
+
time_done: int
|
|
569
|
+
time_done_msc: int
|
|
570
|
+
time_expiration: int
|
|
571
|
+
time_setup: int
|
|
572
|
+
time_setup_msc: int
|
|
573
|
+
tp: float
|
|
574
|
+
type: int
|
|
575
|
+
type_filling: int
|
|
576
|
+
type_time: int
|
|
577
|
+
volume_current: float
|
|
578
|
+
volume_initial: float
|
|
579
|
+
def __init__(self) -> None: ...
|
|
580
|
+
|
|
581
|
+
class TradePosition:
|
|
582
|
+
comment: str
|
|
583
|
+
external_id: str
|
|
584
|
+
identifier: int
|
|
585
|
+
magic: int
|
|
586
|
+
price_current: float
|
|
587
|
+
price_open: float
|
|
588
|
+
profit: float
|
|
589
|
+
reason: int
|
|
590
|
+
sl: float
|
|
591
|
+
swap: float
|
|
592
|
+
symbol: str
|
|
593
|
+
ticket: int
|
|
594
|
+
time: int
|
|
595
|
+
time_msc: int
|
|
596
|
+
time_update: int
|
|
597
|
+
time_update_msc: int
|
|
598
|
+
tp: float
|
|
599
|
+
type: int
|
|
600
|
+
volume: float
|
|
601
|
+
def __init__(self) -> None: ...
|
|
602
|
+
|
|
603
|
+
class TradeRequest:
|
|
604
|
+
action: int
|
|
605
|
+
comment: str
|
|
606
|
+
deviation: int
|
|
607
|
+
expiration: int
|
|
608
|
+
magic: int
|
|
609
|
+
order: int
|
|
610
|
+
position: int
|
|
611
|
+
position_by: int
|
|
612
|
+
price: float
|
|
613
|
+
sl: float
|
|
614
|
+
stoplimit: float
|
|
615
|
+
symbol: str
|
|
616
|
+
tp: float
|
|
617
|
+
type: int
|
|
618
|
+
type_filling: int
|
|
619
|
+
type_time: int
|
|
620
|
+
volume: float
|
|
621
|
+
@overload
|
|
622
|
+
def __init__(self) -> None: ...
|
|
623
|
+
@overload
|
|
624
|
+
def __init__(self, arg0: dict) -> None: ...
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Overview
|
|
3
|
+
========
|
|
4
|
+
|
|
5
|
+
This Backtesting Module provides a comprehensive suite of tools to test trading strategies in an event-driven system.
|
|
6
|
+
It simulates the execution of trades in historical market conditions to evaluate the performance of trading strategies
|
|
7
|
+
before applying them in live trading environments. Designed with modularity and extensibility in mind, it caters to
|
|
8
|
+
both novices and experts in algorithmic trading.
|
|
9
|
+
|
|
10
|
+
Features
|
|
11
|
+
========
|
|
12
|
+
|
|
13
|
+
- **Event-Driven Architecture**: Processes market data, generates signals, executes orders, and manages portfolio updates in response to events, closely mimicking live trading environments.
|
|
14
|
+
- **Historical Market Data Support**: Utilizes historical OHLCV data from CSV files, Yahoo finance and MT5 terminal allowing for the testing of strategies over various market conditions and time frames.
|
|
15
|
+
- **Performance Metrics Calculation**: Includes tools for calculating key performance indicators, such as `Sharpe Ratio`, `Sortino Ratio`, and `drawdowns`, to evaluate the effectiveness of trading strategies.
|
|
16
|
+
- **Visualization**: Generates plots of the `equity curve`, `returns`, `drawdowns`, and other metrics for comprehensive strategy `performance analysis`.
|
|
17
|
+
|
|
18
|
+
Components
|
|
19
|
+
==========
|
|
20
|
+
|
|
21
|
+
- **BacktestEgine**: Orchestrates the backtesting process, managing events and invoking components.
|
|
22
|
+
- **Event**: Abstract class for events, with implementations for market data, signals, fill and order events.
|
|
23
|
+
- **DataHandler**: Abstract class for market data handling, with an implementation for `CSVDataHandler`, `MT5DataHandler`, `YFDataHandler`. We will add another data handling in the future such as MacroEconomic Data, Fundamental Data, TICK Data and Real-time Data.
|
|
24
|
+
- **Portfolio**: Manages positions and calculates performance metrics, responding to market data and signals.
|
|
25
|
+
- **ExecutionHandler**: Abstract class for order execution, with a simulated execution handler provided with an implementation for `SimExecutionHandler`.
|
|
26
|
+
- **Performance**: Utility functions for calculating performance metrics and visualizing strategy performance.
|
|
27
|
+
|
|
28
|
+
Examples
|
|
29
|
+
========
|
|
30
|
+
|
|
31
|
+
>>> from bbstrader.btengine import run_backtest
|
|
32
|
+
>>> from datetime import datetime
|
|
33
|
+
>>> run_backtest(
|
|
34
|
+
... symbol_list=['AAPL', 'GOOG'],
|
|
35
|
+
... start_date=datetime(2020, 1, 1),
|
|
36
|
+
... data_handler=DataHandler,
|
|
37
|
+
... strategy=Strategy,
|
|
38
|
+
... exc_handler=ExecutionHandler,
|
|
39
|
+
... initial_capital=500000.0,
|
|
40
|
+
... heartbeat=1.0
|
|
41
|
+
... )
|
|
42
|
+
|
|
43
|
+
Notes
|
|
44
|
+
=====
|
|
45
|
+
|
|
46
|
+
See `bbstrader.btengine.backtest.run_backtest` for more details on the backtesting process and its parameters.
|
|
47
|
+
"""
|
|
48
|
+
from bbstrader.btengine.backtest import * # noqa: F403
|
|
49
|
+
from bbstrader.btengine.data import * # noqa: F403
|
|
50
|
+
from bbstrader.btengine.event import * # noqa: F403
|
|
51
|
+
from bbstrader.btengine.execution import * # noqa: F403
|
|
52
|
+
from bbstrader.btengine.performance import * # noqa: F403
|
|
53
|
+
from bbstrader.btengine.portfolio import * # noqa: F403
|
|
54
|
+
from bbstrader.btengine.strategy import * # noqa: F403
|