Example #1
0
 def ar(self, n: int, array: bool = False) -> Union[float, np.ndarray]:
     """
     人气指数
     """
     result = (talib.SUM(self.high_array - self.close_array, n) / talib.SUM(self.open_array - self.low_array, n)) * 100
     if array:
         return result
     return result[-1]
Example #2
0
 def kdj(self, n, s, f, array=False):
     """KDJ指标"""
     c = self.close
     hhv = self.hhv(n)
     llv = self.llv(n)
     shl = talib.SUM(hhv - llv, s)
     scl = talib.SUM(c - llv, s)
     k = 100 * shl / scl
     d = talib.SMA(k, f)
     j = 3 * k - 2 * d
     if array:
         return k, d, j
     return k[-1], d[-1], j[-1]
Example #3
0
    def add_stock_index(self, df, index_list=None):
        close = df["close"]
        if "MA" in index_list:
            for p in self.timePeriodList:
                df["ma" + str(p)] = ta.MA(close, timeperiod=p)
                df["mam" + str(p)] = mam = df.apply(
                    lambda row: self.mam(row, p), axis=1)
                df["mam" + str(p) + "_2"] = ta.SUM(mam, timeperiod=2)
                df["mam" + str(p) + "_3"] = ta.SUM(mam, timeperiod=3)

        df['vol'] = df['volume'] / ta.MA(df['volume'], timeperiod=60)
        df['atr'] = ta.ATR(df['high'], df['low'], close,
                           timeperiod=1) / close.shift(1)
        return df
Example #4
0
File: chop.py Project: zx9r/jesse
def chop(candles: np.ndarray,
         period: int = 14,
         scalar: float = 100,
         drift: int = 1,
         sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Choppiness Index (CHOP)

    :param candles: np.ndarray
    :param period: int - default: 30
    :param sequential: bool - default=False

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

    candles_close = candles[:, 2]
    candles_high = candles[:, 3]
    candles_low = candles[:, 4]

    atr_sum = talib.SUM(
        talib.ATR(candles_high, candles_low, candles_close, timeperiod=drift),
        period)

    hh = talib.MAX(candles_high, period)
    ll = talib.MIN(candles_low, period)

    res = (scalar * (np.log10(atr_sum) - np.log10(hh - ll))) / np.log10(period)

    return res if sequential else res[-1]
Example #5
0
    def __recoundAvgVol(self):
        """计算平均成交量"""

        # 1、lineBar满足长度才执行计算
        if self.inputVolLen <= 0:  # 不计算
            return

        if len(self.lineBar) < self.inputVolLen + 1:
            self.debugCtaLog(u'数据未充分,当前Bar数据数量:{0},计算Avg Vol需要:{1}'.format(
                len(self.lineBar), self.inputVolLen + 1))
            return

        if self.mode == self.TICK_MODE:
            listVol = [
                x.volume for x in self.lineBar[-self.inputVolLen - 1:-1]
            ]
        else:
            listVol = [x.volume for x in self.lineBar[-self.inputVolLen:]]

        sumVol = ta.SUM(numpy.array(listVol, dtype=float),
                        timeperiod=self.inputVolLen)[-1]

        avgVol = round(sumVol / self.inputVolLen, 0)

        self.lineAvgVol.append(avgVol)
Example #6
0
File: ui.py Project: xsa-dev/jesse
def ui(candles: np.ndarray,
       period: int = 14,
       scalar: float = 100,
       source_type: str = "close",
       sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Ulcer Index (UI)

    :param candles: np.ndarray
    :param period: int - default: 14
    :param scalar: float - default: 100
    :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)

    highest_close = talib.MAX(source, period)
    downside = scalar * (source - highest_close)
    downside /= highest_close
    d2 = downside * downside

    res = np.sqrt(talib.SUM(d2, period) / period)

    return res if sequential else res[-1]
Example #7
0
def Math_Operators(dataframe):
	#Math Operator Functions
	#ADD - Vector Arithmetic Add
	df[f'{ratio}_ADD'] = talib.ADD(High, Low)
	#c - Vector Arithmetic Div
	df[f'{ratio}_ADD'] = talib.DIV(High, Low)
	#MAX - Highest value over a specified period
	df[f'{ratio}_MAX'] = talib.MAX(Close, timeperiod=30)
	#MAXINDEX - Index of Highest value over a specified period
	#integer = MAXINDEX(Close, timeperiod=30)
	#MIN - Lowest value over a specified period
	df[f'{ratio}_MIN'] = talib.MIN(Close, timeperiod=30)
	#MININDEX - Index of Lowest value over a specified period
	integer = talib.MININDEX(Close, timeperiod=30)
	#MINMAX - Lowest and Highest values over a specified period
	min, max = talib.MINMAX(Close, timeperiod=30)
	#MINMAXINDEX - Indexes of Lowest and Highest values over a specified period
	minidx, maxidx = talib.MINMAXINDEX(Close, timeperiod=30)
	#MULT - Vector Arithmetic Mult
	df[f'{ratio}_MULT'] = talib.MULT(High, Low)
	#SUB - Vector Arithmetic Substraction
	df[f'{ratio}_SUB'] = talib.SUB(High, Low)
	#SUM - Summation
	df[f'{ratio}_SUM'] = talib.SUM(Close, timeperiod=30)

	return
Example #8
0
def pfe(candles: np.ndarray,
        period: int = 10,
        smoothing: int = 5,
        source_type: str = "close",
        sequential: bool = False) -> Union[float, np.ndarray]:
    """
    Polarized Fractal Efficiency (PFE)

    :param candles: np.ndarray
    :param period: int - default: 10
    :param smoothing: int - default: 5
    :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)

    ln = period - 1
    diff = np.diff(source, ln)
    a = np.sqrt(np.power(diff, 2) + np.power(period, 2))
    b = talib.SUM(np.sqrt(1 + np.power(np.diff(source, 1), 2)), ln)
    pfetmp = 100 * same_length(source, a) / same_length(source, b)
    res = talib.EMA(np.where(same_length(source, diff) > 0, pfetmp, -pfetmp),
                    smoothing)

    return res if sequential else res[-1]
Example #9
0
    def kamaSignal(self, am, paraDict):
        kamaFastest = paraDict['kamaFastest']
        kamaSlowest = paraDict['kamaSlowest']
        kamaPeriod = paraDict['kamaPeriod']
        smaPeriod = paraDict['smaPeriod']

        if len(self.kamaList) == 0:
            self.kamaList.append(ta.MA(am.close, kamaPeriod)[-1])
        elif len(self.kamaList):
            change = np.abs(am.close[kamaPeriod:] - am.close[:-kamaPeriod])
            volatility = ta.SUM(np.abs(am.close[1:] - am.close[:-1]),
                                kamaPeriod)
            er = change[-kamaPeriod:] / volatility[-kamaPeriod:]
            smooth = er[-1] * (2 / (kamaFastest + 1)) + (1 - er[-1]) * (
                2 / (kamaSlowest + 1))
            sc = smooth**2
            newKama = self.kamaList[-1] + sc * (am.close[-1] -
                                                self.kamaList[-1])
            self.kamaList.append(newKama)
        if len(self.kamaList) > (kamaPeriod + 1):
            self.kamaList.pop(0)

        sma = ta.MA(am.close, smaPeriod)

        kamaDirection = 0
        if sma[-1] > self.kamaList[-1]:
            kamaDirection = 1
        elif sma[-1] < self.kamaList[-1]:
            kamaDirection = -1
        return kamaDirection, self.kamaList[-1], sma[-1]
Example #10
0
    def start_5(self, codes, n):
        time0 = time.time()
        self.Rice = interface_Rice()
        self.Record = stock_orderForm()

        Base = stock_baseInfo()
        self.dict = Base.getDict(isBound=0)
        #l =  [str(c) for c in self.Rice.getValidDate1(start='1999-01-01', end=public.getDate())]
        #self.validDates= pd.Series(l,name='date')
        #print(self.validDates)

        dfs = self.Rice.get_financials(codes, years=20)
        for c in codes:
            if c not in dfs.keys(): continue
            self.uid = '%s_stock5' % (c)
            df = dfs[c]
            df = df.iloc[::-1]
            df.loc[:, 'code'] = c
            #df['code'] = c
            df['date'] = df['announce_date'].apply(lambda x: public.parseTime(
                str(x), format='%Y%m%d', style='%Y-%m-%d')
                                                   if not np.isnan(x) else '')

            df['powm'] = df['adjusted_return_on_equity_diluted'].apply(
                lambda x: 1 if x >= self.incomeRatioLine else 0)

            df['sum'] = ta.SUM(df['powm'], timeperiod=5)

            if self.keyCode == c:
                print(df)

            self.saveStage(df)

        print(n, 'finished time:', time.time() - time0)
Example #11
0
def strthindi(bars, timeperiod):
    rr = bars['Close'].pct_change()
    # tmp0 = rr[rr > 0]
    tmp0 = rr.apply(lambda x: x if x > 0 else 0.0)
    tmp1 = talib.SUM(tmp0.values, timeperiod=timeperiod)
    tmp1 = pd.Series(tmp1, index=tmp0.index)
    tmp2 = talib.SUM(rr.abs().values, timeperiod=timeperiod)
    tmp2 = pd.Series(tmp2, index=rr.index)
    rrsi = tmp1 / tmp2
    rrsi = pd.Series(rrsi, index=rr.index)
    rrsi.name = bars['code'].iloc[0]
    rmean = talib.SUM(rr.values, timeperiod=timeperiod)
    rmean = pd.Series(rmean, index=rr.index)
    rmean.name = bars['code'].iloc[0]
    # print(rrsi)
    # print(type(rrsi))
    return rrsi
Example #12
0
def handle_bar(context, bar_dict):

    price = history_bars(context.s1, context.PERIOD + 1, '1d', 'close')
    volume = history_bars(context.s1, context.PERIOD + 1, '1d', 'volume')
    denominator = price * volume
    #!!!talib.SUM是加总函数,这个还从未遇到过;同时注意这里没有用滚动函数,因为该引擎本身就是个循环滚动的
    VWAP = talib.SUM(denominator, context.PERIOD) / talib.SUM(
        volume, context.PERIOD)

    cur_position = context.portfolio.positions[context.s1].quantity
    shares = context.portfolio.cash / bar_dict[context.s1].close

    if price[-1] < VWAP[-1] and cur_position > 0:
        order_target_value(context.s1, 0)

    if price[-1] > VWAP[-1]:
        order_shares(context.s1, shares)
Example #13
0
def Cal_ARBR(inputs,N=26):
    """
    BR:=SUM(MAX(0,HIGH-REF(CLOSE,1)),N)/SUM(MAX(0,REF(CLOSE,1)-LOW),N)*100;
    AR:=SUM(HIGH-OPEN,N)/SUM(OPEN-LOW,N)*100;
    BR〈40 OR AR<40;
    """
    OPEN = inputs['open']
    CLOSE = inputs['close']
    HIGH = inputs['high']    
    LOW = inputs['low']
    CLOSE_REF_1 = REF(CLOSE,1)
    t1 = HIGH-CLOSE_REF_1
    t1[t1<0] = 0
    t2 = CLOSE_REF_1-LOW
    t2[t2<0] = 0
    BR = talib.SUM(t1,N)/talib.SUM(t2,N)*100.0
    AR = talib.SUM(HIGH-OPEN,N) / talib.SUM(OPEN-LOW,N) * 100.0
    #ARBR = (BR<40) * (AR<40)
    return AR,BR
Example #14
0
    def higher_order_moment(self, moment_order, n, array=False):
        """因为收益率均值较小,此处返回高阶原点矩"""
        # 对数收益率序列,长度size-1
        log_r = self.log_return(True)
        # 原点矩
        result = talib.SUM(log_r**moment_order, n)/n

        if array:
            return result
        return result[-1]
Example #15
0
 def __init__(self, series, period):
     if isinstance(series, NumericSeries):
         series = series.series
         try:
             series[np.isinf(series)] = 0
             series = talib.SUM(series, period)
         except Exception as e:
             raise FormulaException(e)
     super(SumSeries, self).__init__(series)
     self.extra_create_kwargs["period"] = period
Example #16
0
    def bias_SMA_Accumulated_signal(self, ma_len, window_len, std_n, array=False):
        """价格-均线l窗口std通道信号"""
        signal = np.zeros(self.size)
        bias = self.close - talib.SMA(self.close, ma_len)
        bias_Accu = talib.SUM(bias, window_len)
        bias_var = talib.VAR(bias, ma_len)
        bias_Accu_std = talib.SQRT(talib.SUM(bias_var, window_len))

        for i in range(self.size):
            if bias_Accu[i] > std_n * bias_Accu_std[i]:
                signal[i] = 1
            elif bias_Accu[i] < -1 * std_n * bias_Accu_std[i]:
                signal[i] = -1
            else:
                signal[i] = 0
        
        if array:
            return signal
        return signal[-1]
Example #17
0
def std_zdf_tp(df0, n, m, l):

    df = df0.copy()
    df['tp'] = 0
    df['bd'] = df['close'] - df['open']
    df['std'] = talib.STDDEV(df['bd'], n) * m
    df.loc[df['bd'] > df['std'], 'tp'] = 1
    df['tp'] = talib.SUM(df['tp'], l)

    return df['tp']
Example #18
0
def SUM(close, timeperiod=30):
    ''' Summation 周期内求和

    分组: Math Operator 数学运算符

    简介:

    real = SUM(close, timeperiod=30)
    '''
    return talib.SUM(close, timeperiod)
Example #19
0
def Cal_VR(inputs,N=26, M=6):
    """
    TH:=SUM(IF(CLOSE>REF(CLOSE,1),VOL,0),N);
    TL:=SUM(IF(CLOSE<REF(CLOSE,1),VOL,0),N);
    TQ:=SUM(IF(CLOSE=REF(CLOSE,1),VOL,0),N);
    VR:100*(TH*2+TQ)/(TL*2+TQ);
    MAVR:MA(VR,M);
    """
    CLOSE = inputs['close']
    CLOSE_REF_1 = REF(CLOSE,1)
    VOL = inputs['volume']    
    TH = talib.SUM( ( CLOSE>CLOSE_REF_1 ) * VOL, N)
    TL = talib.SUM( ( CLOSE<CLOSE_REF_1 ) * VOL, N)
    TQ = talib.SUM( ( CLOSE==CLOSE_REF_1 ) * VOL, N)
    VR = 100*(TH*2+TQ)/(TL*2+TQ)
    if sum(np.isnan(VR))==len(VR):
        MAVR=np.zeros(VR.shape) * np.nan
    else:
        MAVR=talib.SMA(VR, M)
    return VR,MAVR
Example #20
0
def Cal_PSY(inputs,N=12,M=6):
    """
    PSY:COUNT(CLOSE>REF(CLOSE,1),N)/N*100;
    PSYMA:MA(PSY,M);
    """
    CLOSE = inputs['close']    
    NN = min(len(CLOSE),N)
    #PSY = sum((CLOSE>REF(CLOSE,1))[-1*NN:]) / NN * 100.0
    if NN<2:
        PSY = np.array([0.0])
    else:
        PSY = talib.SUM( 1.0*(CLOSE>REF(CLOSE,1)), NN) / NN * 100.0
    return PSY
Example #21
0
def rebalance(context, data):
    history = data.history(assets=context.asset,
                           fields=['open', 'high', 'low', 'close'],
                           bar_count=context.bar_count,
                           frequency='1d')
    date = history.index.values[-1]
    open = history['open'].values
    high = history['high'].values
    low = history['low'].values

    HO = high - open
    OL = open - low

    ar = ta.SUM(HO, timeperiod=context.period) / ta.SUM(
        OL, timeperiod=context.period) * 100

    buy_signal_triggered = False
    sell_signal_triggered = False

    price = data[context.asset].price
    record(price=price)

    if ar[-1] < context.over_sell:
        buy_signal_triggered = True
    elif ar[-1] > context.over_buy:
        sell_signal_triggered = True

    current_position = context.portfolio.positions[context.asset].amount

    if buy_signal_triggered and current_position == 0:
        print(str(date) + '==>Buy')
        order_target_percent(context.asset, 0.5)

    elif sell_signal_triggered and current_position > 0:
        print(str(date) + '==>Sell')
        order_target_percent(context.asset, 0.0)
    else:
        print("No trading")
    def feature(self, data_fed, nperiod):

        stk_data = data_fed['tick_data'].dropna()
        price_series = stk_data['Mid'].astype(float)
        if len(price_series) < 1:
            return price_series

        n = nperiod
        N = nperiod * 3
        price = price_series.values
        ref_price = price_series.shift(1).fillna(0).values
        res = ta.SUM((price > ref_price).astype(float), N)
        res = np.where(np.isfinite(res), res, 0)
        result = pd.Series(ta.MA(res, N), index=price_series.index)
        return result
Example #23
0
    def dsEnvUp(self, am, paraDict):
        dsPeriod = paraDict['dsPeriod']
        dsSmaPeriod = paraDict['dsSmaPeriod']
        dsLmaPeriod = paraDict['dsLmaPeriod']
        dsthreshold = paraDict['dsThreshold']

        density = (ta.MAX(am.high, dsPeriod)-ta.MIN(am.low, dsPeriod))/ta.SUM(am.high-am.low, dsPeriod)
        dsSma = ta.EMA(density, dsSmaPeriod)
        dsLma = ta.MA(density, dsLmaPeriod)

        dsUp = dsSma[-1]>dsLma[-1]
        dsCan = (dsSma[-1]>dsthreshold)
        
        dsTrendEnv = True if dsUp and dsCan else False
        return dsTrendEnv, dsSma, dsLma
Example #24
0
File: mab.py Project: xsa-dev/jesse
def mab(candles: np.ndarray,
        fast_period: int = 10,
        slow_period: int = 50,
        devup: float = 1,
        devdn: float = 1,
        fast_matype: int = 0,
        slow_matype: int = 0,
        source_type: str = "close",
        sequential: bool = False) -> MAB:
    """
    Moving Average Bands

    :param candles: np.ndarray
    :param fast_period: int - default: 10
    :param slow_period: int - default: 50
    :param devup: float - default: 1
    :param devdn: float - default: 1
    :param fast_matype: int - default: 0
    :param slow_matype: int - default: 0
    :param source_type: str - default: "close"
    :param sequential: bool - default: False

    :return: MAB(upperband, middleband, lowerband)
    """
    candles = slice_candles(candles, sequential)

    source = get_candle_source(candles, source_type=source_type)

    fastEma = ma(source,
                 period=fast_period,
                 matype=fast_matype,
                 sequential=True)
    slowEma = ma(source,
                 period=slow_period,
                 matype=slow_matype,
                 sequential=True)
    sqAvg = talib.SUM(np.power(fastEma - slowEma, 2),
                      fast_period) / fast_period
    dev = np.sqrt(sqAvg)

    middlebands = fastEma
    upperbands = slowEma + devup * dev
    lowerbands = slowEma - devdn * dev

    if sequential:
        return MAB(upperbands, middlebands, lowerbands)
    else:
        return MAB(upperbands[-1], middlebands[-1], lowerbands[-1])
Example #25
0
def moveff(bars, timeperiod, col='Close'):
    mov = np.diff(bars[col].values)  # 执行的是后一个元素减去前一个元素
    mov = np.abs(mov)
    mov = np.insert(mov, 0, np.NaN)
    # print(mov[:10])
    movpath = talib.SUM(mov, timeperiod=timeperiod)
    # print(movpath[:10])
    movrange = talib.MAX(bars[col].values, timeperiod=timeperiod) - \
               talib.MIN(bars[col].values, timeperiod=timeperiod)
    # print(movrange[:10])
    moveff_ = movrange / movpath
    moveff_ = pd.Series(moveff_, index=bars.index)
    moveff_.name = bars['code'].iloc[0]
    # print(moveff_)

    return moveff_
    def feature(self, data_fed, nperiod):

        stk_data = data_fed['tick_data'].dropna()
        tran_vol = stk_data['TransactionVol'].astype(float)
        price_series = stk_data['Mid'].astype(float)
        N = nperiod * 3
        M = nperiod
        if len(tran_vol) < 1:
            return tran_vol
        ref_price = price_series.shift(1).fillna(0)
        VA = np.sign(price_series.values - ref_price.values) * tran_vol.values
        OBV = ta.SUM(VA, M)
        MAOBV = ta.MA(OBV, N)
        STDOBV = ta.STDDEV(OBV, N)
        res = pd.Series((OBV - MAOBV)) / pd.Series(STDOBV)
        result = pd.Series(array_clean(res.values), index=price_series.index)
        return result
Example #27
0
    def dsEnv(self, am, paraDict):
        dsPeriod = paraDict['dsPeriod']
        dsSmaPeriod = paraDict['dsSmaPeriod']
        dsLmaPeriod = paraDict['dsLmaPeriod']
        dsthreshold = paraDict['dsThreshold']

        density = (ta.MAX(am.high, dsPeriod) - ta.MIN(
            am.low, dsPeriod)) / ta.SUM(am.high - am.low, dsPeriod)
        dsSma = ta.MA(density, dsSmaPeriod)
        dsLma = ta.MA(density, dsLmaPeriod)

        dsUp = dsSma[-1] > dsLma[-1]
        dsCan = dsSma[-1] > dsthreshold

        preferTrade = dsUp and dsCan
        canTrade = dsCan

        return preferTrade, canTrade, dsSma, dsLma
Example #28
0
 def erSignalCal(self, am, paraDict):
     atrPeriod = paraDict['atrPeriod']
     er_atrPeriod = paraDict['er_atrPeriod']
     erThreshold_low = paraDict['erThreshold_low']
     erThreshold_high = paraDict['erThreshold_high']
     erMaPeriod = paraDict['erMaPeriod']
     erPeriod = int(er_atrPeriod * atrPeriod)
     direction = ta.MOM(am.close, erPeriod)
     volatility = ta.SUM(np.abs(ta.MOM(am.close, 1)), erPeriod)
     er = direction / volatility
     erMa = ta.MA(er, erMaPeriod)
     if erMa[-1] >= erThreshold_low and erMa[-1] <= erThreshold_high:
         erSignal = 1
     elif erMa[-1] <= -erThreshold_low and erMa[-1] >= -erThreshold_high:
         erSignal = -1
     else:
         erSignal = 0
     return erSignal, er
Example #29
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]
 def calExitFilter(self, am, kind, period, threshold, cmiMAPeriod, gene4):
     if kind == 0:
         self.exitFilter = 1
     elif kind == 1:
         self.exitFilter = 1 if (ta.ADX(am.high, am.low, am.close,
                                        period)[-1] > threshold) else 0
     elif kind == 2:
         diff = np.insert(abs(am.close[period:] - am.close[:-period]), 0,
                          [0 for _ in range(period)])
         de = np.insert(ta.SUM(abs(am.close[1:] - am.close[:-1]), period),
                        0, 0)
         ER = ta.DIV(diff, de) * 100
         self.exitFilter = 1 if (ER[-1] > threshold) else 0
     elif kind == 3:
         diff = np.insert(abs(am.close[period:] - am.close[:-period]), 0,
                          [0 for _ in range(period)])
         de = ta.MAX(am.close, period) - ta.MIN(am.close, period)
         cmi = ta.MA(ta.DIV(diff, de) * 100, cmiMAPeriod)
         self.exitFilter = 1 if (cmi[-1] > threshold) else 0