In [4]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math
import pandas_datareader
%matplotlib inline

def main(ticker):
    start="2019-10-01"
    end="2019-12-13"
    num_simulations = 100
    predicted_days = 251
    df = get_data_yahoo(ticker, start, end)
    simulation_df = monte_carlo_sim(df, num_simulations, predicted_days)
    plot_graph(simulation_df, ticker, num_simulations)

def plot_graph(df, ticker, num_simulations):
    df = df[df.columns[df.iloc[-1, :].argsort()]]
    plt.figure()
    qs = [math.ceil(num_simulations * 0.95), math.ceil(num_simulations * 0.05), math.ceil(num_simulations * 0.5)]
    plt.plot(df, linewidth=0.3)
    labels = [95, 5, 50]
    for q, l in zip(qs, labels):
        v = df.iloc[:, q]
        plt.plot(v, linewidth=3, label="{} % - Quantil: {}".format(l, np.round(v.iloc[-1], 2)))
    plt.legend(loc="upper left")
    plt.title("Monte Carlo Simulation of {} price".format(ticker))
    plt.grid()
    plt.show()

def get_data_yahoo(ticker, start, end):
    data_source = "yahoo"
    df = pandas_datareader.DataReader(ticker, data_source, start=start, end=end)["Adj Close"]
    df.name = ticker
    return df

def monte_carlo_sim(df, num_simulations, predicted_days):
    returns = df.pct_change()
    prices = df
    last_price = prices[-1]
    simulation_df = pd.DataFrame()
    daily_std = returns.std()
    daily_mean = returns.mean()
    
    for i in range(num_simulations):
        count = 0
        price_series = []
        price = last_price * (1 + np.random.normal(daily_mean, daily_std))
        price_series.append(price)

        for j in range(predicted_days):
            if count == predicted_days:
                break
            price = price_series[count] * (1 + np.random.normal(daily_mean, daily_std))
            price_series.append(price)
            count += 1
        simulation_df[i] = price_series

    return simulation_df

if __name__ == "__main__":
    main("FB")
    main("AMZN")
    main("AAPL")
    main("NFLX")
    main("GOOG")
In [ ]:
 
In [ ]: