bbstrader 0.2.4__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/config.py ADDED
@@ -0,0 +1,133 @@
1
+ import logging
2
+ from pathlib import Path
3
+ from typing import List
4
+
5
+ AMG_PATH = "C:\\Program Files\\Admirals Group MT5 Terminal\\terminal64.exe"
6
+ FTMO_PATH = "C:\\Program Files\\FTMO MetaTrader 5\\terminal64.exe"
7
+ XCB_PATH = "C:\\Program Files\\4xCube MT5 Terminal\\terminal64.exe"
8
+ TML_PATH = "C:\\Program Files\\Trinota Markets MetaTrader 5 Terminal\\terminal64.exe"
9
+
10
+ BROKERS_PATHS = {
11
+ "AMG": AMG_PATH,
12
+ "FTMO": FTMO_PATH,
13
+ "XCB": XCB_PATH,
14
+ "TML": TML_PATH,
15
+ }
16
+
17
+
18
+ def get_config_dir(name: str = ".bbstrader") -> Path:
19
+ """
20
+ Get the path to the configuration directory.
21
+
22
+ Args:
23
+ name: The name of the configuration directory.
24
+
25
+ Returns:
26
+ The path to the configuration directory.
27
+ """
28
+ home_dir = Path.home() / name
29
+ if not home_dir.exists():
30
+ home_dir.mkdir()
31
+ return home_dir
32
+
33
+
34
+ BBSTRADER_DIR = get_config_dir()
35
+
36
+
37
+ class LogLevelFilter(logging.Filter):
38
+ def __init__(self, levels: List[int]):
39
+ """
40
+ Initializes the filter with specific logging levels.
41
+
42
+ Args:
43
+ levels: A list of logging level values (integers) to include.
44
+ """
45
+ super().__init__()
46
+ self.levels = levels
47
+
48
+ def filter(self, record: logging.LogRecord) -> bool:
49
+ """
50
+ Filters log records based on their level.
51
+
52
+ Args:
53
+ record: The log record to check.
54
+
55
+ Returns:
56
+ True if the record's level is in the allowed levels, False otherwise.
57
+ """
58
+ return record.levelno in self.levels
59
+
60
+
61
+ class CustomFormatter(logging.Formatter):
62
+ def formatTime(self, record, datefmt=None):
63
+ if hasattr(record, "custom_time"):
64
+ # Use the custom time if provided
65
+ record.created = record.custom_time.timestamp()
66
+ return super().formatTime(record, datefmt)
67
+
68
+
69
+ class CustomLogger(logging.Logger):
70
+ def __init__(self, name, level=logging.NOTSET):
71
+ super().__init__(name, level)
72
+
73
+ def _log(
74
+ self,
75
+ level,
76
+ msg,
77
+ args,
78
+ exc_info=None,
79
+ extra=None,
80
+ stack_info=False,
81
+ stacklevel=1,
82
+ custom_time=None,
83
+ ):
84
+ if extra is None:
85
+ extra = {}
86
+ # Add custom_time to the extra dictionary if provided
87
+ if custom_time:
88
+ extra["custom_time"] = custom_time
89
+ super()._log(level, msg, args, exc_info, extra, stack_info, stacklevel)
90
+
91
+ def info(self, msg, *args, custom_time=None, **kwargs):
92
+ self._log(logging.INFO, msg, args, custom_time=custom_time, **kwargs)
93
+
94
+ def debug(self, msg, *args, custom_time=None, **kwargs):
95
+ self._log(logging.DEBUG, msg, args, custom_time=custom_time, **kwargs)
96
+
97
+ def warning(self, msg, *args, custom_time=None, **kwargs):
98
+ self._log(logging.WARNING, msg, args, custom_time=custom_time, **kwargs)
99
+
100
+ def error(self, msg, *args, custom_time=None, **kwargs):
101
+ self._log(logging.ERROR, msg, args, custom_time=custom_time, **kwargs)
102
+
103
+ def critical(self, msg, *args, custom_time=None, **kwargs):
104
+ self._log(logging.CRITICAL, msg, args, custom_time=custom_time, **kwargs)
105
+
106
+
107
+ def config_logger(log_file: str, console_log=True):
108
+ # Use the CustomLogger
109
+ logging.setLoggerClass(CustomLogger)
110
+ logger = logging.getLogger(__name__)
111
+ logger.setLevel(logging.DEBUG)
112
+
113
+ # File handler
114
+ file_handler = logging.FileHandler(log_file)
115
+ file_handler.setLevel(logging.INFO)
116
+
117
+ # Custom formatter
118
+ formatter = CustomFormatter(
119
+ "%(asctime)s - %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S"
120
+ )
121
+ file_handler.setFormatter(formatter)
122
+
123
+ # Add the handler to the logger
124
+ logger.addHandler(file_handler)
125
+
126
+ if console_log:
127
+ # Handler for the console with a different level
128
+ console_handler = logging.StreamHandler()
129
+ console_handler.setLevel(logging.DEBUG)
130
+ console_handler.setFormatter(formatter)
131
+ logger.addHandler(console_handler)
132
+
133
+ return logger
File without changes
bbstrader/core/data.py ADDED
@@ -0,0 +1,22 @@
1
+ from financetoolkit import Toolkit
2
+
3
+ __all__ = [
4
+ 'FMP',
5
+ ]
6
+
7
+
8
+ class FMP(Toolkit):
9
+ """
10
+ FMPData class for fetching data from Financial Modeling Prep API
11
+ using the Toolkit class from financetoolkit package.
12
+
13
+ See `financetoolkit` for more details.
14
+
15
+ """
16
+
17
+ def __init__(self, api_key: str = '', symbols: str | list = 'AAPL'):
18
+ super().__init__(tickers=symbols, api_key=api_key)
19
+
20
+
21
+ class DataBendo:
22
+ ...
@@ -0,0 +1,57 @@
1
+ from enum import Enum
2
+ from dataclasses import dataclass
3
+
4
+
5
+ class TradeAction(Enum):
6
+ """
7
+ An enumeration class for trade actions.
8
+ """
9
+ BUY = "LONG"
10
+ LONG = "LONG"
11
+ SELL = "SHORT"
12
+ EXIT = "EXIT"
13
+ BMKT = "BMKT"
14
+ SMKT = "SMKT"
15
+ BLMT = "BLMT"
16
+ SLMT = "SLMT"
17
+ BSTP = "BSTP"
18
+ SSTP = "SSTP"
19
+ SHORT = "SHORT"
20
+ BSTPLMT = "BSTPLMT"
21
+ SSTPLMT = "SSTPLMT"
22
+ EXIT_LONG = "EXIT_LONG"
23
+ EXIT_SHORT = "EXIT_SHORT"
24
+ EXIT_STOP = "EXIT_STOP"
25
+ EXIT_LIMIT = "EXIT_LIMIT"
26
+ EXIT_LONG_STOP = "EXIT_LONG_STOP"
27
+ EXIT_LONG_LIMIT = "EXIT_LONG_LIMIT"
28
+ EXIT_SHORT_STOP = "EXIT_SHORT_STOP"
29
+ EXIT_SHORT_LIMIT = "EXIT_SHORT_LIMIT"
30
+ EXIT_LONG_STOP_LIMIT = "EXIT_LONG_STOP_LIMIT"
31
+ EXIT_SHORT_STOP_LIMIT = "EXIT_SHORT_STOP_LIMIT"
32
+ EXIT_PROFITABLES = "EXIT_PROFITABLES"
33
+ EXIT_LOSINGS = "EXIT_LOSINGS"
34
+ EXIT_ALL_POSITIONS = "EXIT_ALL_POSITIONS"
35
+ EXIT_ALL_ORDERS = "EXIT_ALL_ORDERS"
36
+
37
+ def __str__(self):
38
+ return self.value
39
+
40
+
41
+ @dataclass()
42
+ class TradeSignal:
43
+ """
44
+ A dataclass for storing trading signal.
45
+ """
46
+
47
+ id: int
48
+ symbol: str
49
+ action: TradeAction
50
+ price: float = None
51
+ stoplimit: float = None
52
+
53
+ def __repr__(self):
54
+ return (
55
+ f"TradeSignal(id={self.id}, symbol='{self.symbol}', "
56
+ f"action='{self.action.value}', price={self.price}, stoplimit={self.stoplimit})"
57
+ )
File without changes
File without changes
@@ -0,0 +1,6 @@
1
+
2
+ from bbstrader.metatrader.account import * # noqa: F403
3
+ from bbstrader.metatrader.rates import * # noqa: F403
4
+ from bbstrader.metatrader.risk import * # noqa: F403
5
+ from bbstrader.metatrader.trade import * # noqa: F403
6
+ from bbstrader.metatrader.utils import * # noqa: F403