Financial Planning¶
In [1]:
# Import libraries and dependencies
import requests
import pandas as pd
from MCForecastTools import MCSimulation
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
/opt/anaconda3/envs/dev/lib/python3.12/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer). warnings.warn(
In [2]:
import os
from dotenv import load_dotenv
import alpaca_trade_api as tradeapi
# Load .env file
load_dotenv('api.env')
# Fetch keys
alpaca_api_key = os.getenv("ALPACA_API_KEY")
alpaca_secret_key = os.getenv("ALPACA_SECRET_KEY")
# Initialize API
api = tradeapi.REST(
alpaca_api_key,
alpaca_secret_key,
base_url='https://paper-api.alpaca.markets',
api_version='v2'
)
Part 1 - Personal Finance Planner¶
Collect Crypto Prices Using the requests Library¶
In [3]:
# Crypto API URLs
btc_url = "https://api.alternative.me/v2/ticker/Bitcoin/?convert=USD"
eth_url = "https://api.alternative.me/v2/ticker/Ethereum/?convert=USD"
# Fetch current BTC price
btc_data = requests.get(btc_url).json()
btc_price = btc_data['data']['1']['quotes']['USD']['price']
print(f"The current price of BTC is ${btc_price:0.2f}")
# Fetch current ETH price
eth_data = requests.get(eth_url).json()
eth_price = eth_data['data']['1027']['quotes']['USD']['price']
print(f"The current price of ETH is ${eth_price:0.2f}")
The current price of BTC is $118841.00 The current price of ETH is $3154.76
In [4]:
# Compute current value of btc
my_btc = 1.2
my_btc_value = my_btc * btc_price
# Compute current value of eth
my_eth = 5.3
my_eth_value = my_eth * eth_price
# Compute current value of my crypto portfolio
my_crypto_port = my_btc + my_eth
my_crypto_value = my_btc_value + my_eth_value
# Print current crypto wallet balance
print(f"The current value of your {my_btc} BTC is ${my_btc_value:0.2f}")
print(f"The current value of your {my_eth} ETH is ${my_eth_value:0.2f}")
print(f"The current value of your {my_crypto_port} Crypto Portfolio is ${my_crypto_value:0.2f}")
The current value of your 1.2 BTC is $142609.20 The current value of your 5.3 ETH is $16720.23 The current value of your 6.5 Crypto Portfolio is $159329.43
Collect Investments Data Using Alpaca: SPY (stocks) and AGG (bonds)¶
In [5]:
# Format current date as ISO format
today = pd.Timestamp("2024-02-5", tz="America/New_York").isoformat()
# Set the tickers
tickers = ["AGG", "SPY"]
# Set timeframe to "1Day" for Alpaca API
timeframe = "1Day"
# Get current closing prices for SPY and AGG
df_portfolio = api.get_bars(tickers, timeframe, start = today, end = today).df
# Display sample data
df_portfolio
Out[5]:
| close | high | low | trade_count | open | volume | vwap | symbol | |
|---|---|---|---|---|---|---|---|---|
| timestamp | ||||||||
| 2024-02-05 05:00:00+00:00 | 97.65 | 97.9100 | 97.56 | 33471 | 97.890 | 7656888 | 97.681006 | AGG |
| 2024-02-05 05:00:00+00:00 | 492.55 | 494.3778 | 490.23 | 537117 | 493.695 | 75685102 | 492.614541 | SPY |
In [6]:
# Reorganize the DataFrame. Separate ticker data
AGG = df_portfolio[df_portfolio['symbol']=='AGG'].drop('symbol', axis=1)
SPY = df_portfolio[df_portfolio['symbol']=='SPY'].drop('symbol', axis=1)
# Concatenate the ticker DataFrames
df_portfolio = pd.concat([AGG, SPY],axis=1, keys=['AGG','SPY'])
# Drop the time component of the date
df_portfolio.index = df_portfolio.index.date
In [7]:
# Pick AGG and SPY close prices
agg_close_price = df_portfolio[('AGG', 'close')]
spy_close_price = df_portfolio[('SPY', 'close')]
# Print AGG and SPY close prices
print(f"Current AGG closing price: ${agg_close_price}")
print(f"Current SPY closing price: ${spy_close_price}")
Current AGG closing price: $2024-02-05 97.65 Name: (AGG, close), dtype: float64 Current SPY closing price: $2024-02-05 492.55 Name: (SPY, close), dtype: float64
In [8]:
# Set current amount of shares
my_spy = 50
my_agg = 200
# Compute the current value of shares
my_spy_value = my_spy * spy_close_price[0]
my_agg_value = my_agg * agg_close_price[0]
# Print current value of shares
print(f"The current value of your {my_spy} SPY shares is ${my_spy_value:0.2f}")
print(f"The current value of your {my_agg} AGG shares is ${my_agg_value:0.2f}")
The current value of your 50 SPY shares is $24627.50 The current value of your 200 AGG shares is $19530.00
Savings Health Analysis¶
In [9]:
# Consolidate financial assets data
savings_data = [my_crypto_value, my_spy_value + my_agg_value]
# Create savings DataFrame
savings_df = pd.DataFrame(savings_data, columns=['amount'], index = ["crypto", "shares"])
# Display savings DataFrame
display(savings_df)
| amount | |
|---|---|
| crypto | 159329.428 |
| shares | 44157.500 |
In [10]:
# Plot savings pie chart
savings_df.plot.pie(y="amount", title='Composition of Personal Savings')
plt.tight_layout
plt.show()
In [11]:
# Set monthly household income
monthly_income = 12000
print(f"Monthly Income equals {monthly_income}")
# Set ideal emergency fund
emergency_fund = monthly_income * 3
print(f"Emergency Fund equals {emergency_fund}")
# Calculate total amount of savings
total_portfolio_value = int(savings_df.sum()[0])
print(f"Total Portfolio Value equals {total_portfolio_value}")
Monthly Income equals 12000 Emergency Fund equals 36000 Total Portfolio Value equals 203486
In [12]:
# Validate saving health
if total_portfolio_value > emergency_fund:
print("Congratulations you have enough money in this fund")
elif total_portfolio_value == emergency_fund:
print("Congratulations you have reached an important financial goal of having just enough savings")
else:
print(f"Sorry you are {emergency_fund} from reaching your goal")
Congratulations you have enough money in this fund
Get Past 3 Year's Worth of Price Data via Alpaca API Call for AGG & SPY¶
In [13]:
# Set timeframe to "1Day"
timeframe = "1Day"
# Set start and end datetimes between now and 3 years ago.
start_date = pd.Timestamp('2021-02-06', tz="America/New_York").isoformat()
end_date = pd.Timestamp('2024-02-06', tz="America/New_York").isoformat()
# Set the ticker information
tickers = ["AGG","SPY"]
# Get 3 year's worth of historical price data
df_ticker = api.get_bars(tickers,timeframe,start=start_date,end=end_date).df
# Display sample data
df_ticker.head()
Out[13]:
| close | high | low | trade_count | open | volume | vwap | symbol | |
|---|---|---|---|---|---|---|---|---|
| timestamp | ||||||||
| 2021-02-08 05:00:00+00:00 | 116.83 | 116.9285 | 116.7200 | 17012 | 116.75 | 5022996 | 116.827144 | AGG |
| 2021-02-09 05:00:00+00:00 | 116.88 | 116.9700 | 116.8215 | 15321 | 116.94 | 4766282 | 116.909346 | AGG |
| 2021-02-10 05:00:00+00:00 | 116.99 | 117.0100 | 116.9200 | 13889 | 116.97 | 5139131 | 116.978509 | AGG |
| 2021-02-11 05:00:00+00:00 | 116.85 | 117.0300 | 116.8000 | 12628 | 117.03 | 3597042 | 116.930479 | AGG |
| 2021-02-12 05:00:00+00:00 | 116.58 | 116.7400 | 116.5418 | 14201 | 116.67 | 3422139 | 116.628811 | AGG |
In [14]:
# Reorganize the DataFrame. Separate ticker data
AGG = df_ticker[df_ticker["symbol"]=="AGG"].drop("symbol", axis=1)
SPY = df_ticker[df_ticker["symbol"]=="SPY"].drop("symbol", axis=1)
# Concatenate the ticker DataFrames
df_ticker = pd.concat([AGG,SPY], axis=1, keys=["AGG","SPY"])
# Display sample data
df_ticker.head()
Out[14]:
| AGG | SPY | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| close | high | low | trade_count | open | volume | vwap | close | high | low | trade_count | open | volume | vwap | |
| timestamp | ||||||||||||||
| 2021-02-08 05:00:00+00:00 | 116.83 | 116.9285 | 116.7200 | 17012 | 116.75 | 5022996 | 116.827144 | 390.52 | 390.56 | 388.35 | 240716 | 389.27 | 39380252 | 389.448700 |
| 2021-02-09 05:00:00+00:00 | 116.88 | 116.9700 | 116.8215 | 15321 | 116.94 | 4766282 | 116.909346 | 390.31 | 390.89 | 389.17 | 235682 | 389.61 | 36248491 | 390.254656 |
| 2021-02-10 05:00:00+00:00 | 116.99 | 117.0100 | 116.9200 | 13889 | 116.97 | 5139131 | 116.978509 | 390.17 | 392.28 | 387.50 | 352180 | 392.12 | 59678427 | 389.851166 |
| 2021-02-11 05:00:00+00:00 | 116.85 | 117.0300 | 116.8000 | 12628 | 117.03 | 3597042 | 116.930479 | 390.71 | 391.69 | 388.10 | 272447 | 391.24 | 43822781 | 390.154207 |
| 2021-02-12 05:00:00+00:00 | 116.58 | 116.7400 | 116.5418 | 14201 | 116.67 | 3422139 | 116.628811 | 392.73 | 392.90 | 389.77 | 251164 | 389.85 | 51799016 | 391.585723 |
In [15]:
# Configure a Monte Carlo simulation to forecast five years cumulative returns
MC_even_dist = MCSimulation(portfolio_data = df_ticker, weights = [.40,.60], num_simulation = 500, num_trading_days = 252*30)
# Print the simulation input data
MC_even_dist.portfolio_data.head()
Out[15]:
| AGG | SPY | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| close | high | low | trade_count | open | volume | vwap | daily_return | close | high | low | trade_count | open | volume | vwap | daily_return | |
| timestamp | ||||||||||||||||
| 2021-02-08 05:00:00+00:00 | 116.83 | 116.9285 | 116.7200 | 17012 | 116.75 | 5022996 | 116.827144 | NaN | 390.52 | 390.56 | 388.35 | 240716 | 389.27 | 39380252 | 389.448700 | NaN |
| 2021-02-09 05:00:00+00:00 | 116.88 | 116.9700 | 116.8215 | 15321 | 116.94 | 4766282 | 116.909346 | 0.000428 | 390.31 | 390.89 | 389.17 | 235682 | 389.61 | 36248491 | 390.254656 | -0.000538 |
| 2021-02-10 05:00:00+00:00 | 116.99 | 117.0100 | 116.9200 | 13889 | 116.97 | 5139131 | 116.978509 | 0.000941 | 390.17 | 392.28 | 387.50 | 352180 | 392.12 | 59678427 | 389.851166 | -0.000359 |
| 2021-02-11 05:00:00+00:00 | 116.85 | 117.0300 | 116.8000 | 12628 | 117.03 | 3597042 | 116.930479 | -0.001197 | 390.71 | 391.69 | 388.10 | 272447 | 391.24 | 43822781 | 390.154207 | 0.001384 |
| 2021-02-12 05:00:00+00:00 | 116.58 | 116.7400 | 116.5418 | 14201 | 116.67 | 3422139 | 116.628811 | -0.002311 | 392.73 | 392.90 | 389.77 | 251164 | 389.85 | 51799016 | 391.585723 | 0.005170 |
In [16]:
# Run a Monte Carlo simulation to forecast thirty years cumulative returns
MC_even_dist.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.
Out[16]:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 | 1.003204 | 1.000119 | 1.012604 | 1.005102 | 0.989331 | 1.004718 | 0.996018 | 1.005640 | 0.987078 | 1.003725 | ... | 1.001325 | 0.993700 | 0.987104 | 1.001868 | 1.001903 | 0.991314 | 0.998468 | 1.004519 | 1.007071 | 1.005935 |
| 2 | 0.985801 | 1.006227 | 1.003960 | 1.009120 | 0.997721 | 1.009395 | 0.991927 | 1.004882 | 0.981104 | 1.012074 | ... | 0.993165 | 0.993061 | 0.991126 | 1.008984 | 0.993293 | 0.989430 | 0.995351 | 1.000966 | 1.005849 | 0.999203 |
| 3 | 0.978981 | 1.013963 | 1.007317 | 0.995534 | 1.004474 | 1.005296 | 0.984037 | 0.995395 | 0.973532 | 1.002707 | ... | 0.988731 | 0.991871 | 0.993276 | 1.007796 | 0.991724 | 0.976800 | 1.001212 | 1.011073 | 0.998124 | 1.001077 |
| 4 | 0.993136 | 1.015046 | 0.999851 | 1.002406 | 1.006490 | 0.998183 | 0.995389 | 0.996047 | 0.977041 | 1.004628 | ... | 0.991400 | 0.994769 | 0.997443 | 1.021671 | 0.989517 | 0.974263 | 1.009125 | 1.018308 | 1.006633 | 0.998498 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 7556 | 1.867061 | 1.548299 | 1.193088 | 9.562023 | 2.152656 | 4.680691 | 2.610067 | 2.546608 | 1.430731 | 1.971441 | ... | 1.805447 | 4.479677 | 1.780729 | 3.015321 | 1.654884 | 2.354878 | 5.031860 | 1.669546 | 1.224447 | 2.947676 |
| 7557 | 1.889999 | 1.554944 | 1.194366 | 9.454720 | 2.139823 | 4.697877 | 2.608140 | 2.523638 | 1.424121 | 1.965644 | ... | 1.805798 | 4.487902 | 1.765170 | 3.001138 | 1.658373 | 2.372542 | 5.046396 | 1.658362 | 1.232009 | 2.941151 |
| 7558 | 1.879903 | 1.547495 | 1.188868 | 9.447247 | 2.130714 | 4.720892 | 2.599267 | 2.506908 | 1.413706 | 1.983415 | ... | 1.824500 | 4.504066 | 1.752838 | 2.994184 | 1.648464 | 2.410131 | 5.071703 | 1.656778 | 1.217567 | 2.923600 |
| 7559 | 1.892328 | 1.560564 | 1.179985 | 9.517726 | 2.140060 | 4.710551 | 2.607579 | 2.495121 | 1.412069 | 1.975245 | ... | 1.824206 | 4.550974 | 1.762618 | 2.994415 | 1.654502 | 2.442290 | 5.143401 | 1.663081 | 1.223265 | 2.921678 |
| 7560 | 1.906886 | 1.571335 | 1.178256 | 9.416646 | 2.121916 | 4.749879 | 2.591621 | 2.514609 | 1.425328 | 1.975258 | ... | 1.837070 | 4.586123 | 1.752053 | 2.990244 | 1.655598 | 2.434351 | 5.128849 | 1.646921 | 1.237461 | 2.913373 |
7561 rows × 500 columns
In [17]:
# Plot simulation outcomes
line_plot = MC_even_dist.plot_simulation()
plt.tight_layout
plt.show()
In [18]:
# Plot probability distribution and confidence intervals
dist_plot = MC_even_dist.plot_distribution()
In [19]:
# Fetch summary statistics from the Monte Carlo simulation results
even_tbl = MC_even_dist.summarize_cumulative_return()
# Print summary statistics
print(even_tbl)
count 500.000000 mean 2.802675 std 1.762083 min 0.419950 25% 1.583829 50% 2.306270 75% 3.483734 max 13.293602 95% CI Lower 0.830669 95% CI Upper 7.386548 Name: 7560, dtype: float64
In [20]:
# Set Initial Investment
initial_investment = 20000
# Use the lower and upper `95%` confidence intervals to calculate the range of the possible outcomes of our $15,000 investments in stocks
even_ci_lower = round(even_tbl[8]*initial_investment,2)
even_ci_upper = round(even_tbl[9]*initial_investment,2)
# Print results
print(f"There is a 95% chance that an initial investment of $20,000 in the portfolio"
f" over the next 5 years will end within in the range of"
f" ${even_ci_lower} and ${even_ci_upper}.")
There is a 95% chance that an initial investment of $20,000 in the portfolio over the next 5 years will end within in the range of $16613.38 and $147730.95.
In [21]:
# Configuring a Monte Carlo simulation to forecast 10 years cumulative returns
MC_even_dist = MCSimulation(portfolio_data = df_ticker, weights = [.20,.80], num_simulation = 500, num_trading_days = 252*10)
# Print the simulation input data
MC_even_dist.portfolio_data.head()
Out[21]:
| AGG | SPY | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| close | high | low | trade_count | open | volume | vwap | daily_return | close | high | low | trade_count | open | volume | vwap | daily_return | |
| timestamp | ||||||||||||||||
| 2021-02-08 05:00:00+00:00 | 116.83 | 116.9285 | 116.7200 | 17012 | 116.75 | 5022996 | 116.827144 | NaN | 390.52 | 390.56 | 388.35 | 240716 | 389.27 | 39380252 | 389.448700 | NaN |
| 2021-02-09 05:00:00+00:00 | 116.88 | 116.9700 | 116.8215 | 15321 | 116.94 | 4766282 | 116.909346 | 0.000428 | 390.31 | 390.89 | 389.17 | 235682 | 389.61 | 36248491 | 390.254656 | -0.000538 |
| 2021-02-10 05:00:00+00:00 | 116.99 | 117.0100 | 116.9200 | 13889 | 116.97 | 5139131 | 116.978509 | 0.000941 | 390.17 | 392.28 | 387.50 | 352180 | 392.12 | 59678427 | 389.851166 | -0.000359 |
| 2021-02-11 05:00:00+00:00 | 116.85 | 117.0300 | 116.8000 | 12628 | 117.03 | 3597042 | 116.930479 | -0.001197 | 390.71 | 391.69 | 388.10 | 272447 | 391.24 | 43822781 | 390.154207 | 0.001384 |
| 2021-02-12 05:00:00+00:00 | 116.58 | 116.7400 | 116.5418 | 14201 | 116.67 | 3422139 | 116.628811 | -0.002311 | 392.73 | 392.90 | 389.77 | 251164 | 389.85 | 51799016 | 391.585723 | 0.005170 |
In [22]:
# Running a Monte Carlo simulation to forecast 10 years cumulative returns
MC_even_dist.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.
Out[22]:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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.996167 | 1.000851 | 1.000649 | 0.997784 | 0.995560 | 0.993029 | 0.989345 | 0.990485 | 0.996272 | 0.997725 | ... | 1.007965 | 1.000846 | 1.003590 | 0.987262 | 0.996550 | 1.006967 | 1.007883 | 0.996019 | 1.003603 | 1.012476 |
| 2 | 0.997598 | 1.007988 | 0.995040 | 0.994521 | 1.003876 | 0.997889 | 0.979497 | 0.978171 | 1.006638 | 0.976856 | ... | 1.015826 | 1.003888 | 1.001433 | 0.994949 | 0.997667 | 0.993882 | 1.003826 | 0.986372 | 1.001047 | 1.017333 |
| 3 | 1.003755 | 1.002872 | 0.989829 | 0.994760 | 0.992807 | 0.983775 | 0.972871 | 0.989205 | 1.006660 | 0.983436 | ... | 1.013864 | 1.018187 | 1.015175 | 1.006813 | 1.008873 | 0.995359 | 0.997939 | 0.975482 | 1.017562 | 1.004009 |
| 4 | 1.012336 | 0.999020 | 0.989207 | 0.988877 | 0.998457 | 0.966823 | 0.969741 | 0.991850 | 0.998811 | 0.983347 | ... | 1.015791 | 1.044457 | 1.020494 | 1.006324 | 1.012624 | 0.983829 | 0.991577 | 0.984492 | 1.011486 | 1.000753 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2516 | 1.002390 | 2.818109 | 2.853148 | 1.360125 | 1.022064 | 2.946971 | 1.863717 | 1.314694 | 2.172356 | 1.754403 | ... | 1.873494 | 2.988420 | 2.899911 | 3.232998 | 1.486186 | 1.378355 | 1.070163 | 2.249612 | 0.990972 | 2.406265 |
| 2517 | 1.024335 | 2.832969 | 2.856496 | 1.372663 | 1.023998 | 2.964430 | 1.877884 | 1.341329 | 2.161234 | 1.736271 | ... | 1.873974 | 3.020369 | 2.833336 | 3.206866 | 1.502259 | 1.366764 | 1.079219 | 2.236625 | 0.990749 | 2.439796 |
| 2518 | 1.026539 | 2.850640 | 2.852947 | 1.391632 | 1.031350 | 2.953021 | 1.871521 | 1.344611 | 2.162653 | 1.734532 | ... | 1.874377 | 3.026167 | 2.861372 | 3.198498 | 1.496510 | 1.363438 | 1.074463 | 2.248704 | 0.993303 | 2.481243 |
| 2519 | 1.032611 | 2.865814 | 2.903328 | 1.384588 | 1.014867 | 2.944334 | 1.865918 | 1.345609 | 2.138341 | 1.734360 | ... | 1.891539 | 2.993534 | 2.860177 | 3.213181 | 1.535001 | 1.356934 | 1.079276 | 2.253157 | 0.991859 | 2.453504 |
| 2520 | 1.036207 | 2.896447 | 2.936293 | 1.369887 | 1.014015 | 2.931878 | 1.864548 | 1.324220 | 2.104036 | 1.763696 | ... | 1.888993 | 3.001408 | 2.852821 | 3.191897 | 1.522324 | 1.361770 | 1.076610 | 2.246741 | 1.009353 | 2.418645 |
2521 rows × 500 columns
In [23]:
# Plot simulation outcomes
line_plot = MC_even_dist.plot_simulation()
plt.tight_layout
plt.show()
In [24]:
# Plot probability distribution and confidence intervals
dist_plot = MC_even_dist.plot_distribution()
plt.tight_layout
plt.show()
In [25]:
# Fetch summary statistics from the Monte Carlo simulation results
even_tbl = MC_even_dist.summarize_cumulative_return()
# Print summary statistics
print(even_tbl)
count 500.000000 mean 1.830267 std 0.820703 min 0.187619 25% 1.232357 50% 1.667490 75% 2.246873 max 4.975646 95% CI Lower 0.664741 95% CI Upper 3.968226 Name: 2520, dtype: float64
In [26]:
# Set Initial Investment
initial_investment = 20000
# Use the lower and upper `95%` confidence intervals to calculate the range of the possible outcomes of our $15,000 investments in stocks
even_ci_lower = round(even_tbl[8]*initial_investment,2)
even_ci_upper = round(even_tbl[9]*initial_investment,2)
# Print results
print(f"There is a 95% chance that an initial investment of $20,000 in the portfolio"
f" over the next 5 years will end within in the range of"
f" ${even_ci_lower} and ${even_ci_upper}.")
There is a 95% chance that an initial investment of $20,000 in the portfolio over the next 5 years will end within in the range of $13294.83 and $79364.53.
In [27]:
# Yes, it is much more likely that credit union members can retire comfortably due to
# a much higher upper bound ($80K) and not that much less lower bound ($14K)