Пример #1
0
def cusum(other_args: List[str], stock: pd.DataFrame):
    """Cumulative sum algorithm (CUSUM) to detect abrupt changes in data

    Parameters
    ----------
    other_args : str
        Command line arguments to be processed with argparse
    ticker : str
        Ticker of the stock
    stock : pd.DataFrame
        Stock data
    """
    parser = argparse.ArgumentParser(
        add_help=False,
        prog="cusum",
        description="""
            Cumulative sum algorithm (CUSUM) to detect abrupt changes in data
        """,
    )
    parser.add_argument(
        "-t",
        "--threshold",
        dest="threshold",
        type=float,
        default=(max(stock["Adj Close"].values) -
                 min(stock["Adj Close"].values)) / 40,
        help="threshold",
    )
    parser.add_argument(
        "-d",
        "--drift",
        dest="drift",
        type=float,
        default=(max(stock["Adj Close"].values) -
                 min(stock["Adj Close"].values)) / 80,
        help="drift",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, other_args)
        if not ns_parser:
            return

        stock = stock["Adj Close"]

        detect_cusum(stock.values, ns_parser.threshold, ns_parser.drift, True,
                     True)

        if gtff.USE_ION:
            plt.ion()

        plt.show()
        print("")

    except Exception as e:
        print(e, "\n")
        return
Пример #2
0
def display_cusum(df: pd.DataFrame, target: str, threshold: float,
                  drift: float):
    """Cumulative sum algorithm (CUSUM) to detect abrupt changes in data

    Parameters
    ----------
    df : pd.DataFrame
        Dataframe
    target : str
        Column of data to look at
    threshold : float
        Threshold value
    drift : float
        Drift parameter
    """
    detect_cusum(df[target].values, threshold, drift, True, True)
    if gtff.USE_ION:
        plt.ion()
    plt.show()
    print("")
Пример #3
0
def calculate_cusum(data, threshold, drift):
    ta, tai, taf, amp = detect_cusum(data['Data'], threshold, drift, ending=True, show=False)

    data["Cumulative Sum Algorithm"] = 0
    start = False
    for i in range(5, len(data["Cumulative Sum Algorithm"])):
        if i in tai:
            start = True
        elif i in taf:
            start = False
        if start:
            data["Cumulative Sum Algorithm"].at[i] = 1

    plt.clf()
    return "Cumulative Sum Algorithm"
Пример #4
0
def cu_changepoint(f, window=25):
    # change point detection based on cusum
    # no generic way to set up threshold and drift
    # f, window = pre_changepoint(ts_, window=window)
    # ycol = 'dtrend_diff'  # dtrend               # used to detect changes in trend
    # ts = f[ycol].values
    ts = f['dtrend_diff'].values
    if f['period'].isnull().sum() == 0:
        window = f.loc[f.index[0], 'period']
    min_ix = f.index.min()
    m = 8.0
    threshold = m * f['dtrend_diff'].std()
    thres = threshold
    while thres >= threshold / m:
        drift = f['dtrend_diff'].std()
        while drift > f['dtrend_diff'].std() / 10:
            ta, tai, taf, amp = detect_cusum(ts, threshold=thres, drift=drift, ending=False, show=False)
            print('thres: ' + str(thres) + ' drift: ' + str(drift) + ' ta: ' + str(min_ix + ta) + ' tai: ' + str(min_ix + tai) + ' taf: ' + str(taf))
            drift /= 2
        thres /= 2
Пример #5
0
def analyseStocks(symbol, investAmount, thresholdMargin=50000):
    df = getDailyDataFromMarketstack(symbol, '2020-07-01')

    if df.empty:
        return ('empty', symbol, 0, 0)

    minClose = min(df['Close'])
    maxClose = max(df['Close'])
    lastClose = df['Close'][-1]
    difMinMax = maxClose - minClose

    dateValue = pd.DataFrame()
    dateValue['Date'] = df['Date']
    dateValue['Value'] = df['Close']

    lastFallDelta = getLastFallDelta(dateValue)

    #logging.debug("minClose: ", minClose, " maxClose: ", maxClose, "lastClose: ", lastClose, " diffMinMax: ", difMinMax, ' lastFallDelta: ', lastFallDelta)

    ta, tai, taf, amp = detect_cusum(df['Close'], 200, .05, True, False)

    #logging.debug(ta, tai, taf, amp)

    stocksToBuy = getAdjustedStocksToBuy(lastClose, investAmount)
    totalInvestCost = lastClose * stocksToBuy + transactionTax(investAmount)

    logging.debug("totalinvestcost: %s", totalInvestCost)
    potentialStocksSold = maxClose * stocksToBuy + transactionTax(investAmount)
    potentialRevenue = potentialStocksSold - totalInvestCost

    logging.info("potentialRevenue last fall: %s", potentialRevenue)

    if (int(potentialRevenue) > thresholdMargin):
        logging.debug("Comprar")
        return ('buy', symbol, lastClose, potentialRevenue)

    return ('pass', symbol, lastClose, potentialRevenue)
Пример #6
0
def display_cusum(
    df: pd.DataFrame,
    target: str,
    threshold: float,
    drift: float,
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Cumulative sum algorithm (CUSUM) to detect abrupt changes in data

    Parameters
    ----------
    df : pd.DataFrame
        Dataframe
    target : str
        Column of data to look at
    threshold : float
        Threshold value
    drift : float
        Drift parameter
    external_axes : Optional[List[plt.Axes]], optional
        External axes (2 axes are expected in the list), by default None
    """
    target_series = df[target].values

    # The code for this plot was adapted from detecta's sources because at the
    # time of writing this detect_cusum had a bug related to external axes support.
    # see https://github.com/demotu/detecta/pull/3
    tap, tan = 0, 0
    ta, tai, taf, _ = detect_cusum(
        x=target_series,
        threshold=threshold,
        drift=drift,
        ending=True,
        show=False,
    )
    # Thus some variable names are left unchanged and unreadable...
    gp, gn = np.zeros(target_series.size), np.zeros(target_series.size)
    for i in range(1, target_series.size):
        s = target_series[i] - target_series[i - 1]
        gp[i] = gp[i - 1] + s - drift  # cumulative sum for + change
        gn[i] = gn[i - 1] - s - drift  # cumulative sum for - change
        if gp[i] < 0:
            gp[i], tap = 0, i
        if gn[i] < 0:
            gn[i], tan = 0, i
        if gp[i] > threshold or gn[i] > threshold:  # change detected!
            ta = np.append(ta, i)  # alarm index
            tai = np.append(tai, tap if gp[i] > threshold else tan)  # start
            gp[i], gn[i] = 0, 0  # reset alarm

    if external_axes is None:
        _, axes = plt.subplots(
            2,
            1,
            sharex=True,
            figsize=plot_autoscale(),
            dpi=PLOT_DPI,
        )
        (ax1, ax2) = axes
    else:
        if len(external_axes) != 2:
            logger.error("Expected list of two axis items.")
            console.print("[red]Expected list of 2 axis items./n[/red]")
            return
        (ax1, ax2) = external_axes

    target_series_indexes = range(df[target].size)
    ax1.plot(target_series_indexes, target_series)
    if len(ta):
        ax1.plot(
            tai,
            target_series[tai],
            ">",
            markerfacecolor=theme.up_color,
            markersize=5,
            label="Start",
        )
        ax1.plot(
            taf,
            target_series[taf],
            "<",
            markerfacecolor=theme.down_color,
            markersize=5,
            label="Ending",
        )
        ax1.plot(
            ta,
            target_series[ta],
            "o",
            markerfacecolor=theme.get_colors()[-1],
            markeredgecolor=theme.get_colors()[-2],
            markeredgewidth=1,
            markersize=3,
            label="Alarm",
        )
        ax1.legend()
    ax1.set_xlim(-0.01 * target_series.size, target_series.size * 1.01 - 1)
    ax1.set_ylabel("Amplitude")
    ymin, ymax = (
        target_series[np.isfinite(target_series)].min(),
        target_series[np.isfinite(target_series)].max(),
    )
    y_range = ymax - ymin if ymax > ymin else 1
    ax1.set_ylim(ymin - 0.1 * y_range, ymax + 0.1 * y_range)
    ax1.set_title(
        "Time series and detected changes " +
        f"(threshold= {threshold:.3g}, drift= {drift:.3g}): N changes = {len(tai)}",
        fontsize=10,
    )
    theme.style_primary_axis(ax1)

    ax2.plot(target_series_indexes, gp, label="+")
    ax2.plot(target_series_indexes, gn, label="-")
    ax2.set_xlim(-0.01 * target_series.size, target_series.size * 1.01 - 1)
    ax2.set_xlabel("Data points")
    ax2.set_ylim(-0.01 * threshold, 1.1 * threshold)
    ax2.axhline(threshold)
    theme.style_primary_axis(ax2)

    ax2.set_title(
        "Time series of the cumulative sums of positive and negative changes",
        fontsize=10,
    )
    ax2.legend()

    if external_axes is None:
        theme.visualize_output()
Пример #7
0
plt.plot(y)
plt.xlabel('Samples')
plt.show()'''
'''x1 = [0, 0, 3, 7, 9]
y1 = [0, 8, 12, 13, 14]
x2 = [0, 0, 1, 1, 2, 3, 9]
y2 = [0, 13, 13, 14, 14, 15, 15]
plt.xlim((0,9))
plt.ylim((0,16))
plt.xlabel('False Positive')
plt.ylabel('True Positive')
plt.plot(x1, y1, label = 'CUSUM')
plt.plot(x2, y2, label = 'NLMS')
plt.legend()
plt.show()'''

start2 = time()
ta, tai, taf, amp = detect_cusum(data_test, 2000, 10000, True, True)
end2 = time()

time1 = end1 - start1
time2 = end2 - start2

x1 = ['NLMS', 'CUSUM']
y1 = [time1, time2]
plt.bar(x1, y1)
plt.ylabel("Time(sec)")
plt.show()
a = 1