/alpaca_trading

Primary LanguageJupyter Notebook

Student Activity: Financial Forecasting

In this activity, Harold's manager wants Harold to take a look at one year's worth of TSLA stock prices and plot a potential stock trajectory for where TSLA stock prices could go in the next 3 years. In addition, he would like to know how a $10,000 investment would perform given the simulated results.

Help Harold by creating a Monte Carlo simulation that simulates the next 252 * 3 trading days using three years worth of TSLA stock data. Plot the simulated results of TSLA daily returns over the next 3 years as well as the corresponding simulated outcomes.

# Import libraries and dependencies
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import alpaca_trade_api as tradeapi
from MCForecastTools import MCSimulation

%matplotlib inline
# Load .env enviroment variables
from dotenv import load_dotenv
load_dotenv()

# Set Alpaca API key and secret
alpaca_api_key = os.getenv("ALPACA_API_KEY")
alpaca_secret_key = os.getenv("ALPACA_SECRET_KEY")

api = tradeapi.REST(
    alpaca_api_key,
    alpaca_secret_key,
    api_version = "v2"
)

Get 3 Years Worth of Data via API Call and Read in as DataFrame

# Set the ticker
ticker = "TSLA"

# Set timeframe to '1D'
timeframe = "1D"

# Set start and end datetimes of 3 years from Today
start_date = pd.Timestamp("2017-05-04", tz="America/New_York").isoformat()
end_date = pd.Timestamp("2020-05-04", tz="America/New_York").isoformat()

# Get 3 years worth of historical data for TSLA
ticker_data = api.get_barset(
    ticker,
    timeframe,
    start=start_date,
    end=end_date,
    limit=1000,
).df

ticker_data.head()
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead tr th {
    text-align: left;
}
</style>
TSLA
open high low close volume
2017-05-04 00:00:00-04:00 307.435 307.77 290.7601 295.36 11653966
2017-05-05 00:00:00-04:00 298.000 308.55 296.8000 308.35 6695227
2017-05-08 00:00:00-04:00 310.600 313.79 305.8200 307.20 5969091
2017-05-09 00:00:00-04:00 309.380 321.99 309.1000 321.27 8158739
2017-05-10 00:00:00-04:00 321.560 325.40 318.1200 325.22 4754047

Run the Monte Carlo Simulation

# Set number of simulations
num_sims = 1000

# Configure a Monte Carlo simulation to forecast three years daily returns
MC_TSLA = MCSimulation(
    portfolio_data = ticker_data,
    num_simulation = num_sims,
    num_trading_days = 252*3
)
# Run Monte Carlo simulations to forecast three years daily returns
MC_TSLA.calc_cumulative_return()
Running Monte Carlo simulation number 0.
Running Monte Carlo simulation number 10.
Running Monte Carlo simulation number 20.
Running Monte Carlo simulation number 30.
Running Monte Carlo simulation number 40.
Running Monte Carlo simulation number 50.
Running Monte Carlo simulation number 60.
Running Monte Carlo simulation number 70.
Running Monte Carlo simulation number 80.
Running Monte Carlo simulation number 90.
Running Monte Carlo simulation number 100.
Running Monte Carlo simulation number 110.
Running Monte Carlo simulation number 120.
Running Monte Carlo simulation number 130.
Running Monte Carlo simulation number 140.
Running Monte Carlo simulation number 150.
Running Monte Carlo simulation number 160.
Running Monte Carlo simulation number 170.
Running Monte Carlo simulation number 180.
Running Monte Carlo simulation number 190.
Running Monte Carlo simulation number 200.
Running Monte Carlo simulation number 210.
Running Monte Carlo simulation number 220.
Running Monte Carlo simulation number 230.
Running Monte Carlo simulation number 240.
Running Monte Carlo simulation number 250.
Running Monte Carlo simulation number 260.
Running Monte Carlo simulation number 270.
Running Monte Carlo simulation number 280.
Running Monte Carlo simulation number 290.
Running Monte Carlo simulation number 300.
Running Monte Carlo simulation number 310.
Running Monte Carlo simulation number 320.
Running Monte Carlo simulation number 330.
Running Monte Carlo simulation number 340.
Running Monte Carlo simulation number 350.
Running Monte Carlo simulation number 360.
Running Monte Carlo simulation number 370.
Running Monte Carlo simulation number 380.
Running Monte Carlo simulation number 390.
Running Monte Carlo simulation number 400.
Running Monte Carlo simulation number 410.
Running Monte Carlo simulation number 420.
Running Monte Carlo simulation number 430.
Running Monte Carlo simulation number 440.
Running Monte Carlo simulation number 450.
Running Monte Carlo simulation number 460.
Running Monte Carlo simulation number 470.
Running Monte Carlo simulation number 480.
Running Monte Carlo simulation number 490.
Running Monte Carlo simulation number 500.
Running Monte Carlo simulation number 510.
Running Monte Carlo simulation number 520.
Running Monte Carlo simulation number 530.
Running Monte Carlo simulation number 540.
Running Monte Carlo simulation number 550.
Running Monte Carlo simulation number 560.
Running Monte Carlo simulation number 570.
Running Monte Carlo simulation number 580.
Running Monte Carlo simulation number 590.
Running Monte Carlo simulation number 600.
Running Monte Carlo simulation number 610.
Running Monte Carlo simulation number 620.
Running Monte Carlo simulation number 630.
Running Monte Carlo simulation number 640.
Running Monte Carlo simulation number 650.
Running Monte Carlo simulation number 660.
Running Monte Carlo simulation number 670.
Running Monte Carlo simulation number 680.
Running Monte Carlo simulation number 690.
Running Monte Carlo simulation number 700.
Running Monte Carlo simulation number 710.
Running Monte Carlo simulation number 720.
Running Monte Carlo simulation number 730.
Running Monte Carlo simulation number 740.
Running Monte Carlo simulation number 750.
Running Monte Carlo simulation number 760.
Running Monte Carlo simulation number 770.
Running Monte Carlo simulation number 780.
Running Monte Carlo simulation number 790.
Running Monte Carlo simulation number 800.
Running Monte Carlo simulation number 810.
Running Monte Carlo simulation number 820.
Running Monte Carlo simulation number 830.
Running Monte Carlo simulation number 840.
Running Monte Carlo simulation number 850.
Running Monte Carlo simulation number 860.
Running Monte Carlo simulation number 870.
Running Monte Carlo simulation number 880.
Running Monte Carlo simulation number 890.
Running Monte Carlo simulation number 900.
Running Monte Carlo simulation number 910.
Running Monte Carlo simulation number 920.
Running Monte Carlo simulation number 930.
Running Monte Carlo simulation number 940.
Running Monte Carlo simulation number 950.
Running Monte Carlo simulation number 960.
Running Monte Carlo simulation number 970.
Running Monte Carlo simulation number 980.
Running Monte Carlo simulation number 990.
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
0 1 2 3 4 5 6 7 8 9 ... 990 991 992 993 994 995 996 997 998 999
0 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 ... 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1 0.981222 0.990782 1.001497 0.968636 1.025662 0.985579 0.979159 0.959626 0.915200 1.100719 ... 1.035320 0.974333 1.129787 0.991942 1.026417 1.070166 1.043902 1.019487 0.967719 0.982966
2 0.979845 0.932936 0.950812 1.001255 0.978447 0.956805 0.971956 0.959406 0.916128 1.014008 ... 1.066326 0.974253 1.142736 1.009477 1.010455 1.083022 1.034498 1.023799 0.886175 0.955799
3 0.982248 0.958489 0.907635 1.076008 0.924043 0.941103 0.972826 0.994823 0.953968 1.040536 ... 1.099464 0.990134 1.172254 0.948681 0.967827 1.055193 1.048936 1.023842 0.954594 0.966601
4 1.007947 0.994389 0.863432 1.100683 0.928010 0.884032 0.965998 0.947342 0.920592 1.079854 ... 1.135327 0.972608 1.139030 0.909896 0.982004 1.046113 0.950495 0.958808 0.951463 0.908549
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
752 2.964285 6.281219 3.528422 5.569597 1.537283 1.927135 1.835281 2.273169 4.462258 6.555616 ... 2.991133 3.373659 3.035196 1.345995 0.360124 34.367965 1.629844 8.824132 3.348889 10.723148
753 2.898127 5.929781 3.630850 5.614963 1.532372 1.913588 1.905665 2.160138 4.445566 6.939099 ... 3.156057 3.510643 3.030412 1.298904 0.357633 34.687223 1.666808 9.236994 3.099606 10.409932
754 2.805524 5.824232 3.821479 6.019107 1.466395 1.944477 1.955238 2.174833 4.450806 6.638072 ... 3.260135 3.581977 2.908168 1.199393 0.386841 36.692925 1.657787 9.105443 3.114519 10.542502
755 2.719517 5.297904 3.993555 6.214585 1.463815 1.966690 1.964821 2.180150 4.592842 6.726524 ... 3.448536 3.769620 3.132997 1.138237 0.379576 37.370551 1.649728 9.167870 3.188418 10.650525
756 2.812057 5.466324 3.981998 6.201528 1.494064 2.016463 1.833008 2.172569 4.570772 6.460053 ... 3.498799 3.943865 3.263377 1.214728 0.371717 37.689524 1.629001 9.286477 3.326631 10.344296

757 rows × 1000 columns

Plot the Simulated Daily Returns Trajectory for TSLA over the Next Year (252 Trading Days)

# Compute summary statistics from the simulated daily returns
simulated_returns_data = {
    "mean": list(MC_TSLA.simulated_return.mean(axis=1)),
    "median": list(MC_TSLA.simulated_return.median(axis=1)),
    "min": list(MC_TSLA.simulated_return.min(axis=1)),
    "max": list(MC_TSLA.simulated_return.max(axis=1))
}

# Create a DataFrame with the summary statistics
df_simulated_returns = pd.DataFrame(simulated_returns_data)

# Display sample data
df_simulated_returns.head()
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
mean median min max
0 1.000000 1.000000 1.000000 1.000000
1 1.002953 1.002788 0.856863 1.129787
2 1.005907 1.005676 0.826181 1.203377
3 1.007616 1.006666 0.801393 1.232933
4 1.008332 1.004927 0.768805 1.294849
# Use the `plot` function to visually analyze the trajectory of TSLA stock daily returns on the next three years of trading days simulation
df_simulated_returns.plot(title="Simulated Daily Returns Behavior of TSLA Stock Over the Next Year")
<matplotlib.axes._subplots.AxesSubplot at 0x7faaf8c88610>

png

Calculate the Simulated Profits/Losses of $10,000 Investment in TSLA Over the Next Three Years

# Set initial investment
initial_investment = 10000

# Multiply an initial investment by the daily returns of simulative stock prices to return the progression of daily returns in terms of money
cumulative_pnl = initial_investment * df_simulated_returns

# Display sample data
cumulative_pnl.head()
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
mean median min max
0 10000.000000 10000.000000 10000.000000 10000.000000
1 10029.532050 10027.879860 8568.632158 11297.874167
2 10059.066285 10056.758964 8261.814625 12033.766254
3 10076.159026 10066.656818 8013.931073 12329.325621
4 10083.317080 10049.269047 7688.053281 12948.490424

Plot the Simulated Profits/Losses of $10,000 Investment in TSLA Over the Next 252 Trading Days

# Use the 'plot' function to create a chart of the simulated profits/losses
cumulative_pnl.plot(title="Simulated Outcomes Behavior of TSLA Stock Over the Next Year")
<matplotlib.axes._subplots.AxesSubplot at 0x7faaf2e62190>

png

Calculate the range of the possible outcomes of our $10,000 investments in TSLA stocks

# Fetch summary statistics from the Monte Carlo simulation results
tbl = MC_TSLA.summarize_cumulative_return()

# Print summary statistics
print(tbl)
count           1000.000000
mean               4.906131
std                6.899562
min                0.126797
25%                1.232316
50%                2.655507
75%                6.011975
max               85.991793
95% CI Lower       0.371666
95% CI Upper      23.772773
Name: 756, dtype: float64
# Use the lower and upper `95%` confidence intervals to calculate the range of the possible outcomes of our $10,000 investments in TSLA stocks
ci_lower = round(tbl[8]*10000,2)
ci_upper = round(tbl[9]*10000,2)

# Print results
print(f"There is a 95% chance that an initial investment of $10,000 in the portfolio"
      f" over the next year will end within in the range of"
      f" ${ci_lower} and ${ci_upper}.")
There is a 95% chance that an initial investment of $10,000 in the portfolio over the next year will end within in the range of $3716.66 and $237727.73.