feat(Project): use SKLearn models directly, removed custom ensembling, use 5 minute data, batch inference, numba cusum filter (#192)

* feat(Project): use 5 minute data, running training in parallel, sped up cusum filter by 10x with numba

* fix(WalkForward): inference mini-batch parallelization

* fix(WalkForward): don't use the parallel version of any of the functions

* feat(CI): download the data required

* fix(Project): 5min_crypto folder added

* fix(Evaluate): make sure we have numerical stability in returns

* feat(Models): use SKLearn models directly to enable composability

* feat(Inference): batched inference now working, added forecasting_horizon

* fix(Inference): works again

* fix(Inference)

* chore(Models): remove unused Ensemble model

* fix(Labeller): don't just forward shift returns, also take the sum of the data happened until then

* Update test.yml
This commit is contained in:
Mark Aron Szulyovszky
2022-02-17 16:36:35 +01:00
committed by GitHub
parent 5c94af8b01
commit 9d47ee942d
52 changed files with 470 additions and 628 deletions
+26 -17
View File
@@ -1,8 +1,11 @@
from numpy import float32
from ..types import EventFilter
from data_loader.types import ReturnSeries
import pandas as pd
from numba import njit
from numba.typed import List
class CUSUMVolatilityEventFilter(EventFilter):
@@ -11,7 +14,7 @@ class CUSUMVolatilityEventFilter(EventFilter):
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
rolling_vol = returns.rolling(self.vol_period).std() * 0.15
rolling_vol = returns.rolling(self.vol_period).std().mean()
filtered_indices = []
pos_threshold = 0
@@ -39,22 +42,28 @@ class CUSUMFixedEventFilter(EventFilter):
self.threshold = threshold
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
filtered_indices = []
pos_threshold = 0
neg_threshold = 0
diff = returns.diff()
for index in diff.index[1:]:
pos_threshold, neg_threshold = (
max(0, pos_threshold + diff.loc[index]),
min(0, neg_threshold + diff.loc[index]),
)
diffed_returns = returns.diff()
int_indicies = _process(List(diffed_returns.to_list()), abs(returns.mean()) * self.threshold)
if neg_threshold < -self.threshold:
neg_threshold = 0
filtered_indices.append(index)
return pd.DatetimeIndex([returns.index[i] for i in int_indicies])
elif pos_threshold > self.threshold:
pos_threshold = 0
filtered_indices.append(index)
@njit
def _process(diffed_returns: List, threshold: float32) -> List:
pos_threshold: float32 = 0.0 # type: ignore
neg_threshold: float32 = 0.0 # type: ignore
filtered_indicies = List()
for index in range(1, len(diffed_returns[1:])):
pos_threshold, neg_threshold = ( # type: ignore
max(0, pos_threshold + diffed_returns[index]), # type: ignore
min(0, neg_threshold + diffed_returns[index]), # type: ignore
)
return pd.DatetimeIndex(filtered_indices)
if neg_threshold < -threshold:
neg_threshold = 0.0 # type: ignore
filtered_indicies.append(index)
elif pos_threshold > threshold:
pos_threshold = 0.0 # type: ignore
filtered_indicies.append(index)
return filtered_indicies