Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
 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")
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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)