bbstrader 0.2.7__tar.gz → 0.2.8__tar.gz
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-0.2.7/bbstrader.egg-info → bbstrader-0.2.8}/PKG-INFO +4 -4
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/data.py +13 -10
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/portfolio.py +3 -5
- bbstrader-0.2.8/bbstrader/compat.py +23 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/metatrader/account.py +1 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/metatrader/rates.py +3 -1
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/metatrader/risk.py +1 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/metatrader/trade.py +39 -17
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/metatrader/utils.py +1 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/trading/execution.py +1 -1
- {bbstrader-0.2.7 → bbstrader-0.2.8/bbstrader.egg-info}/PKG-INFO +4 -4
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader.egg-info/SOURCES.txt +1 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader.egg-info/requires.txt +0 -2
- {bbstrader-0.2.7 → bbstrader-0.2.8}/requirements.txt +2 -1
- {bbstrader-0.2.7 → bbstrader-0.2.8}/setup.py +7 -2
- {bbstrader-0.2.7 → bbstrader-0.2.8}/LICENSE +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/MANIFEST.in +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/README.md +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/__ini__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/__init__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/backtest.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/event.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/execution.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/performance.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/btengine/strategy.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/config.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/core/__init__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/core/data.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/core/utils.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/ibkr/__init__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/ibkr/utils.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/metatrader/__init__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/models/__init__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/models/factors.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/models/ml.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/models/optimization.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/models/portfolio.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/models/risk.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/trading/__init__.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/trading/scripts.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/trading/strategies.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader/tseries.py +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader.egg-info/dependency_links.txt +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/bbstrader.egg-info/top_level.txt +0 -0
- {bbstrader-0.2.7 → bbstrader-0.2.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: bbstrader
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
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/
|
|
@@ -19,6 +19,8 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Operating System :: Microsoft :: Windows
|
|
22
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
23
|
+
Classifier: Operating System :: MacOS
|
|
22
24
|
Classifier: License :: OSI Approved :: MIT License
|
|
23
25
|
Description-Content-Type: text/markdown
|
|
24
26
|
License-File: LICENSE
|
|
@@ -53,8 +55,7 @@ Requires-Dist: financetoolkit
|
|
|
53
55
|
Requires-Dist: tables
|
|
54
56
|
Requires-Dist: lightgbm
|
|
55
57
|
Requires-Dist: alphalens-reloaded
|
|
56
|
-
|
|
57
|
-
Requires-Dist: MetaTrader5; extra == "mt5"
|
|
58
|
+
Requires-Dist: MetaTrader5
|
|
58
59
|
Dynamic: author
|
|
59
60
|
Dynamic: author-email
|
|
60
61
|
Dynamic: classifier
|
|
@@ -66,7 +67,6 @@ Dynamic: keywords
|
|
|
66
67
|
Dynamic: license
|
|
67
68
|
Dynamic: maintainer
|
|
68
69
|
Dynamic: project-url
|
|
69
|
-
Dynamic: provides-extra
|
|
70
70
|
Dynamic: requires-dist
|
|
71
71
|
Dynamic: summary
|
|
72
72
|
|
|
@@ -203,10 +203,11 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
203
203
|
self.symbol_data[s] = self.symbol_data[s].reindex(
|
|
204
204
|
index=comb_index, method="pad"
|
|
205
205
|
)
|
|
206
|
+
if "adj_close" not in new_names:
|
|
207
|
+
self.columns.append("adj_close")
|
|
208
|
+
self.symbol_data[s]["adj_close"] = self.symbol_data[s]["close"]
|
|
206
209
|
self.symbol_data[s]["returns"] = (
|
|
207
|
-
self.symbol_data[s][
|
|
208
|
-
"adj_close" if "adj_close" in new_names else "close"
|
|
209
|
-
]
|
|
210
|
+
self.symbol_data[s]["adj_close" if "adj_close" in new_names else "close"]
|
|
210
211
|
.pct_change()
|
|
211
212
|
.dropna()
|
|
212
213
|
)
|
|
@@ -229,7 +230,7 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
229
230
|
try:
|
|
230
231
|
bars_list = self.latest_symbol_data[symbol]
|
|
231
232
|
except KeyError:
|
|
232
|
-
print("
|
|
233
|
+
print(f"{symbol} not available in the historical data set.")
|
|
233
234
|
raise
|
|
234
235
|
else:
|
|
235
236
|
return bars_list[-1]
|
|
@@ -244,7 +245,7 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
244
245
|
try:
|
|
245
246
|
bars_list = self.latest_symbol_data[symbol]
|
|
246
247
|
except KeyError:
|
|
247
|
-
print("
|
|
248
|
+
print(f"{symbol} not available in the historical data set.")
|
|
248
249
|
raise
|
|
249
250
|
else:
|
|
250
251
|
if df:
|
|
@@ -260,7 +261,7 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
260
261
|
try:
|
|
261
262
|
bars_list = self.latest_symbol_data[symbol]
|
|
262
263
|
except KeyError:
|
|
263
|
-
print("
|
|
264
|
+
print(f"{symbol} not available in the historical data set.")
|
|
264
265
|
raise
|
|
265
266
|
else:
|
|
266
267
|
return bars_list[-1][0]
|
|
@@ -274,7 +275,7 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
274
275
|
try:
|
|
275
276
|
bars_list = self.get_latest_bars(symbol, N)
|
|
276
277
|
except KeyError:
|
|
277
|
-
print("
|
|
278
|
+
print(f"{symbol} not available in the historical data set for .")
|
|
278
279
|
raise
|
|
279
280
|
else:
|
|
280
281
|
return [b[0] for b in bars_list]
|
|
@@ -287,14 +288,14 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
287
288
|
try:
|
|
288
289
|
bars_list = self.latest_symbol_data[symbol]
|
|
289
290
|
except KeyError:
|
|
290
|
-
print("
|
|
291
|
+
print(f"{symbol} not available in the historical data set.")
|
|
291
292
|
raise
|
|
292
293
|
else:
|
|
293
294
|
try:
|
|
294
295
|
return getattr(bars_list[-1][1], val_type)
|
|
295
296
|
except AttributeError:
|
|
296
297
|
print(
|
|
297
|
-
f"Value type {val_type} not available in the historical data set."
|
|
298
|
+
f"Value type {val_type} not available in the historical data set for {symbol}."
|
|
298
299
|
)
|
|
299
300
|
raise
|
|
300
301
|
|
|
@@ -306,7 +307,7 @@ class BaseCSVDataHandler(DataHandler):
|
|
|
306
307
|
try:
|
|
307
308
|
bars_list = self.get_latest_bars(symbol, N, df=False)
|
|
308
309
|
except KeyError:
|
|
309
|
-
print("
|
|
310
|
+
print(f"{symbol} not available in the historical data set.")
|
|
310
311
|
raise
|
|
311
312
|
else:
|
|
312
313
|
try:
|
|
@@ -497,6 +498,8 @@ class YFDataHandler(BaseCSVDataHandler):
|
|
|
497
498
|
multi_level_index=False,
|
|
498
499
|
progress=False,
|
|
499
500
|
)
|
|
501
|
+
if "Adj Close" not in data.columns:
|
|
502
|
+
data["Adj Close"] = data["Close"]
|
|
500
503
|
if data.empty:
|
|
501
504
|
raise ValueError(f"No data found for {symbol}")
|
|
502
505
|
data.to_csv(filepath)
|
|
@@ -195,14 +195,12 @@ class Portfolio(object):
|
|
|
195
195
|
try:
|
|
196
196
|
price = self.bars.get_latest_bar_value(symbol, "adj_close")
|
|
197
197
|
return price
|
|
198
|
-
except AttributeError:
|
|
198
|
+
except (AttributeError, KeyError, ValueError):
|
|
199
199
|
try:
|
|
200
200
|
price = self.bars.get_latest_bar_value(symbol, "close")
|
|
201
201
|
return price
|
|
202
|
-
except AttributeError:
|
|
203
|
-
|
|
204
|
-
"Bars object must have 'adj_close' or 'close' prices"
|
|
205
|
-
)
|
|
202
|
+
except (AttributeError, KeyError, ValueError):
|
|
203
|
+
return 0.0
|
|
206
204
|
|
|
207
205
|
def update_timeindex(self, event: MarketEvent):
|
|
208
206
|
"""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def setup_mock_metatrader():
|
|
6
|
+
"""Mock MetaTrader5 on Linux to prevent import errors."""
|
|
7
|
+
if platform.system() == "Linux":
|
|
8
|
+
from unittest.mock import MagicMock
|
|
9
|
+
|
|
10
|
+
class Mock(MagicMock):
|
|
11
|
+
@classmethod
|
|
12
|
+
def __getattr__(cls, name):
|
|
13
|
+
return MagicMock()
|
|
14
|
+
|
|
15
|
+
MOCK_MODULES = ["MetaTrader5"]
|
|
16
|
+
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
|
|
17
|
+
|
|
18
|
+
print(
|
|
19
|
+
"Warning: MetaTrader5 is not available on Linux. A mock version is being used."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
setup_mock_metatrader()
|
|
@@ -4,6 +4,7 @@ import urllib.request
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
|
6
6
|
|
|
7
|
+
from bbstrader import compat # noqa: F401
|
|
7
8
|
import MetaTrader5 as mt5
|
|
8
9
|
import pandas as pd
|
|
9
10
|
from currency_converter import SINGLE_DAY_ECB_URL, CurrencyConverter
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from typing import Optional, Union
|
|
3
3
|
|
|
4
|
+
from bbstrader import compat # noqa: F401
|
|
4
5
|
import MetaTrader5 as Mt5
|
|
5
6
|
import pandas as pd
|
|
6
7
|
from exchange_calendars import get_calendar, get_calendar_names
|
|
7
8
|
from pandas.tseries.holiday import USFederalHolidayCalendar
|
|
8
9
|
from pandas.tseries.offsets import CustomBusinessDay
|
|
9
10
|
|
|
11
|
+
|
|
10
12
|
from bbstrader.metatrader.account import AMG_EXCHANGES, Account, check_mt5_connection
|
|
11
13
|
from bbstrader.metatrader.utils import TIMEFRAMES, TimeFrame, raise_mt5_error
|
|
12
14
|
|
|
@@ -172,7 +174,7 @@ class Rates(object):
|
|
|
172
174
|
480,
|
|
173
175
|
720,
|
|
174
176
|
]:
|
|
175
|
-
key = f"{minutes//60}h" if minutes >= 60 else f"{minutes}m"
|
|
177
|
+
key = f"{minutes // 60}h" if minutes >= 60 else f"{minutes}m"
|
|
176
178
|
time_frame_mapping[key] = int(td * (60 / minutes) * sd)
|
|
177
179
|
time_frame_mapping["D1"] = int(td)
|
|
178
180
|
|
|
@@ -4,6 +4,7 @@ from datetime import datetime
|
|
|
4
4
|
from logging import Logger
|
|
5
5
|
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple
|
|
6
6
|
|
|
7
|
+
from bbstrader import compat # noqa: F401
|
|
7
8
|
import MetaTrader5 as Mt5
|
|
8
9
|
import pandas as pd
|
|
9
10
|
from tabulate import tabulate
|
|
@@ -89,7 +90,7 @@ class Trade(RiskManagement):
|
|
|
89
90
|
symbol: str = "EURUSD",
|
|
90
91
|
expert_name: str = "bbstrader",
|
|
91
92
|
expert_id: int = 9818,
|
|
92
|
-
version: str = "
|
|
93
|
+
version: str = "2.0",
|
|
93
94
|
target: float = 5.0,
|
|
94
95
|
start_time: str = "1:00",
|
|
95
96
|
finishing_time: str = "23:00",
|
|
@@ -604,7 +605,7 @@ class Trade(RiskManagement):
|
|
|
604
605
|
result = self.send_order(request)
|
|
605
606
|
if result.retcode == Mt5.TRADE_RETCODE_DONE:
|
|
606
607
|
break
|
|
607
|
-
elif result.retcode == Mt5.TRADE_RETCODE_INVALID_VOLUME:
|
|
608
|
+
elif result.retcode == Mt5.TRADE_RETCODE_INVALID_VOLUME: # 10014
|
|
608
609
|
new_volume = int(request["volume"])
|
|
609
610
|
if new_volume >= 1:
|
|
610
611
|
request["volume"] = new_volume
|
|
@@ -660,7 +661,7 @@ class Trade(RiskManagement):
|
|
|
660
661
|
self.sell_positions.append(position.ticket)
|
|
661
662
|
profit = round(self.get_account_info().profit, 5)
|
|
662
663
|
order_info = (
|
|
663
|
-
f"2. {order_type} Position Opened, Symbol: {self.symbol}, Price: @{round(position.price_open,5)}, "
|
|
664
|
+
f"2. {order_type} Position Opened, Symbol: {self.symbol}, Price: @{round(position.price_open, 5)}, "
|
|
664
665
|
f"Sl: @{position.sl} Tp: @{position.tp}"
|
|
665
666
|
)
|
|
666
667
|
self.logger.info(order_info)
|
|
@@ -922,21 +923,35 @@ class Trade(RiskManagement):
|
|
|
922
923
|
return current_profit >= th_profit
|
|
923
924
|
return False
|
|
924
925
|
|
|
926
|
+
def _get_trail_after_points(self, trail_after_points: int | str) -> int:
|
|
927
|
+
if isinstance(trail_after_points, str):
|
|
928
|
+
if trail_after_points == "SL":
|
|
929
|
+
return self.get_stop_loss()
|
|
930
|
+
elif trail_after_points == "TP":
|
|
931
|
+
return self.get_take_profit()
|
|
932
|
+
elif trail_after_points == "BE":
|
|
933
|
+
return self.get_break_even()
|
|
934
|
+
# TODO: Add other combinations (e.g. "SL+TP", "SL+BE", "TP+BE", "SL*N", etc.)
|
|
935
|
+
return trail_after_points
|
|
936
|
+
|
|
925
937
|
def break_even(
|
|
926
938
|
self,
|
|
927
939
|
mm=True,
|
|
928
940
|
id: Optional[int] = None,
|
|
929
941
|
trail: Optional[bool] = True,
|
|
930
942
|
stop_trail: Optional[int] = None,
|
|
931
|
-
trail_after_points:
|
|
943
|
+
trail_after_points: int | str = None,
|
|
932
944
|
be_plus_points: Optional[int] = None,
|
|
933
945
|
):
|
|
934
946
|
"""
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
If
|
|
939
|
-
|
|
947
|
+
Manages the break-even level of a trading position.
|
|
948
|
+
|
|
949
|
+
This function checks whether it is time to set a break-even stop loss for an open position.
|
|
950
|
+
If the break-even level is already set, it monitors price movement and updates the stop loss
|
|
951
|
+
accordingly if the `trail` parameter is enabled.
|
|
952
|
+
|
|
953
|
+
When `trail` is enabled, the function dynamically adjusts the break-even level based on the
|
|
954
|
+
`trail_after_points` and `stop_trail` parameters.
|
|
940
955
|
|
|
941
956
|
Args:
|
|
942
957
|
id (int): The strategy ID or expert ID.
|
|
@@ -944,8 +959,12 @@ class Trade(RiskManagement):
|
|
|
944
959
|
trail (bool): Whether to trail the stop loss or not.
|
|
945
960
|
stop_trail (int): Number of points to trail the stop loss by.
|
|
946
961
|
It represent the distance from the current price to the stop loss.
|
|
947
|
-
trail_after_points (int): Number of points in profit
|
|
962
|
+
trail_after_points (int, str): Number of points in profit
|
|
948
963
|
from where the strategy will start to trail the stop loss.
|
|
964
|
+
If set to str, it must be one of the following values:
|
|
965
|
+
- 'SL' to trail the stop loss after the profit reaches the stop loss level in points.
|
|
966
|
+
- 'TP' to trail the stop loss after the profit reaches the take profit level in points.
|
|
967
|
+
- 'BE' to trail the stop loss after the profit reaches the break-even level in points.
|
|
949
968
|
be_plus_points (int): Number of points to add to the break-even level.
|
|
950
969
|
Represents the minimum profit to secure.
|
|
951
970
|
"""
|
|
@@ -956,16 +975,19 @@ class Trade(RiskManagement):
|
|
|
956
975
|
positions = self.get_positions(symbol=self.symbol)
|
|
957
976
|
be = self.get_break_even()
|
|
958
977
|
if trail_after_points is not None:
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
978
|
+
if isinstance(trail_after_points, int):
|
|
979
|
+
assert trail_after_points > be, (
|
|
980
|
+
"trail_after_points must be greater than break even or set to None"
|
|
981
|
+
)
|
|
982
|
+
trail_after_points = self._get_trail_after_points(trail_after_points)
|
|
962
983
|
if positions is not None:
|
|
963
984
|
for position in positions:
|
|
964
985
|
if position.magic == Id:
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
986
|
+
symbol_info = self.get_symbol_info(self.symbol)
|
|
987
|
+
size = symbol_info.trade_tick_size
|
|
988
|
+
value = symbol_info.trade_tick_value
|
|
989
|
+
point = symbol_info.point
|
|
990
|
+
digits = symbol_info.digits
|
|
969
991
|
points = position.profit * (size / value / position.volume)
|
|
970
992
|
break_even = float(points / point) >= be
|
|
971
993
|
if break_even:
|
|
@@ -621,7 +621,7 @@ class MT5ExecutionEngine:
|
|
|
621
621
|
optimizer: str = "equal",
|
|
622
622
|
trail: bool = True,
|
|
623
623
|
stop_trail: Optional[int] = None,
|
|
624
|
-
trail_after_points:
|
|
624
|
+
trail_after_points: int | str = None,
|
|
625
625
|
be_plus_points: Optional[int] = None,
|
|
626
626
|
show_positions_orders: bool = False,
|
|
627
627
|
iter_time: int | float = 5,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: bbstrader
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
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/
|
|
@@ -19,6 +19,8 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Operating System :: Microsoft :: Windows
|
|
22
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
23
|
+
Classifier: Operating System :: MacOS
|
|
22
24
|
Classifier: License :: OSI Approved :: MIT License
|
|
23
25
|
Description-Content-Type: text/markdown
|
|
24
26
|
License-File: LICENSE
|
|
@@ -53,8 +55,7 @@ Requires-Dist: financetoolkit
|
|
|
53
55
|
Requires-Dist: tables
|
|
54
56
|
Requires-Dist: lightgbm
|
|
55
57
|
Requires-Dist: alphalens-reloaded
|
|
56
|
-
|
|
57
|
-
Requires-Dist: MetaTrader5; extra == "mt5"
|
|
58
|
+
Requires-Dist: MetaTrader5
|
|
58
59
|
Dynamic: author
|
|
59
60
|
Dynamic: author-email
|
|
60
61
|
Dynamic: classifier
|
|
@@ -66,7 +67,6 @@ Dynamic: keywords
|
|
|
66
67
|
Dynamic: license
|
|
67
68
|
Dynamic: maintainer
|
|
68
69
|
Dynamic: project-url
|
|
69
|
-
Dynamic: provides-extra
|
|
70
70
|
Dynamic: requires-dist
|
|
71
71
|
Dynamic: summary
|
|
72
72
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import sys
|
|
3
3
|
from os import path
|
|
4
|
+
import platform
|
|
4
5
|
|
|
5
6
|
from setuptools import setup
|
|
6
7
|
|
|
@@ -16,7 +17,10 @@ with io.open(path.join(here, "README.md"), encoding="utf-8") as f:
|
|
|
16
17
|
with io.open(path.join(here, "requirements.txt"), encoding="utf-8") as f:
|
|
17
18
|
REQUIREMENTS = [line.rstrip() for line in f]
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
if platform.system() == "Linux":
|
|
21
|
+
REQUIREMENTS.remove("MetaTrader5")
|
|
22
|
+
|
|
23
|
+
VERSION = "0.2.08"
|
|
20
24
|
DESCRIPTION = "Simplified Investment & Trading Toolkit"
|
|
21
25
|
|
|
22
26
|
KEYWORDS = [
|
|
@@ -54,6 +58,8 @@ CLASSIFIERS = [
|
|
|
54
58
|
"Programming Language :: Python :: 3.11",
|
|
55
59
|
"Programming Language :: Python :: 3.12",
|
|
56
60
|
"Operating System :: Microsoft :: Windows",
|
|
61
|
+
"Operating System :: POSIX :: Linux",
|
|
62
|
+
"Operating System :: MacOS",
|
|
57
63
|
"License :: OSI Approved :: MIT License",
|
|
58
64
|
]
|
|
59
65
|
|
|
@@ -88,7 +94,6 @@ setup(
|
|
|
88
94
|
packages=INLCUDE,
|
|
89
95
|
install_requires=REQUIREMENTS,
|
|
90
96
|
extras_require={
|
|
91
|
-
"MT5": ["MetaTrader5"],
|
|
92
97
|
# 'zipline': ['zipline'],
|
|
93
98
|
# 'cerebro': ['backtrader'],
|
|
94
99
|
},
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|