diff --git a/.gitignore b/.gitignore index 2173875..e2e5b04 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,5 @@ lightning/lightning_logs/ results.csv predictions.csv wandb/ + +.cachedir/** \ No newline at end of file diff --git a/config/config.py b/config/config.py index c5aa2be..6d5b4d0 100644 --- a/config/config.py +++ b/config/config.py @@ -15,7 +15,7 @@ def get_default_level_1_daily_config() -> tuple[dict, dict, dict]: ) data_config = dict( - assets = ['hourly_crypto'], + assets = ['daily_crypto'], other_assets = [], exogenous_data = [], load_non_target_asset= True, @@ -23,10 +23,11 @@ def get_default_level_1_daily_config() -> tuple[dict, dict, dict]: forecasting_horizon = 1, own_features = ['level_2', 'date_days'], other_features = ['single_mom'], - exogenous_features = ['fracdiff'], + exogenous_features = ['standard_scaling'], index_column= 'int', method= 'classification', - no_of_classes= 'three-balanced' + no_of_classes= 'three-balanced', + narrow_format = False, ) regression_models = ["Lasso"] @@ -64,10 +65,11 @@ def get_default_level_2_hourly_config() -> tuple[dict, dict, dict]: forecasting_horizon = 1, own_features = ['level_2', 'date_days', 'lags_up_to_5'], other_features = ['level_2'], - exogenous_features = ['fracdiff'], + exogenous_features = ['standard_scaling'], index_column= 'int', method= 'classification', - no_of_classes= 'three-balanced' + no_of_classes= 'three-balanced', + narrow_format = False, ) regression_models = ["Lasso", "KNN", "RF"] @@ -105,17 +107,18 @@ def get_default_level_2_daily_config() -> tuple[dict, dict, dict]: load_non_target_asset= True, log_returns= True, forecasting_horizon = 1, - own_features = ['level_2', 'date_days', 'fracdiff'], - other_features = ['level_2', 'fracdiff'], - exogenous_features = ['fracdiff'], + own_features = ['level_2', 'date_days', 'lags_up_to_5'], + other_features = ['level_2', 'lags_up_to_5'], + exogenous_features = ['standard_scaling'], index_column= 'int', method= 'classification', - no_of_classes= 'three-balanced' + no_of_classes= 'three-balanced', + narrow_format = False, ) regression_models = ["Lasso", "KNN", "RF"] regression_ensemble_model = 'KNN' - classification_models = ["LDA", "KNN", "CART", "RF", "StaticMom"] + classification_models = ['LR', 'LDA', 'KNN', 'CART', 'NB', 'AB', 'RF', 'XGB', 'StaticMom'] classification_ensemble_model = 'Ensemble_Average' model_config = dict( diff --git a/config/hashing.py b/config/hashing.py new file mode 100644 index 0000000..594c14d --- /dev/null +++ b/config/hashing.py @@ -0,0 +1,24 @@ + +from utils.types import DataCollection + +def hash_data_config(data_config: dict) -> str: + + def hash_data_collection(data_collection: DataCollection) -> str: return ''.join([a[0] + a[1] for a in data_collection]) + def hash_feature_extractors(feature_extractos) -> str: return ''.join([f[0] for f in feature_extractos]) + def to_str(x): return ''.join([str(i) for i in x]) + return '_'.join(to_str([ + hash_data_collection(data_config['assets']), + hash_data_collection(data_config['other_assets']), + hash_data_collection(data_config['exogenous_data']), + data_config['target_asset'][0] + data_config['target_asset'][1], + data_config['load_non_target_asset'], + data_config['log_returns'], + data_config['forecasting_horizon'], + hash_feature_extractors(data_config['own_features']), + hash_feature_extractors(data_config['other_features']), + hash_feature_extractors(data_config['exogenous_features']), + data_config['index_column'], + data_config['method'], + data_config['no_of_classes'], + data_config['narrow_format'] + ])) diff --git a/data_loader/load_data.py b/data_loader/load_data.py index c9ccd05..59fabc7 100644 --- a/data_loader/load_data.py +++ b/data_loader/load_data.py @@ -6,8 +6,20 @@ from data_loader.collections import DataCollection from typing import Literal import ray import os +from config.hashing import hash_data_config +from diskcache import Cache +cache = Cache(".cachedir/data") -def load_data(assets: DataCollection, +def load_data(**kwargs): + hashed = hash_data_config(kwargs) + if hashed in cache: + return cache.get(hashed) + else: + return_value = __load_data(**kwargs) + cache[hashed] = return_value + return return_value + +def __load_data(assets: DataCollection, other_assets: DataCollection, exogenous_data: DataCollection, target_asset: DataSource, @@ -33,13 +45,22 @@ def load_data(assets: DataCollection, target_file = [f for f in assets if f[1].startswith(target_asset[1])] assert len(target_file) == 1, "There should be exactly one target file" other_files = [f for f in assets if load_non_target_asset == True and f[1].startswith(target_asset[1]) == False] - files = target_file + other_files + other_assets - def is_target_asset(target_asset: str, file: str): return file.split('.')[0].startswith(target_asset) + files = other_files + other_assets + + target_asset_future = [__load_df.remote( + data_source=data_source, + prefix=data_source[1], + returns='log_returns' if log_returns else 'returns', + feature_extractors=own_features, + narrow_format=narrow_format, + ) for data_source in target_file] + target_asset_df = ray.get(target_asset_future) + asset_futures = [__load_df.remote( data_source=data_source, prefix=data_source[1], returns='log_returns' if log_returns else 'returns', - feature_extractors=own_features if is_target_asset(target_asset[1], data_source[1]) else other_features, + feature_extractors=other_features, narrow_format=narrow_format, ) for data_source in files] asset_dfs = ray.get(asset_futures) @@ -47,19 +68,19 @@ def load_data(assets: DataCollection, exogenous_futures = [__load_df.remote( data_source=data_source, prefix=data_source[1], - returns='returns', + returns='none', feature_extractors=exogenous_features, narrow_format=narrow_format, ) for data_source in exogenous_data] exogenous_dfs = ray.get(exogenous_futures) - dfs = asset_dfs + exogenous_dfs + dfs = target_asset_df + asset_dfs + exogenous_dfs dfs = [deduplicate_indexes(df) for df in dfs] - longest_df = max(dfs, key=lambda df: df.shape[0]) + target_df = dfs[0] if narrow_format: - dfs = pd.concat([df.sort_index().reindex(longest_df.index) for df in dfs], axis=0).fillna(0.) + dfs = pd.concat([df.sort_index().reindex(target_df.index) for df in dfs], axis=0).fillna(0.) else: - dfs = pd.concat([df.sort_index().reindex(longest_df.index) for df in dfs], axis=1).fillna(0.) + dfs = pd.concat([df.sort_index().reindex(target_df.index) for df in dfs], axis=1).fillna(0.) dfs.index = pd.DatetimeIndex(dfs.index) @@ -90,7 +111,7 @@ def load_data(assets: DataCollection, @ray.remote def __load_df(data_source: DataSource, prefix: str, - returns: Literal['price', 'returns', 'log_returns'], + returns: Literal['none', 'price', 'returns', 'log_returns'], feature_extractors: list[tuple[str, FeatureExtractor, list[int]]], narrow_format: bool = False) -> pd.DataFrame: df = pd.read_csv(os.path.join(data_source[0], data_source[1] + '.csv'), header=0, index_col=0).fillna(0) @@ -99,7 +120,7 @@ def __load_df(data_source: DataSource, df['returns'] = np.log(df['close']).diff(1) elif returns == 'price': df['returns'] = df['close'] - else: + elif returns == 'returns': df['returns'] = df['close'].pct_change() df = __apply_feature_extractors(df, log_returns=True if returns == 'log_returns' else False, feature_extractors = feature_extractors) @@ -124,7 +145,7 @@ def __apply_feature_extractors(df: pd.DataFrame, if type(features) == pd.DataFrame: df = pd.concat([df, features], axis=1) elif type(features) == pd.Series: - df[name + '_' + str(period)] = extractor(df, period, log_returns) + df[name + '_' + str(period)] = features else: assert False, "Feature extractor must return a pd.DataFrame or pd.Series" return df diff --git a/environment.yml b/environment.yml index 78a0fc9..c210fc5 100644 --- a/environment.yml +++ b/environment.yml @@ -24,7 +24,9 @@ dependencies: - tqdm - pip - pandas-ta + - xgboost - pip: - fracdiff - ray + - diskcache prefix: /usr/local/anaconda3/envs/quant diff --git a/exploration.ipynb b/exploration.ipynb index 9c92176..a2a7739 100644 --- a/exploration.ipynb +++ b/exploration.ipynb @@ -2,24 +2,23 @@ "cells": [ { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[2m\u001b[36m(__load_df pid=33339)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", - "\u001b[2m\u001b[36m(__load_df pid=33339)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", - "\u001b[2m\u001b[36m(__load_df pid=33345)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", - "\u001b[2m\u001b[36m(__load_df pid=33345)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", - "\u001b[2m\u001b[36m(__load_df pid=33342)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", - "\u001b[2m\u001b[36m(__load_df pid=33342)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", - "\u001b[2m\u001b[36m(__load_df pid=33344)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", - "\u001b[2m\u001b[36m(__load_df pid=33344)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", - "\u001b[2m\u001b[36m(__load_df pid=33349)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", - "\u001b[2m\u001b[36m(__load_df pid=33349)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", - "\u001b[2m\u001b[36m(__load_df pid=33341)\u001b[0m \n" + "\u001b[2m\u001b[36m(__load_df pid=52067)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", + "\u001b[2m\u001b[36m(__load_df pid=52067)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", + "\u001b[2m\u001b[36m(__load_df pid=52074)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", + "\u001b[2m\u001b[36m(__load_df pid=52074)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", + "\u001b[2m\u001b[36m(__load_df pid=52071)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", + "\u001b[2m\u001b[36m(__load_df pid=52071)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", + "\u001b[2m\u001b[36m(__load_df pid=52072)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", + "\u001b[2m\u001b[36m(__load_df pid=52072)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n", + "\u001b[2m\u001b[36m(__load_df pid=52069)\u001b[0m /usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: divide by zero encountered in log\n", + "\u001b[2m\u001b[36m(__load_df pid=52069)\u001b[0m result = getattr(ufunc, method)(*inputs, **kwargs)\n" ] } ], @@ -41,74 +40,33 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "Index(['ADA_USD_returns', 'ADA_USD_mom_10', 'ADA_USD_mom_20', 'ADA_USD_mom_30',\n", + " 'ADA_USD_mom_60', 'ADA_USD_mom_90', 'ADA_USD_vol_10', 'ADA_USD_vol_20',\n", + " 'ADA_USD_vol_30', 'ADA_USD_vol_60',\n", + " ...\n", + " 'msol_standard_scaling_0', 'dormancy_standard_scaling_0',\n", + " 'liveliness_standard_scaling_0',\n", + " 'relative_unrealized_profit_standard_scaling_0',\n", + " 'relative_unrealized_loss_standard_scaling_0',\n", + " 'nupl_standard_scaling_0', 'sth_nupl_standard_scaling_0',\n", + " 'lth_nupl_standard_scaling_0', 'ssr_standard_scaling_0',\n", + " 'bvin_standard_scaling_0'],\n", + " dtype='object', length=542)" ] }, - "execution_count": 11, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" } ], "source": [ - "X['sth_nupl_fracdiff_30'].plot()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/anaconda3/envs/quant/lib/python3.9/site-packages/pandas/core/arraylike.py:364: RuntimeWarning: invalid value encountered in log\n", - " result = getattr(ufunc, method)(*inputs, **kwargs)\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "np.log(X['sth_nupl_fracdiff_30']).plot()" + "X.columns" ] }, { @@ -128,7 +86,39 @@ }, { "data": { - "image/png": "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", + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "X['liveliness_standard_scaling_0'].plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", "text/plain": [ "
" ] @@ -152,34 +142,6 @@ "# pd.plotting.scatter_matrix(X, figsize=(12, 12));" ] }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Index(['ADA_USD_returns', 'ADA_USD_mom_10', 'ADA_USD_mom_20', 'ADA_USD_mom_30',\n", - " 'ADA_USD_mom_60', 'ADA_USD_mom_90', 'ADA_USD_vol_10', 'ADA_USD_vol_20',\n", - " 'ADA_USD_vol_30', 'ADA_USD_vol_60',\n", - " ...\n", - " 'sth_nupl_fracdiff_30', 'lth_nupl_returns', 'lth_nupl_fracdiff_10',\n", - " 'lth_nupl_fracdiff_30', 'ssr_returns', 'ssr_fracdiff_10',\n", - " 'ssr_fracdiff_30', 'bvin_returns', 'bvin_fracdiff_10',\n", - " 'bvin_fracdiff_30'],\n", - " dtype='object', length=588)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "X.columns" - ] - }, { "cell_type": "code", "execution_count": null, diff --git a/feature_extractors/feature_extractor_presets.py b/feature_extractors/feature_extractor_presets.py index 5eaa306..6dba829 100644 --- a/feature_extractors/feature_extractor_presets.py +++ b/feature_extractors/feature_extractor_presets.py @@ -1,7 +1,7 @@ -from feature_extractors.feature_extractors import feature_lag, feature_mom, feature_ROC, feature_RSI, feature_STOD, feature_STOK, feature_vol, feature_day_of_month, feature_day_of_week, feature_month, feature_debug_future_lookahead +from feature_extractors.feature_extractors import feature_lag, feature_mom, feature_ROC, feature_RSI, feature_STOD, feature_STOK, feature_standard_scaling, feature_vol, feature_day_of_month, feature_day_of_week, feature_month, feature_debug_future_lookahead from utils.types import FeatureExtractorConfig from utils.helpers import flatten -from feature_extractors.fractional_differentiation import feature_fractional_differentiation +from feature_extractors.fractional_differentiation import feature_fractional_differentiation, feature_fractional_differentiation_log __presets = dict( debug_future_lookahead = [('debug_future', feature_debug_future_lookahead, [1])], @@ -24,6 +24,8 @@ __presets = dict( stod = [('stod', feature_STOD, [10, 30, 200])], stok = [('stok', feature_STOK, [10, 30, 200])], fracdiff = [('fracdiff', feature_fractional_differentiation, [10, 30])], + fracdiff_log = [('fracdiff_log', feature_fractional_differentiation_log, [10, 30])], + standard_scaling = [('standard_scaling', feature_standard_scaling, [0])], ) presets = __presets | dict( diff --git a/feature_extractors/feature_extractors.py b/feature_extractors/feature_extractors.py index f2b915a..154efc5 100644 --- a/feature_extractors/feature_extractors.py +++ b/feature_extractors/feature_extractors.py @@ -1,6 +1,8 @@ import pandas as pd import numpy as np from feature_extractors.utils import get_close_low_high +from feature_extractors.utils import apply_log_if_necessary_series +from sklearn.preprocessing import StandardScaler def feature_debug_future_lookahead(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series: return df['returns'].shift(-period) @@ -9,6 +11,10 @@ def feature_lag(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series assert period > 0 return df['returns'].shift(period) +def feature_standard_scaling(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series: + scaler = StandardScaler() + return pd.Series(scaler.fit_transform(df['close'].to_numpy().reshape(-1, 1)).squeeze(), index = df.index) + def feature_day_of_week(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.DataFrame: return pd.get_dummies(pd.DatetimeIndex(df.index).dayofweek, drop_first=True, prefix="date_day_week").set_index(df.index) @@ -31,7 +37,7 @@ def feature_STOK(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Serie close, low, high = get_close_low_high(df) STOK = ((close - low.rolling(period).min()) / (high.rolling(period).max() - low.rolling(period).min())) * 100 - return STOK + return apply_log_if_necessary_series(STOK, "stok") def feature_STOD(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series: stok = feature_STOK(df, period, is_log_return) @@ -48,10 +54,11 @@ def feature_RSI(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series d[d.index[period-1]] = np.mean( d[:period] ) #first value is sum of avg losses d = d.drop(d.index[:(period-1)]) rs = u.ewm(com=period-1, adjust=False).mean() / \ d.ewm(com=period-1, adjust=False).mean() - return 100-100/(1+rs) + return apply_log_if_necessary_series(100-100/(1+rs), "rsi") def feature_ROC(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series: returns = df['returns'] M = returns.diff(period - 1) N = returns.shift(period - 1) - return pd.Series(((M / N) * 100), name = 'ROC_' + str(period)) \ No newline at end of file + roc = pd.Series(((M / N) * 100), name = 'ROC_' + str(period)) + return apply_log_if_necessary_series(roc, "roc") \ No newline at end of file diff --git a/feature_extractors/fractional_differentiation.py b/feature_extractors/fractional_differentiation.py index b43821c..fc3dcbc 100644 --- a/feature_extractors/fractional_differentiation.py +++ b/feature_extractors/fractional_differentiation.py @@ -1,9 +1,15 @@ from fracdiff.sklearn import FracdiffStat import pandas as pd import numpy as np +from feature_extractors.utils import apply_log_if_necessary_series def feature_fractional_differentiation(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series: frac_diff = FracdiffStat(window = period) input_series = df["close"].to_numpy().reshape(-1, 1) result = frac_diff.fit_transform(input_series) - return pd.Series(result.squeeze(), index = df.index) \ No newline at end of file + return pd.Series(result.squeeze(), index = df.index) + +def feature_fractional_differentiation_log(df: pd.DataFrame, period: int, is_log_return: bool) -> pd.Series: + series = feature_fractional_differentiation(df, period, is_log_return) + return apply_log_if_necessary_series(series, "fracdiff") + \ No newline at end of file diff --git a/feature_extractors/utils.py b/feature_extractors/utils.py index 9ccf652..6206ace 100644 --- a/feature_extractors/utils.py +++ b/feature_extractors/utils.py @@ -1,7 +1,25 @@ import pandas as pd +import numpy as np +from scipy.stats import shapiro def get_close_low_high(df: pd.DataFrame) -> tuple[pd.Series, pd.Series, pd.Series]: close = df['close'] low = df['low'] high = df['high'] - return close, low, high \ No newline at end of file + return close, low, high + + +def apply_log_if_necessary_series(series: pd.Series, name: str) -> pd.Series: + values = series.to_numpy() + no_of_unique_values = np.unique(values) + if len(no_of_unique_values) < 4: + return series + is_normal = shapiro(values).pvalue > 0.05 + if not is_normal: + # print("Applying log to column: " + column) + min_value = np.min(series) + series = (series + min_value).apply(lambda x: np.log(x)) + is_normal_after_log = shapiro(series).pvalue > 0.05 + if not is_normal_after_log: + print("Failed to normalize column: ", name) + return series diff --git a/feature_selection/feature_selection.py b/feature_selection/feature_selection.py index de1ca4a..4ad4789 100644 --- a/feature_selection/feature_selection.py +++ b/feature_selection/feature_selection.py @@ -2,14 +2,31 @@ from sklearn.feature_selection import RFE from sklearn.model_selection import TimeSeriesSplit import pandas as pd from models.base import Model, SKLearnModel -from sklearn.decomposition import PCA +from utils.scaler import get_scaler +from utils.types import ScalerTypes +from utils.hashing import hash_df, hash_series +from diskcache import Cache +cache = Cache(".cachedir/feature_selection") -def select_features(X: pd.DataFrame, y: pd.Series, model: Model, n_features_to_select: int, backup_model: SKLearnModel) -> pd.DataFrame: +def select_features(**kwargs): + hashed = kwargs['data_config_hash'] + kwargs['model'].get_name() + str(kwargs['n_features_to_select']) + kwargs['backup_model'].get_name() + kwargs['scaling'] + if hashed in cache: + return cache.get(hashed) + else: + return_value = __select_features(**kwargs) + cache[hashed] = return_value + return return_value + +def __select_features(X: pd.DataFrame, y: pd.Series, model: Model, n_features_to_select: int, backup_model: SKLearnModel, scaling: ScalerTypes, data_config_hash: str) -> pd.DataFrame: ''' Select features using RFECV, returns a pd.DataFrame (X) with only the selected features.''' if model.model_type != 'ml': return X # 2. Recursive feature selection cv = TimeSeriesSplit(n_splits=5) + scaler = get_scaler(scaling) + X_scaled = X.copy() + if scaler is not None: + X_scaled = scaler.fit_transform(X_scaled) feat_selector_model = model.model if hasattr(feat_selector_model, 'feature_importances_') == False and hasattr(feat_selector_model, 'coef_') == False: @@ -17,7 +34,7 @@ def select_features(X: pd.DataFrame, y: pd.Series, model: Model, n_features_to_s # selector = RFECV(feat_selector_model, cv = cv, step=5, min_features_to_select=min_features_to_select) selector = RFE(feat_selector_model, n_features_to_select= n_features_to_select) - selector = selector.fit(X, y) - print("Kept %d features out of %d" % (selector.n_features_, X.shape[1])) + selector = selector.fit(X_scaled, y) + print("Kept %d features out of %d" % (selector.n_features_, X_scaled.shape[1])) return pd.DataFrame(X[X.columns[selector.support_]], index= X.index) diff --git a/models/average.py b/models/average.py index 243d049..a7aa5cf 100644 --- a/models/average.py +++ b/models/average.py @@ -1,3 +1,4 @@ +from __future__ import annotations from models.base import Model import numpy as np @@ -10,16 +11,20 @@ class StaticAverageModel(Model): only_column = 'model_' feature_selection = 'off' model_type = 'static' + predict_window_size = 'single_timestamp' - def fit(self, X, y, prev_model): + def fit(self, X: np.ndarray, y: np.ndarray) -> None: # This is a static model, it can' learn anything pass - def predict(self, X): + def predict(self, X) -> tuple[float, np.ndarray]: # Make sure there's data to average assert X.shape[1] > 0 prediction = np.average(X[-1]) - return np.array([prediction]) + return (prediction, np.array([])) - def clone(self): - return self \ No newline at end of file + def clone(self) -> StaticAverageModel: + return self + + def get_name(self) -> str: + return 'static_average' \ No newline at end of file diff --git a/models/base.py b/models/base.py index 31f8244..d99a2ea 100644 --- a/models/base.py +++ b/models/base.py @@ -1,7 +1,8 @@ - +from __future__ import annotations from typing import Literal, Optional from sklearn.base import clone -from abc import ABC, abstractmethod, abstractproperty +from abc import ABC, abstractmethod +import numpy as np class Model(ABC): @@ -10,18 +11,22 @@ class Model(ABC): # data_format: Literal["wide", "narrow"] only_column: Optional[str] model_type: Literal['ml', 'static'] + predict_window_size: Literal['single_timestamp', 'window_size'] @abstractmethod - def fit(self, X, y, prev_model): - pass + def fit(self, X: np.ndarray, y: np.ndarray) -> None: + raise NotImplementedError @abstractmethod - def predict(self, X): - pass + def predict(self, X) -> tuple[float, np.ndarray]: + raise NotImplementedError @abstractmethod - def clone(self): - pass + def clone(self) -> Model: + raise NotImplementedError + + def get_name(self) -> str: + raise NotImplementedError class SKLearnModel(Model): @@ -30,15 +35,21 @@ class SKLearnModel(Model): only_column = None feature_selection = 'on' model_type = 'ml' + predict_window_size = 'single_timestamp' def __init__(self, model): self.model = model - def fit(self, X, y, prev_model): + def fit(self, X: np.ndarray, y: np.ndarray) -> None: self.model.fit(X, y) - def predict(self, X): - return self.model.predict(X) + def predict(self, X) -> tuple[float, np.ndarray]: + pred = self.model.predict(X).item() + probability = self.model.predict_proba(X).squeeze() + return (pred, probability) - def clone(self): - return SKLearnModel(clone(self.model)) \ No newline at end of file + def clone(self) -> SKLearnModel: + return SKLearnModel(clone(self.model)) + + def get_name(self) -> str: + return self.model.__class__.__name__ \ No newline at end of file diff --git a/models/model_map.py b/models/model_map.py index d84e63e..df78219 100644 --- a/models/model_map.py +++ b/models/model_map.py @@ -11,6 +11,7 @@ from models.base import SKLearnModel from models.momentum import StaticMomentumModel from models.average import StaticAverageModel from models.naive import StaticNaiveModel +from xgboost import XGBClassifier model_map = { @@ -34,6 +35,7 @@ model_map = { NB= SKLearnModel(GaussianNB()), AB= SKLearnModel(AdaBoostClassifier(n_estimators=15)), RF= SKLearnModel(RandomForestClassifier(n_jobs=-1, max_depth=20, random_state=1)), + XGB= SKLearnModel(XGBClassifier(n_jobs=-1, max_depth = 20, random_state=1, use_label_encoder=True, objective='multi:softprob', eval_metric='mlogloss')), StaticMom= StaticMomentumModel(allow_short=True), Ensemble_Average = StaticAverageModel(), ), diff --git a/models/momentum.py b/models/momentum.py index cdd10bb..efb1faa 100644 --- a/models/momentum.py +++ b/models/momentum.py @@ -1,3 +1,4 @@ +from __future__ import annotations from models.base import Model import numpy as np @@ -10,19 +11,23 @@ class StaticMomentumModel(Model): only_column = 'mom' feature_selection = 'off' model_type = 'static' + predict_window_size = 'single_timestamp' def __init__(self, allow_short: bool) -> None: super().__init__() self.allow_short = allow_short - def fit(self, X, y, prev_model): + def fit(self, X: np.ndarray, y: np.ndarray) -> None: # This is a static model, it can' learn anything pass - def predict(self, X): + def predict(self, X) -> tuple[float, np.ndarray]: negative_class = -1.0 if self.allow_short == True else 0.0 prediction = 1.0 if X[-1][0] > 0 else negative_class - return np.array([prediction]) + return (prediction, np.array([])) - def clone(self): - return self \ No newline at end of file + def clone(self) -> StaticMomentumModel: + return self + + def get_name(self) -> str: + return 'static_mom' \ No newline at end of file diff --git a/models/naive.py b/models/naive.py index b134675..5e9234d 100644 --- a/models/naive.py +++ b/models/naive.py @@ -1,3 +1,4 @@ +from __future__ import annotations from models.base import Model import numpy as np @@ -10,13 +11,17 @@ class StaticNaiveModel(Model): only_column = None feature_selection = 'off' model_type = 'static' + predict_window_size = 'single_timestamp' - def fit(self, X, y, prev_model): + def fit(self, X: np.ndarray, y: np.ndarray) -> None: # This is a static model, it can' learn anything pass - def predict(self, X): - return np.array([X[-1][0]]) + def predict(self, X) -> tuple[float, np.ndarray]: + return (X[-1][0], np.array([])) - def clone(self): - return self \ No newline at end of file + def clone(self) -> StaticNaiveModel: + return self + + def get_name(self) -> str: + return 'static_naive' \ No newline at end of file diff --git a/run_clean_cache.py b/run_clean_cache.py new file mode 100644 index 0000000..0b87e99 --- /dev/null +++ b/run_clean_cache.py @@ -0,0 +1,5 @@ +from diskcache import Cache +cache_1 = Cache(".cachedir/feature_selection") +cache_2 = Cache(".cachedir/data") +cache_1.clear() +cache_2.clear() \ No newline at end of file diff --git a/run_pipeline.py b/run_pipeline.py index 265e154..4619d0b 100644 --- a/run_pipeline.py +++ b/run_pipeline.py @@ -1,3 +1,4 @@ +from config.hashing import hash_data_config from data_loader.load_data import load_data import pandas as pd from training.training import run_single_asset_trainig @@ -26,11 +27,11 @@ def setup_pipeline(project_name:str, with_wandb: bool, sweep: bool): def pipeline(project_name:str, wandb, sweep:bool, model_config:dict, training_config:dict, data_config:dict): results = pd.DataFrame() all_predictions = pd.DataFrame() + all_probabilities = pd.DataFrame() validate_config(model_config, training_config, data_config) for asset in data_config['assets']: print('--------\nPredicting: ', asset[1]) - all_predictions = pd.DataFrame() # 1. Load data data_params = data_config.copy() @@ -53,11 +54,11 @@ def pipeline(project_name:str, wandb, sweep:bool, model_config:dict, training_co print("Feature Selection started") # TODO: this needs to be done per model! backup_model = default_feature_selector_regression if data_config['method'] == 'regression' else default_feature_selector_classification - X = select_features(X, y, model_config['level_1_models'][0][1], n_features_to_select = training_config['n_features_to_select'], backup_model = backup_model) + X = select_features(X = X, y = y, model = model_config['level_1_models'][0][1], n_features_to_select = training_config['n_features_to_select'], backup_model = backup_model, scaling = training_config['scaler'], data_config_hash = hash_data_config(data_params)) print("Feature Selection ended") # 3. Train Level-1 models - current_result, current_predictions = run_single_asset_trainig( + current_result, current_predictions, current_probabilities = run_single_asset_trainig( ticker_to_predict = asset[1], original_X = original_X, X = X, @@ -75,14 +76,15 @@ def pipeline(project_name:str, wandb, sweep:bool, model_config:dict, training_co results = pd.concat([results, current_result], axis=1) # With static models, because of the lag in the indicator, the first prediction is NA, so we fill it with zero. all_predictions = pd.concat([all_predictions, current_predictions], axis=1).fillna(0.) + all_probabilities = pd.concat([all_probabilities, current_probabilities], axis=1).fillna(0.) # 3. Train Level-2 (Ensemble) model (Optional) if model_config['level_2_model'] is not None: - ensemble_X = all_predictions + ensemble_X = pd.concat([all_predictions, all_probabilities], axis = 1) if training_config['include_original_data_in_ensemble']: ensemble_X = pd.concat([ensemble_X, X], axis=1) - ensemble_result, ensemble_preds = run_single_asset_trainig( + ensemble_result, ensemble_preds, ensemble_probabilities = run_single_asset_trainig( ticker_to_predict = asset[1], original_X = ensemble_X, X = ensemble_X, @@ -100,6 +102,7 @@ def pipeline(project_name:str, wandb, sweep:bool, model_config:dict, training_co results = pd.concat([results, ensemble_result], axis=1) all_predictions = pd.concat([all_predictions, ensemble_preds], axis=1) + all_probabilities = pd.concat([all_probabilities, ensemble_probabilities], axis=1).fillna(0.) results.to_csv('results.csv') diff --git a/sweep_fracdiff.yaml b/sweep_exo_data.yaml similarity index 91% rename from sweep_fracdiff.yaml rename to sweep_exo_data.yaml index 2f6f356..6b2d846 100644 --- a/sweep_fracdiff.yaml +++ b/sweep_exo_data.yaml @@ -1,7 +1,7 @@ program: run_sweep.py method: grid project: price-forecasting -name: Fractional differentiation / number of features +name: Exogenous data / data transformation metric: goal: maximize name: sharpe @@ -24,8 +24,7 @@ parameters: feature_selection: value: True n_features_to_select: - values: [30, 40] - distribution: categorical + value: 30 dimensionality_reduction: value: True retrain_every: @@ -57,5 +56,5 @@ parameters: values: [['level_2', 'lags_up_to_5'], ['level_2', 'fracdiff']] distribution: categorical exogenous_features: - values: [[], ['fracdiff']] + values: [[], ['fracdiff'], ['standard_scaling']] distribution: categorical diff --git a/tests/test_evaluation.py b/tests/test_evaluation.py index 57c9a0f..e8ebe14 100644 --- a/tests/test_evaluation.py +++ b/tests/test_evaluation.py @@ -42,13 +42,13 @@ class EvenOddStubModel(Model): super().__init__() self.window_length = window_length - def fit(self, X, y, prev_model): + def fit(self, X, y): assert len(X) == self.window_length for i in range(len(X)): assert y[i] == -1 if X[i][0] == 1 else 1 def predict(self, X): - return np.array([-1 if X[0][0] == 1 else 1]) + return (-1 if X[0][0] == 1 else 1, np.array([])) def clone(self): return self @@ -62,7 +62,7 @@ def test_evaluation(): model = EvenOddStubModel(window_length = window_length) scaler = None - models, predictions = walk_forward_train_test( + models, predictions, probs = walk_forward_train_test( model_name='test', model=model, X=X, diff --git a/tests/test_walk_forward.py b/tests/test_walk_forward.py index d1a1506..5273721 100644 --- a/tests/test_walk_forward.py +++ b/tests/test_walk_forward.py @@ -40,13 +40,13 @@ class IncrementingStubModel(Model): super().__init__() self.window_length = window_length - def fit(self, X, y, prev_model): + def fit(self, X, y): assert len(X) == self.window_length for i in range(len(X)): assert X[i][0] + 1 == y[i] def predict(self, X): - return np.array([X[0][0] + 1]) + return (X[0][0] + 1, np.array([])) def clone(self): return self @@ -59,7 +59,7 @@ def test_walk_forward_train_test(): model = IncrementingStubModel(window_length = window_length) scaler = None - models, predictions = walk_forward_train_test( + models, predictions, probs = walk_forward_train_test( model_name='test', model=model, X=X, diff --git a/training/training.py b/training/training.py index 87bed18..e6631ed 100644 --- a/training/training.py +++ b/training/training.py @@ -1,19 +1,10 @@ import pandas as pd from typing import Literal from training.walk_forward import walk_forward_train_test -from sklearn.preprocessing import MinMaxScaler, Normalizer, StandardScaler from utils.evaluate import evaluate_predictions from models.base import Model - -def __get_scaler(type: Literal['normalize', 'minmax', 'standardize', 'none']): - if type == 'normalize': - return Normalizer() - elif type == 'minmax': - return MinMaxScaler(feature_range= (-1, 1)) - elif type == 'standardize': - return StandardScaler() - else: - return None +from utils.scaler import get_scaler +from utils.types import ScalerTypes def run_single_asset_trainig( ticker_to_predict: str, @@ -26,19 +17,20 @@ def run_single_asset_trainig( expanding_window: bool, sliding_window_size: int, retrain_every: int, - scaler: Literal['normalize', 'minmax', 'standardize', 'none'], + scaler: ScalerTypes, no_of_classes: Literal['two', 'three-balanced', 'three-imbalanced'], level: int - ) -> tuple[pd.DataFrame, pd.DataFrame]: + ) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: - scaler = __get_scaler(scaler) + scaler = get_scaler(scaler) results = pd.DataFrame() - predictions = pd.DataFrame() + predictions = pd.DataFrame(index=y.index) + probabilities = pd.DataFrame(index=y.index) for model_name, model in models: - model_over_time, preds = walk_forward_train_test( + model_over_time, preds, probs = walk_forward_train_test( model_name=model_name, model = model, X = X if model.feature_selection == 'on' else original_X, @@ -58,10 +50,13 @@ def run_single_asset_trainig( method = method, no_of_classes=no_of_classes ) - column_name = ticker_to_predict + "_" + model_name + "_lvl" + str(level) + column_name = "model_" + ticker_to_predict + "_" + model_name + "_lvl" + str(level) results[column_name] = result # column names for model outputs should be different, so we can differentiate between original data and model predictions later, where necessary - predictions["model_" + column_name] = preds + predictions[column_name] = preds + probs_column_name = "probs_" + ticker_to_predict + "_" + model_name + "_lvl" + str(level) + probs.columns = [probs_column_name + "_" + c for c in probs.columns] + probabilities = pd.concat([probabilities, probs], axis=1) - return results, predictions \ No newline at end of file + return results, predictions, probabilities \ No newline at end of file diff --git a/training/walk_forward.py b/training/walk_forward.py index 2ca8e98..c5f2238 100644 --- a/training/walk_forward.py +++ b/training/walk_forward.py @@ -16,9 +16,10 @@ def walk_forward_train_test( window_size: int, retrain_every: int, scaler, - ) -> tuple[pd.Series, pd.Series]: + ) -> tuple[pd.Series, pd.Series, pd.DataFrame]: assert len(X) == len(y) predictions = pd.Series(index=y.index).rename(model_name) + probabilities = pd.DataFrame(index=y.index) models = pd.Series(index=y.index).rename(model_name) first_nonzero_return = max(get_first_valid_return_index(target_returns), get_first_valid_return_index(X.iloc[:,0])) @@ -45,8 +46,8 @@ def walk_forward_train_test( train_window_end = index - 1 if is_scaling_on: - # First we need to fit on the expanding window data slice - # This is our only way to avoid lookahead bia + # We need to fit on the expanding window data slice + # This is our only way to avoid lookahead bias X_expanding_window = X[first_nonzero_return:train_window_end] scaler.fit(X_expanding_window.values) @@ -59,7 +60,7 @@ def walk_forward_train_test( X_slice = X_slice.to_numpy() current_model = model.clone() - current_model.fit(X_slice, y_slice.to_numpy(), models[index-1]) + current_model.fit(X_slice, y_slice.to_numpy()) iterations_before_retrain = retrain_every else: current_model = models[index-1] @@ -70,8 +71,12 @@ def walk_forward_train_test( if is_scaling_on: next_timestep = scaler.transform(next_timestep) - prediction = current_model.predict(next_timestep).item() + prediction, probs = current_model.predict(next_timestep) predictions[index] = prediction + if len(probabilities.columns) != len(probs): + probabilities = probabilities.reindex(columns = ["prob_" + str(num) for num in range(0, len(probs.T))]) + probabilities.iloc[index] = probs + iterations_before_retrain -= 1 - return models, predictions + return models, predictions, probabilities diff --git a/utils/hashing.py b/utils/hashing.py new file mode 100644 index 0000000..1a5704e --- /dev/null +++ b/utils/hashing.py @@ -0,0 +1,10 @@ +from hashlib import sha256 +import pandas as pd + +def hash_df(df: pd.DataFrame) -> str: + s = str(df.columns) + str(df.index) + str(df.values) + return sha256(s.encode()).hexdigest() + +def hash_series(df: pd.Series) -> str: + s = str(df.name) + str(df.index) + str(df.values) + return sha256(s.encode()).hexdigest() \ No newline at end of file diff --git a/utils/normalize.py b/utils/normalize.py deleted file mode 100644 index 057a9aa..0000000 --- a/utils/normalize.py +++ /dev/null @@ -1,6 +0,0 @@ -import pandas as pd - -def normalize(data: pd.DataFrame) -> pd.DataFrame: - data_mean = data.mean(axis=0) - data_std = data.std(axis=0) - return ((data - data_mean) / data_std).fillna(0.) diff --git a/utils/scaler.py b/utils/scaler.py new file mode 100644 index 0000000..d36e5d0 --- /dev/null +++ b/utils/scaler.py @@ -0,0 +1,13 @@ +from sklearn.preprocessing import MinMaxScaler, Normalizer, StandardScaler +from typing import Optional, Union +from utils.types import ScalerTypes + +def get_scaler(type: ScalerTypes) -> Optional[Union[MinMaxScaler, Normalizer, StandardScaler]]: + if type == 'normalize': + return Normalizer() + elif type == 'minmax': + return MinMaxScaler(feature_range= (-1, 1)) + elif type == 'standardize': + return StandardScaler() + else: + return None \ No newline at end of file diff --git a/utils/types.py b/utils/types.py index 4eb73ad..0dc5699 100644 --- a/utils/types.py +++ b/utils/types.py @@ -1,4 +1,4 @@ -from typing import Callable, Union +from typing import Callable, Union, Literal import pandas as pd Period = int @@ -9,4 +9,6 @@ FeatureExtractorConfig = tuple[Name, FeatureExtractor, list[Period]] Path = str FileName = str DataSource = list[tuple[Path, FileName]] -DataCollection = list[DataSource] \ No newline at end of file +DataCollection = list[DataSource] + +ScalerTypes = Literal['normalize', 'minmax', 'standardize', 'none'] \ No newline at end of file