mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 05:21:48 +00:00
Add Monte Carlo prediction technique (#846)
* Add monte carlo forecast * Add hugo * Update _index.md * review edits Co-authored-by: James Maslek <james@macbook-pro.myfiosgateway.com>
This commit is contained in:
47
gamestonk_terminal/common/prediction_techniques/mc_model.py
Normal file
47
gamestonk_terminal/common/prediction_techniques/mc_model.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""Monte Carlo Model"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Union
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from scipy.stats import norm
|
||||
|
||||
|
||||
def get_mc_brownian(
|
||||
data: Union[pd.Series, np.array], n_future: int, n_sims: int, use_log=True
|
||||
) -> np.array:
|
||||
"""Performs monte carlo forecasting for brownian motion with drift
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data : Union[pd.Series, np.array]
|
||||
Input data.
|
||||
n_future : int
|
||||
Number of future steps
|
||||
n_sims : int
|
||||
Number of simulations to run
|
||||
use_log : bool, optional
|
||||
Flag to use log returns, by default True
|
||||
|
||||
Returns
|
||||
-------
|
||||
np.array
|
||||
Array of predictions. Has shape (n_future, n_sims)
|
||||
"""
|
||||
changes = data.pct_change().dropna()
|
||||
if use_log:
|
||||
changes = np.log(1 + changes)
|
||||
|
||||
dist_mean = changes.mean()
|
||||
dist_var = changes.var()
|
||||
dist_drift = dist_mean - 0.5 * dist_var
|
||||
dist_std = np.sqrt(dist_var)
|
||||
|
||||
random_steps = norm.ppf(np.random.rand(n_future, n_sims))
|
||||
predicted_change = np.exp(dist_drift + dist_std * random_steps)
|
||||
possible_paths = np.zeros_like(predicted_change)
|
||||
possible_paths[0] = data.values[-1]
|
||||
|
||||
for t in range(1, n_future):
|
||||
possible_paths[t] = possible_paths[t - 1] * predicted_change[t]
|
||||
return possible_paths
|
||||
70
gamestonk_terminal/common/prediction_techniques/mc_view.py
Normal file
70
gamestonk_terminal/common/prediction_techniques/mc_view.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""Monte Carlo View"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Union
|
||||
import os
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import seaborn as sns
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
|
||||
from gamestonk_terminal.common.prediction_techniques import mc_model
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
plot_autoscale,
|
||||
get_next_stock_market_days,
|
||||
export_data,
|
||||
)
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
|
||||
|
||||
def display_mc_forecast(
|
||||
data: Union[pd.Series, np.array],
|
||||
n_future: int,
|
||||
n_sims: int,
|
||||
use_log=True,
|
||||
export: str = "",
|
||||
):
|
||||
"""Display monte carlo forecasting
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data : Union[pd.Series, np.array]
|
||||
Data to forecast
|
||||
n_future : int
|
||||
Number of days to forecast
|
||||
n_sims : int
|
||||
Number of simulations to run
|
||||
use_log : bool, optional
|
||||
Flag to use lognormal, by default True
|
||||
export: str
|
||||
Format to export data
|
||||
"""
|
||||
predicted_values = mc_model.get_mc_brownian(data, n_future, n_sims, use_log)
|
||||
future_index = get_next_stock_market_days(data.index[-1], n_next_days=n_future)
|
||||
dateFmt = mdates.DateFormatter("%m/%d/%Y")
|
||||
|
||||
fig, ax = plt.subplots(1, 2, figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
|
||||
ax[0].plot(data)
|
||||
ax[0].plot(future_index, predicted_values, alpha=0.3)
|
||||
ax[0].set_title("Data Predictions")
|
||||
ax[0].xaxis.set_major_formatter(dateFmt)
|
||||
ax[0].tick_params(axis="x", labelrotation=45)
|
||||
ax[0].grid("on")
|
||||
|
||||
sns.histplot(predicted_values[-1, :], ax=ax[1], kde=True)
|
||||
ax[1].set_xlabel("Price")
|
||||
ax[1].set_title(f"Distribution of data after {n_future} days.")
|
||||
ax[1].set_xlim(np.min(predicted_values[-1, :]), np.max(predicted_values[-1, :]))
|
||||
ax[1].grid("on")
|
||||
|
||||
fig.tight_layout(pad=2)
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
plt.show()
|
||||
export_data(export, os.path.dirname(os.path.abspath(__file__)), "mc")
|
||||
print("")
|
||||
@@ -27,6 +27,7 @@ from gamestonk_terminal.common.prediction_techniques import (
|
||||
neural_networks_view,
|
||||
regression_view,
|
||||
pred_helper,
|
||||
mc_view,
|
||||
)
|
||||
from gamestonk_terminal.stocks.stocks_helper import load
|
||||
|
||||
@@ -46,6 +47,7 @@ class PredictionTechniquesController:
|
||||
"rnn",
|
||||
"lstm",
|
||||
"conv1d",
|
||||
"mc",
|
||||
]
|
||||
CHOICES += CHOICES_MODELS
|
||||
|
||||
@@ -105,6 +107,7 @@ Models:
|
||||
rnn Recurrent Neural Network
|
||||
lstm Long-Short Term Memory
|
||||
conv1d 1D Convolutional Neural Network
|
||||
mc Monte-Carlo simulations
|
||||
"""
|
||||
print(help_string)
|
||||
|
||||
@@ -724,6 +727,59 @@ Models:
|
||||
finally:
|
||||
pred_helper.restore_env()
|
||||
|
||||
def call_mc(self, other_args: List[str]):
|
||||
"""Process mc command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
add_help=False,
|
||||
prog="mc",
|
||||
description="""
|
||||
Perform Monte Carlo forecasting
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--days",
|
||||
help="Days to predict",
|
||||
dest="n_days",
|
||||
type=check_positive,
|
||||
default=30,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--num",
|
||||
help="Number of simulations to perform",
|
||||
dest="n_sims",
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dist",
|
||||
choices=["normal", "lognormal"],
|
||||
default="lognormal",
|
||||
dest="dist",
|
||||
help="Whether to model returns or log returns",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(
|
||||
parser, other_args, export_allowed=EXPORT_ONLY_FIGURES_ALLOWED
|
||||
)
|
||||
if not ns_parser:
|
||||
return
|
||||
if self.target != "AdjClose":
|
||||
print("MC Prediction designed for AdjClose prices")
|
||||
return
|
||||
|
||||
mc_view.display_mc_forecast(
|
||||
data=self.stock[self.target],
|
||||
n_future=ns_parser.n_days,
|
||||
n_sims=ns_parser.n_sims,
|
||||
use_log=ns_parser.dist == "lognormal",
|
||||
export=ns_parser.export,
|
||||
)
|
||||
except Exception as e:
|
||||
print(e, "\n")
|
||||
|
||||
|
||||
def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame):
|
||||
"""Prediction Techniques Menu"""
|
||||
|
||||
20
website/content/stocks/prediction_techniques/mc/_index.md
vendored
Normal file
20
website/content/stocks/prediction_techniques/mc/_index.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
```
|
||||
usage: mc [-d N_DAYS] [-n N_SIMS] [--dist {normal,lognormal}] [-h] [--export {png,jpg,pdf,svg}]
|
||||
```
|
||||
|
||||
Perform Monte Carlo forecasting
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-d N_DAYS, --days N_DAYS
|
||||
Days to predict (default: 30)
|
||||
-n N_SIMS, --num N_SIMS
|
||||
Number of simulations to perform (default: 100)
|
||||
--dist {normal,lognormal}
|
||||
Whether to model returns or log returns (default: lognormal)
|
||||
-h, --help show this help message (default: False)
|
||||
--export {png,jpg,pdf,svg}
|
||||
Export figure into png, jpg, pdf, svg (default: )
|
||||
```
|
||||
|
||||

|
||||
2
website/data/menu/main.yml
vendored
2
website/data/menu/main.yml
vendored
@@ -508,6 +508,8 @@ main:
|
||||
ref: "/stocks/prediction_techniques/lstm"
|
||||
- name: conv1d
|
||||
ref: "/stocks/prediction_techniques/conv1d"
|
||||
- name: mc
|
||||
ref: "/stocks/prediction_techniques/mc"
|
||||
- name: report
|
||||
ref: "/stocks/report"
|
||||
- name: forex
|
||||
|
||||
Reference in New Issue
Block a user