mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 21:12:16 +00:00
Refactor prediction menu to controller, and fbprophet optional
This commit is contained in:
@@ -16,6 +16,9 @@ USE_PROMPT_TOOLKIT = strtobool(os.getenv("GTFF_USE_PROMPT_TOOLKIT", "False"))
|
||||
# Enable Prediction features
|
||||
ENABLE_PREDICT = strtobool(os.getenv("GTFF_ENABLE_PREDICT", "False"))
|
||||
|
||||
# Enable FB Prophet
|
||||
ENABLE_FBPROPHET = strtobool(os.getenv("GTFF_ENABLE_FBPROPHET", "False"))
|
||||
|
||||
# Enable plot autoscaling
|
||||
USE_PLOT_AUTOSCALING = strtobool(os.getenv("GTFF_USE_PLOT_AUTOSCALING", "False"))
|
||||
|
||||
|
||||
207
gamestonk_terminal/prediction_techniques/pred_controller.py
Normal file
207
gamestonk_terminal/prediction_techniques/pred_controller.py
Normal file
@@ -0,0 +1,207 @@
|
||||
import argparse
|
||||
from typing import List
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
import matplotlib.pyplot as plt
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import get_flair
|
||||
from gamestonk_terminal.menu import session
|
||||
from gamestonk_terminal.prediction_techniques import (
|
||||
arima,
|
||||
ets,
|
||||
knn,
|
||||
neural_networks,
|
||||
regression,
|
||||
sma,
|
||||
)
|
||||
from prompt_toolkit.completion import NestedCompleter
|
||||
|
||||
|
||||
class PredictionTechniquesController:
|
||||
"""Prediction Techniques Controller class"""
|
||||
|
||||
# Command choices
|
||||
CHOICES = [
|
||||
"help",
|
||||
"q",
|
||||
"quit",
|
||||
"sma",
|
||||
"ets",
|
||||
"knn",
|
||||
"linear",
|
||||
"quadratic",
|
||||
"cubic",
|
||||
"regression",
|
||||
"arima",
|
||||
"mlp",
|
||||
"rnn",
|
||||
"lstm",
|
||||
]
|
||||
|
||||
if gtff.ENABLE_FBPROPHET:
|
||||
CHOICES.append("prophet")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
stock: pd.DataFrame,
|
||||
ticker: str,
|
||||
start: datetime,
|
||||
interval: str,
|
||||
):
|
||||
"""Constructor"""
|
||||
self.stock = stock
|
||||
self.ticker = ticker
|
||||
self.start = start
|
||||
self.interval = interval
|
||||
self.pred_parser = argparse.ArgumentParser(add_help=False, prog="pred")
|
||||
self.pred_parser.add_argument(
|
||||
"cmd",
|
||||
choices=self.CHOICES,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def print_help(self):
|
||||
""" Print help """
|
||||
|
||||
s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"]
|
||||
|
||||
if self.start:
|
||||
print(
|
||||
f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})"
|
||||
)
|
||||
else:
|
||||
print(f"\n{s_intraday} Stock: {self.ticker}")
|
||||
|
||||
print("\nPrediction Techniques:")
|
||||
print(" help show this prediction techniques menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("")
|
||||
print(" sma simple moving average")
|
||||
print(" ets exponential smoothing (e.g. Holt-Winters)")
|
||||
print(" knn k-Nearest Neighbors")
|
||||
print(" linear linear regression (polynomial 1)")
|
||||
print(" quadratic quadratic regression (polynomial 2)")
|
||||
print(" cubic cubic regression (polynomial 3)")
|
||||
print(" regression regression (other polynomial)")
|
||||
print(" arima autoregressive integrated moving average")
|
||||
print(" mlp MultiLayer Perceptron")
|
||||
print(" rnn Recurrent Neural Network")
|
||||
print(" lstm Long-Short Term Memory")
|
||||
if gtff.ENABLE_FBPROPHET:
|
||||
print(" prophet Facebook's prophet prediction")
|
||||
print("")
|
||||
|
||||
def switch(self, an_input: str):
|
||||
"""Process and dispatch input
|
||||
|
||||
Returns
|
||||
-------
|
||||
True, False or None
|
||||
False - quit the menu
|
||||
True - quit the program
|
||||
None - continue in the menu
|
||||
"""
|
||||
(known_args, other_args) = self.pred_parser.parse_known_args(an_input.split())
|
||||
|
||||
return getattr(
|
||||
self, "call_" + known_args.cmd, lambda: "Command not recognized!"
|
||||
)(other_args)
|
||||
|
||||
def call_help(self, _):
|
||||
"""Process Help command"""
|
||||
self.print_help(self)
|
||||
|
||||
def call_q(self, _):
|
||||
"""Process Q command - quit the menu"""
|
||||
return False
|
||||
|
||||
def call_quit(self, _):
|
||||
"""Process Quit command - quit the program"""
|
||||
return True
|
||||
|
||||
def call_sma(self, other_args: List[str]):
|
||||
"""Process sma command"""
|
||||
sma.simple_moving_average(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_ets(self, other_args: List[str]):
|
||||
"""Process ets command"""
|
||||
ets.exponential_smoothing(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_knn(self, other_args: List[str]):
|
||||
"""Process knn command"""
|
||||
knn.k_nearest_neighbors(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_linear(self, other_args: List[str]):
|
||||
"""Process linear command"""
|
||||
regression.regression(other_args, self.ticker, self.stock, regression.LINEAR)
|
||||
|
||||
def call_quadratic(self, other_args: List[str]):
|
||||
"""Process quadratic command"""
|
||||
regression.regression(other_args, self.ticker, self.stock, regression.QUADRATIC)
|
||||
|
||||
def call_cubic(self, other_args: List[str]):
|
||||
"""Process cubic command"""
|
||||
regression.regression(other_args, self.ticker, self.stock, regression.CUBIC)
|
||||
|
||||
def call_regression(self, other_args: List[str]):
|
||||
"""Process regression command"""
|
||||
regression.regression(
|
||||
other_args, self.ticker, self.stock, regression.USER_INPUT
|
||||
)
|
||||
|
||||
def call_arima(self, other_args: List[str]):
|
||||
"""Process arima command"""
|
||||
arima.arima(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_mlp(self, other_args: List[str]):
|
||||
"""Process mlp command"""
|
||||
neural_networks.mlp(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_rnn(self, other_args: List[str]):
|
||||
"""Process rnn command"""
|
||||
neural_networks.rnn(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_lstm(self, other_args: List[str]):
|
||||
"""Process lstm command"""
|
||||
neural_networks.lstm(other_args, self.ticker, self.stock)
|
||||
|
||||
if gtff.ENABLE_FBPROPHET:
|
||||
|
||||
def call_prophet(self, other_args: List[str]):
|
||||
"""Process prophet command"""
|
||||
from gamestonk_terminal.prediction_techniques import fbprophet
|
||||
|
||||
fbprophet.fbprophet(other_args, self.ticker, self.stock)
|
||||
|
||||
|
||||
def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str):
|
||||
"""Comparison Analysis Menu"""
|
||||
|
||||
pred_controller = PredictionTechniquesController(stock, ticker, start, interval)
|
||||
pred_controller.call_help(None)
|
||||
|
||||
while True:
|
||||
# Get input command from user
|
||||
if session and gtff.USE_PROMPT_TOOLKIT:
|
||||
completer = NestedCompleter.from_nested_dict(
|
||||
{c: None for c in pred_controller.CHOICES}
|
||||
)
|
||||
an_input = session.prompt(
|
||||
f"{get_flair()} (pred)> ",
|
||||
completer=completer,
|
||||
)
|
||||
else:
|
||||
an_input = input(f"{get_flair()} (pred)> ")
|
||||
|
||||
try:
|
||||
plt.close("all")
|
||||
|
||||
process_input = pred_controller.switch(an_input)
|
||||
|
||||
if process_input is not None:
|
||||
return process_input
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
@@ -1,145 +0,0 @@
|
||||
import argparse
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import get_flair
|
||||
from gamestonk_terminal.menu import session
|
||||
from gamestonk_terminal.prediction_techniques import (
|
||||
arima,
|
||||
ets,
|
||||
fbprophet,
|
||||
knn,
|
||||
neural_networks,
|
||||
regression,
|
||||
sma,
|
||||
)
|
||||
from prompt_toolkit.completion import NestedCompleter
|
||||
|
||||
|
||||
def print_prediction(s_ticker, s_start, s_interval):
|
||||
""" Print help """
|
||||
|
||||
s_intraday = (f"Intraday {s_interval}", "Daily")[s_interval == "1440min"]
|
||||
|
||||
if s_start:
|
||||
print(f"\n{s_intraday} Stock: {s_ticker} (from {s_start.strftime('%Y-%m-%d')})")
|
||||
else:
|
||||
print(f"\n{s_intraday} Stock: {s_ticker}")
|
||||
|
||||
print("\nPrediction Techniques:")
|
||||
print(" help show this prediction techniques menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("")
|
||||
print(" sma simple moving average")
|
||||
print(" ets exponential smoothing (e.g. Holt-Winters)")
|
||||
print(" knn k-Nearest Neighbors")
|
||||
print(" linear linear regression (polynomial 1)")
|
||||
print(" quadratic quadratic regression (polynomial 2)")
|
||||
print(" cubic cubic regression (polynomial 3)")
|
||||
print(" regression regression (other polynomial)")
|
||||
print(" arima autoregressive integrated moving average")
|
||||
print(" prophet Facebook's prophet prediction")
|
||||
print(" mlp MultiLayer Perceptron")
|
||||
print(" rnn Recurrent Neural Network")
|
||||
print(" lstm Long-Short Term Memory")
|
||||
print("")
|
||||
|
||||
|
||||
def pred_menu(df_stock, s_ticker, s_start, s_interval):
|
||||
|
||||
# Add list of arguments that the prediction techniques parser accepts
|
||||
pred_parser = argparse.ArgumentParser(prog="pred", add_help=False)
|
||||
choices = [
|
||||
"help",
|
||||
"q",
|
||||
"quit",
|
||||
"sma",
|
||||
"ets",
|
||||
"knn",
|
||||
"linear",
|
||||
"quadratic",
|
||||
"cubic",
|
||||
"regression",
|
||||
"arima",
|
||||
"prophet",
|
||||
"mlp",
|
||||
"rnn",
|
||||
"lstm",
|
||||
]
|
||||
pred_parser.add_argument("cmd", choices=choices)
|
||||
completer = NestedCompleter.from_nested_dict({c: None for c in choices})
|
||||
|
||||
print_prediction(s_ticker, s_start, s_interval)
|
||||
|
||||
# Loop forever and ever
|
||||
while True:
|
||||
# Get input command from user
|
||||
if session and gtff.USE_PROMPT_TOOLKIT:
|
||||
as_input = session.prompt(
|
||||
f"{get_flair()} (pred)> ",
|
||||
completer=completer,
|
||||
)
|
||||
else:
|
||||
as_input = input(f"{get_flair()} (pred)> ")
|
||||
|
||||
# Images are non blocking - allows to close them if we type other command
|
||||
plt.close("all")
|
||||
|
||||
# Parse prediction techniques command of the list of possible commands
|
||||
try:
|
||||
(ns_known_args, l_args) = pred_parser.parse_known_args(as_input.split())
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
|
||||
if ns_known_args.cmd == "help":
|
||||
print_prediction(s_ticker, s_start, s_interval)
|
||||
|
||||
elif ns_known_args.cmd == "q":
|
||||
# Just leave the FA menu
|
||||
return False
|
||||
|
||||
elif ns_known_args.cmd == "quit":
|
||||
# Abandon the program
|
||||
return True
|
||||
|
||||
elif ns_known_args.cmd == "sma":
|
||||
sma.simple_moving_average(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "ets":
|
||||
ets.exponential_smoothing(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "knn":
|
||||
knn.k_nearest_neighbors(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "linear":
|
||||
regression.regression(l_args, s_ticker, df_stock, regression.LINEAR)
|
||||
|
||||
elif ns_known_args.cmd == "quadratic":
|
||||
regression.regression(l_args, s_ticker, df_stock, regression.QUADRATIC)
|
||||
|
||||
elif ns_known_args.cmd == "cubic":
|
||||
regression.regression(l_args, s_ticker, df_stock, regression.CUBIC)
|
||||
|
||||
elif ns_known_args.cmd == "regression":
|
||||
regression.regression(l_args, s_ticker, df_stock, regression.USER_INPUT)
|
||||
|
||||
elif ns_known_args.cmd == "arima":
|
||||
arima.arima(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "prophet":
|
||||
fbprophet.fbprophet(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "mlp":
|
||||
neural_networks.mlp(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "rnn":
|
||||
neural_networks.rnn(l_args, s_ticker, df_stock)
|
||||
|
||||
elif ns_known_args.cmd == "lstm":
|
||||
neural_networks.lstm(l_args, s_ticker, df_stock)
|
||||
|
||||
else:
|
||||
print("Command not recognized!")
|
||||
@@ -252,7 +252,7 @@ def main():
|
||||
|
||||
try:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from gamestonk_terminal.prediction_techniques import pred_menu as pm
|
||||
from gamestonk_terminal.prediction_techniques import pred_controller
|
||||
except ModuleNotFoundError as e:
|
||||
print("One of the optional packages seems to be missing")
|
||||
print("Optional packages need to be installed")
|
||||
@@ -265,7 +265,7 @@ def main():
|
||||
continue
|
||||
|
||||
if s_interval == "1440min":
|
||||
b_quit = pm.pred_menu(df_stock, s_ticker, s_start, s_interval)
|
||||
b_quit = pred_controller.menu(df_stock, s_ticker, s_start, s_interval)
|
||||
# If stock data is intradaily, we need to get data again as prediction
|
||||
# techniques work on daily adjusted data. By default we load data from
|
||||
# Alpha Vantage because the historical data loaded gives a larger
|
||||
@@ -282,7 +282,7 @@ def main():
|
||||
# pylint: disable=no-member
|
||||
df_stock_pred = df_stock_pred.sort_index(ascending=True)
|
||||
df_stock_pred = df_stock_pred[s_start:]
|
||||
b_quit = pm.pred_menu(
|
||||
b_quit = pred_controller.menu(
|
||||
df_stock_pred, s_ticker, s_start, s_interval="1440min"
|
||||
)
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user