mirror of
https://github.com/webclinic017/drift.git
synced 2026-08-12 18:38:06 +00:00
chore(Linter): reformatted code with black (#211)
* chore(Linter): reformatted code with black * Create black.yaml
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
from numpy import float32
|
||||
from ..types import EventFilter
|
||||
from data_loader.types import ReturnSeries
|
||||
@@ -7,8 +5,8 @@ import pandas as pd
|
||||
from numba import njit
|
||||
from numba.typed import List
|
||||
|
||||
class CUSUMVolatilityEventFilter(EventFilter):
|
||||
|
||||
class CUSUMVolatilityEventFilter(EventFilter):
|
||||
def __init__(self, vol_period: int):
|
||||
self.vol_period = vol_period
|
||||
|
||||
@@ -36,34 +34,37 @@ class CUSUMVolatilityEventFilter(EventFilter):
|
||||
|
||||
return pd.DatetimeIndex(filtered_indices)
|
||||
|
||||
class CUSUMFixedEventFilter(EventFilter):
|
||||
|
||||
class CUSUMFixedEventFilter(EventFilter):
|
||||
def __init__(self, threshold: float):
|
||||
self.threshold = threshold
|
||||
|
||||
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
||||
diffed_returns = returns.diff()
|
||||
int_indicies = _process(List(diffed_returns.to_list()), abs(returns.mean()) * self.threshold)
|
||||
int_indicies = _process(
|
||||
List(diffed_returns.to_list()), abs(returns.mean()) * self.threshold
|
||||
)
|
||||
|
||||
return pd.DatetimeIndex([returns.index[i] for i in int_indicies])
|
||||
|
||||
|
||||
@njit
|
||||
def _process(diffed_returns: List, threshold: float32) -> List:
|
||||
pos_threshold: float32 = 0.0 # type: ignore
|
||||
neg_threshold: float32 = 0.0 # type: ignore
|
||||
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
|
||||
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 < -threshold:
|
||||
neg_threshold = 0.0 # type: ignore
|
||||
neg_threshold = 0.0 # type: ignore
|
||||
filtered_indicies.append(index)
|
||||
|
||||
elif pos_threshold > threshold:
|
||||
pos_threshold = 0.0 # type: ignore
|
||||
pos_threshold = 0.0 # type: ignore
|
||||
filtered_indicies.append(index)
|
||||
|
||||
return filtered_indicies
|
||||
return filtered_indicies
|
||||
|
||||
@@ -2,8 +2,7 @@ from ..types import EventFilter
|
||||
from data_loader.types import ReturnSeries
|
||||
import pandas as pd
|
||||
|
||||
class NoEventFilter(EventFilter):
|
||||
|
||||
class NoEventFilter(EventFilter):
|
||||
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
||||
return returns.index
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from .event_filters.nofilter import NoEventFilter
|
||||
from .event_filters.cusum import CUSUMVolatilityEventFilter, CUSUMFixedEventFilter
|
||||
|
||||
eventfilters_map = dict(
|
||||
none = NoEventFilter(),
|
||||
cusum_vol = CUSUMVolatilityEventFilter(vol_period = 20),
|
||||
cusum_fixed = CUSUMFixedEventFilter(threshold = 500)
|
||||
)
|
||||
none=NoEventFilter(),
|
||||
cusum_vol=CUSUMVolatilityEventFilter(vol_period=20),
|
||||
cusum_fixed=CUSUMFixedEventFilter(threshold=500),
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ from ..types import EventLabeller, EventsDataFrame
|
||||
import pandas as pd
|
||||
from .utils import create_forward_returns
|
||||
|
||||
|
||||
class FixedTimeHorionThreeClassBalancedEventLabeller(EventLabeller):
|
||||
|
||||
time_horizon: int
|
||||
@@ -10,7 +11,9 @@ class FixedTimeHorionThreeClassBalancedEventLabeller(EventLabeller):
|
||||
def __init__(self, time_horizon: int):
|
||||
self.time_horizon = time_horizon
|
||||
|
||||
def label_events(self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
def label_events(
|
||||
self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries
|
||||
) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
|
||||
forward_returns = create_forward_returns(returns, self.time_horizon)
|
||||
cutoff_point = returns.index[-self.time_horizon]
|
||||
@@ -18,7 +21,7 @@ class FixedTimeHorionThreeClassBalancedEventLabeller(EventLabeller):
|
||||
event_candidates = forward_returns[event_start_times]
|
||||
|
||||
def get_bins_threeway(x):
|
||||
bins = pd.qcut(event_candidates, 3, retbins=True, duplicates = 'drop')[1]
|
||||
bins = pd.qcut(event_candidates, 3, retbins=True, duplicates="drop")[1]
|
||||
|
||||
if len(bins) != 4:
|
||||
# if we don't have enough data for the quantiles, we'll need to add hard-coded values
|
||||
@@ -26,6 +29,7 @@ class FixedTimeHorionThreeClassBalancedEventLabeller(EventLabeller):
|
||||
upper_bound = bins[-1]
|
||||
bins = [lower_bound] + [-0.02, 0.02] + [upper_bound]
|
||||
return bins
|
||||
|
||||
bins = get_bins_threeway(event_candidates)
|
||||
|
||||
def map_class_threeway(current_value):
|
||||
@@ -37,12 +41,17 @@ class FixedTimeHorionThreeClassBalancedEventLabeller(EventLabeller):
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
labels = event_candidates.map(map_class_threeway)
|
||||
|
||||
return (pd.DataFrame({
|
||||
'start': event_start_times,
|
||||
'end': event_start_times + pd.Timedelta(days=self.time_horizon),
|
||||
'label': labels,
|
||||
'returns': forward_returns[event_start_times]
|
||||
}), forward_returns[event_start_times])
|
||||
|
||||
labels = event_candidates.map(map_class_threeway)
|
||||
|
||||
return (
|
||||
pd.DataFrame(
|
||||
{
|
||||
"start": event_start_times,
|
||||
"end": event_start_times + pd.Timedelta(days=self.time_horizon),
|
||||
"label": labels,
|
||||
"returns": forward_returns[event_start_times],
|
||||
}
|
||||
),
|
||||
forward_returns[event_start_times],
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ from ..types import EventLabeller, EventsDataFrame, ReturnSeries, ForwardReturnS
|
||||
import pandas as pd
|
||||
from .utils import create_forward_returns
|
||||
|
||||
|
||||
class FixedTimeHorionThreeClassImbalancedEventLabeller(EventLabeller):
|
||||
|
||||
time_horizon: int
|
||||
@@ -9,7 +10,9 @@ class FixedTimeHorionThreeClassImbalancedEventLabeller(EventLabeller):
|
||||
def __init__(self, time_horizon: int):
|
||||
self.time_horizon = time_horizon
|
||||
|
||||
def label_events(self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
def label_events(
|
||||
self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries
|
||||
) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
|
||||
forward_returns = create_forward_returns(returns, self.time_horizon)
|
||||
cutoff_point = returns.index[-self.time_horizon]
|
||||
@@ -17,7 +20,7 @@ class FixedTimeHorionThreeClassImbalancedEventLabeller(EventLabeller):
|
||||
event_candidates = forward_returns[event_start_times]
|
||||
|
||||
def get_bins_threeway(x):
|
||||
bins = pd.qcut(event_candidates, 4, retbins=True, duplicates = 'drop')[1]
|
||||
bins = pd.qcut(event_candidates, 4, retbins=True, duplicates="drop")[1]
|
||||
|
||||
if len(bins) != 5:
|
||||
# if we don't have enough data for the quantiles, we'll need to add hard-coded values
|
||||
@@ -25,6 +28,7 @@ class FixedTimeHorionThreeClassImbalancedEventLabeller(EventLabeller):
|
||||
upper_bound = bins[-1]
|
||||
bins = [lower_bound] + [-0.02, 0.0, 0.02] + [upper_bound]
|
||||
return bins
|
||||
|
||||
bins = get_bins_threeway(event_candidates)
|
||||
|
||||
def map_class_threeway(current_value):
|
||||
@@ -36,13 +40,17 @@ class FixedTimeHorionThreeClassImbalancedEventLabeller(EventLabeller):
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
labels = event_candidates.map(map_class_threeway)
|
||||
|
||||
return (pd.DataFrame({
|
||||
'start': event_start_times,
|
||||
'end': event_start_times + pd.Timedelta(days=self.time_horizon),
|
||||
'label': labels,
|
||||
'returns': forward_returns[event_start_times]
|
||||
}), forward_returns[event_start_times])
|
||||
|
||||
|
||||
return (
|
||||
pd.DataFrame(
|
||||
{
|
||||
"start": event_start_times,
|
||||
"end": event_start_times + pd.Timedelta(days=self.time_horizon),
|
||||
"label": labels,
|
||||
"returns": forward_returns[event_start_times],
|
||||
}
|
||||
),
|
||||
forward_returns[event_start_times],
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ from ..types import EventLabeller, EventsDataFrame, ReturnSeries, ForwardReturnS
|
||||
import pandas as pd
|
||||
from .utils import create_forward_returns
|
||||
|
||||
|
||||
class FixedTimeHorionTwoClassEventLabeller(EventLabeller):
|
||||
|
||||
time_horizon: int
|
||||
@@ -9,7 +10,9 @@ class FixedTimeHorionTwoClassEventLabeller(EventLabeller):
|
||||
def __init__(self, time_horizon: int):
|
||||
self.time_horizon = time_horizon
|
||||
|
||||
def label_events(self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
def label_events(
|
||||
self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries
|
||||
) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
|
||||
forward_returns = create_forward_returns(returns, self.time_horizon)
|
||||
cutoff_point = returns.index[-self.time_horizon]
|
||||
@@ -18,14 +21,17 @@ class FixedTimeHorionTwoClassEventLabeller(EventLabeller):
|
||||
|
||||
def get_class_binary(x: float) -> int:
|
||||
return -1 if x <= 0.0 else 1
|
||||
|
||||
labels = event_candidates.map(get_class_binary)
|
||||
|
||||
return (pd.DataFrame({
|
||||
'start': event_start_times,
|
||||
'end': event_start_times + pd.Timedelta(days=self.time_horizon),
|
||||
'label': labels,
|
||||
'returns': forward_returns[event_start_times]
|
||||
}), forward_returns[event_start_times])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
pd.DataFrame(
|
||||
{
|
||||
"start": event_start_times,
|
||||
"end": event_start_times + pd.Timedelta(days=self.time_horizon),
|
||||
"label": labels,
|
||||
"returns": forward_returns[event_start_times],
|
||||
}
|
||||
),
|
||||
forward_returns[event_start_times],
|
||||
)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import pandas as pd
|
||||
from data_loader.types import ForwardReturnSeries
|
||||
|
||||
|
||||
def create_forward_returns(series: pd.Series, period: int) -> ForwardReturnSeries:
|
||||
assert period > 0
|
||||
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=period)
|
||||
|
||||
|
||||
forward_returns = series.rolling(window=indexer).sum()
|
||||
return forward_returns
|
||||
return forward_returns
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
from .labellers.fixed_time_three_class_balanced import FixedTimeHorionThreeClassBalancedEventLabeller
|
||||
from .labellers.fixed_time_three_class_imbalanced import FixedTimeHorionThreeClassImbalancedEventLabeller
|
||||
from .labellers.fixed_time_three_class_balanced import (
|
||||
FixedTimeHorionThreeClassBalancedEventLabeller,
|
||||
)
|
||||
from .labellers.fixed_time_three_class_imbalanced import (
|
||||
FixedTimeHorionThreeClassImbalancedEventLabeller,
|
||||
)
|
||||
from .labellers.fixed_time_two_class import FixedTimeHorionTwoClassEventLabeller
|
||||
|
||||
labellers_map = dict(
|
||||
two_class = FixedTimeHorionTwoClassEventLabeller,
|
||||
three_class_balanced = FixedTimeHorionThreeClassBalancedEventLabeller,
|
||||
three_class_imbalanced = FixedTimeHorionThreeClassImbalancedEventLabeller
|
||||
)
|
||||
two_class=FixedTimeHorionTwoClassEventLabeller,
|
||||
three_class_balanced=FixedTimeHorionThreeClassBalancedEventLabeller,
|
||||
three_class_imbalanced=FixedTimeHorionThreeClassImbalancedEventLabeller,
|
||||
)
|
||||
|
||||
+17
-11
@@ -1,19 +1,25 @@
|
||||
from .types import EventFilter, EventLabeller, EventsDataFrame
|
||||
from data_loader.types import ForwardReturnSeries, XDataFrame, ReturnSeries, ySeries
|
||||
|
||||
|
||||
def label_data(
|
||||
event_filter: EventFilter,
|
||||
event_labeller: EventLabeller,
|
||||
X: XDataFrame,
|
||||
returns: ReturnSeries) -> tuple[EventsDataFrame, XDataFrame, ySeries, ForwardReturnSeries]:
|
||||
event_filter: EventFilter,
|
||||
event_labeller: EventLabeller,
|
||||
X: XDataFrame,
|
||||
returns: ReturnSeries,
|
||||
) -> tuple[EventsDataFrame, XDataFrame, ySeries, ForwardReturnSeries]:
|
||||
|
||||
event_start_times = event_filter.get_event_start_times(returns)
|
||||
print("| Filtered out ", (1 - (len(event_start_times) / len(returns))) * 100, "% of timestamps" )
|
||||
event_start_times = event_filter.get_event_start_times(returns)
|
||||
print(
|
||||
"| Filtered out ",
|
||||
(1 - (len(event_start_times) / len(returns))) * 100,
|
||||
"% of timestamps",
|
||||
)
|
||||
|
||||
events, forward_returns = event_labeller.label_events(event_start_times, returns)
|
||||
events, forward_returns = event_labeller.label_events(event_start_times, returns)
|
||||
|
||||
X = X.filter(items = events.index, axis = 0)
|
||||
y = events['label']
|
||||
forward_returns = events['returns']
|
||||
X = X.filter(items=events.index, axis=0)
|
||||
y = events["label"]
|
||||
forward_returns = events["returns"]
|
||||
|
||||
return events, X, y, forward_returns
|
||||
return events, X, y, forward_returns
|
||||
|
||||
+5
-4
@@ -4,8 +4,8 @@ import pandas as pd
|
||||
import pandera as pa
|
||||
from pandera.typing import DataFrame, Series
|
||||
|
||||
class EventFilter(ABC):
|
||||
|
||||
class EventFilter(ABC):
|
||||
@abstractmethod
|
||||
def get_event_start_times(self, returns: ReturnSeries) -> pd.DatetimeIndex:
|
||||
raise NotImplementedError
|
||||
@@ -17,12 +17,13 @@ class EventSchema(pa.SchemaModel):
|
||||
label: Series[int]
|
||||
returns: Series[float]
|
||||
|
||||
|
||||
EventsDataFrame = DataFrame[EventSchema]
|
||||
|
||||
|
||||
class EventLabeller(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def label_events(self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
def label_events(
|
||||
self, event_start_times: pd.DatetimeIndex, returns: ReturnSeries
|
||||
) -> tuple[EventsDataFrame, ForwardReturnSeries]:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
Reference in New Issue
Block a user