bbstrader 0.2.95__py3-none-any.whl → 0.2.97__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/__main__.py CHANGED
@@ -6,7 +6,7 @@ from colorama import Fore
6
6
 
7
7
  from bbstrader.btengine.scripts import backtest
8
8
  from bbstrader.metatrader.scripts import copy_trades
9
- from bbstrader.trading.script import execute_strategy
9
+ from bbstrader.trading.scripts import execute_strategy
10
10
 
11
11
  DESCRIPTION = "BBSTRADER"
12
12
  USAGE_TEXT = """
@@ -26,6 +26,7 @@ FONT = pyfiglet.figlet_format("BBSTRADER", font="big")
26
26
 
27
27
  def main():
28
28
  print(Fore.BLUE + FONT)
29
+ print(Fore.WHITE + "")
29
30
  parser = argparse.ArgumentParser(
30
31
  prog="BBSTRADER",
31
32
  usage=USAGE_TEXT,
@@ -36,7 +37,7 @@ def main():
36
37
  parser.add_argument("--run", type=str, nargs="?", default=None, help="Run a module")
37
38
  args, unknown = parser.parse_known_args()
38
39
  if ("-h" in sys.argv or "--help" in sys.argv) and args.run is None:
39
- print(USAGE_TEXT)
40
+ print(Fore.WHITE + USAGE_TEXT)
40
41
  sys.exit(0)
41
42
  if args.run == "copier":
42
43
  copy_trades(unknown)
@@ -66,21 +66,21 @@ class DataHandler(metaclass=ABCMeta):
66
66
  """
67
67
  Returns the last bar updated.
68
68
  """
69
- raise NotImplementedError("Should implement get_latest_bar()")
69
+ pass
70
70
 
71
71
  @abstractmethod
72
72
  def get_latest_bars(self, symbol, N=1, df=True) -> pd.DataFrame | List[pd.Series]:
73
73
  """
74
74
  Returns the last N bars updated.
75
75
  """
76
- raise NotImplementedError("Should implement get_latest_bars()")
76
+ pass
77
77
 
78
78
  @abstractmethod
79
79
  def get_latest_bar_datetime(self, symbol) -> datetime | pd.Timestamp:
80
80
  """
81
81
  Returns a Python datetime object for the last bar.
82
82
  """
83
- raise NotImplementedError("Should implement get_latest_bar_datetime()")
83
+ pass
84
84
 
85
85
  @abstractmethod
86
86
  def get_latest_bar_value(self, symbol, val_type) -> float:
@@ -88,7 +88,7 @@ class DataHandler(metaclass=ABCMeta):
88
88
  Returns one of the Open, High, Low, Close, Adj Close, Volume or Returns
89
89
  from the last bar.
90
90
  """
91
- raise NotImplementedError("Should implement get_latest_bar_value()")
91
+ pass
92
92
 
93
93
  @abstractmethod
94
94
  def get_latest_bars_values(self, symbol, val_type, N=1) -> np.ndarray:
@@ -96,7 +96,7 @@ class DataHandler(metaclass=ABCMeta):
96
96
  Returns the last N bar values from the
97
97
  latest_symbol list, or N-k if less available.
98
98
  """
99
- raise NotImplementedError("Should implement get_latest_bars_values()")
99
+ pass
100
100
 
101
101
  @abstractmethod
102
102
  def update_bars(self):
@@ -105,7 +105,7 @@ class DataHandler(metaclass=ABCMeta):
105
105
  in a tuple OHLCVI format: (datetime, Open, High, Low,
106
106
  Close, Adj Close, Volume, Retruns).
107
107
  """
108
- raise NotImplementedError("Should implement update_bars()")
108
+ pass
109
109
 
110
110
 
111
111
  class BaseCSVDataHandler(DataHandler):
@@ -46,7 +46,7 @@ class ExecutionHandler(metaclass=ABCMeta):
46
46
  Args:
47
47
  event (OrderEvent): Contains an Event object with order information.
48
48
  """
49
- raise NotImplementedError("Should implement execute_order()")
49
+ pass
50
50
 
51
51
 
52
52
  class SimExecutionHandler(ExecutionHandler):
@@ -12,7 +12,7 @@ from loguru import logger
12
12
  from bbstrader.btengine.data import DataHandler
13
13
  from bbstrader.btengine.event import FillEvent, SignalEvent
14
14
  from bbstrader.config import BBSTRADER_DIR
15
- from bbstrader.core.utils import TradeSignal
15
+ from bbstrader.metatrader.trade import TradeSignal
16
16
  from bbstrader.metatrader.account import (
17
17
  Account,
18
18
  AdmiralMarktsGroup,
@@ -55,7 +55,7 @@ class Strategy(metaclass=ABCMeta):
55
55
 
56
56
  @abstractmethod
57
57
  def calculate_signals(self, *args, **kwargs) -> List[TradeSignal]:
58
- raise NotImplementedError("Should implement calculate_signals()")
58
+ pass
59
59
 
60
60
  def check_pending_orders(self, *args, **kwargs): ...
61
61
  def get_update_from_portfolio(self, *args, **kwargs): ...
@@ -503,108 +503,96 @@ class MT5Strategy(Strategy):
503
503
  """
504
504
  Check for pending orders and handle them accordingly.
505
505
  """
506
- for symbol in self.symbols:
507
- dtime = self.data.get_latest_bar_datetime(symbol)
508
506
 
509
- def logmsg(order, type):
510
- return self.logger.info(
511
- f"{type} ORDER EXECUTED: SYMBOL={symbol}, QUANTITY={order.quantity}, "
512
- f"PRICE @ {order.price}",
513
- custom_time=dtime,
514
- )
507
+ def logmsg(order, type, symbol, dtime):
508
+ return self.logger.info(
509
+ f"{type} ORDER EXECUTED: SYMBOL={symbol}, QUANTITY={order.quantity}, "
510
+ f"PRICE @ {order.price}",
511
+ custom_time=dtime,
512
+ )
515
513
 
516
- for order in self._orders[symbol]["BLMT"].copy():
517
- if self.data.get_latest_bar_value(symbol, "close") <= order.price:
518
- self.buy_mkt(
519
- order.strategy_id, symbol, order.price, order.quantity, dtime
520
- )
521
- try:
522
- self._orders[symbol]["BLMT"].remove(order)
523
- assert order not in self._orders[symbol]["BLMT"]
524
- logmsg(order, "BUY LIMIT")
525
- except AssertionError:
526
- self._orders[symbol]["BLMT"] = [
527
- o for o in self._orders[symbol]["BLMT"] if o != order
528
- ]
529
- logmsg(order, "BUY LIMIT")
530
- for order in self._orders[symbol]["SLMT"].copy():
531
- if self.data.get_latest_bar_value(symbol, "close") >= order.price:
532
- self.sell_mkt(
533
- order.strategy_id, symbol, order.price, order.quantity, dtime
534
- )
514
+ def process_orders(order_type, condition, execute_fn, log_label, symbol, dtime):
515
+ for order in self._orders[symbol][order_type].copy():
516
+ if condition(order):
517
+ execute_fn(order)
535
518
  try:
536
- self._orders[symbol]["SLMT"].remove(order)
537
- assert order not in self._orders[symbol]["SLMT"]
538
- logmsg(order, "SELL LIMIT")
519
+ self._orders[symbol][order_type].remove(order)
520
+ assert order not in self._orders[symbol][order_type]
539
521
  except AssertionError:
540
- self._orders[symbol]["SLMT"] = [
541
- o for o in self._orders[symbol]["SLMT"] if o != order
522
+ self._orders[symbol][order_type] = [
523
+ o for o in self._orders[symbol][order_type] if o != order
542
524
  ]
543
- logmsg(order, "SELL LIMIT")
544
- for order in self._orders[symbol]["BSTP"].copy():
545
- if self.data.get_latest_bar_value(symbol, "close") >= order.price:
546
- self.buy_mkt(
547
- order.strategy_id, symbol, order.price, order.quantity, dtime
548
- )
549
- try:
550
- self._orders[symbol]["BSTP"].remove(order)
551
- assert order not in self._orders[symbol]["BSTP"]
552
- logmsg(order, "BUY STOP")
553
- except AssertionError:
554
- self._orders[symbol]["BSTP"] = [
555
- o for o in self._orders[symbol]["BSTP"] if o != order
556
- ]
557
- logmsg(order, "BUY STOP")
558
- for order in self._orders[symbol]["SSTP"].copy():
559
- if self.data.get_latest_bar_value(symbol, "close") <= order.price:
560
- self.sell_mkt(
561
- order.strategy_id, symbol, order.price, order.quantity, dtime
562
- )
563
- try:
564
- self._orders[symbol]["SSTP"].remove(order)
565
- assert order not in self._orders[symbol]["SSTP"]
566
- logmsg(order, "SELL STOP")
567
- except AssertionError:
568
- self._orders[symbol]["SSTP"] = [
569
- o for o in self._orders[symbol]["SSTP"] if o != order
570
- ]
571
- logmsg(order, "SELL STOP")
572
- for order in self._orders[symbol]["BSTPLMT"].copy():
573
- if self.data.get_latest_bar_value(symbol, "close") >= order.price:
574
- self.buy_limit(
575
- order.strategy_id,
576
- symbol,
577
- order.stoplimit,
578
- order.quantity,
579
- dtime,
580
- )
581
- try:
582
- self._orders[symbol]["BSTPLMT"].remove(order)
583
- assert order not in self._orders[symbol]["BSTPLMT"]
584
- logmsg(order, "BUY STOP LIMIT")
585
- except AssertionError:
586
- self._orders[symbol]["BSTPLMT"] = [
587
- o for o in self._orders[symbol]["BSTPLMT"] if o != order
588
- ]
589
- logmsg(order, "BUY STOP LIMIT")
590
- for order in self._orders[symbol]["SSTPLMT"].copy():
591
- if self.data.get_latest_bar_value(symbol, "close") <= order.price:
592
- self.sell_limit(
593
- order.strategy_id,
594
- symbol,
595
- order.stoplimit,
596
- order.quantity,
597
- dtime,
598
- )
599
- try:
600
- self._orders[symbol]["SSTPLMT"].remove(order)
601
- assert order not in self._orders[symbol]["SSTPLMT"]
602
- logmsg(order, "SELL STOP LIMIT")
603
- except AssertionError:
604
- self._orders[symbol]["SSTPLMT"] = [
605
- o for o in self._orders[symbol]["SSTPLMT"] if o != order
606
- ]
607
- logmsg(order, "SELL STOP LIMIT")
525
+ logmsg(order, log_label, symbol, dtime)
526
+
527
+ for symbol in self.symbols:
528
+ dtime = self.data.get_latest_bar_datetime(symbol)
529
+ latest_close = self.data.get_latest_bar_value(symbol, "close")
530
+
531
+ process_orders(
532
+ "BLMT",
533
+ lambda o: latest_close <= o.price,
534
+ lambda o: self.buy_mkt(
535
+ o.strategy_id, symbol, o.price, o.quantity, dtime
536
+ ),
537
+ "BUY LIMIT",
538
+ symbol,
539
+ dtime,
540
+ )
541
+
542
+ process_orders(
543
+ "SLMT",
544
+ lambda o: latest_close >= o.price,
545
+ lambda o: self.sell_mkt(
546
+ o.strategy_id, symbol, o.price, o.quantity, dtime
547
+ ),
548
+ "SELL LIMIT",
549
+ symbol,
550
+ dtime,
551
+ )
552
+
553
+ process_orders(
554
+ "BSTP",
555
+ lambda o: latest_close >= o.price,
556
+ lambda o: self.buy_mkt(
557
+ o.strategy_id, symbol, o.price, o.quantity, dtime
558
+ ),
559
+ "BUY STOP",
560
+ symbol,
561
+ dtime,
562
+ )
563
+
564
+ process_orders(
565
+ "SSTP",
566
+ lambda o: latest_close <= o.price,
567
+ lambda o: self.sell_mkt(
568
+ o.strategy_id, symbol, o.price, o.quantity, dtime
569
+ ),
570
+ "SELL STOP",
571
+ symbol,
572
+ dtime,
573
+ )
574
+
575
+ process_orders(
576
+ "BSTPLMT",
577
+ lambda o: latest_close >= o.price,
578
+ lambda o: self.buy_limit(
579
+ o.strategy_id, symbol, o.stoplimit, o.quantity, dtime
580
+ ),
581
+ "BUY STOP LIMIT",
582
+ symbol,
583
+ dtime,
584
+ )
585
+
586
+ process_orders(
587
+ "SSTPLMT",
588
+ lambda o: latest_close <= o.price,
589
+ lambda o: self.sell_limit(
590
+ o.strategy_id, symbol, o.stoplimit, o.quantity, dtime
591
+ ),
592
+ "SELL STOP LIMIT",
593
+ symbol,
594
+ dtime,
595
+ )
608
596
 
609
597
  @staticmethod
610
598
  def calculate_pct_change(current_price, lh_price):
@@ -0,0 +1,2 @@
1
+ from bbstrader.core.data import * # noqa: F403
2
+ from bbstrader.core.utils import * # noqa: F403