Skip to content

Instantly share code, notes, and snippets.

@marcosan93
Created April 15, 2022 22:44
Show Gist options
  • Save marcosan93/c915dae42f2400c4e9e3d52febc29a32 to your computer and use it in GitHub Desktop.
Save marcosan93/c915dae42f2400c4e9e3d52febc29a32 to your computer and use it in GitHub Desktop.
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