sovai 0.2.0__tar.gz → 0.2.2__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.
- {sovai-0.2.0 → sovai-0.2.2}/PKG-INFO +3 -1
- {sovai-0.2.0 → sovai-0.2.2}/pyproject.toml +3 -1
- {sovai-0.2.0 → sovai-0.2.2}/sovai/__init__.py +10 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/pandas_extensions.py +13 -0
- sovai-0.2.2/sovai/extensions/technical_indicators.py +219 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/get_data.py +118 -160
- {sovai-0.2.0 → sovai-0.2.2}/sovai/get_plots.py +10 -2
- {sovai-0.2.0 → sovai-0.2.2}/sovai/get_reports.py +5 -0
- sovai-0.2.2/sovai/get_tools.py +17 -0
- sovai-0.2.2/sovai/plots/earnings_surprise/__init__.py +1 -0
- sovai-0.2.2/sovai/plots/earnings_surprise/earnings_surprise_plots.py +135 -0
- sovai-0.2.2/sovai/plots/news/news_plots.py +795 -0
- sovai-0.2.2/sovai/reports/news/__inti__.py +1 -0
- sovai-0.2.2/sovai/reports/news/news_econometric_analysis.py +396 -0
- sovai-0.2.2/sovai/token_auth.py +15 -0
- sovai-0.2.2/sovai/tools/sec/sec_10_k_8_k_filings.py +535 -0
- sovai-0.2.2/sovai/tools/sec/sec_edgar_search.py +212 -0
- sovai-0.2.2/sovai/utils/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/client_side.py +2 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/file_management.py +2 -1
- sovai-0.2.0/data/tickers.parq +0 -0
- sovai-0.2.0/sovai/assets/tickers.parq +0 -0
- sovai-0.2.0/sovai/plots/news/news_plots.py +0 -116
- sovai-0.2.0/sovai/token_auth.py +0 -7
- {sovai-0.2.0 → sovai-0.2.2}/LICENSE +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/README.md +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/api_config.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/assets/dropdown.css +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/assets/features_mapping.parq +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/basic_auth.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/computations/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/computations/functions.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/errors/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/errors/sovai_errors.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/anomalies.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/change_point_generator.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/clustering.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/core_kshape.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/cum_sum_torch.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/cusum.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/dimensionality_reduction.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/feature_extraction.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/feature_importance.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/feature_neutralizer.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/fractional_differencing.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/nowcasting.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/pairwise.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/parallel_functions.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/pfa_feature_selector.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/regime_change.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/regime_change_pca.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/shapley_global_importance.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/shapley_importance.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/signal_evaluation.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/time_decomposition.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/extensions/weight_optimization.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/get_compute.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/accounting/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/accounting/accounting_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/allocation/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/allocation/allocation_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/bankruptcy/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/bankruptcy/bankruptcy_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/breakout/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/breakout/breakout_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/corp_risk/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/corp_risk/corp_risk_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/insider/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/insider/insider_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/institutional/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/institutional/institutional_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/news/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/ratios/__init__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/plots/ratios/ratios_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/reports/accounting/__inti__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/reports/accounting/accounting_balance_sheet.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/reports/bankruptcy/__inti__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/reports/bankruptcy/bankruptcy_monthly_top.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/reports/general/__inti__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/reports/general/general_plots.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/studies/nowcasting.py +0 -0
- /sovai-0.2.0/sovai/utils/__init__.py → /sovai-0.2.2/sovai/tools/sec/__inti__.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/converter.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/datetime_formats.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/get_tickers.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/helpers.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/pandas_extensions copy.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/plot.py +0 -0
- {sovai-0.2.0 → sovai-0.2.2}/sovai/utils/stream.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sovai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: python for asset management
|
|
5
5
|
License: Proprietary License
|
|
6
6
|
Author: Derek Snow
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Requires-Dist: boto3 (>=1.20)
|
|
15
15
|
Requires-Dist: dash (>=2.0)
|
|
16
16
|
Requires-Dist: great-tables (>=0.9)
|
|
17
|
+
Requires-Dist: ipywidgets (>=8.1.3,<9.0.0)
|
|
17
18
|
Requires-Dist: joblib (>=1.0)
|
|
18
19
|
Requires-Dist: lightgbm (>=4.5.0,<5.0.0)
|
|
19
20
|
Requires-Dist: matplotlib (>=3.0)
|
|
@@ -25,6 +26,7 @@ Requires-Dist: pandas (>=1.0)
|
|
|
25
26
|
Requires-Dist: pexpect (>=4.9.0,<5.0.0)
|
|
26
27
|
Requires-Dist: plotly (>=5.0)
|
|
27
28
|
Requires-Dist: polars (>=0.20.30)
|
|
29
|
+
Requires-Dist: polars-talib (==0.1.3)
|
|
28
30
|
Requires-Dist: pyarrow (>=5.0)
|
|
29
31
|
Requires-Dist: python-dateutil (>=2.8)
|
|
30
32
|
Requires-Dist: python-dotenv (>=0.10)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "sovai"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.2"
|
|
4
4
|
description = "python for asset management"
|
|
5
5
|
authors = ["Derek Snow <d.snow@outlook.com>"]
|
|
6
6
|
license = "Proprietary License"
|
|
@@ -56,6 +56,8 @@ openai = ">=1.0"
|
|
|
56
56
|
mfles = ">=0.2"
|
|
57
57
|
pexpect = "^4.9.0"
|
|
58
58
|
lightgbm = "^4.5.0"
|
|
59
|
+
ipywidgets = "^8.1.3"
|
|
60
|
+
polars-talib = "0.1.3"
|
|
59
61
|
|
|
60
62
|
[build-system]
|
|
61
63
|
requires = ["poetry-core"]
|
|
@@ -19,6 +19,16 @@ from .extensions.pandas_extensions import CustomDataFrame as extension
|
|
|
19
19
|
from .utils.file_management import save_or_update_tickers
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
|
|
23
|
+
from .get_tools import sec_search
|
|
24
|
+
|
|
25
|
+
from .get_tools import sec_filing
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
22
32
|
# Call the function to ensure tickers data is up-to-date
|
|
23
33
|
save_or_update_tickers()
|
|
24
34
|
|
|
@@ -76,6 +76,8 @@ from sovai.extensions.weight_optimization import WeightOptimization
|
|
|
76
76
|
|
|
77
77
|
from sovai.extensions.signal_evaluation import SignalEvaluator
|
|
78
78
|
|
|
79
|
+
from sovai.extensions.technical_indicators import techn_indicators
|
|
80
|
+
|
|
79
81
|
|
|
80
82
|
import warnings
|
|
81
83
|
|
|
@@ -908,6 +910,17 @@ class CustomDataFrame(pd.DataFrame):
|
|
|
908
910
|
)
|
|
909
911
|
|
|
910
912
|
return CustomDataFrame(avg_shap_values)
|
|
913
|
+
|
|
914
|
+
def technical_indicators(self):
|
|
915
|
+
"""
|
|
916
|
+
Computes feature importance using SHAP values based on multiple simulations.
|
|
917
|
+
|
|
918
|
+
:param num_simulations: The number of simulations to run (default 4).
|
|
919
|
+
:param clustering_method: The clustering method to use ('OPTICS' or 'KMeans').
|
|
920
|
+
:return: A DataFrame with average SHAP values per feature.
|
|
921
|
+
"""
|
|
922
|
+
|
|
923
|
+
return CustomDataFrame(techn_indicators(self))
|
|
911
924
|
|
|
912
925
|
|
|
913
926
|
# # Example usage
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import polars as pl
|
|
2
|
+
import polars_talib as plta
|
|
3
|
+
import warnings
|
|
4
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
5
|
+
|
|
6
|
+
def func_ts_date(df_group: pl.DataFrame) -> pl.DataFrame:
|
|
7
|
+
# Ensure the data is sorted by date
|
|
8
|
+
df_group = df_group.sort("date")
|
|
9
|
+
|
|
10
|
+
# Calculate technical indicators
|
|
11
|
+
df_group = df_group.with_columns([
|
|
12
|
+
plta.bbands(timeperiod=20, nbdevup=2, nbdevdn=2).alias('BBANDS'),
|
|
13
|
+
plta.ema(timeperiod=20).alias('EMA_20'),
|
|
14
|
+
plta.macd(fastperiod=12, slowperiod=26, signalperiod=9).alias('MACD'),
|
|
15
|
+
plta.adx(timeperiod=14).alias('ADX_14'),
|
|
16
|
+
plta.cci(timeperiod=14).alias('CCI_14'),
|
|
17
|
+
plta.mfi(timeperiod=14).alias('MFI_14'),
|
|
18
|
+
plta.mom(timeperiod=10).alias('MOM_10'),
|
|
19
|
+
plta.stoch(fastk_period=5, slowk_period=3, slowd_period=3).alias('STOCH'),
|
|
20
|
+
plta.willr(timeperiod=14).alias('WILLR_14'),
|
|
21
|
+
plta.atr(timeperiod=14).alias('ATR_14'),
|
|
22
|
+
plta.obv().alias('OBV'),
|
|
23
|
+
plta.ad().alias('AD'),
|
|
24
|
+
plta.aroon(timeperiod=14).alias('AROON_14'),
|
|
25
|
+
plta.bop().alias('BOP'),
|
|
26
|
+
plta.cmo(timeperiod=14).alias('CMO_14'),
|
|
27
|
+
plta.dx(timeperiod=14).alias('DX_14'),
|
|
28
|
+
plta.kama(timeperiod=30).alias('KAMA_30'),
|
|
29
|
+
plta.ppo().alias('PPO'),
|
|
30
|
+
plta.rocr(timeperiod=10).alias('ROCR_10'),
|
|
31
|
+
plta.trix(timeperiod=30).alias('TRIX_30'),
|
|
32
|
+
plta.ultosc().alias('ULTOSC'),
|
|
33
|
+
plta.natr(timeperiod=14).alias('NATR_14'),
|
|
34
|
+
plta.ht_dcperiod().alias('HT_DCPERIOD'),
|
|
35
|
+
plta.ht_dcphase().alias('HT_DCPHASE'),
|
|
36
|
+
plta.ht_phasor().alias('HT_PHASOR'),
|
|
37
|
+
plta.ht_sine().alias('HT_SINE'),
|
|
38
|
+
plta.ht_trendmode().alias('HT_TRENDMODE'),
|
|
39
|
+
plta.avgprice().alias('AVGPRICE'),
|
|
40
|
+
plta.medprice().alias('MEDPRICE'),
|
|
41
|
+
plta.typprice().alias('TYPPRICE'),
|
|
42
|
+
plta.wclprice().alias('WCLPRICE'),
|
|
43
|
+
plta.beta(timeperiod=5).alias('BETA_5'),
|
|
44
|
+
plta.correl(timeperiod=30).alias('CORREL_30'),
|
|
45
|
+
plta.linearreg(timeperiod=14).alias('LINEARREG_14'),
|
|
46
|
+
plta.linearreg_angle(timeperiod=14).alias('LINEARREG_ANGLE_14'),
|
|
47
|
+
plta.linearreg_intercept(timeperiod=14).alias('LINEARREG_INTERCEPT_14'),
|
|
48
|
+
plta.linearreg_slope(timeperiod=14).alias('LINEARREG_SLOPE_14'),
|
|
49
|
+
plta.tsf(timeperiod=14).alias('TSF_14'),
|
|
50
|
+
plta.var(timeperiod=5).alias('VAR_5'),
|
|
51
|
+
plta.sar(acceleration=0.02, maximum=0.2).alias('SAR'),
|
|
52
|
+
plta.adxr(timeperiod=14).alias('ADXR_14'),
|
|
53
|
+
plta.apo(fastperiod=12, slowperiod=26, matype=0).alias('APO'),
|
|
54
|
+
plta.aroonosc(timeperiod=14).alias('AROONOSC_14'),
|
|
55
|
+
plta.dema(timeperiod=30).alias('DEMA_30'),
|
|
56
|
+
plta.ht_trendline().alias('HT_TRENDLINE'),
|
|
57
|
+
plta.ma(timeperiod=30, matype=0).alias('MA_30'),
|
|
58
|
+
plta.mama().alias('MAMA'),
|
|
59
|
+
plta.mavp(periods=pl.col("volume"), minperiod=2, maxperiod=30, matype=0).alias('MAVP'),
|
|
60
|
+
plta.midpoint(timeperiod=14).alias('MIDPOINT_14'),
|
|
61
|
+
plta.midprice(timeperiod=14).alias('MIDPRICE_14'),
|
|
62
|
+
plta.sarext().alias('SAREXT'),
|
|
63
|
+
plta.sma(timeperiod=30).alias('SMA_30'),
|
|
64
|
+
plta.t3(timeperiod=5, vfactor=0.7).alias('T3_5'),
|
|
65
|
+
plta.tema(timeperiod=30).alias('TEMA_30'),
|
|
66
|
+
plta.trima(timeperiod=30).alias('TRIMA_30'),
|
|
67
|
+
plta.wma(timeperiod=30).alias('WMA_30'),
|
|
68
|
+
plta.cdl2crows().alias('CDL2CROWS'),
|
|
69
|
+
plta.cdl3blackcrows().alias('CDL3BLACKCROWS'),
|
|
70
|
+
plta.cdl3inside().alias('CDL3INSIDE'),
|
|
71
|
+
plta.cdl3linestrike().alias('CDL3LINESTRIKE'),
|
|
72
|
+
plta.cdl3outside().alias('CDL3OUTSIDE'),
|
|
73
|
+
plta.cdl3starsinsouth().alias('CDL3STARSINSOUTH'),
|
|
74
|
+
plta.cdl3whitesoldiers().alias('CDL3WHITESOLDIERS'),
|
|
75
|
+
plta.cdlabandonedbaby().alias('CDLABANDONEDBABY'),
|
|
76
|
+
plta.cdladvanceblock().alias('CDLADVANCEBLOCK'),
|
|
77
|
+
plta.cdlbelthold().alias('CDLBELTHOLD'),
|
|
78
|
+
plta.cdlbreakaway().alias('CDLBREAKAWAY'),
|
|
79
|
+
plta.cdlclosingmarubozu().alias('CDLCLOSINGMARUBOZU'),
|
|
80
|
+
plta.cdlconcealbabyswall().alias('CDLCONCEALBABYSWALL'),
|
|
81
|
+
plta.cdlcounterattack().alias('CDLCOUNTERATTACK'),
|
|
82
|
+
plta.cdldarkcloudcover().alias('CDLDARKCLOUDCOVER'),
|
|
83
|
+
plta.cdldoji().alias('CDLDOJI'),
|
|
84
|
+
plta.cdldojistar().alias('CDLDOJISTAR'),
|
|
85
|
+
plta.cdldragonflydoji().alias('CDLDRAGONFLYDOJI'),
|
|
86
|
+
plta.cdlengulfing().alias('CDLENGULFING'),
|
|
87
|
+
plta.cdleveningdojistar().alias('CDLEVENINGDOJISTAR'),
|
|
88
|
+
plta.cdleveningstar().alias('CDLEVENINGSTAR'),
|
|
89
|
+
plta.cdlgapsidesidewhite().alias('CDLGAPSIDESIDEWHITE'),
|
|
90
|
+
plta.cdlgravestonedoji().alias('CDLGRAVESTONEDOJI'),
|
|
91
|
+
plta.cdlhammer().alias('CDLHAMMER'),
|
|
92
|
+
plta.cdlhangingman().alias('CDLHANGINGMAN'),
|
|
93
|
+
plta.cdlharami().alias('CDLHARAMI'),
|
|
94
|
+
plta.cdlharamicross().alias('CDLHARAMICROSS'),
|
|
95
|
+
plta.cdlhighwave().alias('CDLHIGHWAVE'),
|
|
96
|
+
plta.cdlhikkake().alias('CDLHIKKAKE'),
|
|
97
|
+
plta.cdlhikkakemod().alias('CDLHIKKAKEMOD'),
|
|
98
|
+
plta.cdlhomingpigeon().alias('CDLHOMINGPIGEON'),
|
|
99
|
+
plta.cdlidentical3crows().alias('CDLIDENTICAL3CROWS'),
|
|
100
|
+
plta.cdlinneck().alias('CDLINNECK'),
|
|
101
|
+
plta.cdlinvertedhammer().alias('CDLINVERTEDHAMMER'),
|
|
102
|
+
plta.cdlkicking().alias('CDLKICKING'),
|
|
103
|
+
plta.cdlkickingbylength().alias('CDLKICKINGBYLENGTH'),
|
|
104
|
+
plta.cdlladderbottom().alias('CDLLADDERBOTTOM'),
|
|
105
|
+
plta.cdllongleggeddoji().alias('CDLLONGLEGGEDDOJI'),
|
|
106
|
+
plta.cdllongline().alias('CDLLONGLINE'),
|
|
107
|
+
plta.cdlmarubozu().alias('CDLMARUBOZU'),
|
|
108
|
+
plta.cdlmatchinglow().alias('CDLMATCHINGLOW'),
|
|
109
|
+
plta.cdlmathold().alias('CDLMATHOLD'),
|
|
110
|
+
plta.cdlmorningdojistar().alias('CDLMORNINGDOJISTAR'),
|
|
111
|
+
plta.cdlmorningstar().alias('CDLMORNINGSTAR'),
|
|
112
|
+
plta.cdlonneck().alias('CDLONNECK'),
|
|
113
|
+
plta.cdlpiercing().alias('CDLPIERCING'),
|
|
114
|
+
plta.cdlrickshawman().alias('CDLRICKSHAWMAN'),
|
|
115
|
+
plta.cdlrisefall3methods().alias('CDLRISEFALL3METHODS'),
|
|
116
|
+
plta.cdlseparatinglines().alias('CDLSEPARATINGLINES'),
|
|
117
|
+
plta.cdlshootingstar().alias('CDLSHOOTINGSTAR'),
|
|
118
|
+
plta.cdlshortline().alias('CDLSHORTLINE'),
|
|
119
|
+
plta.cdlspinningtop().alias('CDLSPINNINGTOP'),
|
|
120
|
+
plta.cdlstalledpattern().alias('CDLSTALLEDPATTERN'),
|
|
121
|
+
plta.cdlsticksandwich().alias('CDLSTICKSANDWICH'),
|
|
122
|
+
plta.cdltakuri().alias('CDLTAKURI'),
|
|
123
|
+
plta.cdltasukigap().alias('CDLTASUKIGAP'),
|
|
124
|
+
plta.cdlthrusting().alias('CDLTHRUSTING'),
|
|
125
|
+
plta.cdltristar().alias('CDLTRISTAR'),
|
|
126
|
+
plta.cdlunique3river().alias('CDLUNIQUE3RIVER'),
|
|
127
|
+
plta.cdlupsidegap2crows().alias('CDLUPSIDEGAP2CROWS'),
|
|
128
|
+
plta.cdlxsidegap3methods().alias('CDLXSIDEGAP3METHODS'),
|
|
129
|
+
plta.trange().alias('TRANGE'),
|
|
130
|
+
plta.adosc(fastperiod=3, slowperiod=10).alias('ADOSC'),
|
|
131
|
+
plta.roc(timeperiod=10).alias('ROC_10'),
|
|
132
|
+
plta.rocp(timeperiod=10).alias('ROCP_10'),
|
|
133
|
+
plta.rocr100(timeperiod=10).alias('ROCR100_10'),
|
|
134
|
+
plta.rsi(timeperiod=14).alias('RSI_14'),
|
|
135
|
+
plta.stochf(fastk_period=5, fastd_period=3, fastd_matype=0).alias('STOCHF'),
|
|
136
|
+
plta.stochrsi(timeperiod=14, fastk_period=5, fastd_period=3, fastd_matype=0).alias('STOCHRSI'),
|
|
137
|
+
plta.add(pl.col("high")).alias('ADD'),
|
|
138
|
+
plta.div(pl.col("high")).alias('DIV'),
|
|
139
|
+
plta.max(timeperiod=30).alias('MAX_30'),
|
|
140
|
+
plta.maxindex(timeperiod=30).alias('MAXINDEX_30'),
|
|
141
|
+
plta.min(timeperiod=30).alias('MIN_30'),
|
|
142
|
+
plta.minindex(timeperiod=30).alias('MININDEX_30'),
|
|
143
|
+
plta.minmax(timeperiod=30).alias('MINMAX_30'),
|
|
144
|
+
plta.minmaxindex(timeperiod=30).alias('MINMAXINDEX_30'),
|
|
145
|
+
plta.mult(pl.col("high")).alias('MULT'),
|
|
146
|
+
plta.sub(pl.col("high")).alias('SUB'),
|
|
147
|
+
plta.sum(timeperiod=30).alias('SUM_30'),
|
|
148
|
+
plta.acos().alias('ACOS'),
|
|
149
|
+
plta.asin().alias('ASIN'),
|
|
150
|
+
plta.atan().alias('ATAN'),
|
|
151
|
+
plta.ceil().alias('CEIL'),
|
|
152
|
+
plta.cos().alias('COS'),
|
|
153
|
+
plta.cosh().alias('COSH'),
|
|
154
|
+
plta.exp().alias('EXP'),
|
|
155
|
+
plta.floor().alias('FLOOR'),
|
|
156
|
+
plta.ln().alias('LN'),
|
|
157
|
+
plta.log10().alias('LOG10'),
|
|
158
|
+
plta.sin().alias('SIN'),
|
|
159
|
+
plta.sinh().alias('SINH'),
|
|
160
|
+
plta.sqrt().alias('SQRT'),
|
|
161
|
+
plta.tan().alias('TAN'),
|
|
162
|
+
plta.tanh().alias('TANH'),
|
|
163
|
+
plta.stddev(timeperiod=5).alias('STDDEV_5'),
|
|
164
|
+
])
|
|
165
|
+
|
|
166
|
+
# Handle multi-value returns
|
|
167
|
+
df_group = df_group.with_columns([
|
|
168
|
+
pl.col('BBANDS').struct.field('upperband').alias('BBANDS_upper'),
|
|
169
|
+
pl.col('BBANDS').struct.field('middleband').alias('BBANDS_middle'),
|
|
170
|
+
pl.col('BBANDS').struct.field('lowerband').alias('BBANDS_lower'),
|
|
171
|
+
pl.col('MACD').struct.field('macd').alias('MACD_macd'),
|
|
172
|
+
pl.col('MACD').struct.field('macdsignal').alias('MACD_signal'),
|
|
173
|
+
pl.col('MACD').struct.field('macdhist').alias('MACD_hist'),
|
|
174
|
+
pl.col('STOCH').struct.field('slowk').alias('STOCH_slowk'),
|
|
175
|
+
pl.col('STOCH').struct.field('slowd').alias('STOCH_slowd'),
|
|
176
|
+
pl.col('AROON_14').struct.field('aroondown').alias('AROON_down'),
|
|
177
|
+
pl.col('AROON_14').struct.field('aroonup').alias('AROON_up'),
|
|
178
|
+
pl.col('HT_PHASOR').struct.field('inphase').alias('HT_PHASOR_inphase'),
|
|
179
|
+
pl.col('HT_PHASOR').struct.field('quadrature').alias('HT_PHASOR_quadrature'),
|
|
180
|
+
pl.col('HT_SINE').struct.field('sine').alias('HT_SINE_sine'),
|
|
181
|
+
pl.col('HT_SINE').struct.field('leadsine').alias('HT_SINE_leadsine'),
|
|
182
|
+
pl.col('MAMA').struct.field('mama').alias('MAMA_mama'),
|
|
183
|
+
pl.col('MAMA').struct.field('fama').alias('MAMA_fama'),
|
|
184
|
+
pl.col('STOCHF').struct.field('fastk').alias('STOCHF_fastk'),
|
|
185
|
+
pl.col('STOCHF').struct.field('fastd').alias('STOCHF_fastd'),
|
|
186
|
+
pl.col('STOCHRSI').struct.field('fastk').alias('STOCHRSI_fastk'),
|
|
187
|
+
pl.col('STOCHRSI').struct.field('fastd').alias('STOCHRSI_fastd'),
|
|
188
|
+
pl.col('MINMAX_30').struct.field('min').alias('MINMAX_30_min'),
|
|
189
|
+
pl.col('MINMAX_30').struct.field('max').alias('MINMAX_30_max'),
|
|
190
|
+
pl.col('MINMAXINDEX_30').struct.field('minidx').alias('MINMAXINDEX_30_minidx'),
|
|
191
|
+
pl.col('MINMAXINDEX_30').struct.field('maxidx').alias('MINMAXINDEX_30_maxidx'),
|
|
192
|
+
])
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# Drop the original struct columns
|
|
196
|
+
df_group = df_group.drop(['BBANDS', 'MACD', 'STOCH', 'AROON_14', 'HT_PHASOR', 'HT_SINE','MAMA','STOCHF','MINMAX_30','MINMAXINDEX_30'])
|
|
197
|
+
|
|
198
|
+
return df_group
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def techn_indicators(df_price):
|
|
202
|
+
# Assuming df_polars is your initial DataFrame
|
|
203
|
+
df_polars = pl.from_pandas(df_price.reset_index())
|
|
204
|
+
df_polars = df_polars.group_by("ticker").map_groups(func_ts_date).to_pandas().set_index(["ticker","date"]).sort_index()
|
|
205
|
+
|
|
206
|
+
# List of columns to remove
|
|
207
|
+
columns_to_remove = [
|
|
208
|
+
'OBV', 'AD', 'ADOSC', 'VAR_5', 'TRANGE',
|
|
209
|
+
'STOCHRSI',
|
|
210
|
+
'DIV', 'LN', 'LOG10',
|
|
211
|
+
'COS',
|
|
212
|
+
'EMA_20', 'MOM_10', 'AVGPRICE', 'MEDPRICE', 'TYPPRICE', 'WCLPRICE',
|
|
213
|
+
'BETA_5', 'CORREL_30', 'LINEARREG_14', 'TSF_14', 'SAR', 'MAVP', 'SAREXT'
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
# Remove problematic columns
|
|
217
|
+
df_polars = df_polars.drop(columns=[col for col in columns_to_remove if col in df_polars.columns])
|
|
218
|
+
|
|
219
|
+
return df_polars
|
|
@@ -21,7 +21,8 @@ import boto3
|
|
|
21
21
|
from io import BytesIO
|
|
22
22
|
import json
|
|
23
23
|
|
|
24
|
-
# from fastapi import HTTPException
|
|
24
|
+
# from fastapi import HTTPException ## Dee
|
|
25
|
+
|
|
25
26
|
import pyarrow.parquet as pq
|
|
26
27
|
import time
|
|
27
28
|
import hashlib
|
|
@@ -105,7 +106,104 @@ def read_parquet(
|
|
|
105
106
|
return pl.read_parquet(url)
|
|
106
107
|
else:
|
|
107
108
|
return CustomDataFrame(pd.read_parquet(url))
|
|
109
|
+
|
|
108
110
|
|
|
111
|
+
import pandas as pd
|
|
112
|
+
from typing import Union, List
|
|
113
|
+
|
|
114
|
+
def filter_data(
|
|
115
|
+
data: Union[pd.DataFrame, 'pl.DataFrame'],
|
|
116
|
+
columns: Union[str, List[str]] = None,
|
|
117
|
+
start_date: str = None,
|
|
118
|
+
end_date: str = None,
|
|
119
|
+
use_polars: bool = False
|
|
120
|
+
) -> Union[pd.DataFrame, 'pl.DataFrame']:
|
|
121
|
+
"""
|
|
122
|
+
Filter the data based on specified columns and date range.
|
|
123
|
+
Always includes 'ticker', 'date', and 'calculation' columns if they exist in the original DataFrame.
|
|
124
|
+
|
|
125
|
+
:param data: Input DataFrame (pandas or polars)
|
|
126
|
+
:param columns: Columns to select (string or list of strings)
|
|
127
|
+
:param start_date: Start date for filtering (string in 'YYYY-MM-DD' format)
|
|
128
|
+
:param end_date: End date for filtering (string in 'YYYY-MM-DD' format)
|
|
129
|
+
:param use_polars: Boolean indicating whether to use polars instead of pandas
|
|
130
|
+
:return: Filtered DataFrame
|
|
131
|
+
"""
|
|
132
|
+
if use_polars:
|
|
133
|
+
import polars as pl
|
|
134
|
+
|
|
135
|
+
# Prepare columns list
|
|
136
|
+
if columns:
|
|
137
|
+
if isinstance(columns, str):
|
|
138
|
+
columns = columns.split(',')
|
|
139
|
+
columns = [col.strip() for col in columns]
|
|
140
|
+
else:
|
|
141
|
+
columns = data.columns.to_list()
|
|
142
|
+
|
|
143
|
+
# Always include 'ticker', 'date', and 'calculation' if they exist
|
|
144
|
+
for col in ['calculation', 'date', 'ticker']:
|
|
145
|
+
if col in data.columns and col not in columns:
|
|
146
|
+
columns.insert(0, col)
|
|
147
|
+
|
|
148
|
+
# Column filtering
|
|
149
|
+
data = data.select(columns)
|
|
150
|
+
|
|
151
|
+
# Date filtering
|
|
152
|
+
if start_date or end_date:
|
|
153
|
+
if 'date' in data.columns:
|
|
154
|
+
if start_date:
|
|
155
|
+
data = data.filter(pl.col('date') >= pl.Date.parse(start_date))
|
|
156
|
+
if end_date:
|
|
157
|
+
data = data.filter(pl.col('date') <= pl.Date.parse(end_date))
|
|
158
|
+
else:
|
|
159
|
+
# Assume date is in index if not in columns
|
|
160
|
+
data = data.with_row_count('temp_index')
|
|
161
|
+
if start_date:
|
|
162
|
+
data = data.filter(pl.col('temp_index').cast(pl.Date) >= pl.Date.parse(start_date))
|
|
163
|
+
if end_date:
|
|
164
|
+
data = data.filter(pl.col('temp_index').cast(pl.Date) <= pl.Date.parse(end_date))
|
|
165
|
+
data = data.drop('temp_index')
|
|
166
|
+
|
|
167
|
+
else:
|
|
168
|
+
# Prepare columns list
|
|
169
|
+
if columns:
|
|
170
|
+
if isinstance(columns, str):
|
|
171
|
+
columns = columns.split(',')
|
|
172
|
+
columns = [col.strip() for col in columns]
|
|
173
|
+
else:
|
|
174
|
+
columns = list(data.columns)
|
|
175
|
+
|
|
176
|
+
# Always include 'ticker', 'date', and 'calculation' if they exist
|
|
177
|
+
for col in ['calculation', 'date', 'ticker']:
|
|
178
|
+
if col in data.columns and col not in columns:
|
|
179
|
+
columns.insert(0, col)
|
|
180
|
+
|
|
181
|
+
# Column filtering
|
|
182
|
+
data = data[columns]
|
|
183
|
+
|
|
184
|
+
if start_date or end_date:
|
|
185
|
+
if 'date' in data.columns:
|
|
186
|
+
data['date'] = pd.to_datetime(data['date'])
|
|
187
|
+
if start_date:
|
|
188
|
+
data = data[data['date'] >= pd.to_datetime(start_date)]
|
|
189
|
+
if end_date:
|
|
190
|
+
data = data[data['date'] <= pd.to_datetime(end_date)]
|
|
191
|
+
elif isinstance(data.index, pd.DatetimeIndex):
|
|
192
|
+
if start_date:
|
|
193
|
+
data = data[data.index >= pd.to_datetime(start_date)]
|
|
194
|
+
if end_date:
|
|
195
|
+
data = data[data.index <= pd.to_datetime(end_date)]
|
|
196
|
+
elif isinstance(data.index, pd.MultiIndex) and any(isinstance(level, pd.DatetimeIndex) for level in data.index.levels):
|
|
197
|
+
date_level = next(level for level in data.index.levels if isinstance(level, pd.DatetimeIndex))
|
|
198
|
+
if start_date:
|
|
199
|
+
data = data[data.index.get_level_values(date_level.name) >= pd.to_datetime(start_date)]
|
|
200
|
+
if end_date:
|
|
201
|
+
data = data[data.index.get_level_values(date_level.name) <= pd.to_datetime(end_date)]
|
|
202
|
+
else:
|
|
203
|
+
print("Warning: Unable to filter by date. Date column or index not found.")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
return data
|
|
109
207
|
|
|
110
208
|
# Global cache
|
|
111
209
|
_query_cache = {}
|
|
@@ -115,6 +213,9 @@ _query_cache = {}
|
|
|
115
213
|
## None means no ticker. "" Mean ticker but on parquet for all.
|
|
116
214
|
|
|
117
215
|
endpoint_to_ticker = {
|
|
216
|
+
"/risks": "",
|
|
217
|
+
"/government/traffic/domains": "",
|
|
218
|
+
"/government/traffic/agencies": "",
|
|
118
219
|
"/risks": "",
|
|
119
220
|
"/bankruptcy": "",
|
|
120
221
|
"/bankruptcy/shapleys": "",
|
|
@@ -172,7 +273,10 @@ endpoint_to_ticker = {
|
|
|
172
273
|
"/complaints/public": "",
|
|
173
274
|
"/short/over_shorted": "",
|
|
174
275
|
"/earnings/surprise": "",
|
|
175
|
-
"/
|
|
276
|
+
"/news/sentiment_score": "",
|
|
277
|
+
"/news/topic_probability": "",
|
|
278
|
+
"/news/polarity_score": "",
|
|
279
|
+
|
|
176
280
|
}
|
|
177
281
|
|
|
178
282
|
## There are give types of file retrievals
|
|
@@ -375,17 +479,24 @@ def data(
|
|
|
375
479
|
_query_cache[cache_key] = data
|
|
376
480
|
return data
|
|
377
481
|
|
|
482
|
+
|
|
483
|
+
# Example usage in your existing code:
|
|
378
484
|
if is_all(tickers):
|
|
379
485
|
verbose_mode.vprint("All ticker Initialized")
|
|
380
486
|
url = res.text.strip('"')
|
|
381
487
|
verbose_mode.vprint(url, " (download link)")
|
|
382
488
|
data = read_parquet(url, use_polars=use_polars)
|
|
383
|
-
|
|
384
|
-
|
|
489
|
+
|
|
490
|
+
# Apply filters
|
|
491
|
+
data = filter_data(data, columns=columns, start_date=start_date, end_date=end_date, use_polars=use_polars)
|
|
385
492
|
|
|
386
493
|
verbose_mode.vprint("It reached the DF")
|
|
387
|
-
|
|
388
|
-
|
|
494
|
+
try:
|
|
495
|
+
data = CustomDataFrame(convert_data2df(res.json()))
|
|
496
|
+
_query_cache[cache_key] = data
|
|
497
|
+
except:
|
|
498
|
+
_query_cache[cache_key] = data
|
|
499
|
+
|
|
389
500
|
verbose_mode.vprint("It passed the DF")
|
|
390
501
|
|
|
391
502
|
if plot:
|
|
@@ -394,6 +505,7 @@ def data(
|
|
|
394
505
|
return data
|
|
395
506
|
except Exception as err:
|
|
396
507
|
verbose_mode.vprint("An error occurred:", err)
|
|
508
|
+
return data
|
|
397
509
|
if res.status_code == 404:
|
|
398
510
|
msg = res.json()
|
|
399
511
|
msg.update({"status_code": 404, "error": err.args[0]})
|
|
@@ -401,160 +513,6 @@ def data(
|
|
|
401
513
|
return None
|
|
402
514
|
|
|
403
515
|
|
|
404
|
-
# def print_tickers_value(tickers):
|
|
405
|
-
# if tickers is None:
|
|
406
|
-
# print("tickers is None")
|
|
407
|
-
# elif tickers is False:
|
|
408
|
-
# print("tickers is False")
|
|
409
|
-
# else:
|
|
410
|
-
# print(f"tickers is: {tickers}")
|
|
411
|
-
|
|
412
|
-
# # Example usage
|
|
413
|
-
|
|
414
|
-
# def data(
|
|
415
|
-
# endpoint: str,
|
|
416
|
-
# tickers: Union[str, list, None] = None,
|
|
417
|
-
# chart: Optional[str] = None,
|
|
418
|
-
# columns_name: Optional[str] = None,
|
|
419
|
-
# version: Optional[str] = None,
|
|
420
|
-
# start_date: Optional[str] = None,
|
|
421
|
-
# end_date: Optional[str] = None,
|
|
422
|
-
# predict: bool = False,
|
|
423
|
-
# plot: bool = False,
|
|
424
|
-
# rows: Optional[int] = None,
|
|
425
|
-
# limit: Optional[int] = None,
|
|
426
|
-
# params: Optional[dict] = None,
|
|
427
|
-
# body: Optional[dict] = None,
|
|
428
|
-
# use_polars: bool = False,
|
|
429
|
-
# purge_cache: bool = False,
|
|
430
|
-
# parquet: bool = True,
|
|
431
|
-
# ) -> Union[pd.DataFrame, None]:
|
|
432
|
-
# params = params or {}
|
|
433
|
-
# params.update(
|
|
434
|
-
# _prepare_params(
|
|
435
|
-
# tickers=tickers,
|
|
436
|
-
# chart=chart,
|
|
437
|
-
# version=version,
|
|
438
|
-
# from_date=start_date,
|
|
439
|
-
# to_date=end_date,
|
|
440
|
-
# limit=rows or limit,
|
|
441
|
-
# predict=predict,
|
|
442
|
-
# columns=columns_name,
|
|
443
|
-
# )
|
|
444
|
-
# )
|
|
445
|
-
# endpoint, params = _prepare_endpoint(endpoint, params)
|
|
446
|
-
# print(endpoint)
|
|
447
|
-
# params = params or None
|
|
448
|
-
# headers = {"Authorization": f"Bearer {ApiConfig.token}"}
|
|
449
|
-
# url = ApiConfig.base_url + endpoint
|
|
450
|
-
|
|
451
|
-
# print(f"Requesting URL: {url} with params: {params}")
|
|
452
|
-
|
|
453
|
-
# # Create a unique cache key
|
|
454
|
-
# cache_key = hashlib.sha256(json.dumps([url, params], sort_keys=True).encode()).hexdigest()
|
|
455
|
-
|
|
456
|
-
# # Check if the result is already in the cache
|
|
457
|
-
# # Purge cache if requested
|
|
458
|
-
# if purge_cache and cache_key in _query_cache:
|
|
459
|
-
# del _query_cache[cache_key]
|
|
460
|
-
# print("Cache entry purged.")
|
|
461
|
-
|
|
462
|
-
# # Check if the result is already in the cache
|
|
463
|
-
# if not purge_cache and cache_key in _query_cache:
|
|
464
|
-
# print("Returning cached data")
|
|
465
|
-
# return _query_cache[cache_key]
|
|
466
|
-
|
|
467
|
-
# try:
|
|
468
|
-
# res = requests.get(
|
|
469
|
-
# url=url,
|
|
470
|
-
# headers=headers,
|
|
471
|
-
# data=body,
|
|
472
|
-
# params=params,
|
|
473
|
-
# stream=True,
|
|
474
|
-
# verify=ApiConfig.verify_ssl,
|
|
475
|
-
# )
|
|
476
|
-
# res.raise_for_status()
|
|
477
|
-
# print(f"Response Status: {res.status_code}")
|
|
478
|
-
# print(f"Response Content-Type: {res.headers.get('content-type')}")
|
|
479
|
-
|
|
480
|
-
# # Print a small part of the response for preview
|
|
481
|
-
# # response_preview = res.text[:2] # Adjust the number of characters as needed
|
|
482
|
-
# # print(f"Response Preview: {response_preview}")
|
|
483
|
-
# print_tickers_value(tickers)
|
|
484
|
-
|
|
485
|
-
# print(params)
|
|
486
|
-
|
|
487
|
-
# # print("Before check..")
|
|
488
|
-
# # print(is_all(tickers))
|
|
489
|
-
# # if is_all(tickers):
|
|
490
|
-
# # response_dict = res.json()
|
|
491
|
-
# # print("this is loading parquet")
|
|
492
|
-
# # # Assuming response_dict is a dictionary containing the required keys
|
|
493
|
-
# # print("Bucket Name:", response_dict["bucket_name"])
|
|
494
|
-
# # print("File Name:", response_dict["file_name"])
|
|
495
|
-
# # print("Access Key:", response_dict["access_key"])
|
|
496
|
-
# # print("Secret Key:", response_dict["secret_key"])
|
|
497
|
-
|
|
498
|
-
# # return load_df_from_wasabi(response_dict["bucket_name"], response_dict["file_name"], response_dict["access_key"], response_dict["secret_key"])
|
|
499
|
-
|
|
500
|
-
# tickers = get_ticker_from_endpoint(endpoint, tickers, endpoint_to_ticker)
|
|
501
|
-
|
|
502
|
-
# print_tickers_value(tickers)
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
# data_format = res.headers.get("X-Data-Format")
|
|
506
|
-
# content_type = res.headers["content-type"]
|
|
507
|
-
|
|
508
|
-
# if content_type == "application/octet-stream":
|
|
509
|
-
# if data_format == "pyarrow":
|
|
510
|
-
# data = CustomDataFrame(stream_data_pyarrow(res))
|
|
511
|
-
# else:
|
|
512
|
-
# data = CustomDataFrame(stream_data(res))
|
|
513
|
-
# _query_cache[cache_key] = data
|
|
514
|
-
# return data
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
# if is_all(tickers):
|
|
518
|
-
# print("All ticker Initialized")
|
|
519
|
-
# url = res.text.strip('"')
|
|
520
|
-
# print(url, " (download link)", )
|
|
521
|
-
# data = read_parquet(url, use_polars=use_polars)
|
|
522
|
-
# _query_cache[cache_key] = data
|
|
523
|
-
|
|
524
|
-
# return data
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
# print("It reached the DF")
|
|
528
|
-
# data = CustomDataFrame(convert_data2df(res.json()))
|
|
529
|
-
# _query_cache[cache_key] = data
|
|
530
|
-
# print("It passsed the DF")
|
|
531
|
-
|
|
532
|
-
# if plot:
|
|
533
|
-
# _draw_graphs(data)
|
|
534
|
-
# return None
|
|
535
|
-
# return data
|
|
536
|
-
# except Exception as err:
|
|
537
|
-
# print("An error occurred:", err)
|
|
538
|
-
# if res.status_code == 404:
|
|
539
|
-
# msg = res.json()
|
|
540
|
-
# msg.update({"status_code": 404, "error": err.args[0]})
|
|
541
|
-
# raise InvalidInputData(str(msg))
|
|
542
|
-
# return None
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
# def _prepare_params(**kwargs):
|
|
546
|
-
# finish_params = {}
|
|
547
|
-
# if isinstance(kwargs["tickers"], list):
|
|
548
|
-
# kwargs["tickers"] = ",".join(kwargs["tickers"])
|
|
549
|
-
# if isinstance(kwargs["columns"], list):
|
|
550
|
-
# kwargs["columns"] = ",".join(kwargs["columns"])
|
|
551
|
-
# for server_param, client_param in kwargs.items():
|
|
552
|
-
# if client_param:
|
|
553
|
-
# finish_params[server_param] = str(client_param)
|
|
554
|
-
|
|
555
|
-
# return finish_params
|
|
556
|
-
|
|
557
|
-
|
|
558
516
|
def _prepare_params(**kwargs):
|
|
559
517
|
finish_params = {}
|
|
560
518
|
|
|
@@ -5,11 +5,12 @@ from .plots.breakout.breakout_plots import *
|
|
|
5
5
|
from .plots.accounting.accounting_plots import *
|
|
6
6
|
from .plots.ratios.ratios_plots import *
|
|
7
7
|
from .plots.institutional.institutional_plots import *
|
|
8
|
-
from .plots.news.news_plots import
|
|
8
|
+
from .plots.news.news_plots import plot_news_daily, create_plot_news_sent_price, plot_above_sentiment_returns, run_dash_news_ts
|
|
9
9
|
from .plots.corp_risk.corp_risk_plots import *
|
|
10
10
|
|
|
11
11
|
from .plots.insider.insider_plots import *
|
|
12
12
|
from .plots.allocation.allocation_plots import *
|
|
13
|
+
from .plots.earnings_surprise.earnings_surprise_plots import *
|
|
13
14
|
|
|
14
15
|
from sovai.utils.plot import plotting_data
|
|
15
16
|
from typing import Optional, Union, Tuple, List, Dict
|
|
@@ -70,6 +71,7 @@ def generate_error_message(analysis_type, chart_type, source, verbose):
|
|
|
70
71
|
else:
|
|
71
72
|
display(Markdown("**An unknown error occurred.**"))
|
|
72
73
|
|
|
74
|
+
##
|
|
73
75
|
|
|
74
76
|
plot_ticker_widget
|
|
75
77
|
|
|
@@ -110,9 +112,15 @@ PLOT_FUNCTION_MAPPER = {
|
|
|
110
112
|
("insider", "flows", "local"): insider_flows_plot,
|
|
111
113
|
("insider", "prediction", "local"): insider_flow_predictions_plot,
|
|
112
114
|
("news", "sentiment", "local"): plot_above_sentiment_returns,
|
|
115
|
+
("news", "strategy", "local"): plot_news_daily,
|
|
116
|
+
("news", "analysis", "local"): run_dash_news_ts,
|
|
113
117
|
("corprisk/risks", "line", "local"): plotting_corp_risk_line,
|
|
114
118
|
("allocation", "line", "local"): create_line_plot_allocation,
|
|
115
119
|
("allocation", "stacked", "local"): create_stacked_bar_plot_allocation,
|
|
120
|
+
("earnings", "line", "local"): create_earnings_surprise_plot,
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
116
124
|
|
|
117
125
|
# Add other mappings as needed
|
|
118
126
|
}
|
|
@@ -120,7 +128,7 @@ PLOT_FUNCTION_MAPPER = {
|
|
|
120
128
|
|
|
121
129
|
def plot(
|
|
122
130
|
dataset_name,
|
|
123
|
-
chart_type=
|
|
131
|
+
chart_type=None,
|
|
124
132
|
df=None,
|
|
125
133
|
tickers: Optional[List[str]] = None,
|
|
126
134
|
verbose=False,
|