class LinearWeightedMovingAverage(CustomFactor, SingleInputMixin): """ Weighted Average Value of an arbitrary column **Default Inputs**: None **Default Window Length**: None """ # numpy's nan functions throw warnings when passed an array containing only # nans, but they still returns the desired value (nan), so we ignore the # warning. ctx = ignore_nanwarnings() def compute(self, today, assets, out, data): ndays = data.shape[0] # Initialize weights array weights = arange(1, ndays + 1, dtype=float64_dtype).reshape(ndays, 1) # Compute normalizer normalizer = (ndays * (ndays + 1)) / 2 # Weight the data weighted_data = data * weights # Compute weighted averages out[:] = nansum(weighted_data, axis=0) / normalizer
class SimpleMovingAverage(CustomFactor, SingleInputMixin): """ Average Value of an arbitrary column **Default Inputs**: None **Default Window Length**: None """ # numpy's nan functions throw warnings when passed an array containing only # nans, but they still returns the desired value (nan), so we ignore the # warning. ctx = ignore_nanwarnings() def compute(self, today, assets, out, data): out[:] = nanmean(data, axis=0)
class MaxDrawdown(CustomFactor, SingleInputMixin): """ Max Drawdown **Default Inputs:** None **Default Window Length:** None """ ctx = ignore_nanwarnings() def compute(self, today, assets, out, data): drawdowns = fmax.accumulate(data, axis=0) - data drawdowns[isnan(drawdowns)] = NINF drawdown_ends = nanargmax(drawdowns, axis=0) # TODO: Accelerate this loop in Cython or Numba. for i, end in enumerate(drawdown_ends): peak = nanmax(data[:end + 1, i]) out[i] = (peak - data[end, i]) / data[end, i]