mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-15 08:46:56 +08:00
fix ops & EMA support alpha
This commit is contained in:
@@ -117,7 +117,7 @@ cdef class Rsquare(Expanding):
|
|||||||
self.na_count += 1
|
self.na_count += 1
|
||||||
else:
|
else:
|
||||||
self.x_sum += size
|
self.x_sum += size
|
||||||
self.x2_sum += size
|
self.x2_sum += size * size
|
||||||
self.y_sum += val
|
self.y_sum += val
|
||||||
self.y2_sum += val * val
|
self.y2_sum += val * val
|
||||||
self.xy_sum += size * val
|
self.xy_sum += size * val
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ from __future__ import print_function
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
from scipy.stats import percentileofscore
|
||||||
|
|
||||||
from .base import Expression, ExpressionOps
|
from .base import Expression, ExpressionOps
|
||||||
from ..log import get_module_logger
|
from ..log import get_module_logger
|
||||||
|
|
||||||
@@ -687,6 +689,8 @@ class Rolling(ExpressionOps):
|
|||||||
# isnull = series.isnull() # NOTE: isnull = NaN, inf is not null
|
# isnull = series.isnull() # NOTE: isnull = NaN, inf is not null
|
||||||
if self.N == 0:
|
if self.N == 0:
|
||||||
series = getattr(series.expanding(min_periods=1), self.func)()
|
series = getattr(series.expanding(min_periods=1), self.func)()
|
||||||
|
elif 0 < self.N < 1:
|
||||||
|
series = series.ewm(alpha=self.N, min_periods=1).mean()
|
||||||
else:
|
else:
|
||||||
series = getattr(series.rolling(self.N, min_periods=1), self.func)()
|
series = getattr(series.rolling(self.N, min_periods=1), self.func)()
|
||||||
# series.iloc[:self.N-1] = np.nan
|
# series.iloc[:self.N-1] = np.nan
|
||||||
@@ -696,6 +700,8 @@ class Rolling(ExpressionOps):
|
|||||||
def get_longest_back_rolling(self):
|
def get_longest_back_rolling(self):
|
||||||
if self.N == 0:
|
if self.N == 0:
|
||||||
return np.inf
|
return np.inf
|
||||||
|
if 0 < self.N < 1:
|
||||||
|
return int(np.log(1e-6) / np.log(1 - self.N)) # (1 - N)**window == 1e-6
|
||||||
return self.feature.get_longest_back_rolling() + self.N - 1
|
return self.feature.get_longest_back_rolling() + self.N - 1
|
||||||
|
|
||||||
def get_extended_window_size(self):
|
def get_extended_window_size(self):
|
||||||
@@ -704,6 +710,11 @@ class Rolling(ExpressionOps):
|
|||||||
# remove such support for N == 0?
|
# remove such support for N == 0?
|
||||||
get_module_logger(self.__class__.__name__).warning("The Rolling(ATTR, 0) will not be accurately calculated")
|
get_module_logger(self.__class__.__name__).warning("The Rolling(ATTR, 0) will not be accurately calculated")
|
||||||
return self.feature.get_extended_window_size()
|
return self.feature.get_extended_window_size()
|
||||||
|
elif 0 < self.N < 1:
|
||||||
|
lft_etd, rght_etd = self.feature.get_extended_window_size()
|
||||||
|
size = int(np.log(1e-6) / np.log(1 - self.N))
|
||||||
|
lft_etd = max(lft_etd + size - 1, lft_etd)
|
||||||
|
return lft_etd, rght_etd
|
||||||
else:
|
else:
|
||||||
lft_etd, rght_etd = self.feature.get_extended_window_size()
|
lft_etd, rght_etd = self.feature.get_extended_window_size()
|
||||||
lft_etd = max(lft_etd + self.N - 1, lft_etd)
|
lft_etd = max(lft_etd + self.N - 1, lft_etd)
|
||||||
@@ -1087,7 +1098,7 @@ class Rank(Rolling):
|
|||||||
x1 = x[~np.isnan(x)]
|
x1 = x[~np.isnan(x)]
|
||||||
if x1.shape[0] == 0:
|
if x1.shape[0] == 0:
|
||||||
return np.nan
|
return np.nan
|
||||||
return (x1.argsort()[-1] + 1) / len(x1)
|
return percentileofscore(x1, x1[-1]) / len(x1)
|
||||||
|
|
||||||
if self.N == 0:
|
if self.N == 0:
|
||||||
series = series.expanding(min_periods=1).apply(rank, raw=True)
|
series = series.expanding(min_periods=1).apply(rank, raw=True)
|
||||||
@@ -1273,7 +1284,7 @@ class EMA(Rolling):
|
|||||||
----------
|
----------
|
||||||
feature : Expression
|
feature : Expression
|
||||||
feature instance
|
feature instance
|
||||||
N : int
|
N : int, float
|
||||||
rolling window size
|
rolling window size
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@@ -1296,6 +1307,8 @@ class EMA(Rolling):
|
|||||||
|
|
||||||
if self.N == 0:
|
if self.N == 0:
|
||||||
series = series.expanding(min_periods=1).apply(exp_weighted_mean, raw=True)
|
series = series.expanding(min_periods=1).apply(exp_weighted_mean, raw=True)
|
||||||
|
elif 0 < self.N < 1:
|
||||||
|
series = series.ewm(alpha=self.N, min_periods=1).mean()
|
||||||
else:
|
else:
|
||||||
series = series.ewm(span=self.N, min_periods=1).mean()
|
series = series.ewm(span=self.N, min_periods=1).mean()
|
||||||
return series
|
return series
|
||||||
|
|||||||
Reference in New Issue
Block a user