mirror of
https://github.com/webclinic017/drift.git
synced 2026-08-19 05:48:09 +00:00
feat(Filters): added numba compiled cusum filter (#243)
This commit is contained in:
@@ -12,28 +12,14 @@ class CUSUMVolatilityEventFilter(EventFilter):
|
|||||||
self.multiplier = multiplier
|
self.multiplier = multiplier
|
||||||
|
|
||||||
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
||||||
|
|
||||||
rolling_vol = returns.rolling(self.vol_period).std() * self.multiplier
|
rolling_vol = returns.rolling(self.vol_period).std() * self.multiplier
|
||||||
|
diffed_returns = returns.diff()
|
||||||
|
|
||||||
filtered_indices = []
|
int_indicies = _process_vol_based(
|
||||||
pos_threshold = 0
|
List(diffed_returns.to_list()), List(rolling_vol.to_list())
|
||||||
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]),
|
|
||||||
)
|
|
||||||
|
|
||||||
if neg_threshold < -rolling_vol[index]:
|
return pd.DatetimeIndex([returns.index[i] for i in int_indicies])
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
class CUSUMFixedEventFilter(EventFilter):
|
class CUSUMFixedEventFilter(EventFilter):
|
||||||
@@ -42,7 +28,7 @@ class CUSUMFixedEventFilter(EventFilter):
|
|||||||
|
|
||||||
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
||||||
diffed_returns = returns.diff()
|
diffed_returns = returns.diff()
|
||||||
int_indicies = _process(
|
int_indicies = _process_fixed(
|
||||||
List(diffed_returns.to_list()), abs(returns.mean()) * self.threshold
|
List(diffed_returns.to_list()), abs(returns.mean()) * self.threshold
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -50,7 +36,7 @@ class CUSUMFixedEventFilter(EventFilter):
|
|||||||
|
|
||||||
|
|
||||||
@njit
|
@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
|
pos_threshold: float32 = 0.0 # type: ignore
|
||||||
neg_threshold: float32 = 0.0 # type: ignore
|
neg_threshold: float32 = 0.0 # type: ignore
|
||||||
filtered_indicies = List()
|
filtered_indicies = List()
|
||||||
@@ -69,3 +55,25 @@ def _process(diffed_returns: List, threshold: float32) -> List:
|
|||||||
filtered_indicies.append(index)
|
filtered_indicies.append(index)
|
||||||
|
|
||||||
return filtered_indicies
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user