feat(Filters): added numba compiled cusum filter (#243)

This commit is contained in:
Mark Aron Szulyovszky
2022-03-15 14:32:49 +01:00
committed by GitHub
parent 4fc1070f45
commit 345b48a67c
+29 -21
View File
@@ -12,28 +12,14 @@ class CUSUMVolatilityEventFilter(EventFilter):
self.multiplier = multiplier
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
rolling_vol = returns.rolling(self.vol_period).std() * self.multiplier
diffed_returns = returns.diff()
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]),
)
int_indicies = _process_vol_based(
List(diffed_returns.to_list()), List(rolling_vol.to_list())
)
if neg_threshold < -rolling_vol[index]:
neg_threshold = 0
filtered_indices.append(index)
elif pos_threshold > rolling_vol[index]:
pos_threshold = 0
filtered_indices.append(index)
return pd.DatetimeIndex(filtered_indices)
return pd.DatetimeIndex([returns.index[i] for i in int_indicies])
class CUSUMFixedEventFilter(EventFilter):
@@ -42,7 +28,7 @@ class CUSUMFixedEventFilter(EventFilter):
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
diffed_returns = returns.diff()
int_indicies = _process(
int_indicies = _process_fixed(
List(diffed_returns.to_list()), abs(returns.mean()) * self.threshold
)
@@ -50,7 +36,7 @@ class CUSUMFixedEventFilter(EventFilter):
@njit
def _process(diffed_returns: List, threshold: float32) -> List:
def _process_fixed(diffed_returns: List, threshold: float32) -> List:
pos_threshold: float32 = 0.0 # type: ignore
neg_threshold: float32 = 0.0 # type: ignore
filtered_indicies = List()
@@ -69,3 +55,25 @@ def _process(diffed_returns: List, threshold: float32) -> List:
filtered_indicies.append(index)
return filtered_indicies
@njit
def _process_vol_based(diffed_returns: List, rolling_vol: List) -> 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
)
if neg_threshold < -rolling_vol[index]:
neg_threshold = 0.0 # type: ignore
filtered_indicies.append(index)
elif pos_threshold > rolling_vol[index]:
pos_threshold = 0.0 # type: ignore
filtered_indicies.append(index)
return filtered_indicies