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.

@@ -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(self.symbol, self._tf, 0, interval, **self.kwargs)
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(self.symbol, tf, 0, interval, **self.kwargs)
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()
@@ -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
- for position in positions:
653
- if position.ticket == result.order:
654
- if position.type == 0:
655
- order_type = "BUY"
656
- self.buy_positions.append(position.ticket)
657
- else:
658
- order_type = "SELL"
659
- self.sell_positions.append(position.ticket)
660
- profit = round(self.get_account_info().profit, 5)
661
- order_info = (
662
- f"2. {order_type} Position Opened, Symbol: {self.symbol}, Price: @{round(position.price_open,5)}, "
663
- f"Sl: @{position.sl} Tp: @{position.tp}"
664
- )
665
- self.logger.info(order_info)
666
- pos_info = (
667
- f"3. [OPEN POSITIONS ON {self.symbol} = {len(positions)}, ACCOUNT OPEN PnL = {profit} "
668
- f"{self.get_account_info().currency}]\n"
669
- )
670
- self.logger.info(pos_info)
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
- fees_points = round((fees / risk), 3)
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
- min_be = round((fees / risk)) + 2
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
@@ -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}, SYMBOL={symbol}, TYPE={symbol_type}, DESCRIPTION={desc}, "
196
- f"PRICE={price}, STOPLIMIT={stoplimit}, STRATEGY={STRATEGY}, TIMEFRAME={time_frame}"
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
- raise ValueError(
403
- f"iter_time must be a multiple of the {time_frame} !!!"
404
- f"(e.g., if time_frame is 15m, iter_time must be 1.5, 3, 3, 15 etc)"
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 / len(symbols) >= 20
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 / len(symbols) >= 20:
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: bbstrader
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Simplified Investment & Trading Toolkit
5
5
  Home-page: https://github.com/bbalouki/bbstrader
6
6
  Download-URL: https://pypi.org/project/bbstrader/
@@ -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=OkQ5qOcgy7qHkr6sx4N1B5JJCPBo1HYiIFxGwePTtwc,27479
21
- bbstrader/metatrader/trade.py,sha256=2H0JSKgaWASaG9UeOnkxI5d12zI5CQ_NBIf4YpEDNCk,73248
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=Iht2WjXbELhtfvxSYZSEXmPCM7SPmQNRP4bS7VIQuFI,30724
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.6.dist-info/LICENSE,sha256=P3PBO9RuYPzl6-PkjysTNnwmwMB64ph36Bz9DBj8MS4,1115
34
- bbstrader-0.2.6.dist-info/METADATA,sha256=lPALTQr6DmLRXW5jpyfkZY4bKXlgF5ihbwRrcQfWd64,11271
35
- bbstrader-0.2.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
36
- bbstrader-0.2.6.dist-info/top_level.txt,sha256=Wwj322jZmxGZ6gD_TdaPiPLjED5ReObm5omerwlmZIg,10
37
- bbstrader-0.2.6.dist-info/RECORD,,
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,,