Exemple #1
0
def arima(l_args, s_ticker, df_stock):
    parser = argparse.ArgumentParser(
        prog="arima",
        description="""
            In statistics and econometrics, and in particular in time series analysis, an
            autoregressive integrated moving average (ARIMA) model is a generalization of an
            autoregressive moving average (ARMA) model. Both of these models are fitted to time
            series data either to better understand the data or to predict future points in the
            series (forecasting). ARIMA(p,d,q) where parameters p, d, and q are non-negative
            integers, p is the order (number of time lags) of the autoregressive model, d is the
            degree of differencing (the number of times the data have had past values subtracted),
            and q is the order of the moving-average model.
        """,
    )

    parser.add_argument(
        "-d",
        "--days",
        action="store",
        dest="n_days",
        type=check_positive,
        default=5,
        help="prediction days.",
    )
    parser.add_argument(
        "-i",
        "--ic",
        action="store",
        dest="s_ic",
        type=str,
        default="aic",
        choices=["aic", "aicc", "bic", "hqic", "oob"],
        help="information criteria.",
    )
    parser.add_argument(
        "-s",
        "--seasonal",
        action="store_true",
        default=False,
        dest="b_seasonal",
        help="Use weekly seasonal data.",
    )
    parser.add_argument(
        "-o",
        "--order",
        action="store",
        dest="s_order",
        type=str,
        help="arima model order (p,d,q) in format: pdq.",
    )
    parser.add_argument(
        "-r",
        "--results",
        action="store_true",
        dest="b_results",
        default=False,
        help="results about ARIMA summary flag.",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, l_args)

        # Machine Learning model
        if ns_parser.s_order:
            t_order = tuple([int(ord) for ord in list(ns_parser.s_order)])
            model = ARIMA(df_stock["5. adjusted close"].values, order=t_order).fit()
            l_predictions = model.predict(
                start=len(df_stock["5. adjusted close"]) + 1,
                end=len(df_stock["5. adjusted close"]) + ns_parser.n_days,
            )
        else:
            if ns_parser.b_seasonal:
                model = pmdarima.auto_arima(
                    df_stock["5. adjusted close"].values,
                    error_action="ignore",
                    seasonal=True,
                    m=5,
                    information_criteria=ns_parser.s_ic,
                )
            else:
                model = pmdarima.auto_arima(
                    df_stock["5. adjusted close"].values,
                    error_action="ignore",
                    seasonal=False,
                    information_criteria=ns_parser.s_ic,
                )
            l_predictions = model.predict(n_periods=ns_parser.n_days)

        # Prediction data
        l_pred_days = get_next_stock_market_days(
            last_stock_day=df_stock["5. adjusted close"].index[-1],
            n_next_days=ns_parser.n_days,
        )
        df_pred = pd.Series(l_predictions, index=l_pred_days, name="Price")

        if ns_parser.b_results:
            print(model.summary())
            print("")

        # Plotting
        plt.figure()
        plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2)
        if ns_parser.s_order:
            plt.title(
                f"ARIMA {str(t_order)} on {s_ticker} - {ns_parser.n_days} days prediction"
            )
        else:
            plt.title(
                f"ARIMA {model.order} on {s_ticker} - {ns_parser.n_days} days prediction"
            )
        plt.xlim(
            df_stock.index[0], get_next_stock_market_days(df_pred.index[-1], 1)[-1]
        )
        plt.xlabel("Time")
        plt.ylabel("Share Price ($)")
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
        plt.plot(
            [df_stock.index[-1], df_pred.index[0]],
            [df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
            lw=1,
            c="tab:green",
            linestyle="--",
        )
        plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
        plt.axvspan(
            df_stock.index[-1], df_pred.index[-1], facecolor="tab:orange", alpha=0.2
        )
        _, _, ymin, ymax = plt.axis()
        plt.vlines(
            df_stock.index[-1], ymin, ymax, linewidth=1, linestyle="--", color="k"
        )
        plt.ion()
        plt.show()

        # Print prediction data
        print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1])
        print("")

    except Exception as e:
        print(e)
        print("")
Exemple #2
0
def exponential_smoothing(l_args, s_ticker, df_stock):
    parser = argparse.ArgumentParser(
        add_help=False,
        prog="ets",
        description="""
            Exponential Smoothing, see https://otexts.com/fpp2/taxonomy.html

            Trend='N',  Seasonal='N': Simple Exponential Smoothing
            Trend='N',  Seasonal='A': Exponential Smoothing
            Trend='N',  Seasonal='M': Exponential Smoothing
            Trend='A',  Seasonal='N': Holt’s linear method
            Trend='A',  Seasonal='A': Additive Holt-Winters’ method
            Trend='A',  Seasonal='M': Multiplicative Holt-Winters’ method
            Trend='Ad', Seasonal='N': Additive damped trend method
            Trend='Ad', Seasonal='A': Exponential Smoothing
            Trend='Ad', Seasonal='M': Holt-Winters’ damped method

            Trend component: N: None, A: Additive, Ad: Additive Damped
            Seasonality component: N: None, A: Additive, M: Multiplicative
        """,
    )

    parser.add_argument(
        "-d",
        "--days",
        action="store",
        dest="n_days",
        type=check_positive,
        default=5,
        help="prediction days.",
    )
    parser.add_argument(
        "-t",
        "--trend",
        action="store",
        dest="trend",
        type=check_valid_trend,
        default="N",
        help="Trend component: N: None, A: Additive, Ad: Additive Damped.",
    )
    parser.add_argument(
        "-s",
        "--seasonal",
        action="store",
        dest="seasonal",
        type=check_valid_seasonal,
        default="N",
        help="Seasonality component: N: None, A: Additive, M: Multiplicative.",
    )
    parser.add_argument(
        "-p",
        "--periods",
        action="store",
        dest="seasonal_periods",
        type=check_positive,
        default=5,
        help="Seasonal periods.",
    )

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

        model, title = get_exponential_smoothing_model(
            df_stock["5. adjusted close"].values,
            ns_parser.trend,
            ns_parser.seasonal,
            ns_parser.seasonal_periods,
        )

        if model.mle_retvals.success:
            forecast = model.forecast(ns_parser.n_days)

            l_pred_days = get_next_stock_market_days(
                last_stock_day=df_stock["5. adjusted close"].index[-1],
                n_next_days=ns_parser.n_days,
            )
            df_pred = pd.Series(forecast, index=l_pred_days, name="Price")

            if ~np.isnan(forecast).any():

                print(f"\n{title}")
                print("\nFit model parameters:")
                for key, value in model.params.items():
                    print(f"{key} {' '*(18-len(key))}: {value}")

                print("\nAssess fit model:")
                print(f"AIC: {round(model.aic, 2)}")
                print(f"BIC: {round(model.bic, 2)}")
                print(f"SSE: {round(model.sse, 2)}\n")

                # Plotting
                plt.figure()
                plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2)
                plt.title(f"{title} on {s_ticker}")

                plt.xlim(
                    df_stock.index[0],
                    get_next_stock_market_days(df_pred.index[-1], 1)[-1],
                )
                plt.xlabel("Time")
                plt.ylabel("Share Price ($)")
                plt.grid(b=True, which="major", color="#666666", linestyle="-")
                plt.minorticks_on()
                plt.grid(
                    b=True, which="minor", color="#999999", linestyle="-", alpha=0.2
                )
                plt.plot(
                    [df_stock.index[-1], df_pred.index[0]],
                    [df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
                    lw=1,
                    c="tab:green",
                    linestyle="--",
                )
                plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
                plt.axvspan(
                    df_stock.index[-1],
                    df_pred.index[-1],
                    facecolor="tab:orange",
                    alpha=0.2,
                )
                _, _, ymin, ymax = plt.axis()
                plt.vlines(
                    df_stock.index[-1],
                    ymin,
                    ymax,
                    linewidth=1,
                    linestyle="--",
                    color="k",
                )
                plt.ion()
                plt.show()

                # Print prediction data
                print_pretty_prediction(
                    df_pred, df_stock["5. adjusted close"].values[-1]
                )
                print("")

            else:
                print("RuntimeWarning: invalid value encountered in double_scalars.")
        else:
            print("ConvergenceWarning: Optimization failed to converge.")

    except Exception as e:
        print(e)
        print("")
Exemple #3
0
def k_nearest_neighbors(l_args, s_ticker, df_stock):
    parser = argparse.ArgumentParser(
        prog="knn",
        description="""
            K nearest neighbors is a simple algorithm that stores all
            available cases and predict the numerical target based on a similarity measure
            (e.g. distance functions).
        """,
    )

    parser.add_argument(
        "-i",
        "--input",
        action="store",
        dest="n_inputs",
        type=check_positive,
        default=40,
        help="number of days to use for prediction.",
    )
    parser.add_argument(
        "-d",
        "--days",
        action="store",
        dest="n_days",
        type=check_positive,
        default=5,
        help="prediction days.",
    )
    parser.add_argument(
        "-j",
        "--jumps",
        action="store",
        dest="n_jumps",
        type=check_positive,
        default=1,
        help="number of jumps in training data.",
    )
    parser.add_argument(
        "-n",
        "--neighbors",
        action="store",
        dest="n_neighbors",
        type=check_positive,
        default=20,
        help="number of neighbors to use on the algorithm.",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, l_args)

        # Split training data
        stock_x, stock_y = splitTrain.split_train(
            df_stock["5. adjusted close"].values,
            ns_parser.n_inputs,
            ns_parser.n_days,
            ns_parser.n_jumps,
        )

        # Machine Learning model
        knn = neighbors.KNeighborsRegressor(n_neighbors=ns_parser.n_neighbors)
        knn.fit(stock_x, stock_y)

        # Prediction data
        l_predictions = knn.predict(
            df_stock["5. adjusted close"].values[-ns_parser.n_inputs:].reshape(
                1, -1))[0]
        l_pred_days = get_next_stock_market_days(
            last_stock_day=df_stock["5. adjusted close"].index[-1],
            n_next_days=ns_parser.n_days,
        )
        df_pred = pd.Series(l_predictions, index=l_pred_days, name="Price")

        # Plotting
        plt.figure()
        plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2)
        plt.title(
            f"{ns_parser.n_neighbors}-Nearest Neighbors on {s_ticker} - {ns_parser.n_days} days prediction"
        )
        plt.xlim(df_stock.index[0],
                 get_next_stock_market_days(df_pred.index[-1], 1)[-1])
        plt.xlabel("Time")
        plt.ylabel("Share Price ($)")
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True,
                 which="minor",
                 color="#999999",
                 linestyle="-",
                 alpha=0.2)
        plt.plot(
            [df_stock.index[-1], df_pred.index[0]],
            [df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
            lw=1,
            c="tab:green",
            linestyle="--",
        )
        plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
        plt.axvspan(df_stock.index[-1],
                    df_pred.index[-1],
                    facecolor="tab:orange",
                    alpha=0.2)
        _, _, ymin, ymax = plt.axis()
        plt.vlines(df_stock.index[-1],
                   ymin,
                   ymax,
                   linewidth=1,
                   linestyle="--",
                   color="k")
        plt.ion()
        plt.show()

        # Print prediction data
        print_pretty_prediction(df_pred,
                                df_stock["5. adjusted close"].values[-1])
        print("")

    except Exception as e:
        print(e)
        print("")
Exemple #4
0
def simple_moving_average(l_args, s_ticker, df_stock):
    parser = argparse.ArgumentParser(
        prog="sma",
        description="""
            Moving Averages are used to smooth the data in an array to
            help eliminate noise and identify trends. The Simple Moving Average is literally
            the simplest form of a moving average. Each output value is the average of the
            previous n values. In a Simple Moving Average, each value in the time period carries
            equal weight, and values outside of the time period are not included in the average.
            This makes it less responsive to recent changes in the data, which can be useful for
            filtering out those changes.
        """,
    )

    parser.add_argument(
        "-l",
        "--length",
        action="store",
        dest="n_length",
        type=check_positive,
        default=20,
        help="length of SMA window.",
    )
    parser.add_argument(
        "-d",
        "--days",
        action="store",
        dest="n_days",
        type=check_positive,
        default=5,
        help="prediction days.",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, l_args)

        # Prediction data
        l_predictions = list()
        for pred_day in range(ns_parser.n_days):
            if pred_day < ns_parser.n_length:
                l_ma_stock = df_stock["5. adjusted close"].values[
                    -ns_parser.n_length + pred_day:]
            else:
                l_ma_stock = list()
            l_predictions.append(np.mean(np.append(l_ma_stock, l_predictions)))

        l_pred_days = get_next_stock_market_days(
            last_stock_day=df_stock["5. adjusted close"].index[-1],
            n_next_days=ns_parser.n_days,
        )
        df_pred = pd.Series(l_predictions, index=l_pred_days, name="Price")

        # Plotting
        plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2)
        plt.title(
            f"{ns_parser.n_length} Moving Average on {s_ticker} - {ns_parser.n_days} days prediction"
        )
        plt.xlim(df_stock.index[0],
                 get_next_stock_market_days(df_pred.index[-1], 1)[-1])
        plt.xlabel("Time")
        plt.ylabel("Share Price ($)")
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True,
                 which="minor",
                 color="#999999",
                 linestyle="-",
                 alpha=0.2)
        df_ma = df_stock["5. adjusted close"].rolling(
            window=ns_parser.n_length).mean()
        plt.plot(df_ma.index, df_ma, lw=2, linestyle="--", c="tab:orange")
        plt.plot(
            [df_stock.index[-1], df_pred.index[0]],
            [df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
            lw=1,
            c="tab:green",
            linestyle="--",
        )
        plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
        plt.axvspan(df_stock.index[-1],
                    df_pred.index[-1],
                    facecolor="tab:orange",
                    alpha=0.2)
        _, _, ymin, ymax = plt.axis()
        plt.vlines(df_stock.index[-1],
                   ymin,
                   ymax,
                   linewidth=1,
                   linestyle="--",
                   color="k")
        plt.ion()
        plt.show()

        # Print prediction data
        print_pretty_prediction(df_pred,
                                df_stock["5. adjusted close"].values[-1])
        print("")

    except Exception as e:
        print(e)
        print("")
def regression(l_args, s_ticker, df_stock, polynomial):
    parser = argparse.ArgumentParser(
        prog="regression",
        description="""
            Regression attempts to model the relationship between
            two variables by fitting a linear/quadratic/cubic/other equation to
            observed data. One variable is considered to be an explanatory variable,
            and the other is considered to be a dependent variable.
        """,
    )

    parser.add_argument(
        "-i",
        "--input",
        action="store",
        dest="n_inputs",
        type=check_positive,
        default=40,
        help="number of days to use for prediction.",
    )
    parser.add_argument(
        "-d",
        "--days",
        action="store",
        dest="n_days",
        type=check_positive,
        default=5,
        help="prediction days.",
    )
    parser.add_argument(
        "-j",
        "--jumps",
        action="store",
        dest="n_jumps",
        type=check_positive,
        default=1,
        help="number of jumps in training data.",
    )

    if polynomial == USER_INPUT:
        parser.add_argument(
            "-p",
            "--polynomial",
            action="store",
            dest="n_polynomial",
            type=check_positive,
            required=True,
            help="polynomial associated with regression.",
        )

    try:
        ns_parser = parse_known_args_and_warn(parser, l_args)

        # Split training data
        stock_x, stock_y = splitTrain.split_train(
            df_stock["5. adjusted close"].values,
            ns_parser.n_inputs,
            ns_parser.n_days,
            ns_parser.n_jumps,
        )

        # Machine Learning model
        if polynomial == LINEAR:
            model = linear_model.LinearRegression(n_jobs=-1)
        else:
            if polynomial == USER_INPUT:
                polynomial = ns_parser.n_polynomial
            model = pipeline.make_pipeline(
                preprocessing.PolynomialFeatures(polynomial),
                linear_model.Ridge())

        model.fit(stock_x, stock_y)
        l_predictions = model.predict(
            df_stock["5. adjusted close"].values[-ns_parser.n_inputs:].reshape(
                1, -1))[0]

        # Prediction data
        l_pred_days = get_next_stock_market_days(
            last_stock_day=df_stock["5. adjusted close"].index[-1],
            n_next_days=ns_parser.n_days,
        )
        df_pred = pd.Series(l_predictions, index=l_pred_days, name="Price")

        # Plotting
        plt.figure()
        plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2)
        plt.title(
            f"Regression (polynomial {polynomial}) on {s_ticker} - {ns_parser.n_days} days prediction"
        )
        plt.xlim(df_stock.index[0],
                 get_next_stock_market_days(df_pred.index[-1], 1)[-1])
        plt.xlabel("Time")
        plt.ylabel("Share Price ($)")
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True,
                 which="minor",
                 color="#999999",
                 linestyle="-",
                 alpha=0.2)
        plt.plot(
            [df_stock.index[-1], df_pred.index[0]],
            [df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
            lw=1,
            c="tab:green",
            linestyle="--",
        )
        plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
        plt.axvspan(df_stock.index[-1],
                    df_pred.index[-1],
                    facecolor="tab:orange",
                    alpha=0.2)
        _, _, ymin, ymax = plt.axis()
        plt.vlines(df_stock.index[-1],
                   ymin,
                   ymax,
                   linewidth=1,
                   linestyle="--",
                   color="k")
        plt.ion()
        plt.show()

        # Print prediction data
        print_pretty_prediction(df_pred,
                                df_stock["5. adjusted close"].values[-1])
        print("")

    except Exception as e:
        print(e)
        print("")
Exemple #6
0
def mlp(l_args, s_ticker, df_stock):
    parser = argparse.ArgumentParser(prog="mlp",
                                     description="""Multilayer Perceptron. """)

    parser.add_argument(
        "-d",
        "--days",
        action="store",
        dest="n_days",
        type=check_positive,
        default=5,
        help="prediction days.",
    )
    parser.add_argument(
        "-i",
        "--input",
        action="store",
        dest="n_inputs",
        type=check_positive,
        default=40,
        help="number of days to use for prediction.",
    )
    parser.add_argument(
        "-e",
        "--epochs",
        action="store",
        dest="n_epochs",
        type=check_positive,
        default=200,
        help="number of training epochs.",
    )
    parser.add_argument(
        "-j",
        "--jumps",
        action="store",
        dest="n_jumps",
        type=check_positive,
        default=1,
        help="number of jumps in training data.",
    )
    parser.add_argument(
        "-p",
        "--pp",
        action="store",
        dest="s_preprocessing",
        default="normalization",
        choices=["normalization", "standardization", "none"],
        help="pre-processing data.",
    )
    parser.add_argument(
        "-o",
        "--optimizer",
        action="store",
        dest="s_optimizer",
        default="adam",
        choices=[
            "adam",
            "adagrad",
            "adadelta",
            "adamax",
            "ftrl",
            "nadam",
            "optimizer",
            "rmsprop",
            "sgd",
        ],
        help="optimization technique.",
    )
    parser.add_argument(
        "-l",
        "--loss",
        action="store",
        dest="s_loss",
        default="mae",
        choices=["mae", "mape", "mse", "msle"],
        help="loss function.",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, l_args)

        # Pre-process data
        if ns_parser.s_preprocessing == "standardization":
            scaler = StandardScaler()
            stock_train_data = scaler.fit_transform(
                np.array(df_stock["5. adjusted close"].values.reshape(-1, 1)))
        elif ns_parser.s_preprocessing == "normalization":
            scaler = MinMaxScaler()
            stock_train_data = scaler.fit_transform(
                np.array(df_stock["5. adjusted close"].values.reshape(-1, 1)))
        else:  # No pre-processing
            stock_train_data = np.array(
                df_stock["5. adjusted close"].values.reshape(-1, 1))

        # Split training data for the neural network
        stock_x, stock_y = splitTrain.split_train(
            stock_train_data,
            ns_parser.n_inputs,
            ns_parser.n_days,
            numJumps=ns_parser.n_jumps,
        )
        stock_x = np.array(stock_x)
        stock_x = np.reshape(stock_x, (stock_x.shape[0], stock_x.shape[1]))
        stock_y = np.array(stock_y)
        stock_y = np.reshape(stock_y, (stock_y.shape[0], stock_y.shape[1]))

        # Build Neural Network model
        model = build_neural_network_model(cfg_nn_models.MultiLayer_Perceptron,
                                           ns_parser.n_inputs,
                                           ns_parser.n_days)
        model.compile(optimizer=ns_parser.s_optimizer, loss=ns_parser.s_loss)

        # Train our model
        model.fit(stock_x, stock_y, epochs=ns_parser.n_epochs, verbose=1)
        print("")

        print(model.summary())
        print("")

        # Prediction
        yhat = model.predict(
            stock_train_data[-ns_parser.n_inputs:].reshape(
                1, ns_parser.n_inputs),
            verbose=0,
        )

        # Re-scale the data back
        if (ns_parser.s_preprocessing
                == "standardization") or (ns_parser.s_preprocessing
                                          == "normalization"):
            y_pred_test_t = scaler.inverse_transform(yhat.tolist())
        else:
            y_pred_test_t = yhat

        l_pred_days = get_next_stock_market_days(
            last_stock_day=df_stock["5. adjusted close"].index[-1],
            n_next_days=ns_parser.n_days,
        )
        df_pred = pd.Series(y_pred_test_t[0].tolist(),
                            index=l_pred_days,
                            name="Price")

        # Plotting
        plt.figure()
        plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=3)
        plt.title(f"MLP on {s_ticker} - {ns_parser.n_days} days prediction")
        plt.xlim(df_stock.index[0],
                 get_next_stock_market_days(df_pred.index[-1], 1)[-1])
        plt.xlabel("Time")
        plt.ylabel("Share Price ($)")
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True,
                 which="minor",
                 color="#999999",
                 linestyle="-",
                 alpha=0.2)
        plt.plot(
            [df_stock.index[-1], df_pred.index[0]],
            [df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
            lw=1,
            c="tab:green",
            linestyle="--",
        )
        plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
        plt.axvspan(df_stock.index[-1],
                    df_pred.index[-1],
                    facecolor="tab:orange",
                    alpha=0.2)
        _, _, ymin, ymax = plt.axis()
        plt.vlines(
            df_stock.index[-1],
            ymin,
            ymax,
            colors="k",
            linewidth=3,
            linestyle="--",
            color="k",
        )
        plt.ion()
        plt.show()

        # Print prediction data
        print_pretty_prediction(df_pred,
                                df_stock["5. adjusted close"].values[-1])
        print("")

    except Exception as e:
        print(e)
        print("")