|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +"""Simple_Returns.ipynb |
| 3 | +
|
| 4 | +Automatically generated by Colaboratory. |
| 5 | +
|
| 6 | +Original file is located at |
| 7 | + https://colab.research.google.com/drive/1boqmTDSjvGNyxahoW4FmIBy0YQsIqE4I |
| 8 | +""" |
| 9 | + |
| 10 | +#Description: This is a python program for finance. |
| 11 | +# This program will show you how to compute portfolio simple returns, |
| 12 | +# get daily returns and volatility etc. |
| 13 | + |
| 14 | +#Resources: |
| 15 | +# Efficient Frontier => https://towardsdatascience.com/efficient-frontier-portfolio-optimisation-in-python-e7844051e7f |
| 16 | +# How To Be A Successful Investor => https://towardsdatascience.com/how-to-be-a-successful-investor-simple-portfolio-analysis-with-python-7b66fc90fa68 |
| 17 | +# Financial Python => https://www.quantconnect.com/tutorials/introduction-to-financial-python/rate-of-return,-mean-and-variance |
| 18 | +# How To Calculate stock returns in Python => https://www.codingfinance.com/post/2018-04-03-calc-returns-py/ |
| 19 | +# Log Returns VS Simple Returns => https://fintechprofessor.com/tag/log-returns-vs-simple-returns/ |
| 20 | +# A Tale Of Two Returns => https://www.portfolioprobe.com/2010/10/04/a-tale-of-two-returns/ |
| 21 | +# Stack Overflow => https://stackoverflow.com/questions/20000726/calculate-daily-returns-with-pandas-dataframe |
| 22 | +# Get business days: https://stackoverflow.com/questions/2224742/most-recent-previous-business-day-in-python |
| 23 | +# Log Returns for beginners => https://www.coursera.org/lecture/risk-governance-engage-the-board/video-3-2c-log-returns-for-beginners-Jsnqa |
| 24 | +# Why we use log returns in finance => https://www.youtube.com/watch?v=PtoUlt3V0CI |
| 25 | +# Market Lessons: Why we use log returns => http://mktlssns.blogspot.com/2010/04/why-we-use-log-returns.html |
| 26 | +# Magic of log returns => https://investmentcache.com/magic-of-log-returns-concept-part-1/ |
| 27 | +# An easy mistake with returns => https://www.r-bloggers.com/an-easy-mistake-with-returns/ |
| 28 | +# Sharp Ratio => https://www.investopedia.com/terms/s/sharperatio.asp |
| 29 | +# Simple Calculations to Determine Return on Investments => https://www.thebalance.com/determine-return-on-investment-3140687 |
| 30 | +# How Covariance used portfolio theory => https://www.investopedia.com/ask/answers/041315/how-covariance-used-portfolio-theory.asp |
| 31 | + |
| 32 | +# Import the libraries |
| 33 | +from datetime import datetime |
| 34 | +import numpy as np |
| 35 | +import pandas as pd |
| 36 | +import pandas_datareader as web |
| 37 | +import matplotlib.pyplot as plt |
| 38 | +plt.style.use('fivethirtyeight') |
| 39 | + |
| 40 | +# Get the stock symbols in your portfolio, |
| 41 | +# I am using FAANG for the portfolio stock |
| 42 | +# FAANG is an acronym for the market's five most popular and best-performing tech stocks |
| 43 | +# (Facebook, Amazon, Apple, Netflix, & Google) |
| 44 | +stockSymbols = ["FB", "AMZN", "AAPL", "NFLX", "GOOG"] |
| 45 | + |
| 46 | +#Get the stock starting date |
| 47 | +stockStartDate = '2013-01-01' |
| 48 | + |
| 49 | +# Get todays date and format it in the form YYYY-MM-DD |
| 50 | +today = datetime.today().strftime('%Y-%m-%d') |
| 51 | + |
| 52 | +print(today) |
| 53 | + |
| 54 | +# Get the number of assests in the portfolio |
| 55 | +numAssets = len(stockSymbols) |
| 56 | +# Print the number of assests in your portfolio |
| 57 | +print('You have '+ str(numAssets)+ ' assets in your portfolio') |
| 58 | + |
| 59 | +# Create a function to get the stock price(s) of the portfolio |
| 60 | +def getMyPortfolio(stocks= stockSymbols, start = stockStartDate, end = today, col='Adj Close'): |
| 61 | + #data = web.get_data_yahoo(stocks, start = start, end = end)[col] |
| 62 | + data = web.DataReader(stocks, data_source='yahoo', start=start, end=end)[col] |
| 63 | + return data |
| 64 | + |
| 65 | +# Get the stock portfolio Adj. Close price and store it into my_stocks variable |
| 66 | +my_stocks = getMyPortfolio(stockSymbols) |
| 67 | +# Show my stocks |
| 68 | +my_stocks |
| 69 | + |
| 70 | +# Create a function to visualize the portfolio |
| 71 | +def showGraph(stocks= stockSymbols,start=stockStartDate, end=today, col='Adj Close'): |
| 72 | + |
| 73 | + # Create the title 'Portfolio (High, Low, Open, Close, Volume, Adj Close) Price History |
| 74 | + title = 'Portfolio ' + col + ' Price History' |
| 75 | + #Get the stocks |
| 76 | + my_stocks = getMyPortfolio(stocks= stocks, start=start, end=end, col = col) |
| 77 | + |
| 78 | + # Visualize the price history |
| 79 | + plt.figure(figsize=(12.2,4.5)) #width = 14in, height = 6in shows better |
| 80 | + # Loop through each stock and plot the Adj Close for each day |
| 81 | + for c in my_stocks.columns.values: |
| 82 | + plt.plot( my_stocks[c], label=c)#plt.plot( X-Axis , Y-Axis, line_width, alpha_for_blending, label) |
| 83 | + |
| 84 | + plt.title(title) |
| 85 | + plt.xlabel('Date',fontsize=18) |
| 86 | + plt.ylabel(col +' Price USD ($)',fontsize=18) |
| 87 | + plt.legend(my_stocks.columns.values, loc='upper left') |
| 88 | + plt.show() |
| 89 | + |
| 90 | +# Show the adjusted close price of FAANG and see how the stocks compare with each other |
| 91 | +showGraph(stockSymbols) |
| 92 | + |
| 93 | +# Calculate Simple Returns |
| 94 | +daily_simple_returns = my_stocks.pct_change(1) # 1 for ONE DAY lookback for each individual return NOTE:simple return = new/old - 1 |
| 95 | +# monthly_simple_returns = my_stocks.pct_change(21) # 21 for ONE MONTH lookback for each individual return |
| 96 | +# annual_simple_returns = my_stocks.pct_change(253) # 253 for ONE YEAR lookback for each individual return |
| 97 | +# Show the daily simple returns |
| 98 | +daily_simple_returns |
| 99 | + |
| 100 | +# Show the stock correlation |
| 101 | +# Covariance and correlation are two mathematical concepts which are commonly used in statistics. |
| 102 | +# When comparing data samples from different populations, |
| 103 | +# covariance is used to determine how much two random variables vary together |
| 104 | +# (the directional relationship between two asset prices), |
| 105 | +# whereas correlation is used to determine when a change in one variable can result in a change in another. |
| 106 | + |
| 107 | +# A correlation value of 1 means two stocks have a perfect positive correlation. If one stock moves up while the other goes down, |
| 108 | +# they would have a perfect negative correlation, noted by a value of -1 |
| 109 | + |
| 110 | +# The correlation will always have a measurement value between -1 and 1, and it adds a strength value on how the stocks move together. ... In short, covariance tells you that two variables change |
| 111 | +# the same way while correlation reveals how a change in one variable affects a change in the other. |
| 112 | +daily_simple_returns.corr() |
| 113 | + |
| 114 | +# Show the covariance matrix for simple returns |
| 115 | +# Covariance is an important measurement used in modern portfolio theory. |
| 116 | +# Modern Portfolio Theory attempts to determine an efficient frontier |
| 117 | +# (The efficient frontier is the set of optimal portfolios that offer the highest expected return for a defined level of risk or the lowest risk for a given level of expected return.) for a mix of assets in a portfolio. |
| 118 | +# The efficient frontier seeks to optimize the maximum return versus the degree of risk for the overall combined assets |
| 119 | +# in the portfolio. |
| 120 | + |
| 121 | +# Covariance can tell how the stocks move together |
| 122 | +# The diagonal entries of the covariance matrix are the variances and the other entries are the covariances |
| 123 | +# The covariance of two stocks tells you how likely they are to increase or decrease simultaneously. |
| 124 | + |
| 125 | +# Variance (σ^2) in statistics is a measurement of the spread between numbers in a data set. |
| 126 | +# It measures how far each number in the set is from the mean and therefore from every other number in the set. |
| 127 | +# In finance variance is a measure of dispersion and, most of the time variance is a synonym for risk. |
| 128 | +# The higher the variance of an asset price, the higher risk the asset bears along with a higher return and a higher volatility |
| 129 | +# The lower the variance of an asset price, the lower risk the asset bears along with a lower return and a lower volatility |
| 130 | + |
| 131 | +# Variance measures the stocks volatility if you take the square root, e.g. sqrt(variance) = σ = volatility = standard deviation |
| 132 | +# NOTE: Volatility is the degree of variation of a trading price series over time as measured by the standard deviation of logarithmic returns. |
| 133 | +# Show the covariance matrix for simple returns |
| 134 | +daily_simple_returns.cov() |
| 135 | + |
| 136 | +# Show the variance |
| 137 | +daily_simple_returns.var() |
| 138 | + |
| 139 | +# Print the standard deviation σ (or volatility or sqrt(variance)) for daily simple returns |
| 140 | +print("The Stock Volatility:") |
| 141 | +daily_simple_returns.std() |
| 142 | + |
| 143 | +# Visualize the stocks daily simple returns / volatility and see how the stocks compare to each other |
| 144 | +plt.figure(figsize=(12,4.5)) #Set the figure size (width, height) |
| 145 | + |
| 146 | +# Loop through each stock and plot the simple returns for each day |
| 147 | +for c in daily_simple_returns.columns.values: |
| 148 | + plt.plot(daily_simple_returns.index, daily_simple_returns[c], lw=2, label=c)#plt.plot( X-Axis , Y-Axis, line_width, alpha_for_blending, label) |
| 149 | + |
| 150 | +# Place the legend in the upper left corner with font size of 10 |
| 151 | +plt.legend(loc='upper right', fontsize=10) |
| 152 | + |
| 153 | +plt.title('Volatility') |
| 154 | +plt.ylabel('Daily Simple Returns') #Label the Y-axis simple returns |
| 155 | +plt.xlabel('Date') |
| 156 | +plt.show() |
| 157 | + |
| 158 | +# Show the mean / average of the daily simple return |
| 159 | +dailyMeanSimpleReturns = daily_simple_returns.mean() |
| 160 | + |
| 161 | +# Print the daily mean simple return |
| 162 | +print("The daily mean simple return: ") |
| 163 | +print(dailyMeanSimpleReturns) |
| 164 | + |
| 165 | +# Calculate the expected portfolio daily performance with random weights |
| 166 | +# [0.4, 0.1, 0.3,0.1,0.1] => 40% FB, 10% AMZN, 30% AAPL, 10% NFLX, 10% GOOG |
| 167 | +randomWeights = np.array([0.4, 0.1, 0.3,0.1,0.1]) |
| 168 | +portfolioSimpleReturn = np.sum(dailyMeanSimpleReturns*randomWeights) #NOTE: Be sure to account for rounding of decimal |
| 169 | + |
| 170 | +# Print the daily expected portfolio return |
| 171 | +print("The daily expected portfolio return: " +str(portfolioSimpleReturn)) |
| 172 | + |
| 173 | +# Get the yearly simple return, we multiply by 253 instead of 365 because their are approximately 253 trading days in a year |
| 174 | +# The NYSE and NASDAQ average about 252 or 253 trading days a year. In 2018 there were 252 trading days in 2020 there will be 253. |
| 175 | +# This is from 365.25 (days on average per year) * 5/7 (proportion work days per week) - 6 (weekday holidays) - 3*5/7 (fixed date holidays) = 252.75 ≈ 253. |
| 176 | +# Print the expected annual portfolio simple return |
| 177 | +print("Expected annualised portfolio simple return : "+ str(portfolioSimpleReturn * 253)) |
| 178 | + |
| 179 | +# Calculate the growth of our investment or in other words, |
| 180 | +# calculate the total returns from our investment,to do this we need to calculate the cumulative returns |
| 181 | +# from that investment. |
| 182 | +# The Daily cumulative simple return for n-periods: |
| 183 | +# The simple return from period_1 + 1 times the simple return from period_2 + 1 times ... the simple return from period_n |
| 184 | +# (1+simple_return_1) * (1+simple_return_2) * ... *(1+simple_return_n) |
| 185 | +# Example: (daily_simple_returns["GOOG"][1] + 1) * (daily_simple_returns["GOOG"][2] + 1) = 1.020353 |
| 186 | +# 0.000581 * 0.019760 = 1.020353 |
| 187 | +dailyCumulSimplReturn = (daily_simple_returns+1).cumprod() |
| 188 | +# Show the cumulative simple return |
| 189 | +dailyCumulSimplReturn |
| 190 | + |
| 191 | +# Visualize the daily cumulative simple returns |
| 192 | +fig = plt.figure(figsize=(12.2,4.5)) |
| 193 | +for c in dailyCumulSimplReturn.columns.values: |
| 194 | + plt.plot(dailyCumulSimplReturn.index, dailyCumulSimplReturn[c], lw=2, label=c)#plt.plot( X-Axis , Y-Axis, line_width, alpha_for_blending, label) |
| 195 | + |
| 196 | +# Place the legend in the upper left corner with font size of 10 |
| 197 | +plt.legend(loc='upper left', fontsize=10) |
| 198 | +plt.xlabel("Date") |
| 199 | +plt.ylabel("Growth of $1 investment") |
| 200 | +plt.title("Daily Cumulative Simple Returns") |
| 201 | +plt.show() |
0 commit comments