virgo-modules 0.8.4__py3-none-any.whl → 0.9.0__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.
- virgo_modules/__init__.py +1 -0
- virgo_modules/src/markowitz/__init__.py +0 -0
- virgo_modules/src/markowitz/markowitz_utils.py +44 -0
- virgo_modules/src/ticketer_source.py +73 -0
- {virgo_modules-0.8.4.dist-info → virgo_modules-0.9.0.dist-info}/METADATA +1 -1
- {virgo_modules-0.8.4.dist-info → virgo_modules-0.9.0.dist-info}/RECORD +9 -7
- {virgo_modules-0.8.4.dist-info → virgo_modules-0.9.0.dist-info}/WHEEL +0 -0
- {virgo_modules-0.8.4.dist-info → virgo_modules-0.9.0.dist-info}/licenses/LICENSE +0 -0
- {virgo_modules-0.8.4.dist-info → virgo_modules-0.9.0.dist-info}/top_level.txt +0 -0
virgo_modules/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.9.0"
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from scipy import optimize
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
class MarkowitzOptimizer:
|
|
6
|
+
def __init__(self, data, return_cols, window_cov=10):
|
|
7
|
+
self.data_ = data[["Date"]+return_cols].dropna().sort_values("Date").copy()
|
|
8
|
+
self.window_cov = window_cov
|
|
9
|
+
self.return_cols = return_cols
|
|
10
|
+
self.n_features = len(return_cols)
|
|
11
|
+
|
|
12
|
+
def execute_markowitz(self):
|
|
13
|
+
cons = {'type':'eq','fun':self._check_sum}
|
|
14
|
+
bounds = tuple((0,1) for _ in range(self.n_features)) # weights bounds
|
|
15
|
+
init_guess = [1/self.n_features for _ in range(self.n_features)] ## initial guess of weiths
|
|
16
|
+
feature_result_names = [f"optimal_{x}" for x in self.return_cols]
|
|
17
|
+
self.data_[feature_result_names] = np.nan
|
|
18
|
+
|
|
19
|
+
for i in range(self.window_cov,len(self.data_)):
|
|
20
|
+
self.cov = self.data_.iloc[i-self.window_cov:i,:][self.return_cols].cov()
|
|
21
|
+
self.returns = self.data_.iloc[i][self.return_cols].values
|
|
22
|
+
|
|
23
|
+
opt_results = optimize.minimize(self._neg_sr, init_guess, constraints=cons, bounds=bounds, method='SLSQP')
|
|
24
|
+
optimal_weights = opt_results.x
|
|
25
|
+
self.data_.iloc[i,-self.n_features:] = [float(x) for x in optimal_weights]
|
|
26
|
+
|
|
27
|
+
self.data_[feature_result_names] = self.data_[feature_result_names].astype(float).round(6)
|
|
28
|
+
self.data_["sum_weights"] = self.data_[feature_result_names].sum(axis=1)
|
|
29
|
+
self.feature_result_names = feature_result_names
|
|
30
|
+
return self.data_
|
|
31
|
+
|
|
32
|
+
def _get_ret_vol_sr(self, weights):
|
|
33
|
+
weights = np.array(weights)
|
|
34
|
+
ret = self.returns.dot(weights)
|
|
35
|
+
vol = np.sqrt(weights.T.dot(self.cov.dot(weights)))
|
|
36
|
+
sr = ret / vol
|
|
37
|
+
return np.array([ret, vol, sr])
|
|
38
|
+
|
|
39
|
+
def _neg_sr(self, weights):
|
|
40
|
+
return self._get_ret_vol_sr(weights)[-1] * -1
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def _check_sum(weights):
|
|
44
|
+
return np.sum(weights) - 1
|
|
@@ -174,6 +174,12 @@ class stock_eda_panel(object):
|
|
|
174
174
|
perfom fast stochastic oscilator or william indicator
|
|
175
175
|
vortex_feature(window=int, threshold=float, plot=boolean, save_features=boolean):
|
|
176
176
|
perform vortex oscilator
|
|
177
|
+
expected_return(trad_days:int, feature:str, feature_name:str):
|
|
178
|
+
perform expected log return based on inversed shift of historical data and applying
|
|
179
|
+
rolling_feature(feature: str, window:int, function:callable):
|
|
180
|
+
perform rolling (non expanding) window operation for a given feature
|
|
181
|
+
time_distance(feature_base:str,feature_window:str, result_feature_name:str, max_window:int):
|
|
182
|
+
perform distancce time to a given window feature
|
|
177
183
|
minmax_pricefeature(type_func=str, window=int, distance=bolean, save_features=boolean)
|
|
178
184
|
get relative price/ distance feature with respect to the min/max price in a given window
|
|
179
185
|
pair_index_feature(pair_symbol=str, feature_label=str, window=int, threshold=float, plot=boolean, save_features=boolean):
|
|
@@ -1382,6 +1388,73 @@ class stock_eda_panel(object):
|
|
|
1382
1388
|
name_attr = f'{type_func}_relprice'
|
|
1383
1389
|
|
|
1384
1390
|
setattr(self,f'settings_{name_attr}_pricefeature' , {'type_func': type_func, 'window': window, 'distance': distance})
|
|
1391
|
+
|
|
1392
|
+
def expected_return(self, trad_days, feature, feature_name=False):
|
|
1393
|
+
"""
|
|
1394
|
+
perform expected log return based on inversed shift of historical data and applying
|
|
1395
|
+
|
|
1396
|
+
Parameters
|
|
1397
|
+
----------
|
|
1398
|
+
trad_days (int): window or differenciation
|
|
1399
|
+
feature (int): feature to apply expected log return
|
|
1400
|
+
feature_name (str): resulting feature name
|
|
1401
|
+
|
|
1402
|
+
Returns
|
|
1403
|
+
-------
|
|
1404
|
+
None
|
|
1405
|
+
"""
|
|
1406
|
+
feature_name = feature_name if feature_name else f"{feature}_log_return_{trad_days}"
|
|
1407
|
+
tmp_names = list()
|
|
1408
|
+
for ind in range(1,trad_days+1):
|
|
1409
|
+
tmp_name = f"expected_{ind}"
|
|
1410
|
+
self.df[tmp_name] = self.df[feature].shift(-ind)/self.df[feature]-1
|
|
1411
|
+
tmp_names.append(tmp_name)
|
|
1412
|
+
self.df[feature_name] = self.df[tmp_names].max(axis=1)
|
|
1413
|
+
self.df = self.df.drop(columns = tmp_names)
|
|
1414
|
+
|
|
1415
|
+
def rolling_feature(self, feature, window, function):
|
|
1416
|
+
"""
|
|
1417
|
+
perform rolling (non expanding) window operation for a given feature
|
|
1418
|
+
|
|
1419
|
+
Parameters
|
|
1420
|
+
----------
|
|
1421
|
+
feature (int): feature to apply window operation
|
|
1422
|
+
window (int): window size
|
|
1423
|
+
function (str): window function e.g MIN, MAX, AVG
|
|
1424
|
+
|
|
1425
|
+
Returns
|
|
1426
|
+
-------
|
|
1427
|
+
None
|
|
1428
|
+
"""
|
|
1429
|
+
feature_name = f"{feature}_{window}_{function}"
|
|
1430
|
+
self.df[feature_name] = getattr(self.df.sort_values("Date")[feature].rolling(window), function)()
|
|
1431
|
+
|
|
1432
|
+
def time_distance(self, feature_base,feature_window, result_feature_name, max_window=None):
|
|
1433
|
+
"""
|
|
1434
|
+
perform distancce time to a given window feature
|
|
1435
|
+
|
|
1436
|
+
Parameters
|
|
1437
|
+
----------
|
|
1438
|
+
feature_base (str): name of the underlaying feature
|
|
1439
|
+
feature_window (str): name of the window feature
|
|
1440
|
+
result_feature_name (str): resulting feature name
|
|
1441
|
+
max_window (int): apply a top value to the time to distance feature
|
|
1442
|
+
|
|
1443
|
+
Returns
|
|
1444
|
+
-------
|
|
1445
|
+
None
|
|
1446
|
+
"""
|
|
1447
|
+
self.df["Date_pivot"] = np.nan
|
|
1448
|
+
self.df["Date_pivot"] = self.df["Date_pivot"].case_when([
|
|
1449
|
+
(self.df[feature_base] == self.df[feature_window], self.df["Date"]),
|
|
1450
|
+
|
|
1451
|
+
])
|
|
1452
|
+
self.df["Date_pivot"] = self.df.sort_values("Date")["Date_pivot"].fillna(method="ffill")
|
|
1453
|
+
self.df[result_feature_name] = self.df["Date"] - self.df["Date_pivot"]
|
|
1454
|
+
self.df[result_feature_name] = self.df[result_feature_name].dt.days
|
|
1455
|
+
if max_window:
|
|
1456
|
+
self.df[result_feature_name] = self.df[result_feature_name].clip(0,max_window)
|
|
1457
|
+
self.df = self.df.drop(columns = ["Date_pivot"])
|
|
1385
1458
|
|
|
1386
1459
|
def pair_index_feature(self, pair_symbol, feature_label,threshold, window = None,ta_method='ROC',param_set=False,plot = False, save_features = False):
|
|
1387
1460
|
"""
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
virgo_modules/__init__.py,sha256=
|
|
1
|
+
virgo_modules/__init__.py,sha256=7NrzGOSBvO9S73thMlxEh5aNYKS5SYKLgTxC1YIIPRk,21
|
|
2
2
|
virgo_modules/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
virgo_modules/src/aws_utils.py,sha256=QCyxJwZ6bNCkMpuuxzxkNxejj-hJf4kj2arb1SQPNug,2582
|
|
4
4
|
virgo_modules/src/backtester.py,sha256=OhiWyzDX0PthXGuhChyWUmDN3cLkzVYe95zS4nGtia8,22106
|
|
5
5
|
virgo_modules/src/hmm_utils.py,sha256=D7axAnCdSe1_1EgRyli2PAnM2f6699hTY9GcxjPXG-o,21221
|
|
6
6
|
virgo_modules/src/pull_artifacts.py,sha256=5OPrgR7pcMSdpbevDRhf0ebk7g7ZRjff4NpTIIWAKjE,1989
|
|
7
7
|
virgo_modules/src/re_utils.py,sha256=AQlhyO0cvU-G42dolhedz5E-sniRzeFhf40RD5QVYpo,75506
|
|
8
|
-
virgo_modules/src/ticketer_source.py,sha256=
|
|
8
|
+
virgo_modules/src/ticketer_source.py,sha256=nGjQdZRDWto8cGKhMQCyAqYwvqYy1m6djkCpffiX3Dk,107747
|
|
9
9
|
virgo_modules/src/transformer_utils.py,sha256=SnYdtsFPnSF6u4UFIat0-X3-qVuUWvv_T46kiB-H0Sk,13682
|
|
10
10
|
virgo_modules/src/edge_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
virgo_modules/src/edge_utils/conformal_utils.py,sha256=cKm4KSM261Eu1FJn4oowKYiKIesW81VbqITIvopGSVk,5410
|
|
@@ -15,8 +15,10 @@ virgo_modules/src/edge_utils/shap_utils.py,sha256=FgcHkfddvdFSeUqEubYa2ExRGVAWSt
|
|
|
15
15
|
virgo_modules/src/edge_utils/stack_model.py,sha256=QqE91uLo2KauGEj91AVNANB1xE7J4Fa49YOX7k5mFng,4257
|
|
16
16
|
virgo_modules/src/market/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
virgo_modules/src/market/market_tools.py,sha256=vBt66_7E3ANz7avzfeNw_RHMGvG9lh5PRhxmcf_Oyjc,6880
|
|
18
|
-
virgo_modules
|
|
19
|
-
virgo_modules
|
|
20
|
-
virgo_modules-0.
|
|
21
|
-
virgo_modules-0.
|
|
22
|
-
virgo_modules-0.
|
|
18
|
+
virgo_modules/src/markowitz/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
virgo_modules/src/markowitz/markowitz_utils.py,sha256=2bsnk_QlfWB5QytSNZ5n8elto9hhsEiukcEJBqWEYX4,1970
|
|
20
|
+
virgo_modules-0.9.0.dist-info/licenses/LICENSE,sha256=pNgFyCYgmimaw0o6V20JupZLROycAnOA_HDDh1tX2V4,1097
|
|
21
|
+
virgo_modules-0.9.0.dist-info/METADATA,sha256=z7zb755kS0k15I2FddBWXbFzrTaSmEqUiPvxvtEEzIM,1122
|
|
22
|
+
virgo_modules-0.9.0.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
|
23
|
+
virgo_modules-0.9.0.dist-info/top_level.txt,sha256=ZjI-qEkDtT-8mFwGAWnXfqPOKEGlIhWRW1es1VyXc60,14
|
|
24
|
+
virgo_modules-0.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|