Exemplo n.º 1
0
def obv(close, volume, talib=None, offset=None, **kwargs):
    """Indicator: On Balance Volume (OBV)"""
    # Validate arguments
    close = verify_series(close)
    volume = verify_series(volume)
    offset = get_offset(offset)
    mode_tal = bool(talib) if isinstance(talib, bool) else True

    # Calculate Result
    if Imports["talib"] and mode_tal:
        from talib import OBV
        obv = OBV(close, volume)
    else:
        signed_volume = signed_series(close, initial=1) * volume
        obv = signed_volume.cumsum()

    # Offset
    if offset != 0:
        obv = obv.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        obv.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        obv.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    obv.name = f"OBV"
    obv.category = "volume"

    return obv
Exemplo n.º 2
0
def nvi(close, volume, length=None, initial=None, offset=None, **kwargs):
    """Indicator: Negative Volume Index (NVI)"""
    # Validate arguments
    close = verify_series(close)
    volume = verify_series(volume)
    length = int(length) if length and length > 0 else 1
    min_periods = int(
        kwargs["min_periods"]) if "min_periods" in kwargs and kwargs[
            "min_periods"] is not None else length
    initial = int(initial) if initial and initial > 0 else 1000
    offset = get_offset(offset)

    # Calculate Result
    roc_ = roc(close=close, length=length)
    signed_volume = signed_series(volume, initial=1)
    nvi = signed_volume[signed_volume < 0].abs() * roc_
    nvi.fillna(0, inplace=True)
    nvi.iloc[0] = initial
    nvi = nvi.cumsum()

    # Offset
    if offset != 0:
        nvi = nvi.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        nvi.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        nvi.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    nvi.name = f"NVI_{length}"
    nvi.category = "volume"

    return nvi
Exemplo n.º 3
0
def pvol(close, volume, offset=None, **kwargs):
    """Indicator: Price-Volume (PVOL)"""
    # Validate arguments
    close = verify_series(close)
    volume = verify_series(volume)
    offset = get_offset(offset)
    signed = kwargs.pop("signed", False)

    # Calculate Result
    if signed:
        pvol = signed_series(close, 1) * close * volume
    else:
        pvol = close * volume

    # Offset
    if offset != 0:
        pvol = pvol.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        pvol.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        pvol.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    pvol.name = f"PVOL"
    pvol.category = "volume"

    return pvol
Exemplo n.º 4
0
def pvi(close, volume, length=None, initial=None, offset=None, **kwargs):
    """Indicator: Positive Volume Index (PVI)"""
    # Validate arguments
    length = int(length) if length and length > 0 else 1
    # min_periods = int(kwargs["min_periods"]) if "min_periods" in kwargs and kwargs["min_periods"] is not None else length
    initial = int(initial) if initial and initial > 0 else 1000
    close = verify_series(close, length)
    volume = verify_series(volume, length)
    offset = get_offset(offset)

    if close is None or volume is None: return

    # Calculate Result
    signed_volume = signed_series(volume, 1)
    pvi = roc(close=close,
              length=length) * signed_volume[signed_volume > 0].abs()
    pvi.fillna(0, inplace=True)
    pvi.iloc[0] = initial
    pvi = pvi.cumsum()

    # Offset
    if offset != 0:
        pvi = pvi.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        pvi.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        pvi.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    pvi.name = f"PVI_{length}"
    pvi.category = "volume"

    return pvi
def obv(close, volume, offset=None, **kwargs):
    """Indicator: On Balance Volume (OBV)"""
    # Validate arguments
    close = verify_series(close)
    volume = verify_series(volume)
    offset = get_offset(offset)

    # Calculate Result
    signed_volume = signed_series(close, initial=1) * volume
    obv = signed_volume.cumsum()

    # Offset
    if offset != 0:
        obv = obv.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        obv.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        obv.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    obv.name = f"OBV"
    obv.category = "volume"

    return obv
Exemplo n.º 6
0
def kvo(high,
        low,
        close,
        volume,
        fast=None,
        slow=None,
        signal=None,
        mamode=None,
        drift=None,
        offset=None,
        **kwargs):
    """Indicator: Klinger Volume Oscillator (KVO)"""
    # Validate arguments
    fast = int(fast) if fast and fast > 0 else 34
    slow = int(slow) if slow and slow > 0 else 55
    signal = int(signal) if signal and signal > 0 else 13
    mamode = mamode.lower() if mamode and isinstance(mamode, str) else "ema"
    _length = max(fast, slow, signal)
    high = verify_series(high, _length)
    low = verify_series(low, _length)
    close = verify_series(close, _length)
    volume = verify_series(volume, _length)
    drift = get_drift(drift)
    offset = get_offset(offset)

    if high is None or low is None or close is None or volume is None: return

    # Calculate Result
    signed_volume = volume * signed_series(hlc3(high, low, close), 1)
    sv = signed_volume.loc[signed_volume.first_valid_index():, ]
    kvo = ma(mamode, sv, length=fast) - ma(mamode, sv, length=slow)
    kvo_signal = ma(mamode, kvo.loc[kvo.first_valid_index():, ], length=signal)

    # Offset
    if offset != 0:
        kvo = kvo.shift(offset)
        kvo_signal = kvo_signal.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        kvo.fillna(kwargs["fillna"], inplace=True)
        kvo_signal.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        kvo.fillna(method=kwargs["fill_method"], inplace=True)
        kvo_signal.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    _props = f"_{fast}_{slow}_{signal}"
    kvo.name = f"KVO{_props}"
    kvo_signal.name = f"KVOs{_props}"
    kvo.category = kvo_signal.category = "volume"

    # Prepare DataFrame to return
    data = {kvo.name: kvo, kvo_signal.name: kvo_signal}
    df = DataFrame(data)
    df.name = f"KVO{_props}"
    df.category = kvo.category

    return df
def vp(close, volume, width=None, **kwargs):
    """Indicator: Volume Profile (VP)"""
    # Validate arguments
    width = int(width) if width and width > 0 else 10
    close = verify_series(close, width)
    volume = verify_series(volume, width)
    sort_close = kwargs.pop("sort_close", False)

    if close is None or volume is None: return

    # Setup
    signed_volume = signed_series(volume, initial=1)
    pos_volume = signed_volume[signed_volume > 0] * volume
    neg_volume = signed_volume[signed_volume < 0] * -volume
    vp = concat([close, pos_volume, neg_volume], axis=1)

    close_col = f"{vp.columns[0]}"
    high_price_col = f"high_{close_col}"
    low_price_col = f"low_{close_col}"
    mean_price_col = f"mean_{close_col}"
    mid_price_col = f"mid_{close_col}"

    volume_col = f"{vp.columns[1]}"
    pos_volume_col = f"pos_{volume_col}"
    neg_volume_col = f"neg_{volume_col}"
    total_volume_col = f"total_{volume_col}"
    vp.columns = [close_col, pos_volume_col, neg_volume_col]

    # sort_close: Sort by close before splitting into ranges. Default: False
    # If False, it sorts by date index or chronological versus by price
    if sort_close:
        vp.sort_values(by=[close_col], inplace=True)

    # Calculate Result
    vp_ranges = array_split(vp, width)
    result = ({
        low_price_col: r[close_col].min(),
        mean_price_col: r[close_col].mean(),
        high_price_col: r[close_col].max(),
        pos_volume_col: r[pos_volume_col].sum(),
        neg_volume_col: r[neg_volume_col].sum(),
    } for r in vp_ranges)
    vpdf = DataFrame(result)
    vpdf[total_volume_col] = vpdf[pos_volume_col] + vpdf[neg_volume_col]

    # Handle fills
    if "fillna" in kwargs:
        vpdf.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        vpdf.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    vpdf.name = f"VP_{width}"
    vpdf.category = "volume"

    return vpdf
Exemplo n.º 8
0
def vp(close, volume, width=None, **kwargs):
    """Indicator: Volume Profile (VP)"""
    # Validate arguments
    width = int(width) if width and width > 0 else 10
    close = verify_series(close, width)
    volume = verify_series(volume, width)
    sort_close = kwargs.pop("sort_close", False)

    if close is None or volume is None: return

    # Setup
    signed_price = signed_series(close, 1)
    pos_volume = volume * signed_price[signed_price > 0]
    pos_volume.name = volume.name
    neg_volume = -volume * signed_price[signed_price < 0]
    neg_volume.name = volume.name
    vp = concat([close, pos_volume, neg_volume], axis=1)

    close_col = f"{vp.columns[0]}"
    high_price_col = f"high_{close_col}"
    low_price_col = f"low_{close_col}"
    mean_price_col = f"mean_{close_col}"

    volume_col = f"{vp.columns[1]}"
    pos_volume_col = f"pos_{volume_col}"
    neg_volume_col = f"neg_{volume_col}"
    total_volume_col = f"total_{volume_col}"
    vp.columns = [close_col, pos_volume_col, neg_volume_col]

    # sort_close: Sort by close before splitting into ranges. Default: False
    # If False, it sorts by date index or chronological versus by price

    if sort_close:
        vp[mean_price_col] = vp[close_col]
        vpdf = vp.groupby(cut(vp[close_col], width, include_lowest=True, precision=2)).agg({
            mean_price_col: mean,
            pos_volume_col: sum,
            neg_volume_col: sum,
        })
        vpdf[low_price_col] = [x.left for x in vpdf.index]
        vpdf[high_price_col] = [x.right for x in vpdf.index]
        vpdf = vpdf.reset_index(drop=True)
        vpdf = vpdf[[low_price_col, mean_price_col, high_price_col, pos_volume_col, neg_volume_col]]
    else:
        vp_ranges = array_split(vp, width)
        result = ({
            low_price_col: r[close_col].min(),
            mean_price_col: r[close_col].mean(),
            high_price_col: r[close_col].max(),
            pos_volume_col: r[pos_volume_col].sum(),
            neg_volume_col: r[neg_volume_col].sum(),
        } for r in vp_ranges)
        vpdf = DataFrame(result)
    vpdf[total_volume_col] = vpdf[pos_volume_col] + vpdf[neg_volume_col]

    # Handle fills
    if "fillna" in kwargs:
        vpdf.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        vpdf.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    vpdf.name = f"VP_{width}"
    vpdf.category = "volume"

    return vpdf