bbstrader 0.2.6__py3-none-any.whl → 0.2.7__py3-none-any.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.
Potentially problematic release.
This version of bbstrader might be problematic. Click here for more details.
- bbstrader/metatrader/risk.py +6 -2
- bbstrader/metatrader/trade.py +31 -24
- bbstrader/trading/execution.py +23 -20
- {bbstrader-0.2.6.dist-info → bbstrader-0.2.7.dist-info}/METADATA +1 -1
- {bbstrader-0.2.6.dist-info → bbstrader-0.2.7.dist-info}/RECORD +8 -8
- {bbstrader-0.2.6.dist-info → bbstrader-0.2.7.dist-info}/LICENSE +0 -0
- {bbstrader-0.2.6.dist-info → bbstrader-0.2.7.dist-info}/WHEEL +0 -0
- {bbstrader-0.2.6.dist-info → bbstrader-0.2.7.dist-info}/top_level.txt +0 -0
bbstrader/metatrader/risk.py
CHANGED
|
@@ -329,7 +329,9 @@ class RiskManagement(Account):
|
|
|
329
329
|
tf_int = self._convert_time_frame(self._tf)
|
|
330
330
|
interval = round((minutes / tf_int) * 252)
|
|
331
331
|
|
|
332
|
-
rate = Rates(
|
|
332
|
+
rate = Rates(
|
|
333
|
+
self.symbol, timeframe=self._tf, start_pos=0, count=interval, **self.kwargs
|
|
334
|
+
)
|
|
333
335
|
returns = rate.returns * 100
|
|
334
336
|
std = returns.std()
|
|
335
337
|
point = self.get_symbol_info(self.symbol).point
|
|
@@ -381,7 +383,9 @@ class RiskManagement(Account):
|
|
|
381
383
|
tf_int = self._convert_time_frame(tf)
|
|
382
384
|
interval = round((minutes / tf_int) * 252)
|
|
383
385
|
|
|
384
|
-
rate = Rates(
|
|
386
|
+
rate = Rates(
|
|
387
|
+
self.symbol, timeframe=tf, start_pos=0, count=interval, **self.kwargs
|
|
388
|
+
)
|
|
385
389
|
returns = rate.returns * 100
|
|
386
390
|
p = self.get_account_info().margin_free
|
|
387
391
|
mu = returns.mean()
|
bbstrader/metatrader/trade.py
CHANGED
|
@@ -129,7 +129,7 @@ class Trade(RiskManagement):
|
|
|
129
129
|
- sl
|
|
130
130
|
- tp
|
|
131
131
|
- be
|
|
132
|
-
See the RiskManagement class for more details on these parameters.
|
|
132
|
+
See the ``bbstrader.metatrader.risk.RiskManagement`` class for more details on these parameters.
|
|
133
133
|
See `bbstrader.metatrader.account.check_mt5_connection()` for more details on how to connect to MT5 terminal.
|
|
134
134
|
"""
|
|
135
135
|
# Call the parent class constructor first
|
|
@@ -649,25 +649,26 @@ class Trade(RiskManagement):
|
|
|
649
649
|
if type == "BMKT" or type == "SMKT":
|
|
650
650
|
self.opened_positions.append(result.order)
|
|
651
651
|
positions = self.get_positions(symbol=self.symbol)
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
if position.
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
652
|
+
if positions is not None:
|
|
653
|
+
for position in positions:
|
|
654
|
+
if position.ticket == result.order:
|
|
655
|
+
if position.type == 0:
|
|
656
|
+
order_type = "BUY"
|
|
657
|
+
self.buy_positions.append(position.ticket)
|
|
658
|
+
else:
|
|
659
|
+
order_type = "SELL"
|
|
660
|
+
self.sell_positions.append(position.ticket)
|
|
661
|
+
profit = round(self.get_account_info().profit, 5)
|
|
662
|
+
order_info = (
|
|
663
|
+
f"2. {order_type} Position Opened, Symbol: {self.symbol}, Price: @{round(position.price_open,5)}, "
|
|
664
|
+
f"Sl: @{position.sl} Tp: @{position.tp}"
|
|
665
|
+
)
|
|
666
|
+
self.logger.info(order_info)
|
|
667
|
+
pos_info = (
|
|
668
|
+
f"3. [OPEN POSITIONS ON {self.symbol} = {len(positions)}, ACCOUNT OPEN PnL = {profit} "
|
|
669
|
+
f"{self.get_account_info().currency}]\n"
|
|
670
|
+
)
|
|
671
|
+
self.logger.info(pos_info)
|
|
671
672
|
else:
|
|
672
673
|
msg = trade_retcode_message(result.retcode)
|
|
673
674
|
self.logger.error(
|
|
@@ -1054,7 +1055,10 @@ class Trade(RiskManagement):
|
|
|
1054
1055
|
spread = self.get_symbol_info(self.symbol).spread
|
|
1055
1056
|
fees = self.get_stats()[0]["average_fee"] * -1
|
|
1056
1057
|
risk = self.currency_risk()["trade_profit"]
|
|
1057
|
-
|
|
1058
|
+
try:
|
|
1059
|
+
fees_points = round((fees / risk), 3)
|
|
1060
|
+
except ZeroDivisionError:
|
|
1061
|
+
fees_points = 0
|
|
1058
1062
|
# If Buy
|
|
1059
1063
|
if position.type == 0 and position.price_current > position.price_open:
|
|
1060
1064
|
# Calculate the break-even level and price
|
|
@@ -1161,7 +1165,10 @@ class Trade(RiskManagement):
|
|
|
1161
1165
|
point = self.get_symbol_info(self.symbol).point
|
|
1162
1166
|
fees = self.get_stats()[0]["average_fee"] * -1
|
|
1163
1167
|
risk = self.currency_risk()["trade_profit"]
|
|
1164
|
-
|
|
1168
|
+
try:
|
|
1169
|
+
min_be = round((fees / risk)) + 2
|
|
1170
|
+
except ZeroDivisionError:
|
|
1171
|
+
min_be = self.symbol_info(self.symbol).spread
|
|
1165
1172
|
be = self.get_break_even()
|
|
1166
1173
|
if th is not None:
|
|
1167
1174
|
win_be = th
|
|
@@ -1189,7 +1196,7 @@ class Trade(RiskManagement):
|
|
|
1189
1196
|
# The first one is the opening order
|
|
1190
1197
|
# The second is the closing order
|
|
1191
1198
|
history = self.get_trades_history(position=position, to_df=False)
|
|
1192
|
-
if len(history) == 2:
|
|
1199
|
+
if history is not None and len(history) == 2:
|
|
1193
1200
|
profit += history[1].profit
|
|
1194
1201
|
commission += history[0].commission
|
|
1195
1202
|
swap += history[0].swap
|
|
@@ -1460,7 +1467,7 @@ class Trade(RiskManagement):
|
|
|
1460
1467
|
for position in self.opened_positions:
|
|
1461
1468
|
time.sleep(0.1)
|
|
1462
1469
|
history = self.get_trades_history(position=position, to_df=False)
|
|
1463
|
-
if len(history) == 2:
|
|
1470
|
+
if history is not None and len(history) == 2:
|
|
1464
1471
|
result = history[1].profit
|
|
1465
1472
|
comm = history[0].commission
|
|
1466
1473
|
swap = history[0].swap
|
bbstrader/trading/execution.py
CHANGED
|
@@ -110,6 +110,7 @@ def _mt5_execution(
|
|
|
110
110
|
notify = kwargs.get("notify", False)
|
|
111
111
|
signal_tickers = kwargs.get("signal_tickers", symbols)
|
|
112
112
|
debug_mode = kwargs.get("debug_mode", False)
|
|
113
|
+
delay = kwargs.get("delay", 0)
|
|
113
114
|
if notify:
|
|
114
115
|
telegram = kwargs.get("telegram", False)
|
|
115
116
|
bot_token = kwargs.get("bot_token")
|
|
@@ -192,8 +193,9 @@ def _mt5_execution(
|
|
|
192
193
|
symbol_type = account.get_symbol_type(symbol)
|
|
193
194
|
desc = account.get_symbol_info(symbol).description
|
|
194
195
|
sigmsg = (
|
|
195
|
-
f"SIGNAL = {signal},
|
|
196
|
-
f"
|
|
196
|
+
f"SIGNAL = {signal}, \nSYMBOL={symbol}, \nTYPE={symbol_type}, \nDESCRIPTION={desc}, "
|
|
197
|
+
f"\nPRICE={price}, \nSTOPLIMIT={stoplimit}, \nSTRATEGY={STRATEGY}, \nTIMEFRAME={time_frame}"
|
|
198
|
+
f"\nBROKER={account.broker.name}, \nTIMESTAMP={datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
|
197
199
|
)
|
|
198
200
|
msg = f"Sending {signal} Order ... SYMBOL={symbol}, STRATEGY={STRATEGY}"
|
|
199
201
|
tfmsg = f"Time Frame Not completed !!! SYMBOL={symbol}, STRATEGY={STRATEGY}"
|
|
@@ -399,10 +401,11 @@ def _mt5_execution(
|
|
|
399
401
|
elif trade_time % iter_time == 0:
|
|
400
402
|
time_intervals += iter_time
|
|
401
403
|
else:
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
404
|
+
if use_trade_time:
|
|
405
|
+
raise ValueError(
|
|
406
|
+
f"iter_time must be a multiple of the {time_frame} !!!"
|
|
407
|
+
f"(e.g., if time_frame is 15m, iter_time must be 1.5, 3, 5, 15 etc)"
|
|
408
|
+
)
|
|
406
409
|
try:
|
|
407
410
|
FRIDAY = "friday"
|
|
408
411
|
check_mt5_connection(**kwargs)
|
|
@@ -449,15 +452,15 @@ def _mt5_execution(
|
|
|
449
452
|
period_end_action == "sleep" and today != FRIDAY or not closing
|
|
450
453
|
):
|
|
451
454
|
sleep_time = trades_instances[symbols[-1]].sleep_time()
|
|
452
|
-
sleepmsg(sleep_time)
|
|
453
|
-
time.sleep(60 * sleep_time)
|
|
455
|
+
sleepmsg(sleep_time + delay)
|
|
456
|
+
time.sleep(60 * sleep_time + delay)
|
|
454
457
|
logger.info(sessionmsg)
|
|
455
458
|
elif period_end_action == "sleep" and today == FRIDAY:
|
|
456
459
|
sleep_time = trades_instances[symbols[-1]].sleep_time(
|
|
457
460
|
weekend=True
|
|
458
461
|
)
|
|
459
|
-
sleepmsg(sleep_time)
|
|
460
|
-
time.sleep(60 * sleep_time)
|
|
462
|
+
sleepmsg(sleep_time + delay)
|
|
463
|
+
time.sleep(60 * sleep_time + delay)
|
|
461
464
|
logger.info(sessionmsg)
|
|
462
465
|
|
|
463
466
|
elif period.lower() == "week":
|
|
@@ -476,8 +479,8 @@ def _mt5_execution(
|
|
|
476
479
|
|
|
477
480
|
if day_end and today != FRIDAY:
|
|
478
481
|
sleep_time = trades_instances[symbols[-1]].sleep_time()
|
|
479
|
-
sleepmsg(sleep_time)
|
|
480
|
-
time.sleep(60 * sleep_time)
|
|
482
|
+
sleepmsg(sleep_time + delay)
|
|
483
|
+
time.sleep(60 * sleep_time + delay)
|
|
481
484
|
logger.info(sessionmsg)
|
|
482
485
|
elif day_end and today == FRIDAY:
|
|
483
486
|
strategy.perform_period_end_checks()
|
|
@@ -487,8 +490,8 @@ def _mt5_execution(
|
|
|
487
490
|
sleep_time = trades_instances[symbols[-1]].sleep_time(
|
|
488
491
|
weekend=True
|
|
489
492
|
)
|
|
490
|
-
sleepmsg(sleep_time)
|
|
491
|
-
time.sleep(60 * sleep_time)
|
|
493
|
+
sleepmsg(sleep_time + delay)
|
|
494
|
+
time.sleep(60 * sleep_time + delay)
|
|
492
495
|
logger.info(sessionmsg)
|
|
493
496
|
|
|
494
497
|
elif period.lower() == "month":
|
|
@@ -501,7 +504,7 @@ def _mt5_execution(
|
|
|
501
504
|
elif (
|
|
502
505
|
trade.days_end()
|
|
503
506
|
and today == FRIDAY
|
|
504
|
-
and num_days
|
|
507
|
+
and num_days >= 20
|
|
505
508
|
) and closing:
|
|
506
509
|
for id in expert_ids:
|
|
507
510
|
trade.close_positions(
|
|
@@ -511,17 +514,17 @@ def _mt5_execution(
|
|
|
511
514
|
trade.statistics(save=True)
|
|
512
515
|
if day_end and today != FRIDAY:
|
|
513
516
|
sleep_time = trades_instances[symbols[-1]].sleep_time()
|
|
514
|
-
sleepmsg(sleep_time)
|
|
515
|
-
time.sleep(60 * sleep_time)
|
|
517
|
+
sleepmsg(sleep_time + delay)
|
|
518
|
+
time.sleep(60 * sleep_time + delay)
|
|
516
519
|
logger.info(sessionmsg)
|
|
517
520
|
num_days += 1
|
|
518
521
|
elif day_end and today == FRIDAY:
|
|
519
522
|
sleep_time = trades_instances[symbols[-1]].sleep_time(weekend=True)
|
|
520
|
-
sleepmsg(sleep_time)
|
|
521
|
-
time.sleep(60 * sleep_time)
|
|
523
|
+
sleepmsg(sleep_time + delay)
|
|
524
|
+
time.sleep(60 * sleep_time + delay)
|
|
522
525
|
logger.info(sessionmsg)
|
|
523
526
|
num_days += 1
|
|
524
|
-
elif day_end and today == FRIDAY and num_days
|
|
527
|
+
elif day_end and today == FRIDAY and num_days >= 20:
|
|
525
528
|
strategy.perform_period_end_checks()
|
|
526
529
|
break
|
|
527
530
|
except Exception:
|
|
@@ -17,8 +17,8 @@ bbstrader/ibkr/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
17
17
|
bbstrader/metatrader/__init__.py,sha256=rrL_EtecsOCD2Cwhmpgta5CjSGT0K6vzSBiQoyCLe3M,283
|
|
18
18
|
bbstrader/metatrader/account.py,sha256=Le46-lFqYm4VGQn3nPl1DUVCuiuxNi3EVf56kF8gA5Y,58221
|
|
19
19
|
bbstrader/metatrader/rates.py,sha256=12hNcjRSKcOSjBAhDvpakqAiLaI0ndU6oBhCTIWDzr0,21089
|
|
20
|
-
bbstrader/metatrader/risk.py,sha256=
|
|
21
|
-
bbstrader/metatrader/trade.py,sha256=
|
|
20
|
+
bbstrader/metatrader/risk.py,sha256=H8Iz93g3EVnb9bOdi4RSFF9JN1CY-IutYHs9-epBTpQ,27579
|
|
21
|
+
bbstrader/metatrader/trade.py,sha256=k6IeKaC83sH_th9uNxeEIlNBzVoSzK1J-0jKIDIA7rc,73639
|
|
22
22
|
bbstrader/metatrader/utils.py,sha256=UnwWmmfgY-Cw1V0vL14ehuWr9AhjcJMtVZK8k19b0i4,17672
|
|
23
23
|
bbstrader/models/__init__.py,sha256=SnGBMQ-zcUIpms3oNeqg7EVDFpg-7OPjNAD8kvi_Q84,508
|
|
24
24
|
bbstrader/models/factors.py,sha256=dWuXh83hLkwxUp3XwjgUl-r3_cjVcV_s0aFRlSLIfo8,13332
|
|
@@ -27,11 +27,11 @@ bbstrader/models/optimization.py,sha256=gp0n9a9vwbUldaNiZUYry_4RP2NW0VFZ2k5NoOkz
|
|
|
27
27
|
bbstrader/models/portfolio.py,sha256=-Zq9cmzyOZUlGq9RWfAxClpX0KJZqYZYpc5EGNTcPGI,8302
|
|
28
28
|
bbstrader/models/risk.py,sha256=IFQoHXxpBwJiifANRgwyAUOp7EgTWBAhfJFCO1sGR3g,15405
|
|
29
29
|
bbstrader/trading/__init__.py,sha256=2VoxbzfP1XBLVuxJtjRhjEBCtnv9HqwQzfMV4B5mM7M,468
|
|
30
|
-
bbstrader/trading/execution.py,sha256=
|
|
30
|
+
bbstrader/trading/execution.py,sha256=fFywdEJXtVSSxKNGTpRnFHiprTI1jmDNd94Ox1F1aU4,30999
|
|
31
31
|
bbstrader/trading/scripts.py,sha256=pNwHr-3mW87G5fyIMd93wS43NkzOZn4npt4fLNnSUyk,1922
|
|
32
32
|
bbstrader/trading/strategies.py,sha256=rMvLIhX_8MQg7_Lbo127UqdTRxBUof2m3jgRQTm55p0,37019
|
|
33
|
-
bbstrader-0.2.
|
|
34
|
-
bbstrader-0.2.
|
|
35
|
-
bbstrader-0.2.
|
|
36
|
-
bbstrader-0.2.
|
|
37
|
-
bbstrader-0.2.
|
|
33
|
+
bbstrader-0.2.7.dist-info/LICENSE,sha256=P3PBO9RuYPzl6-PkjysTNnwmwMB64ph36Bz9DBj8MS4,1115
|
|
34
|
+
bbstrader-0.2.7.dist-info/METADATA,sha256=Ce_IeZ9fc-yb5dGN3pmq60woLrcos_WBi3T_Tras30k,11271
|
|
35
|
+
bbstrader-0.2.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
36
|
+
bbstrader-0.2.7.dist-info/top_level.txt,sha256=Wwj322jZmxGZ6gD_TdaPiPLjED5ReObm5omerwlmZIg,10
|
|
37
|
+
bbstrader-0.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|