Created
April 15, 2022 22:44
-
-
Save marcosan93/c915dae42f2400c4e9e3d52febc29a32 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def getStockPrices(stock, n_days, training_days, mov_avg): | |
""" | |
Gets stock prices from now to N days ago and training amount will be in addition | |
to the number of days to train. | |
""" | |
# Designating the Ticker | |
ticker = yf.Ticker(stock) | |
# Getting all price history | |
price_history = ticker.history(period="max") | |
# Check on length | |
if len(price_history)<n_days+training_days+mov_avg: | |
return pd.DataFrame(), price_history | |
# Getting relevant length | |
prices = price_history.tail(n_days+training_days+mov_avg) | |
# Filling NaNs with the most recent values for any missing data | |
prices = prices.fillna(method='ffill') | |
# Getting the N Day Moving Average and rounding the values for some light data preprocessing | |
prices['MA'] = prices[['Close']].rolling( | |
window=mov_avg | |
).mean().apply(lambda x: round(x, 2)) | |
# Resetting format for FBP | |
prices = prices.reset_index().rename( | |
columns={"Date": "ds", "MA": "y"} | |
) | |
# Dropping the Nans | |
prices.dropna(inplace=True, subset=['y']) | |
return prices, price_history | |
def fbpTrainPredict(df, forecast_period, interval_width=0.80): | |
""" | |
Uses FB Prophet and fits to a appropriately formatted DF. Makes a prediction N days into | |
the future based on given forecast period. Returns predicted values as a DF. | |
""" | |
# Setting up prophet | |
m = Prophet( | |
daily_seasonality=True, | |
yearly_seasonality=True, | |
weekly_seasonality=True, | |
interval_width=interval_width | |
) | |
# Fitting to the prices | |
m.fit(df[['ds', 'y']]) | |
# Future DF | |
future = m.make_future_dataframe( | |
periods=forecast_period, | |
freq='B', | |
include_history=False | |
) | |
# Predicting values | |
forecast = m.predict(future) | |
# Returning a set of predicted values | |
return forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']] | |
def runningFBP(prices, forecast_period, training_days, interval_width): | |
""" | |
Runs Facebook Prophet to get predictions over a set period | |
of time. Uses FBP to train and predict every N days and gets the | |
price forecasts. | |
""" | |
# DF for the predicted values | |
pred_df = pd.DataFrame() | |
# Running the model each day | |
for i in tqdm(range(training_days, len(prices)+1), leave=False): | |
# Training then Predicting the last day of the forecast | |
forecast = fbpTrainPredict( | |
prices[i-training_days:i], | |
forecast_period, | |
interval_width=interval_width | |
).tail(1) | |
# Adding the forecast predicted (last day) | |
pred_df = pred_df.append(forecast, ignore_index=True) | |
# Prepping for merge by converting date values to be the same type | |
pred_df['ds'] = pred_df['ds'].apply(lambda x: str(x)[:10]) | |
prices['ds'] = prices['ds'].apply(lambda x: str(x)[:10]) | |
# Shifting the forecasts back in order to compare it to the 'current' open values | |
pred_df[['yhat', 'yhat_lower', 'yhat_upper']] = pred_df[['yhat', 'yhat_lower', 'yhat_upper']].shift(-forecast_period) | |
# Merging with the prices DF in order to compare values for positions later | |
merge_df = prices[['ds', 'Open']].merge( | |
pred_df, | |
on='ds', | |
how='outer' | |
).dropna().set_index('ds') | |
return merge_df |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment