bbstrader 0.3.2__py3-none-any.whl → 0.3.3__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 +5 -5
- bbstrader/btengine/data.py +3 -3
- bbstrader/btengine/strategy.py +9 -7
- bbstrader/core/data.py +3 -1
- bbstrader/core/scripts.py +62 -19
- bbstrader/metatrader/account.py +32 -18
- bbstrader/metatrader/copier.py +321 -171
- bbstrader/metatrader/rates.py +2 -2
- bbstrader/metatrader/trade.py +2 -2
- bbstrader/metatrader/utils.py +1 -5
- bbstrader/models/nlp.py +16 -11
- bbstrader/trading/execution.py +92 -41
- bbstrader/tseries.py +0 -2
- {bbstrader-0.3.2.dist-info → bbstrader-0.3.3.dist-info}/METADATA +2 -2
- {bbstrader-0.3.2.dist-info → bbstrader-0.3.3.dist-info}/RECORD +19 -19
- {bbstrader-0.3.2.dist-info → bbstrader-0.3.3.dist-info}/WHEEL +0 -0
- {bbstrader-0.3.2.dist-info → bbstrader-0.3.3.dist-info}/entry_points.txt +0 -0
- {bbstrader-0.3.2.dist-info → bbstrader-0.3.3.dist-info}/licenses/LICENSE +0 -0
- {bbstrader-0.3.2.dist-info → bbstrader-0.3.3.dist-info}/top_level.txt +0 -0
bbstrader/metatrader/rates.py
CHANGED
|
@@ -124,11 +124,11 @@ class Rates(object):
|
|
|
124
124
|
self.sd = session_duration
|
|
125
125
|
self.start_pos = self._get_start_pos(start_pos, timeframe)
|
|
126
126
|
self.count = count
|
|
127
|
-
self.
|
|
127
|
+
self.__initializ_mt5(**kwargs)
|
|
128
128
|
self.__account = Account(**kwargs)
|
|
129
129
|
self.__data = self.get_rates_from_pos()
|
|
130
130
|
|
|
131
|
-
def
|
|
131
|
+
def __initializ_mt5(self, **kwargs):
|
|
132
132
|
check_mt5_connection(**kwargs)
|
|
133
133
|
|
|
134
134
|
def _get_start_pos(self, index, time_frame):
|
bbstrader/metatrader/trade.py
CHANGED
|
@@ -590,7 +590,7 @@ class Trade(RiskManagement):
|
|
|
590
590
|
else:
|
|
591
591
|
raise ValueError("You need to set a price for pending orders")
|
|
592
592
|
else:
|
|
593
|
-
_price = self.get_tick_info(self.symbol).
|
|
593
|
+
_price = self.get_tick_info(self.symbol).bid
|
|
594
594
|
|
|
595
595
|
lot = volume or self.get_lot()
|
|
596
596
|
stop_loss = self.get_stop_loss()
|
|
@@ -683,7 +683,7 @@ class Trade(RiskManagement):
|
|
|
683
683
|
else:
|
|
684
684
|
raise ValueError("You need to set a price for pending orders")
|
|
685
685
|
else:
|
|
686
|
-
_price = self.get_tick_info(self.symbol).
|
|
686
|
+
_price = self.get_tick_info(self.symbol).ask
|
|
687
687
|
|
|
688
688
|
lot = volume or self.get_lot()
|
|
689
689
|
stop_loss = self.get_stop_loss()
|
bbstrader/metatrader/utils.py
CHANGED
|
@@ -486,11 +486,7 @@ class MT5TerminalError(Exception):
|
|
|
486
486
|
self.code = code
|
|
487
487
|
self.message = message
|
|
488
488
|
|
|
489
|
-
def
|
|
490
|
-
# if self.message is None:
|
|
491
|
-
# return f"{self.__class__.__name__}"
|
|
492
|
-
# else:
|
|
493
|
-
# return f"{self.__class__.__name__}, {self.message}"
|
|
489
|
+
def __repr__(self) -> str:
|
|
494
490
|
msg_str = str(self.message) if self.message is not None else ""
|
|
495
491
|
return f"{self.code} - {self.__class__.__name__}: {msg_str}"
|
|
496
492
|
|
bbstrader/models/nlp.py
CHANGED
|
@@ -12,6 +12,7 @@ import matplotlib.pyplot as plt
|
|
|
12
12
|
import nltk
|
|
13
13
|
import pandas as pd
|
|
14
14
|
import plotly.express as px
|
|
15
|
+
from bbstrader.core.data import FinancialNews
|
|
15
16
|
from dash import dcc, html
|
|
16
17
|
from dash.dependencies import Input, Output
|
|
17
18
|
from nltk.corpus import stopwords
|
|
@@ -19,11 +20,10 @@ from nltk.tokenize import word_tokenize
|
|
|
19
20
|
from textblob import TextBlob
|
|
20
21
|
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
|
|
21
22
|
|
|
22
|
-
from bbstrader.core.data import FinancialNews
|
|
23
|
-
|
|
24
23
|
__all__ = [
|
|
25
24
|
"TopicModeler",
|
|
26
25
|
"SentimentAnalyzer",
|
|
26
|
+
"LEXICON",
|
|
27
27
|
"EQUITY_LEXICON",
|
|
28
28
|
"FOREX_LEXICON",
|
|
29
29
|
"COMMODITIES_LEXICON",
|
|
@@ -331,6 +331,17 @@ FINANCIAL_LEXICON = {
|
|
|
331
331
|
**BONDS_LEXICON,
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
LEXICON = {
|
|
335
|
+
"stock": EQUITY_LEXICON,
|
|
336
|
+
"etf": EQUITY_LEXICON,
|
|
337
|
+
"future": FINANCIAL_LEXICON,
|
|
338
|
+
"forex": FOREX_LEXICON,
|
|
339
|
+
"crypto": CRYPTO_LEXICON,
|
|
340
|
+
"index": EQUITY_LEXICON,
|
|
341
|
+
"bond": BONDS_LEXICON,
|
|
342
|
+
"commodity": COMMODITIES_LEXICON,
|
|
343
|
+
}
|
|
344
|
+
|
|
334
345
|
|
|
335
346
|
class TopicModeler(object):
|
|
336
347
|
def __init__(self):
|
|
@@ -379,11 +390,6 @@ class SentimentAnalyzer(object):
|
|
|
379
390
|
analysis using VADER (SentimentIntensityAnalyzer) and optional TextBlob
|
|
380
391
|
for enhanced polarity scoring.
|
|
381
392
|
|
|
382
|
-
Attributes:
|
|
383
|
-
nlp (spacy.Language): A SpaCy NLP pipeline for tokenization and lemmatization,
|
|
384
|
-
with Named Entity Recognition (NER) disabled.
|
|
385
|
-
analyzer (SentimentIntensityAnalyzer): An instance of VADER's sentiment analyzer
|
|
386
|
-
for financial sentiment scoring.
|
|
387
393
|
"""
|
|
388
394
|
|
|
389
395
|
def __init__(self):
|
|
@@ -395,8 +401,6 @@ class SentimentAnalyzer(object):
|
|
|
395
401
|
- Loads the `en_core_web_sm` SpaCy model with Named Entity Recognition (NER) disabled.
|
|
396
402
|
- Initializes VADER's SentimentIntensityAnalyzer for sentiment scoring.
|
|
397
403
|
|
|
398
|
-
Args:
|
|
399
|
-
use_spacy (bool): If True, uses SpaCy for lemmatization. Defaults to False.
|
|
400
404
|
"""
|
|
401
405
|
nltk.download("punkt", quiet=True)
|
|
402
406
|
nltk.download("stopwords", quiet=True)
|
|
@@ -617,8 +621,9 @@ class SentimentAnalyzer(object):
|
|
|
617
621
|
|
|
618
622
|
# Suppress stdout/stderr from underlying libraries during execution
|
|
619
623
|
with open(os.devnull, "w") as devnull:
|
|
620
|
-
with
|
|
621
|
-
devnull
|
|
624
|
+
with (
|
|
625
|
+
contextlib.redirect_stdout(devnull),
|
|
626
|
+
contextlib.redirect_stderr(devnull),
|
|
622
627
|
):
|
|
623
628
|
with ThreadPoolExecutor() as executor:
|
|
624
629
|
# Map each future to its ticker for easy result lookup
|
bbstrader/trading/execution.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import concurrent.futures
|
|
2
|
+
import functools
|
|
1
3
|
import multiprocessing as mp
|
|
2
4
|
import sys
|
|
3
5
|
import time
|
|
4
6
|
from datetime import date, datetime
|
|
7
|
+
from multiprocessing.synchronize import Event
|
|
5
8
|
from typing import Callable, Dict, List, Literal, Optional
|
|
6
9
|
|
|
7
10
|
import pandas as pd
|
|
@@ -179,6 +182,8 @@ class Mt5ExecutionEngine:
|
|
|
179
182
|
mm: bool = True,
|
|
180
183
|
auto_trade: bool = True,
|
|
181
184
|
prompt_callback: Callable = None,
|
|
185
|
+
multithread: bool = False,
|
|
186
|
+
shutdown_event: Event = None,
|
|
182
187
|
optimizer: str = "equal",
|
|
183
188
|
trail: bool = True,
|
|
184
189
|
stop_trail: Optional[int] = None,
|
|
@@ -207,6 +212,10 @@ class Mt5ExecutionEngine:
|
|
|
207
212
|
the user for confimation.
|
|
208
213
|
prompt_callback : Callback function to prompt the user for confirmation.
|
|
209
214
|
This is useful when integrating with GUI applications.
|
|
215
|
+
multithread : If True, use a thread pool to process signals in parallel.
|
|
216
|
+
If False, process them sequentially. Set this to True only if the engine
|
|
217
|
+
is running in a separate process. Default to False.
|
|
218
|
+
shutdown_event : Use to terminate the copy process when runs in a custum environment like web App or GUI.
|
|
210
219
|
show_positions_orders : Print open positions and orders. Defaults to False.
|
|
211
220
|
iter_time : Interval to check for signals and `mm`. Defaults to 5.
|
|
212
221
|
use_trade_time : Open trades after the time is completed. Defaults to True.
|
|
@@ -251,6 +260,7 @@ class Mt5ExecutionEngine:
|
|
|
251
260
|
self.mm = mm
|
|
252
261
|
self.auto_trade = auto_trade
|
|
253
262
|
self.prompt_callback = prompt_callback
|
|
263
|
+
self.multithread = multithread
|
|
254
264
|
self.optimizer = optimizer
|
|
255
265
|
self.trail = trail
|
|
256
266
|
self.stop_trail = stop_trail
|
|
@@ -274,6 +284,9 @@ class Mt5ExecutionEngine:
|
|
|
274
284
|
|
|
275
285
|
self._initialize_engine(**kwargs)
|
|
276
286
|
self.strategy = self._init_strategy(**kwargs)
|
|
287
|
+
self.shutdown_event = (
|
|
288
|
+
shutdown_event if shutdown_event is not None else mp.Event()
|
|
289
|
+
)
|
|
277
290
|
self._running = True
|
|
278
291
|
|
|
279
292
|
def __repr__(self):
|
|
@@ -316,6 +329,7 @@ class Mt5ExecutionEngine:
|
|
|
316
329
|
def _print_exc(self, msg: str, e: Exception):
|
|
317
330
|
if isinstance(e, KeyboardInterrupt):
|
|
318
331
|
logger.info("Stopping the Execution Engine ...")
|
|
332
|
+
self.stop()
|
|
319
333
|
sys.exit(0)
|
|
320
334
|
if self.debug_mode:
|
|
321
335
|
raise ValueError(msg).with_traceback(e.__traceback__)
|
|
@@ -866,46 +880,79 @@ class Mt5ExecutionEngine:
|
|
|
866
880
|
f"(e.g., if time_frame is 15m, iter_time must be 1.5, 3, 5, 15 etc)"
|
|
867
881
|
)
|
|
868
882
|
|
|
869
|
-
def
|
|
883
|
+
def _handle_one_signal(self, signal, today, buys, sells):
|
|
870
884
|
try:
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
action
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
if len(self.symbols) >= 10:
|
|
895
|
-
if symbol == self.symbols[-1]:
|
|
896
|
-
logger.info(
|
|
897
|
-
f"Not trading Time !!!, STRATEGY={self.STRATEGY} , ACCOUNT={self.ACCOUNT}"
|
|
898
|
-
)
|
|
899
|
-
else:
|
|
885
|
+
symbol = signal.symbol
|
|
886
|
+
trade: Trade = self.trades_instances[symbol]
|
|
887
|
+
if trade.trading_time() and today in self.trading_days:
|
|
888
|
+
if signal.action is not None:
|
|
889
|
+
action = (
|
|
890
|
+
signal.action.value
|
|
891
|
+
if isinstance(signal.action, TradeAction)
|
|
892
|
+
else signal.action
|
|
893
|
+
)
|
|
894
|
+
self._run_trade_algorithm(
|
|
895
|
+
action,
|
|
896
|
+
symbol,
|
|
897
|
+
signal.id,
|
|
898
|
+
trade,
|
|
899
|
+
signal.price,
|
|
900
|
+
signal.stoplimit,
|
|
901
|
+
buys,
|
|
902
|
+
sells,
|
|
903
|
+
signal.comment or self.comment,
|
|
904
|
+
)
|
|
905
|
+
else:
|
|
906
|
+
if len(self.symbols) >= 10:
|
|
907
|
+
if symbol == self.symbols[-1]:
|
|
900
908
|
logger.info(
|
|
901
|
-
f"Not trading Time
|
|
909
|
+
f"Not trading Time !!!, STRATEGY={self.STRATEGY} , ACCOUNT={self.ACCOUNT}"
|
|
902
910
|
)
|
|
903
|
-
|
|
911
|
+
else:
|
|
912
|
+
logger.info(
|
|
913
|
+
f"Not trading Time !!! SYMBOL={trade.symbol}, STRATEGY={self.STRATEGY} , ACCOUNT={self.ACCOUNT}"
|
|
914
|
+
)
|
|
915
|
+
self._check(buys[symbol], sells[symbol], symbol)
|
|
904
916
|
|
|
905
917
|
except Exception as e:
|
|
906
|
-
msg =
|
|
918
|
+
msg = (
|
|
919
|
+
f"Error handling signal for SYMBOL={signal.symbol} (SIGNAL: {action}), "
|
|
920
|
+
f"STRATEGY={self.STRATEGY}, ACCOUNT={self.ACCOUNT}"
|
|
921
|
+
)
|
|
907
922
|
self._print_exc(msg, e)
|
|
908
|
-
|
|
923
|
+
|
|
924
|
+
def _handle_all_signals(self, today, signals, buys, sells, max_workers=50):
|
|
925
|
+
try:
|
|
926
|
+
check_mt5_connection(**self.kwargs)
|
|
927
|
+
except Exception as e:
|
|
928
|
+
msg = "Initial MT5 connection check failed. Aborting signal processing."
|
|
929
|
+
self._print_exc(msg, e)
|
|
930
|
+
return
|
|
931
|
+
|
|
932
|
+
if not signals:
|
|
933
|
+
logger.info("No signals to process.")
|
|
934
|
+
return
|
|
935
|
+
|
|
936
|
+
# We want to create a temporary function that
|
|
937
|
+
# already has the 'today', 'buys', and 'sells' arguments filled in.
|
|
938
|
+
# This is necessary because executor.map only iterates over one sequence (signals).
|
|
939
|
+
signal_processor = functools.partial(
|
|
940
|
+
self._handle_one_signal, today=today, buys=buys, sells=sells
|
|
941
|
+
)
|
|
942
|
+
if self.multithread:
|
|
943
|
+
with concurrent.futures.ThreadPoolExecutor(
|
|
944
|
+
max_workers=max_workers
|
|
945
|
+
) as executor:
|
|
946
|
+
# 'map' will apply our worker function to every item in the 'signals' list.
|
|
947
|
+
# It will automatically manage the distribution of tasks to the worker threads.
|
|
948
|
+
# We wrap it in list() to ensure all tasks are complete before moving on.
|
|
949
|
+
list(executor.map(signal_processor, signals))
|
|
950
|
+
else:
|
|
951
|
+
for signal in signals:
|
|
952
|
+
try:
|
|
953
|
+
signal_processor(signal)
|
|
954
|
+
except Exception as e:
|
|
955
|
+
self._print_exc(f"Failed to process signal {signal}: ", e)
|
|
909
956
|
|
|
910
957
|
def _handle_period_end_actions(self, today):
|
|
911
958
|
try:
|
|
@@ -925,7 +972,7 @@ class Mt5ExecutionEngine:
|
|
|
925
972
|
pass
|
|
926
973
|
|
|
927
974
|
def run(self):
|
|
928
|
-
while self._running:
|
|
975
|
+
while self._running and not self.shutdown_event.is_set():
|
|
929
976
|
try:
|
|
930
977
|
check_mt5_connection(**self.kwargs)
|
|
931
978
|
positions_orders = self._check_positions_orders()
|
|
@@ -943,24 +990,27 @@ class Mt5ExecutionEngine:
|
|
|
943
990
|
self._check(buys[symbol], sells[symbol], symbol)
|
|
944
991
|
else:
|
|
945
992
|
self._update_risk(weights)
|
|
946
|
-
self.
|
|
993
|
+
self._handle_all_signals(today, signals, buys, sells)
|
|
947
994
|
self._sleep()
|
|
948
995
|
self._handle_period_end_actions(today)
|
|
949
996
|
except KeyboardInterrupt:
|
|
950
997
|
logger.info(
|
|
951
998
|
f"Stopping Execution Engine for {self.STRATEGY} STRATEGY on {self.ACCOUNT} Account"
|
|
952
999
|
)
|
|
953
|
-
|
|
1000
|
+
self.stop()
|
|
1001
|
+
sys.exit(0)
|
|
954
1002
|
except Exception as e:
|
|
955
1003
|
msg = f"Running Execution Engine, STRATEGY={self.STRATEGY} , ACCOUNT={self.ACCOUNT}"
|
|
956
1004
|
self._print_exc(msg, e)
|
|
957
1005
|
|
|
958
1006
|
def stop(self):
|
|
959
1007
|
"""Stops the execution engine."""
|
|
960
|
-
self._running
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1008
|
+
if self._running:
|
|
1009
|
+
logger.info(
|
|
1010
|
+
f"Stopping Execution Engine for {self.STRATEGY} STRATEGY on {self.ACCOUNT} Account"
|
|
1011
|
+
)
|
|
1012
|
+
self._running = False
|
|
1013
|
+
self.shutdown_event.set()
|
|
964
1014
|
logger.info("Execution Engine stopped successfully.")
|
|
965
1015
|
|
|
966
1016
|
|
|
@@ -1008,6 +1058,7 @@ def RunMt5Engines(accounts: Dict[str, Dict], start_delay: float = 1.0):
|
|
|
1008
1058
|
|
|
1009
1059
|
for account_id, params in accounts.items():
|
|
1010
1060
|
log.info(f"Starting process for {account_id}")
|
|
1061
|
+
params["multithread"] = True
|
|
1011
1062
|
process = mp.Process(target=RunMt5Engine, args=(account_id,), kwargs=params)
|
|
1012
1063
|
process.start()
|
|
1013
1064
|
processes[process] = account_id
|
bbstrader/tseries.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bbstrader
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
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/
|
|
@@ -380,7 +380,7 @@ You may need to create the `~/.bbstrader/` directory and its subdirectories (lik
|
|
|
380
380
|
|
|
381
381
|
For comprehensive information, including detailed API references, tutorials, and advanced guides for each module, please refer to our full documentation hosted on ReadTheDocs:
|
|
382
382
|
|
|
383
|
-
[**View the Full Documentation
|
|
383
|
+
[**View the Full Documentation**](https://bbstrader.readthedocs.io/en/latest/)
|
|
384
384
|
|
|
385
385
|
Additionally, the codebase is commented and includes docstrings, which can be a valuable resource for understanding the implementation details of specific functions and classes.
|
|
386
386
|
|
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
bbstrader/__init__.py,sha256=4KVGBEYU3ao9zPVM3rMWqNuvCleCeA6C2MVe_AFc4rw,581
|
|
2
|
-
bbstrader/__main__.py,sha256=
|
|
2
|
+
bbstrader/__main__.py,sha256=f6EsJGNrP1OuuNUyS5y_aMAVp4uDYjkHYxFuKwDh0dM,2233
|
|
3
3
|
bbstrader/compat.py,sha256=djbHMvTvy0HYm1zyZ6Ttp_LMwP2PqTSVw1r7pqbz7So,487
|
|
4
4
|
bbstrader/config.py,sha256=riZxwb4hN0I-dSsWcjnROc5dWQpSJ9iKOMIp4PMGfko,3970
|
|
5
|
-
bbstrader/tseries.py,sha256=
|
|
5
|
+
bbstrader/tseries.py,sha256=SM_LTQHJ3ZXVkVJyZ51CefUDzJDl2TkJqBKMp_uM8s4,43833
|
|
6
6
|
bbstrader/btengine/__init__.py,sha256=y1btjaEfhWsH8vuE7mBRpP9Tu-Azt9REhuVYsPCAfBU,2955
|
|
7
7
|
bbstrader/btengine/backtest.py,sha256=o3eoCVzpjykDx-9VgkxK6DKZdGDAuLVeeWLCa2U_zeY,14652
|
|
8
|
-
bbstrader/btengine/data.py,sha256=
|
|
8
|
+
bbstrader/btengine/data.py,sha256=WcBLtabboZkQdtOQS3SjbiJD9BcWc75sdhZ2voQ_lUw,27061
|
|
9
9
|
bbstrader/btengine/event.py,sha256=Ydl1avAXp9WAWOBXDAckcb9g1UkcnCO0rRzcJZwIq20,8714
|
|
10
10
|
bbstrader/btengine/execution.py,sha256=4MytWjcKg8J_w14P43emHqsvKOElkQTfhVYNakU6euQ,11190
|
|
11
11
|
bbstrader/btengine/performance.py,sha256=1ecWrTzHBQbk4ORvbTEKxwCzlL1brcXOEUwgbnjAwx4,12470
|
|
12
12
|
bbstrader/btengine/portfolio.py,sha256=z98M65HQeCyma8gMZkAxspxBA9jtIhzxMyJUHPPj34c,16128
|
|
13
13
|
bbstrader/btengine/scripts.py,sha256=8o66dq4Ex4DsH4s8xvJqUOFjLzZJSnbBvvNBzohtzoE,4837
|
|
14
|
-
bbstrader/btengine/strategy.py,sha256=
|
|
14
|
+
bbstrader/btengine/strategy.py,sha256=MV50N46OPOV-xGLnO0aFp6drbh0A5e3vck_m4SFg7Sc,34400
|
|
15
15
|
bbstrader/core/__init__.py,sha256=GIFzFSStPfE0XM2j7mDeZZQeMTh_AwPsDOQXwMVJLgw,97
|
|
16
|
-
bbstrader/core/data.py,sha256=
|
|
17
|
-
bbstrader/core/scripts.py,sha256=
|
|
16
|
+
bbstrader/core/data.py,sha256=5-ByClb-E3-iqDz8CBJ4om9wBIA7DmUWezu4A-tv5ys,25095
|
|
17
|
+
bbstrader/core/scripts.py,sha256=bMZ5I_hCTPCsAn9v9Sz9fQQ7JFkf_Zwtv7uUJwaqVBU,5466
|
|
18
18
|
bbstrader/core/utils.py,sha256=WjuabzBjhY65ku2KL-f7CMalE2x-wrX-6mCA_qhhFPE,2728
|
|
19
19
|
bbstrader/ibkr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
bbstrader/ibkr/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
bbstrader/metatrader/__init__.py,sha256=A5Ye9tpc2sp9Xk5qjKw-EfYsoRcZtAt8nqvC3tCtZs8,333
|
|
22
|
-
bbstrader/metatrader/account.py,sha256=
|
|
22
|
+
bbstrader/metatrader/account.py,sha256=17HV2lv9K2xhuU0H1SFDQaVZycf8ZAWlwOalwiKj_S8,59688
|
|
23
23
|
bbstrader/metatrader/analysis.py,sha256=pnZWdvEnf9wkPT0vhEIbZipnN5EUf6TaQftplYP9jRs,3564
|
|
24
|
-
bbstrader/metatrader/copier.py,sha256=
|
|
25
|
-
bbstrader/metatrader/rates.py,sha256=
|
|
24
|
+
bbstrader/metatrader/copier.py,sha256=KFlBHguWAvxxlIKdnhs9o6y6OB8i7h-o2ZufMmQZbBA,54030
|
|
25
|
+
bbstrader/metatrader/rates.py,sha256=w9mr6FB6E1zLcHCDtDGt-oMnw6sakIU6Qe3455KDsSg,20782
|
|
26
26
|
bbstrader/metatrader/risk.py,sha256=NhW8qtSg350Z6H9oLcDqOU_erqd_7Y7F5FwpfPN5Qso,27262
|
|
27
27
|
bbstrader/metatrader/scripts.py,sha256=DQGwrzqOZLX4CVWM4Du73kc5k_8RxUaIkoc8rvPTt7c,3558
|
|
28
|
-
bbstrader/metatrader/trade.py,sha256=
|
|
29
|
-
bbstrader/metatrader/utils.py,sha256=
|
|
28
|
+
bbstrader/metatrader/trade.py,sha256=ezkALiUgtIu54R4m4blQjptWoRXNVG5wwuoctP2b90Y,80624
|
|
29
|
+
bbstrader/metatrader/utils.py,sha256=9RC1RqBqgIPiEloUYD5zhXBHkf7_oeOfzhqqYQoZXqY,19561
|
|
30
30
|
bbstrader/models/__init__.py,sha256=B-bn2h_SCK6gRAs2li6dDVnvV8jDT5suZimldk5xxcw,497
|
|
31
31
|
bbstrader/models/factors.py,sha256=Y1rjwhWU4aiSRd-jFOLnLZczFCY0bJUxauCo17HvOFY,12791
|
|
32
32
|
bbstrader/models/ml.py,sha256=CxbasDRXzBF3rOF4ObpIjhJw6IZ9G3C3jwoC-o_BMyI,48809
|
|
33
|
-
bbstrader/models/nlp.py,sha256=
|
|
33
|
+
bbstrader/models/nlp.py,sha256=hcvz9d_8j1cIC1h3oqa1DBjExRIEd6WSiZb95Vr3NPo,32638
|
|
34
34
|
bbstrader/models/optimization.py,sha256=Fa4tdhynMmvKt5KHV9cH1TXmmJVJwU4QWpYkbeVq4aI,6395
|
|
35
35
|
bbstrader/models/portfolio.py,sha256=r-47Zrn2r7iKCHm5YVtwkbBJXAZGM3QYy-rXCWY9-Bg,8079
|
|
36
36
|
bbstrader/models/risk.py,sha256=MKCk53HtGIcivrNzH8Ikm5KMs1rXhFT5zkorUf30PyQ,506
|
|
37
37
|
bbstrader/trading/__init__.py,sha256=ycLyuuxN5SujqtzR9X0Q74UQfK93q2va-GGAXdr-KS8,457
|
|
38
|
-
bbstrader/trading/execution.py,sha256=
|
|
38
|
+
bbstrader/trading/execution.py,sha256=nAxb9EDPNF3g8I5C5vz6e9k0xF5CNNLHmKlHgck0-rY,41460
|
|
39
39
|
bbstrader/trading/scripts.py,sha256=Tf5q33WqqygjpIv43_8nA82VZ3GM0qgb4Ggo3fHJ_wg,5744
|
|
40
40
|
bbstrader/trading/strategies.py,sha256=RZ6P4SfIyRW72v0OnPnrc4Hv8X00FdxR-_sD23xe_Pg,11756
|
|
41
41
|
bbstrader/trading/utils.py,sha256=57dKF9dcRu04oU2VRqydRrzW39dCW2wlDWhVt-sZdRw,1857
|
|
42
|
-
bbstrader-0.3.
|
|
43
|
-
bbstrader-0.3.
|
|
44
|
-
bbstrader-0.3.
|
|
45
|
-
bbstrader-0.3.
|
|
46
|
-
bbstrader-0.3.
|
|
47
|
-
bbstrader-0.3.
|
|
42
|
+
bbstrader-0.3.3.dist-info/licenses/LICENSE,sha256=ZwC_RqqGmOPBUiMDKqLyJZ5HBeHq53LpL7TMRzrJY8c,1094
|
|
43
|
+
bbstrader-0.3.3.dist-info/METADATA,sha256=JPXFWSA0ytHgqPoaOenYRpKsea6toGN-Gc1TcrEt7Bk,27106
|
|
44
|
+
bbstrader-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
45
|
+
bbstrader-0.3.3.dist-info/entry_points.txt,sha256=0yDCbhbgHswOzJnY5wRSM_FjjyMHGvY7lJpSSVh0xtI,54
|
|
46
|
+
bbstrader-0.3.3.dist-info/top_level.txt,sha256=Wwj322jZmxGZ6gD_TdaPiPLjED5ReObm5omerwlmZIg,10
|
|
47
|
+
bbstrader-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|