bbstrader 0.3.4__py3-none-any.whl → 0.3.6__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.

Files changed (38) hide show
  1. bbstrader/__init__.py +10 -1
  2. bbstrader/__main__.py +5 -0
  3. bbstrader/apps/_copier.py +3 -3
  4. bbstrader/btengine/strategy.py +113 -38
  5. bbstrader/compat.py +18 -10
  6. bbstrader/config.py +0 -16
  7. bbstrader/core/scripts.py +4 -3
  8. bbstrader/metatrader/account.py +51 -26
  9. bbstrader/metatrader/analysis.py +30 -16
  10. bbstrader/metatrader/copier.py +136 -58
  11. bbstrader/metatrader/trade.py +39 -45
  12. bbstrader/metatrader/utils.py +5 -4
  13. bbstrader/models/factors.py +17 -13
  14. bbstrader/models/ml.py +96 -49
  15. bbstrader/models/nlp.py +83 -66
  16. bbstrader/trading/execution.py +39 -22
  17. bbstrader/tseries.py +103 -127
  18. {bbstrader-0.3.4.dist-info → bbstrader-0.3.6.dist-info}/METADATA +29 -46
  19. bbstrader-0.3.6.dist-info/RECORD +62 -0
  20. bbstrader-0.3.6.dist-info/top_level.txt +3 -0
  21. docs/conf.py +56 -0
  22. tests/__init__.py +0 -0
  23. tests/engine/__init__.py +1 -0
  24. tests/engine/test_backtest.py +58 -0
  25. tests/engine/test_data.py +536 -0
  26. tests/engine/test_events.py +300 -0
  27. tests/engine/test_execution.py +219 -0
  28. tests/engine/test_portfolio.py +307 -0
  29. tests/metatrader/__init__.py +0 -0
  30. tests/metatrader/test_account.py +1769 -0
  31. tests/metatrader/test_rates.py +292 -0
  32. tests/metatrader/test_risk_management.py +700 -0
  33. tests/metatrader/test_trade.py +439 -0
  34. bbstrader-0.3.4.dist-info/RECORD +0 -49
  35. bbstrader-0.3.4.dist-info/top_level.txt +0 -1
  36. {bbstrader-0.3.4.dist-info → bbstrader-0.3.6.dist-info}/WHEEL +0 -0
  37. {bbstrader-0.3.4.dist-info → bbstrader-0.3.6.dist-info}/entry_points.txt +0 -0
  38. {bbstrader-0.3.4.dist-info → bbstrader-0.3.6.dist-info}/licenses/LICENSE +0 -0
bbstrader/tseries.py CHANGED
@@ -24,7 +24,6 @@ from statsmodels.tsa.vector_ar.var_model import VAR
24
24
  from statsmodels.tsa.vector_ar.vecm import coint_johansen
25
25
  from tqdm import tqdm
26
26
 
27
-
28
27
  __all__ = [
29
28
  "run_kalman_filter",
30
29
  "KalmanFilterModel",
@@ -746,32 +745,40 @@ def select_assets(df: pd.DataFrame, n=100, start=None, end=None, rolling_window=
746
745
 
747
746
 
748
747
  def compute_pair_metrics(security: pd.Series, candidates: pd.DataFrame):
749
- """
750
- Calculates statistical and econometric metrics for a target security and a set of candidate securities.
751
- These metrics are useful in financial modeling and pairs trading strategies,
752
- providing information about drift, volatility, correlation, and cointegration.
748
+ """Calculate statistical and econometric metrics for a security pair.
753
749
 
754
- Args:
755
- security (pd.Series): A time-series of the target security's prices.
756
- The name of the Series should correspond to the security's identifier (e.g., ticker symbol).
757
- candidates (pd.DataFrame): A DataFrame where each column represents a time-series of prices
758
- for candidate securities to be evaluated against the target security.
750
+ These metrics are useful in financial modeling and pairs trading strategies,
751
+ providing information about drift, volatility, correlation, and
752
+ cointegration.
759
753
 
760
- Returns:
761
- pd.DataFrame: A DataFrame combining:
762
- Drift: Estimated drift of spreads between the target security and each candidate.
763
- Volatility: Standard deviation of spreads.
764
- Correlation:
765
- ``corr``: Correlation of normalized prices between the target and each candidate.
766
- ``corr_ret``: Correlation of returns (percentage change) between the target and each candidate.
767
- Cointegration metrics:
768
- Engle-Granger test statistics (``t1``, ``t2``) and p-values (``p1``, ``p2``).
769
- Johansen test trace statistics (``trace0``, ``trace1``) and selected lag order (``k_ar_diff``).
754
+ Parameters
755
+ ----------
756
+ security : pd.Series
757
+ A time-series of the target security's prices. The name of the
758
+ Series should correspond to the security's identifier (e.g., ticker
759
+ symbol).
760
+ candidates : pd.DataFrame
761
+ A DataFrame where each column represents a time-series of prices
762
+ for candidate securities to be evaluated against the target security.
763
+
764
+ Returns
765
+ -------
766
+ pd.DataFrame
767
+ A DataFrame containing the following metrics as columns:
768
+ * ``Drift``: Estimated drift of spreads.
769
+ * ``Volatility``: Standard deviation of spreads.
770
+ * ``corr``: Correlation of normalized prices.
771
+ * ``corr_ret``: Correlation of returns (percentage change).
772
+ * ``t1``, ``p1``: Engle-Granger test statistic and p-value.
773
+ * ``t2``, ``p2``: Engle-Granger test statistic and p-value (alternate form).
774
+ * ``trace0``, ``trace1``: Johansen test trace statistics.
775
+ * ``k_ar_diff``: Selected lag order for the Johansen test.
770
776
 
771
777
  References
772
778
  ----------
773
- Stefan Jansen (2020). Machine Learning for Algorithmic Trading - Second Edition.
774
- chapter 9, Time-Series Models for Volatility Forecasts and Statistical Arbitrage.
779
+ * [1] Jansen, S. (2020). Machine Learning for Algorithmic Trading -
780
+ Second Edition. Packt Publishing. Chapter 9, Time-Series Models
781
+ for Volatility Forecasts and Statistical Arbitrage.
775
782
  """
776
783
  security = security.div(security.iloc[0])
777
784
  ticker = security.name
@@ -834,102 +841,65 @@ def find_cointegrated_pairs(
834
841
  such as cointegration and Engle-Granger significance, to determine pairs suitable
835
842
  for financial strategies like pairs trading.
836
843
 
837
- Args:
838
- securities (`pd.DataFrame`): A DataFrame where each column represents the time-series
839
- prices of target securities to evaluate.
840
- candidates (`pd.DataFrame`): A DataFrame where each column represents the time-series
841
- prices of candidate securities to compare against the target securities.
842
- n (`int`, optional): The number of top pairs to return. If `None`, returns all pairs.
843
- start (`str`, optional): Start date for slicing the data (e.g., 'YYYY-MM-DD').
844
- stop (`str`, optional): End date for slicing the data (e.g., 'YYYY-MM-DD').
845
- coint (`bool`, optional, default=False):
846
- - If `True`, filters for pairs identified as cointegrated.
847
- - If `False`, returns all evaluated pairs.
844
+ Parameters
845
+ ----------
846
+ securities : pd.DataFrame
847
+ A DataFrame where each column represents the time-series
848
+ prices of target securities to evaluate.
849
+ candidates : pd.DataFrame
850
+ A DataFrame where each column represents the time-series
851
+ prices of candidate securities to compare against the target securities.
852
+ n : int, optional
853
+ The number of top pairs to return. If ``None``, returns all pairs.
854
+ start : str, optional
855
+ Start date for slicing the data (e.g., 'YYYY-MM-DD').
856
+ stop : str, optional
857
+ End date for slicing the data (e.g., 'YYYY-MM-DD').
858
+ coint : bool, optional, default=False
859
+ If ``True``, filters for pairs identified as cointegrated.
860
+ If ``False``, returns all evaluated pairs.
861
+
862
+ Returns
863
+ -------
864
+ pd.DataFrame
865
+ A DataFrame containing:
866
+
867
+ **Johansen and Engle-Granger cointegration metrics**
868
+ * ``t1``, ``t2`` : Engle-Granger test statistics for two directions.
869
+ * ``p1``, ``p2`` : Engle-Granger p-values for two directions.
870
+ * ``trace0``, ``trace1`` : Johansen test trace statistics for 0 and 1 cointegration relationships.
871
+
872
+ **Indicators and filters**
873
+ * ``joh_sig`` : Indicates Johansen cointegration significance.
874
+ * ``eg_sig`` : Indicates Engle-Granger significance (p-value < 0.05).
875
+ * ``s1_dep`` : Indicates whether the first series depends on the second (based on p-values).
876
+ * ``coint`` : Combined cointegration indicator (Johansen & Engle-Granger).
877
+
878
+ **Spread and ranking**
879
+ * ``t`` : Minimum of ``t1`` and ``t2``.
880
+ * ``p`` : Minimum of ``p1`` and ``p2``.
848
881
 
849
- Returns:
850
- - ``pd.DataFrame``: A DataFrame containing:
851
- - Johansen and Engle-Granger cointegration metrics:
852
- - `t1`, `t2`: Engle-Granger test statistics for two directions.
853
- - `p1`, `p2`: Engle-Granger p-values for two directions.
854
- - `trace0`, `trace1`: Johansen test trace statistics for 0 and 1 cointegration relationships.
855
- - Indicators and filters:
856
- - `joh_sig`: Indicates Johansen cointegration significance.
857
- - `eg_sig`: Indicates Engle-Granger significance (p-value < 0.05).
858
- - `s1_dep`: Indicates whether the first series depends on the second (based on p-values).
859
- - `coint`: Combined cointegration indicator (Johansen & Engle-Granger).
860
- - Spread and ranking:
861
- - `t`: Minimum of `t1` and `t2`.
862
- - `p`: Minimum of `p1` and `p2`.
863
882
  References
864
883
  ----------
865
- Stefan Jansen (2020). Machine Learning for Algorithmic Trading - Second Edition.
866
- chapter 9, Time-Series Models for Volatility Forecasts and Statistical Arbitrage.
867
-
868
- Example:
869
- >>> import pandas as pd
884
+ Stefan Jansen (2020). *Machine Learning for Algorithmic Trading - Second Edition*.
885
+ Chapter 9, Time-Series Models for Volatility Forecasts and Statistical Arbitrage.
870
886
 
871
- >>> # Sample Data
872
- >>> data_securities = {
873
- ... 'Security1': [100, 102, 101, 103, 105],
874
- ... 'Security2': [50, 52, 53, 51, 54]
875
- ... }
876
- >>> data_candidates = {
877
- ... 'Candidate1': [100, 101, 99, 102, 104],
878
- ... 'Candidate2': [200, 202, 201, 203, 205]
879
- ... }
880
-
881
- >>> securities = pd.DataFrame(data_securities, index=pd.date_range('2023-01-01', periods=5))
882
- >>> candidates = pd.DataFrame(data_candidates, index=pd.date_range('2023-01-01', periods=5))
883
-
884
- >>> # Find cointegrated pairs
885
- >>> top_pairs = find_cointegrated_pairs(securities, candidates, n=2, coint=True)
886
- >>> print(top_pairs)
887
-
888
- >>> | s1 | s2 | t | p | joh_sig | eg_sig | coint |
889
- >>> |----------|-----------|------|-------|---------|--------|-------|
890
- >>> | Security1| Candidate1| -3.5 | 0.01 | 1 | 1 | 1 |
891
- >>> | Security2| Candidate2| -2.9 | 0.04 | 1 | 1 | 1 |
887
+ Examples
888
+ --------
889
+ >>> import pandas as pd
890
+ >>> data_securities = {
891
+ ... 'Security1': [100, 102, 101, 103, 105],
892
+ ... 'Security2': [50, 52, 53, 51, 54]
893
+ ... }
894
+ >>> data_candidates = {
895
+ ... 'Candidate1': [100, 101, 99, 102, 104],
896
+ ... 'Candidate2': [200, 202, 201, 203, 205]
897
+ ... }
898
+ >>> securities = pd.DataFrame(data_securities, index=pd.date_range('2023-01-01', periods=5))
899
+ >>> candidates = pd.DataFrame(data_candidates, index=pd.date_range('2023-01-01', periods=5))
900
+ >>> top_pairs = find_cointegrated_pairs(securities, candidates, n=2, coint=True)
901
+ >>> print(top_pairs)
892
902
  """
893
- trace0_cv = __CRITICAL_VALUES[0][
894
- 0.95
895
- ] # critical value for 0 cointegration relationships
896
- # critical value for 1 cointegration relationship
897
- trace1_cv = __CRITICAL_VALUES[1][0.95]
898
- spreads = []
899
- if start is not None and stop is not None:
900
- securities = securities.loc[str(start) : str(stop), :]
901
- candidates = candidates.loc[str(start) : str(stop), :]
902
- for i, (ticker, prices) in enumerate(securities.items(), 1):
903
- try:
904
- df = compute_pair_metrics(prices, candidates)
905
- spreads.append(df.set_index("s1", append=True))
906
- except np.linalg.LinAlgError:
907
- continue
908
- spreads = pd.concat(spreads)
909
- spreads.index.names = ["s2", "s1"]
910
- spreads = spreads.swaplevel()
911
- spreads["t"] = spreads[["t1", "t2"]].min(axis=1)
912
- spreads["p"] = spreads[["p1", "p2"]].min(axis=1)
913
- spreads["joh_sig"] = (
914
- (spreads.trace0 > trace0_cv) & (spreads.trace1 > trace1_cv)
915
- ).astype(int)
916
- spreads["eg_sig"] = (spreads.p < 0.05).astype(int)
917
- spreads["s1_dep"] = spreads.p1 < spreads.p2
918
- spreads["coint"] = (spreads.joh_sig & spreads.eg_sig).astype(int)
919
- # select top n pairs
920
- if coint:
921
- if n is not None:
922
- top_pairs = (
923
- spreads.query("coint == 1").sort_values("t", ascending=False).head(n)
924
- )
925
- else:
926
- top_pairs = spreads.query("coint == 1").sort_values("t", ascending=False)
927
- else:
928
- if n is not None:
929
- top_pairs = spreads.sort_values("t", ascending=False).head(n)
930
- else:
931
- top_pairs = spreads.sort_values("t", ascending=False)
932
- return top_pairs
933
903
 
934
904
 
935
905
  def analyze_cointegrated_pairs(
@@ -1121,25 +1091,31 @@ def KFSmoother(prices: pd.Series | np.ndarray) -> pd.Series | np.ndarray:
1121
1091
 
1122
1092
 
1123
1093
  def KFHedgeRatio(x: pd.Series | np.ndarray, y: pd.Series | np.ndarray) -> np.ndarray:
1124
- """
1125
- Estimate Hedge Ratio using Kalman Filter.
1126
- Args:
1127
- x : pd.Series or np.ndarray
1128
- The independent variable, which can be either a pandas Series or a numpy array.
1129
- y : pd.Series or np.ndarray
1130
- The dependent variable, which can be either a pandas Series or a numpy array.
1094
+ """Estimate Hedge Ratio using Kalman Filter.
1131
1095
 
1132
- Returns:
1133
- np.ndarray
1134
- The estimated hedge ratio as a numpy array.
1096
+ This function uses a Kalman Filter to dynamically estimate the hedge ratio
1097
+ (beta) and intercept (alpha) for a pair of assets over time.
1135
1098
 
1136
- The function returns the negative of the first state variable of each Kalman Filter estimate,
1137
- which represents the estimated hedge ratio.
1099
+ The function returns the negative of the first state variable (the hedge ratio)
1100
+ for each time step, which is a common convention in pairs trading.
1101
+
1102
+ Parameters
1103
+ ----------
1104
+ x : pd.Series or np.ndarray
1105
+ The independent variable (e.g., price series of asset X).
1106
+ y : pd.Series or np.ndarray
1107
+ The dependent variable (e.g., price series of asset Y).
1108
+
1109
+ Returns
1110
+ -------
1111
+ np.ndarray
1112
+ The time-varying estimated hedge ratio as a numpy array.
1138
1113
 
1139
1114
  References
1140
1115
  ----------
1141
- Stefan Jansen (2020). Machine Learning for Algorithmic Trading - Second Edition.
1142
- chapter 9, Time-Series Models for Volatility Forecasts and Statistical Arbitrage.
1116
+ * [1] Jansen, S. (2020). Machine Learning for Algorithmic Trading -
1117
+ Second Edition. Packt Publishing. Chapter 9, Time-Series Models
1118
+ for Volatility Forecasts and Statistical Arbitrage.
1143
1119
  """
1144
1120
  if not isinstance(x, (np.ndarray, pd.Series)) or not isinstance(
1145
1121
  y, (np.ndarray, pd.Series)
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bbstrader
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Simplified Investment & Trading Toolkit
5
- Home-page: https://github.com/bbalouki/bbstrader
6
- Download-URL: https://pypi.org/project/bbstrader/
7
- Author: Bertin Balouki SIMYELI
8
- Author-email: <bertin@bbstrader.com>
9
- Maintainer: Bertin Balouki SIMYELI
10
- License: The MIT License (MIT)
5
+ Author-email: Bertin Balouki SIMYELI <bertin@bbstrader.com>
6
+ Maintainer-email: Bertin Balouki SIMYELI <bertin@bbstrader.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/bbalouki/bbstrader
9
+ Project-URL: Download, https://pypi.org/project/bbstrader/
11
10
  Project-URL: Documentation, https://bbstrader.readthedocs.io/en/latest/
12
11
  Project-URL: Source Code, https://github.com/bbalouki/bbstrader
13
12
  Keywords: Finance,Toolkit,Financial,Analysis,Fundamental,Quantitative,Database,Equities,Currencies,Economics,ETFs,Funds,Indices,Moneymarkets,Commodities,Futures,CFDs,Derivatives,Trading,Investing,Portfolio,Optimization,Performance
@@ -15,67 +14,51 @@ Classifier: Development Status :: 5 - Production/Stable
15
14
  Classifier: Intended Audience :: Developers
16
15
  Classifier: Intended Audience :: Financial and Insurance Industry
17
16
  Classifier: Topic :: Office/Business :: Financial :: Investment
18
- Classifier: Programming Language :: Python :: 3.10
19
- Classifier: Programming Language :: Python :: 3.11
20
17
  Classifier: Programming Language :: Python :: 3.12
21
18
  Classifier: Operating System :: Microsoft :: Windows
22
19
  Classifier: Operating System :: POSIX :: Linux
23
20
  Classifier: Operating System :: MacOS
24
- Classifier: License :: OSI Approved :: MIT License
21
+ Requires-Python: >=3.12
25
22
  Description-Content-Type: text/markdown
26
23
  License-File: LICENSE
27
- Requires-Dist: alphalens-reloaded>=0.4.5
28
- Requires-Dist: beautifulsoup4>=4.13.1
24
+ Requires-Dist: alphalens-reloaded>=0.4.6
25
+ Requires-Dist: beautifulsoup4>=4.13.5
29
26
  Requires-Dist: colorama>=0.4.6
30
- Requires-Dist: CurrencyConverter>=0.18.2
31
- Requires-Dist: dash>=2.18.2
27
+ Requires-Dist: CurrencyConverter>=0.18.9
28
+ Requires-Dist: dash>=3.2.0
32
29
  Requires-Dist: eodhd>=1.0.32
33
- Requires-Dist: exchange-calendars>=4.9
30
+ Requires-Dist: exchange_calendars>=4.11.1
34
31
  Requires-Dist: filterpy>=1.4.5
35
- Requires-Dist: financetoolkit>=1.9.9
36
- Requires-Dist: ipython>=8.32.0
37
- Requires-Dist: lightgbm>=4.5.0
32
+ Requires-Dist: financetoolkit>=2.0.4
33
+ Requires-Dist: ipython>=9.5.0
34
+ Requires-Dist: lightgbm>=4.6.0
38
35
  Requires-Dist: nltk>=3.9.1
39
- Requires-Dist: notify-py>=0.3.43
40
- Requires-Dist: numpy>=1.26.0
41
- Requires-Dist: pandas_ta<=0.4.67b0
36
+ Requires-Dist: notify_py>=0.3.43
37
+ Requires-Dist: numpy>=2.2.6
38
+ Requires-Dist: pandas-ta>=0.4.67b0
42
39
  Requires-Dist: praw>=7.8.1
43
- Requires-Dist: pyfiglet>=1.0.2
44
- Requires-Dist: pykalman>=0.10.1
40
+ Requires-Dist: pyfiglet>=1.0.4
41
+ Requires-Dist: pykalman>=0.10.2
45
42
  Requires-Dist: pyportfolioopt>=1.5.6
46
- Requires-Dist: python-dotenv>=1.0.1
47
- Requires-Dist: python-telegram-bot>=21.10
43
+ Requires-Dist: python-dotenv>=1.1.1
44
+ Requires-Dist: python-telegram-bot>=22.3
48
45
  Requires-Dist: PyYAML>=6.0.2
49
- Requires-Dist: QuantStats>=0.0.64
50
- Requires-Dist: scikit-learn>=1.6.1
46
+ Requires-Dist: QuantStats>=0.0.77
47
+ Requires-Dist: scikit-learn>=1.7.2
51
48
  Requires-Dist: seaborn>=0.13.2
52
- Requires-Dist: spacy>=3.8.4
53
- Requires-Dist: statsmodels>=0.14.4
49
+ Requires-Dist: spacy>=3.8.7
50
+ Requires-Dist: statsmodels>=0.14.5
54
51
  Requires-Dist: sumy>=0.11.0
55
52
  Requires-Dist: tables>=3.10.2
56
53
  Requires-Dist: tabulate>=0.9.0
57
54
  Requires-Dist: textblob>=0.19.0
58
55
  Requires-Dist: tqdm>=4.67.1
59
- Requires-Dist: tweepy>=4.15.0
56
+ Requires-Dist: tweepy>=4.16.0
60
57
  Requires-Dist: vaderSentiment>=3.3.2
61
- Requires-Dist: yfinance>=0.2.55
58
+ Requires-Dist: yfinance>=0.2.65
62
59
  Provides-Extra: mt5
63
60
  Requires-Dist: MetaTrader5; extra == "mt5"
64
- Dynamic: author
65
- Dynamic: author-email
66
- Dynamic: classifier
67
- Dynamic: description
68
- Dynamic: description-content-type
69
- Dynamic: download-url
70
- Dynamic: home-page
71
- Dynamic: keywords
72
- Dynamic: license
73
61
  Dynamic: license-file
74
- Dynamic: maintainer
75
- Dynamic: project-url
76
- Dynamic: provides-extra
77
- Dynamic: requires-dist
78
- Dynamic: summary
79
62
 
80
63
  # Simplified Investment & Trading Toolkit
81
64
  [![Documentation Status](https://readthedocs.org/projects/bbstrader/badge/?version=latest)](https://bbstrader.readthedocs.io/en/latest/?badge=latest)
@@ -84,7 +67,7 @@ Dynamic: summary
84
67
  [![Supported Python Versions](https://img.shields.io/pypi/pyversions/bbstrader)](https://pypi.org/project/bbstrader/)
85
68
  [![PyPI Downloads](https://static.pepy.tech/badge/bbstrader)](https://pepy.tech/projects/bbstrader)
86
69
  [![CodeFactor](https://www.codefactor.io/repository/github/bbalouki/bbstrader/badge)](https://www.codefactor.io/repository/github/bbalouki/bbstrader)
87
- [![LinkedIn](https://img.shields.io/badge/LinkedIn-grey?logo=Linkedin&logoColor=white)](https://www.linkedin.com/in/bertin-balouki-simyeli-15b17a1a6/)
70
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-grey?logo=Linkedin&logoColor=white)](https://www.linkedin.com/in/bertin-balouki-s-15b17a1a6)
88
71
  [![PayPal Me](https://img.shields.io/badge/PayPal%20Me-blue?logo=paypal)](https://paypal.me/bertinbalouki?country.x=SN&locale.x=en_US)
89
72
 
90
73
  [Dcoumentation](https://bbstrader.readthedocs.io/en/latest/index.html)
@@ -0,0 +1,62 @@
1
+ bbstrader/__init__.py,sha256=kUjCDqDwFaqgcJkaLrgRGiaTwyxG3iTTbOy8V3iefYk,747
2
+ bbstrader/__main__.py,sha256=Cc3cSqHSCOdhk6gsg0lfL5TOaNz_ODXoe1wWgr_DewQ,2745
3
+ bbstrader/compat.py,sha256=bHTPTalffQNVv7MNRPaimJ4d9rQEwQFLSovHlUbxNgA,647
4
+ bbstrader/config.py,sha256=Q8xi6laFo-R-NNGotbHOgy8GLLuwvH6MaoiLhfTbYok,3548
5
+ bbstrader/tseries.py,sha256=fEIsG0kkMuG1TSrMnPK1u-tihzfFIOR675s18p3pg4A,41953
6
+ bbstrader/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ bbstrader/apps/_copier.py,sha256=wI33uEKEw8WElb4QA34UBbsXl4o7OqpjPSV023n_bb8,25393
8
+ bbstrader/btengine/__init__.py,sha256=y1btjaEfhWsH8vuE7mBRpP9Tu-Azt9REhuVYsPCAfBU,2955
9
+ bbstrader/btengine/backtest.py,sha256=o3eoCVzpjykDx-9VgkxK6DKZdGDAuLVeeWLCa2U_zeY,14652
10
+ bbstrader/btengine/data.py,sha256=WcBLtabboZkQdtOQS3SjbiJD9BcWc75sdhZ2voQ_lUw,27061
11
+ bbstrader/btengine/event.py,sha256=Ydl1avAXp9WAWOBXDAckcb9g1UkcnCO0rRzcJZwIq20,8714
12
+ bbstrader/btengine/execution.py,sha256=4MytWjcKg8J_w14P43emHqsvKOElkQTfhVYNakU6euQ,11190
13
+ bbstrader/btengine/performance.py,sha256=1ecWrTzHBQbk4ORvbTEKxwCzlL1brcXOEUwgbnjAwx4,12470
14
+ bbstrader/btengine/portfolio.py,sha256=z98M65HQeCyma8gMZkAxspxBA9jtIhzxMyJUHPPj34c,16128
15
+ bbstrader/btengine/scripts.py,sha256=8o66dq4Ex4DsH4s8xvJqUOFjLzZJSnbBvvNBzohtzoE,4837
16
+ bbstrader/btengine/strategy.py,sha256=6MR2atgXA4bkMQ9TE1lPr6P8vKAUoT0YoLmOFYEJiaA,39242
17
+ bbstrader/core/__init__.py,sha256=GIFzFSStPfE0XM2j7mDeZZQeMTh_AwPsDOQXwMVJLgw,97
18
+ bbstrader/core/data.py,sha256=5-ByClb-E3-iqDz8CBJ4om9wBIA7DmUWezu4A-tv5ys,25095
19
+ bbstrader/core/scripts.py,sha256=7lNddfX7WaZfiE5dENEfzv3XrAPrwoE9FYSaTie3cwM,5524
20
+ bbstrader/core/utils.py,sha256=tHXQimmmlYZHktNnYNKn_wVq6v-85pI7DXF6xlJV7ps,2780
21
+ bbstrader/ibkr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ bbstrader/ibkr/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ bbstrader/metatrader/__init__.py,sha256=A5Ye9tpc2sp9Xk5qjKw-EfYsoRcZtAt8nqvC3tCtZs8,333
24
+ bbstrader/metatrader/account.py,sha256=5YdvRggBxfZ6MQX70EFfwAZ7tuHvGzkwyEw1GgtiR4c,65501
25
+ bbstrader/metatrader/analysis.py,sha256=HuxYiKwa7VYmI_noqc4OAKSoC7bJpYm-OosQGZdMEnU,3694
26
+ bbstrader/metatrader/copier.py,sha256=VOo0RfuNoItc10CRGdX8MsUtcBBAzoY42sfolmvgptg,56052
27
+ bbstrader/metatrader/rates.py,sha256=w9mr6FB6E1zLcHCDtDGt-oMnw6sakIU6Qe3455KDsSg,20782
28
+ bbstrader/metatrader/risk.py,sha256=NhW8qtSg350Z6H9oLcDqOU_erqd_7Y7F5FwpfPN5Qso,27262
29
+ bbstrader/metatrader/scripts.py,sha256=8meq6_zz6jPSibNgtYtaO8Ba-uJZOoLkpqYUIjidk-U,4010
30
+ bbstrader/metatrader/trade.py,sha256=-tMbMBSTGAFJe9xK706uhR0Na8lJu7vfEhmud9Q3XnU,81003
31
+ bbstrader/metatrader/utils.py,sha256=Yt3mx8EgS6u1-irQG6uQn-LhC3kyWOVE00VepnDAtCI,20802
32
+ bbstrader/models/__init__.py,sha256=B-bn2h_SCK6gRAs2li6dDVnvV8jDT5suZimldk5xxcw,497
33
+ bbstrader/models/factors.py,sha256=J7yxtDr1sCTw1AI59kluF89e2b9HkpEXfFyIcfPHUCQ,13008
34
+ bbstrader/models/ml.py,sha256=NVN9zxRRDJn2S8KSgGBkiSHvdFjsDiaNsW2Y6rs51Io,50314
35
+ bbstrader/models/nlp.py,sha256=z_mbL58U5UGXc7ocVtvUR_zUYSk7Om2Gu7xXYBerxQY,32619
36
+ bbstrader/models/optimization.py,sha256=Fa4tdhynMmvKt5KHV9cH1TXmmJVJwU4QWpYkbeVq4aI,6395
37
+ bbstrader/models/portfolio.py,sha256=r-47Zrn2r7iKCHm5YVtwkbBJXAZGM3QYy-rXCWY9-Bg,8079
38
+ bbstrader/models/risk.py,sha256=MKCk53HtGIcivrNzH8Ikm5KMs1rXhFT5zkorUf30PyQ,506
39
+ bbstrader/trading/__init__.py,sha256=ycLyuuxN5SujqtzR9X0Q74UQfK93q2va-GGAXdr-KS8,457
40
+ bbstrader/trading/execution.py,sha256=CPjOKvVFq8ZnANQrOtpakp64ZAhn-73Bu-D9UPCKUws,41832
41
+ bbstrader/trading/scripts.py,sha256=Tf5q33WqqygjpIv43_8nA82VZ3GM0qgb4Ggo3fHJ_wg,5744
42
+ bbstrader/trading/strategies.py,sha256=RZ6P4SfIyRW72v0OnPnrc4Hv8X00FdxR-_sD23xe_Pg,11756
43
+ bbstrader/trading/utils.py,sha256=57dKF9dcRu04oU2VRqydRrzW39dCW2wlDWhVt-sZdRw,1857
44
+ bbstrader-0.3.6.dist-info/licenses/LICENSE,sha256=ZwC_RqqGmOPBUiMDKqLyJZ5HBeHq53LpL7TMRzrJY8c,1094
45
+ docs/conf.py,sha256=q_Z8_iz-YDgHhe4PpCOAtvN5Q-2hHquliG07FDEXdjo,1686
46
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ tests/engine/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
48
+ tests/engine/test_backtest.py,sha256=OmHimBp518BBv0Eg-t_cIrBXMzfiYOGki5FW7kqFeFs,2136
49
+ tests/engine/test_data.py,sha256=jAVICMt4YTKF5PN6ZIxhQ9CuUjbw9_gIPAC4sNA9GsE,19907
50
+ tests/engine/test_events.py,sha256=is3v3mtQVKFVNyn-xF4F7yuBGA5vqgunqsoFgNJeH0c,11755
51
+ tests/engine/test_execution.py,sha256=Sk3d_Rl9T0GjArficd75hEeVyeB_7yOcTD8ltpN4UlY,7961
52
+ tests/engine/test_portfolio.py,sha256=csKWO4W0xWn3obxuPRBFAUHHR60j-IZfAz5bv7Y_u9M,9872
53
+ tests/metatrader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ tests/metatrader/test_account.py,sha256=UiAWP0IRd6a1kmA_pTcEuCZAJjtq0U_Q-PcOdd2l69A,68627
55
+ tests/metatrader/test_rates.py,sha256=dc43jAvkZby9TMJcwkcaEvH21jQudk1D8KQxWLlAYoQ,10424
56
+ tests/metatrader/test_risk_management.py,sha256=lMT0m7dmT3iWihTkEwpMoHdJPPWU3XJmqgCV4qKT-uw,31019
57
+ tests/metatrader/test_trade.py,sha256=gMyinOOgVC2SOV8xLMIKqUTwqXbSUuDGnhSmspXK9cw,15177
58
+ bbstrader-0.3.6.dist-info/METADATA,sha256=zPS1ez6FJWRlX70OAjC9tSNerd1GuQJP9Hxv4mzorgc,26693
59
+ bbstrader-0.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
+ bbstrader-0.3.6.dist-info/entry_points.txt,sha256=0yDCbhbgHswOzJnY5wRSM_FjjyMHGvY7lJpSSVh0xtI,54
61
+ bbstrader-0.3.6.dist-info/top_level.txt,sha256=raTnmqZJ2B3Mvrhy_fV9szurE9yVctrKHBLZ1NJ5vnU,21
62
+ bbstrader-0.3.6.dist-info/RECORD,,
@@ -0,0 +1,3 @@
1
+ bbstrader
2
+ docs
3
+ tests
docs/conf.py ADDED
@@ -0,0 +1,56 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ #
3
+ # For the full list of built-in configuration values, see the documentation:
4
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html
5
+
6
+ # -- Project information -----------------------------------------------------
7
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8
+ import os
9
+ import sys
10
+ from unittest.mock import MagicMock
11
+ from importlib.metadata import version, PackageNotFoundError
12
+
13
+ os.system('pip install ..')
14
+ sys.path.insert(0, os.path.abspath('../bbstrader'))
15
+
16
+ class Mock(MagicMock):
17
+ @classmethod
18
+ def __getattr__(cls, name):
19
+ return MagicMock()
20
+
21
+ # List the mock modules to avoid import errors
22
+ MOCK_MODULES = ['MetaTrader5', 'talib', 'posix']
23
+ sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
24
+
25
+ project = 'bbstrader'
26
+ copyright = '2023 - 2025, Bertin Balouki SIMYELI'
27
+ author = 'Bertin Balouki SIMYELI'
28
+
29
+ try:
30
+ release = version("bbstrader")
31
+ except PackageNotFoundError:
32
+ release = "unknown"
33
+ version = ".".join(release.split('.')[:2])
34
+
35
+ # -- General configuration ---------------------------------------------------
36
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
37
+
38
+
39
+ extensions = [
40
+ 'sphinx.ext.autodoc',
41
+ 'sphinx.ext.napoleon',
42
+ 'sphinx.ext.viewcode',
43
+ 'sphinx.ext.todo',
44
+ ]
45
+
46
+
47
+ templates_path = ['_templates']
48
+ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
49
+
50
+
51
+
52
+ # -- Options for HTML output -------------------------------------------------
53
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
54
+
55
+ html_theme = 'sphinx_rtd_theme'
56
+ html_static_path = ['_static']
tests/__init__.py ADDED
File without changes
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,58 @@
1
+ import unittest
2
+ from unittest.mock import MagicMock
3
+ from datetime import datetime
4
+ from bbstrader.btengine.backtest import BacktestEngine
5
+
6
+
7
+ class TestBacktestEngine(unittest.TestCase):
8
+ def setUp(self):
9
+ # Create mock classes with minimum expected interface
10
+ self.symbol_list = ['FAKE']
11
+ self.initial_capital = 100000.0
12
+ self.heartbeat = 0.0
13
+ self.start_date = datetime(2020, 1, 1)
14
+
15
+ self.mock_data_handler_cls = MagicMock()
16
+ self.mock_strategy_cls = MagicMock()
17
+ self.mock_execution_handler_cls = MagicMock()
18
+
19
+ # Mock data_handler instance
20
+ self.mock_data_handler = MagicMock()
21
+ self.mock_data_handler.continue_backtest = False
22
+ self.mock_data_handler.get_latest_bar_datetime.return_value = self.start_date
23
+ self.mock_data_handler.update_bars.return_value = None
24
+
25
+ # Strategy and portfolio mock
26
+ self.mock_strategy = MagicMock()
27
+ self.mock_strategy.check_pending_orders.return_value = None
28
+ self.mock_strategy.get_update_from_portfolio.return_value = None
29
+
30
+ self.mock_portfolio = MagicMock()
31
+ self.mock_portfolio.all_holdings = [{"Total": self.initial_capital}]
32
+ self.mock_portfolio.current_positions = {}
33
+ self.mock_portfolio.current_holdings = {}
34
+
35
+ self.mock_execution_handler = MagicMock()
36
+
37
+ # Bind mock return values
38
+ self.mock_data_handler_cls.return_value = self.mock_data_handler
39
+ self.mock_strategy_cls.return_value = self.mock_strategy
40
+ self.mock_execution_handler_cls.return_value = self.mock_execution_handler
41
+
42
+ def test_backtest_engine_runs(self):
43
+ engine = BacktestEngine(
44
+ self.symbol_list,
45
+ self.initial_capital,
46
+ self.heartbeat,
47
+ self.start_date,
48
+ self.mock_data_handler_cls,
49
+ self.mock_execution_handler_cls,
50
+ self.mock_strategy_cls,
51
+ )
52
+ engine.portfolio = self.mock_portfolio
53
+
54
+ result = engine.simulate_trading()
55
+ self.assertTrue(hasattr(result, '__class__'))
56
+
57
+ if __name__ == "__main__":
58
+ unittest.main()