Esempio n. 1
0
def gatorosc(candles: np.ndarray,
             source_type="close",
             sequential=False) -> GATOR:
    """
    Gator Oscillator by Bill M. Williams

    :param candles: np.ndarray
    :param source_type: str - default: "close"
    :param sequential: bool - default=False

    :return: GATOR(upper, lower, upper_change, lower_change)
    """

    if not sequential and len(candles) > 240:
        candles = candles[-240:]

    source = get_candle_source(candles, source_type=source_type)

    jaw = np_shift(numpy_ewma(source, 13), 8, fill_value=np.nan)
    teeth = np_shift(numpy_ewma(source, 8), 5, fill_value=np.nan)
    lips = np_shift(numpy_ewma(source, 5), 3, fill_value=np.nan)

    upper = np.abs(jaw - teeth)
    lower = -np.abs(teeth - lips)

    upper_change = talib.MOM(upper, timeperiod=1)
    lower_change = -talib.MOM(lower, timeperiod=1)

    if sequential:
        return GATOR(upper, lower, upper_change, lower_change)
    else:
        return GATOR(upper[-1], lower[-1], upper_change[-1], lower_change[-1])
Esempio n. 2
0
def alligator(candles: np.ndarray,
              source_type: str = "close",
              sequential: bool = False) -> AG:
    """
    Alligator

    :param candles: np.ndarray
    :param source_type: str - default: "close"
    :param sequential: bool - default=False

    :return: AG(jaw, teeth, lips)
    """
    if not sequential and len(candles) > 240:
        candles = candles[-240:]

    source = get_candle_source(candles, source_type=source_type)

    jaw = np_shift(numpy_ewma(source, 13), 8, fill_value=np.nan)
    teeth = np_shift(numpy_ewma(source, 8), 5, fill_value=np.nan)
    lips = np_shift(numpy_ewma(source, 5), 3, fill_value=np.nan)

    if sequential:
        return AG(jaw, teeth, lips)
    else:
        return AG(jaw[-1], teeth[-1], lips[-1])
Esempio n. 3
0
def safezonestop(candles: np.ndarray, period: int = 22, mult: float = 2.5, max_lookback: int = 3,
                 direction: str = "long", sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Safezone Stops

    :param candles: np.ndarray
    :param period: int - default=22
    :param mult: float - default=2.5
    :param max_lookback: int - default=3
    :param direction: str - default=long
    :param sequential: bool - default=False

    :return: float | np.ndarray
    """
    warmup_candles_num = get_config('env.data.warmup_candles_num', 240)
    if not sequential and len(candles) > warmup_candles_num:
        candles = candles[-warmup_candles_num:]

    high = candles[:, 3]
    low = candles[:, 4]

    last_high = np_shift(high, 1, fill_value=np.nan)
    last_low = np_shift(low, 1, fill_value=np.nan)

    if direction == "long":
        res = last_low - mult * talib.MINUS_DM(high, low, timeperiod=period)
        swv = sliding_window_view(res, window_shape=max_lookback)
        res = np.max(swv, axis=-1)
    else:
        res = last_high + mult * talib.PLUS_DM(high, low, timeperiod=period)
        swv = sliding_window_view(res, window_shape=max_lookback)
        res = np.min(swv, axis=-1)

    return np.concatenate((np.full((candles.shape[0] - res.shape[0]), np.nan), res), axis=0) if sequential else res[-1]
Esempio n. 4
0
def safezonestop(candles: np.ndarray, period: int = 22, mult: float = 2.5, max_lookback: int = 3,
                 direction: str = "long", sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Safezone Stops

    :param candles: np.ndarray
    :param period: int - default: 22
    :param mult: float - default: 2.5
    :param max_lookback: int - default: 3
    :param direction: str - default: long
    :param sequential: bool - default: False

    :return: float | np.ndarray
    """
    candles = slice_candles(candles, sequential)

    high = candles[:, 3]
    low = candles[:, 4]

    last_high = np_shift(high, 1, fill_value=np.nan)
    last_low = np_shift(low, 1, fill_value=np.nan)

    if direction == "long":
        res = talib.MAX(last_low - mult * talib.MINUS_DM(high, low, timeperiod=period), max_lookback)
    else:
        res = talib.MIN(last_high + mult * talib.PLUS_DM(high, low, timeperiod=period), max_lookback)

    return res if sequential else res[-1]
Esempio n. 5
0
def crossed(series1: np.ndarray,
            series2: Union[float, int, np.ndarray],
            direction: str = None,
            sequential: bool = False) -> bool:
    """
    Helper for detecion of crosses

    :param series1: np.ndarray
    :param series2: float, int, np.array
    :param direction: str - default: None - above or below

    :return: bool
    """

    if sequential:
        series1_shifted = jh.np_shift(series1, 1, np.nan)

        if type(series2) is np.ndarray:
            series2_shifted = jh.np_shift(series2, 1, np.nan)
        else:
            series2_shifted = series2

        if direction is None or direction == "above":
            cross_above = np.logical_and(series1 > series2,
                                         series1_shifted <= series2_shifted)

        if direction is None or direction == "below":
            cross_below = np.logical_and(series1 < series2,
                                         series1_shifted >= series2_shifted)

        if direction is None:
            cross_any = np.logical_or(cross_above, cross_below)
            return cross_any

        if direction == "above":
            return cross_above
        else:
            return cross_below
    else:
        if not type(series2) is np.ndarray:
            series2 = np.array([series2, series2])

        if direction is None or direction == "above":
            cross_above = series1[-2] <= series2[-2] and series1[-1] > series2[
                -1]
        if direction is None or direction == "below":
            cross_below = series1[-2] >= series2[-2] and series1[-1] < series2[
                -1]

        if direction is None:
            return cross_above or cross_below

        if direction == "above":
            return cross_above
        else:
            return cross_below
Esempio n. 6
0
def ichimoku_cloud_seq(candles: np.ndarray,
                       conversion_line_period: int = 9,
                       base_line_period: int = 26,
                       lagging_line_period: int = 52,
                       displacement: int = 26,
                       sequential: bool = False) -> IchimokuCloud:
    """
    Ichimoku Cloud

    :param candles: np.ndarray
    :param conversion_line_period: int - default=9
    :param base_line_period: int - default=26
    :param lagging_line_period: int - default=52
    :param displacement: - default=26
    :param sequential: bool - default=False

    :return: IchimokuCloud
    """

    if len(candles) < lagging_line_period + displacement:
        raise ValueError(
            "Too few candles available for lagging_line_period + displacement."
        )

    if not sequential and len(candles) > 240:
        candles = candles[-240:]

    small_ph = talib.MAX(candles[:, 3], conversion_line_period)
    small_pl = talib.MIN(candles[:, 4], conversion_line_period)
    conversion_line = (small_ph + small_pl) / 2

    mid_ph = talib.MAX(candles[:, 3], base_line_period)
    mid_pl = talib.MIN(candles[:, 4], base_line_period)
    base_line = (mid_ph + mid_pl) / 2

    long_ph = talib.MAX(candles[:, 3], lagging_line_period)
    long_pl = talib.MIN(candles[:, 4], lagging_line_period)
    span_b_pre = (long_ph + long_pl) / 2
    span_b = np_shift(span_b_pre, displacement, fill_value=np.nan)
    span_a_pre = (conversion_line + base_line) / 2
    span_a = np_shift(span_a_pre, displacement, fill_value=np.nan)

    lagging_line = np_shift(candles[:, 2], displacement - 1, fill_value=np.nan)

    if sequential:
        return IchimokuCloud(conversion_line, base_line, span_a, span_b,
                             lagging_line, span_a_pre, span_b_pre)
    else:
        return IchimokuCloud(conversion_line[-1], base_line[-1], span_a[-1],
                             span_b[-1], lagging_line[-1], span_a_pre[-1],
                             span_b_pre[-1])
Esempio n. 7
0
def correlation_cycle(candles: np.ndarray, period: int = 20, threshold: int = 9, source_type: str = "close",
                      sequential: bool = False) -> CC:
    """
    "Correlation Cycle, Correlation Angle, Market State - John Ehlers

    :param candles: np.ndarray
    :param period: int - default: 20
    :param threshold: int - default: 9
    :param source_type: str - default: "close"
    :param sequential: bool - default: False

    :return: CC(real, imag)
    """
    candles = slice_candles(candles, sequential)

    source = get_candle_source(candles, source_type=source_type)

    realPart, imagPart, angle = go_fast(source, period, threshold)

    priorAngle = np_shift(angle, 1, fill_value=np.nan)
    angle = np.where(np.logical_and(priorAngle > angle, priorAngle - angle < 270.0), priorAngle, angle)

    # Market State Function
    state = np.where(np.abs(angle - priorAngle) < threshold, np.where(angle >= 0.0, 1, np.where(angle < 0.0, -1, 0)), 0)

    if sequential:
        return CC(realPart, imagPart, angle, state)
    else:
        return CC(realPart[-1], imagPart[-1], angle[-1], state[-1])
Esempio n. 8
0
def maaq(candles: np.ndarray,
         period: int = 11,
         fast_period: int = 2,
         slow_period: int = 30,
         source_type: str = "close",
         sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Moving Average Adaptive Q

    :param candles: np.ndarray
    :param period: int - default: 11
    :param fast_period: int - default: 2
    :param slow_period: int - default: 30
    :param source_type: str - default: "close"
    :param sequential: bool - default: False

    :return: float | np.ndarray
    """

    # Accept normal array too.
    if len(candles.shape) == 1:
        source = candles
    else:
        candles = slice_candles(candles, sequential)
        source = get_candle_source(candles, source_type=source_type)

    source = source[~np.isnan(source)]

    diff = np.abs(source - np_shift(source, 1, np.nan))
    signal = np.abs(source - np_shift(source, period, np.nan))
    noise = talib.SUM(diff, period)

    with np.errstate(divide='ignore'):
        ratio = np.where(noise == 0, 0, signal / noise)

    fastSc = 2 / (fast_period + 1)
    slowSc = 2 / (slow_period + 1)
    temp = np.power((ratio * fastSc) + slowSc, 2)

    res = maaq_fast(source, temp, period)
    res = same_length(candles, res)

    return res if sequential else res[-1]
Esempio n. 9
0
File: dti.py Progetto: wcy/jesse
def dti(candles: np.ndarray,
        r: int = 14,
        s: int = 10,
        u: int = 5,
        sequential: bool = False) -> Union[float, np.ndarray]:
    """
    DTI by William Blau

    :param candles: np.ndarray
    :param r: int - default=14
    :param s: int - default=10
    :param u: int - default=5
    :param sequential: bool - default=False

    :return: float
    """
    warmup_candles_num = get_config('env.data.warmup_candles_num', 240)
    if not sequential and len(candles) > warmup_candles_num:
        candles = candles[-warmup_candles_num:]

    high = candles[:, 3]
    low = candles[:, 4]

    high_1 = jh.np_shift(high, 1, np.nan)
    low_1 = jh.np_shift(low, 1, np.nan)

    xHMU = np.where(high - high_1 > 0, high - high_1, 0)
    xLMD = np.where(low - low_1 < 0, -(low - low_1), 0)

    xPrice = xHMU - xLMD
    xPriceAbs = np.absolute(xPrice)

    xuXA = talib.EMA(talib.EMA(talib.EMA(xPrice, r), s), u)
    xuXAAbs = talib.EMA(talib.EMA(talib.EMA(xPriceAbs, r), s), u)

    Val1 = 100 * xuXA
    Val2 = xuXAAbs
    dti_val = np.where(Val2 != 0, Val1 / Val2, 0)

    if sequential:
        return dti_val
    else:
        return None if np.isnan(dti_val[-1]) else dti_val[-1]
Esempio n. 10
0
def vpt(candles: np.ndarray,
        source_type: str = "close",
        sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Volume Price Trend (VPT)

    :param candles: np.ndarray
    :param source_type: str - default: "close"
    :param sequential: bool - default: False

    :return: float | np.ndarray
    """
    candles = slice_candles(candles, sequential)

    source = get_candle_source(candles, source_type=source_type)
    vpt = (candles[:, 5] * ((source - np_shift(source, 1, fill_value=np.nan)) /
                            np_shift(source, 1, fill_value=np.nan)))
    res = np_shift(vpt, 1, fill_value=np.nan) + vpt

    return res if sequential else res[-1]
Esempio n. 11
0
def safezonestop(candles: np.ndarray,
                 period: int = 22,
                 mult: float = 2.5,
                 max_lookback: int = 3,
                 direction: str = "long",
                 sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Safezone Stops

    :param candles: np.ndarray
    :param period: int - default=22
    :param mult: float - default=2.5
    :param max_lookback: int - default=3
    :param direction: str - default=long
    :param sequential: bool - default=False

    :return: float | np.ndarray
    """
    warmup_candles_num = get_config('env.data.warmup_candles_num', 240)
    if not sequential and len(candles) > warmup_candles_num:
        candles = candles[-warmup_candles_num:]

    high = candles[:, 3]
    low = candles[:, 4]

    last_high = np_shift(high, 1, fill_value=np.nan)
    last_low = np_shift(low, 1, fill_value=np.nan)

    if direction == "long":
        res = talib.MAX(
            last_low - mult * talib.MINUS_DM(high, low, timeperiod=period),
            max_lookback)
    else:
        res = talib.MIN(
            last_high + mult * talib.PLUS_DM(high, low, timeperiod=period),
            max_lookback)

    if sequential:
        return res
    else:
        return None if np.isnan(res[-1]) else res[-1]
Esempio n. 12
0
def ichimoku_cloud_seq(candles: np.ndarray,
                       conversion_line_period: int = 9,
                       base_line_period: int = 26,
                       lagging_line_period: int = 52,
                       displacement: int = 26,
                       sequential: bool = False) -> IchimokuCloud:
    """
    Ichimoku Cloud

    :param candles: np.ndarray
    :param conversion_line_period: int - default: 9
    :param base_line_period: int - default: 26
    :param lagging_line_period: int - default: 52
    :param displacement: - default: 26
    :param sequential: bool - default: False

    :return: IchimokuCloud
    """

    if candles.shape[0] < lagging_line_period + displacement:
        raise ValueError(
            "Too few candles available for lagging_line_period + displacement."
        )

    candles = slice_candles(candles, sequential)

    conversion_line = _line_helper(candles, conversion_line_period)
    base_line = _line_helper(candles, base_line_period)
    span_b_pre = _line_helper(candles, lagging_line_period)
    span_b = np_shift(span_b_pre, displacement, fill_value=np.nan)
    span_a_pre = (conversion_line + base_line) / 2
    span_a = np_shift(span_a_pre, displacement, fill_value=np.nan)
    lagging_line = np_shift(candles[:, 2], displacement - 1, fill_value=np.nan)

    if sequential:
        return IchimokuCloud(conversion_line, base_line, span_a, span_b,
                             lagging_line, span_a_pre, span_b_pre)
    else:
        return IchimokuCloud(conversion_line[-1], base_line[-1], span_a[-1],
                             span_b[-1], lagging_line[-1], span_a_pre[-1],
                             span_b_pre[-1])
Esempio n. 13
0
File: vpt.py Progetto: wcy/jesse
def vpt(candles: np.ndarray,
        source_type: str = "close",
        sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Volume Price Trend (VPT)

    :param candles: np.ndarray
    :param source_type: str - default: "close"
    :param sequential: bool - default=False

    :return: float | np.ndarray
    """
    warmup_candles_num = get_config('env.data.warmup_candles_num', 240)
    if not sequential and len(candles) > warmup_candles_num:
        candles = candles[-warmup_candles_num:]

    source = get_candle_source(candles, source_type=source_type)
    vpt = (candles[:, 5] * ((source - np_shift(source, 1, fill_value=np.nan)) /
                            np_shift(source, 1, fill_value=np.nan)))
    res = np_shift(vpt, 1, fill_value=np.nan) + vpt

    return res if sequential else res[-1]
Esempio n. 14
0
    def append(self, item: np.ndarray) -> None:
        self.index += 1

        # expand if the arr is almost full
        if self.index != 0 and (self.index + 1) % self.bucket_size == 0:
            new_bucket = np.zeros(self.shape)
            self.array = np.concatenate((self.array, new_bucket), axis=0)

        # drop N% of the beginning values to free memory
        if (self.drop_at is not None and self.index != 0
                and (self.index + 1) % self.drop_at == 0):
            shift_num = int(self.drop_at / 2)
            self.index -= shift_num
            self.array = np_shift(self.array, -shift_num)

        self.array[self.index] = item
Esempio n. 15
0
def jsa(candles: np.ndarray,
        period: int = 30,
        source_type: str = "close",
        sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Jsa Moving Average

    :param candles: np.ndarray
    :param period: int - default: 30
    :param source_type: str - default: "close"
    :param sequential: bool - default: False

    :return: float | np.ndarray
    """
    if len(candles.shape) == 1:
        source = candles
    else:
        candles = slice_candles(candles, sequential)
        source = get_candle_source(candles, source_type=source_type)

    res = (source + np_shift(source, period, np.nan)) / 2

    return res if sequential else res[-1]
Esempio n. 16
0
def test_np_shift():
    arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    res = jh.np_shift(arr, -3)
    expected = np.array([4, 5, 6, 7, 8, 9, 0, 0, 0])

    np.equal(res, expected)
Esempio n. 17
0
def correlation_cycle(candles: np.ndarray, period: int = 20, threshold: int = 9, source_type: str = "close",
                      sequential: bool = False) -> CC:
    """
    "Correlation Cycle, Correlation Angle, Market State - John Ehlers

    :param candles: np.ndarray
    :param period: int - default: 20
    :param threshold: int - default: 9
    :param source_type: str - default: "close"
    :param sequential: bool - default=False

    :return: CC(real, imag)
    """
    if not sequential and len(candles) > 240:
        candles = candles[-240:]

    source = get_candle_source(candles, source_type=source_type)

    # Correlation Cycle Function
    PIx2 = 4.0 * math.asin(1.0)
    period = max(2, period)

    realPart = np.full_like(source, np.nan)
    imagPart = np.full_like(source, np.nan)

    for i in range(period, source.shape[0]):
        Rx = 0.0
        Rxx = 0.0
        Rxy = 0.0
        Ryy = 0.0
        Ry = 0.0
        Ix = 0.0
        Ixx = 0.0
        Ixy = 0.0
        Iyy = 0.0
        Iy = 0.0

        for j in range(period):
            jMinusOne = j + 1
            if np.isnan(source[i - jMinusOne]):
                X = 0
            else:
                X = source[i - jMinusOne]
            temp = PIx2 * jMinusOne / period
            Yc = np.cos(temp)
            Ys = -np.sin(temp)
            Rx = Rx + X
            Ix = Ix + X
            Rxx = Rxx + X * X
            Ixx = Ixx + X * X
            Rxy = Rxy + X * Yc
            Ixy = Ixy + X * Ys
            Ryy = Ryy + Yc * Yc
            Iyy = Iyy + Ys * Ys
            Ry = Ry + Yc
            Iy = Iy + Ys

        temp_1 = period * Rxx - Rx * Rx
        temp_2 = period * Ryy - Ry * Ry
        if (temp_1 > 0.0 and temp_2 > 0.0):
            realPart[i] = (period * Rxy - Rx * Ry) / np.sqrt(temp_1 * temp_2)

        temp_1 = period * Ixx - Ix * Ix
        temp_2 = period * Iyy - Iy * Iy
        if (temp_1 > 0.0 and temp_2 > 0.0):
            imagPart[i] = (period * Ixy - Ix * Iy) / np.sqrt(temp_1 * temp_2)

    # Correlation Angle Phasor
    HALF_OF_PI = math.asin(1.0)
    angle = np.where(imagPart == 0, 0.0, np.degrees(np.arctan(realPart / imagPart) + HALF_OF_PI))
    angle = np.where(imagPart > 0.0, angle - 180.0, angle)
    priorAngle = np_shift(angle, 1, fill_value=np.nan)
    angle = np.where(np.logical_and(priorAngle > angle, priorAngle - angle < 270.0), priorAngle, angle)

    # Market State Function
    state = np.where(np.abs(angle - priorAngle) < threshold, np.where(angle >= 0.0, 1, np.where(angle < 0.0, -1, 0)), 0)

    if sequential:
        return CC(realPart, imagPart, angle, state)
    else:
        return CC(realPart[-1], imagPart[-1], angle[-1], state[-1])