def exponential_spread_volatility(x: pd.Series, beta: float = 0.75) -> pd.Series: """ Exponentially weighted spread volatility :param x: time series of prices :param beta: how much to weigh the previous price in the time series, thus controlling how much importance we place on the (more distant) past. Must be between 0 (inclusive) and 1 (exclusive) :return: date-based time series of exponential spread volatility of the input series **Usage** Exponentially weights the daily differences of the input series, calculates the annualized standard deviation **Examples** Generate price series and compute exponentially weighted standard deviation of returns >>> prices = generate_series(100) >>> exponential_volatility(prices, 0.9) The above is equivalent to >>> annualize(exponential_std(diff(prices, 1), 0.9)) **See also** :func:`volatility` :func:`exponential_std` :func:`exponential_volatility` """ return annualize(exponential_std(diff(x, 1), beta))
def process(self): a_data = self.children_data.get('a') if isinstance(a_data, ProcessorResult): if a_data.success: result = diff(a_data.data, self.obs) self.value = ProcessorResult(True, result) else: self.value = ProcessorResult(False, "DiffProcessor does not have 'a' series values yet") else: self.value = ProcessorResult(False, "DiffProcessor does not have 'a' series yet")
def relative_strength_index(x: pd.Series, w: Union[Window, int, str] = 14) -> pd.DataFrame: """ Relative Strength Index :param x: time series of prices :param w: Window or int: size of window and ramp up to use. e.g. Window(22, 10) where 22 is the window size and 10 the ramp up value. If w is a string, it should be a relative date like '1m', '1d', etc. Window size defaults to length of series. :return: date-based time series of RSI **Usage** The RSI computes momentum as the ratio of higher closes to lower closes: stocks which have had more or stronger positive changes have a higher RSI than stocks which have had more or stronger negative changes. See `RSI <https://en.wikipedia.org/wiki/Relative_strength_index>`_ for more information **Examples** Compute relative strength index over a :math:`14` day window: >>> prices = generate_series(100) >>> relative_strength_index(prices, 14) **See also** :func:`moving_average` :func:`std` :func:`smoothed_moving_average` """ w = normalize_window(x, w) one_period_change = diff(x, 1)[1:] gains = one_period_change.copy() losses = one_period_change.copy() gains[gains < 0] = 0 losses[losses > 0] = 0 losses[losses < 0] *= -1 moving_avg_gains = smoothed_moving_average(gains, w) moving_avg_losses = smoothed_moving_average(losses, w) rsi_len = len(moving_avg_gains) rsi = moving_avg_gains.copy() rsi *= 0 for index in range(0, rsi_len): if moving_avg_losses[index] == 0: rsi[index] = 100 else: relative_strength = moving_avg_gains[index] / moving_avg_losses[ index] rsi[index] = 100 - (100 / (1 + relative_strength)) return rsi
def rsi(x: pd.Series, w: Union[Window, int] = Window(None, 0)) -> pd.Series: """ The relative strength index of X over a window. :param x: time series :param w: Window or int: size of window and ramp up to use. e.g. Window(22, 10) where 22 is the window size and 10 the ramp up value. Window size defaults to length of series. :return: time series of relative strength index **Usage** Compute the `relative strength index <https://en.wikipedia.org/wiki/Relative_strength_index>`_ :math:`RSI_t = 100 - 100 / ( 1 + RS_t )` where :math:`RS_t` is the ratio of exponentially smoothed gains to exponentially smoothed losses over specified window. See `smoothed or modified moving average <https://en.wikipedia.org/wiki/Moving_average#Modified_moving_average>`_ for more details **Examples** >>> series = generate_series(100) >>> rsi(series) **See also** :func:`diff` """ w = normalize_window(x, w) if not isinstance(w.w, int): raise MqValueError('window length must be an integer to calculate RSI') delta = diff(x) up, down = delta.copy(), delta.copy() up[up < 0] = 0 down[down > 0] = 0 ma_up = up.ewm(alpha=1 / w.w, adjust=False).mean() ma_down = abs_(down.ewm(alpha=1 / w.w, adjust=False).mean()) rs = ma_up / ma_down rsi = 100 - 100 / (1 + rs) rsi[ma_down == 0] = 100 return apply_ramp(rsi, w)