<jupyter_start><jupyter_text>Investment Management 1--- Assignment 1 (hints)**This Colab notebook contains useful tips and hints for Assignment 1. To get started, create a copy of the notebook and save it on your Google drive.** **Part 1: Obtaining financial data [10 pt]**The purpose of this section is to get you used to the basics of Python and the Colab notebook environment. This includes importing data and working with variables, lists, dataframes, and functions.Your code will be checked for clarity and efficiency. If you have trouble with this part of the assignment, please review the introductory Colab notebooks stored in the GitHub course repository. Part 1.1. Loading historical stock prices (6pt)Using any Python financial data library (e.g. `yfinance`) download daily adjusted close prices for 5 U.S. stocks of your choice for the last 5 years and store them in a `pandas` DataFrame object named `stock_prices`. Only stocks that are current constituents of the S&P 500 should be considered.&nbsp;As the financial data library you use is not pre-installed in Google Colab by default, make sure to install it first by executing the following code:```!pip install library_name```The !pip install  command looks for the latest version of the package and installs it. This only needs to be done once per session.If you are unable to install the required library to fetch the data, you can prepare a separate CSV file containing the necessary data and use the following code to read it into a `pandas` dataframe object:```from google.colab import filesfiles.upload()```followed by:```import pandas as pdstock_prices = pd.read_csv('filename.csv')```Note that `filename.csv` should be changed to the exact name of your CSV file.<jupyter_code># step 1: install required libraries using "!pip install"
!pip install ffn
# step 2: import required libraries using "import"
import ffn
import pandas as pd
import numpy as np
# step 3: fetch historical asset prices
start_date = '2016-01-01'
end_date = '2020-12-31'

stock_prices = ffn.get('MSFT, AAPL', start=start_date, end=end_date)
stock_prices.head()<jupyter_output><empty_output><jupyter_text>Part 1.2. Obtaining data on risk-free asset (4pt)Using a financial data library (e.g. `yfinance`) of your choice, obtain daily data on the U.S. risk-free (1-month Treasury Bill) rate for the last 5 years and store them in a `pandas` DataFrame object named `rf`.If you are unable to obtain the risk-free data using your chosen data library, you can prepare a separate CSV file containing the necessary data and use the steps discussed above to read it into a `pandas` dataframe object `rf`.<jupyter_code># step 4: fetch historical risk-free rate
url = 'https://raw.githubusercontent.com/mscouse/TBS_investment_management/main/1_labs_introduction/FF_factors_daily.csv'

rf = pd.read_csv(url, index_col=['date'])
rf.index = pd.to_datetime(rf.index, format='%Y%m%d')

rf.drop(['MRK-RF', 'SMB', 'HML'], axis=1, inplace=True)
rf['RF_dec'] = rf['RF']/100

rf.describe()<jupyter_output><empty_output><jupyter_text>**Part 2: Visualising historical asset prices [10pt]**In this part of the assignment, you will be manipulating dataframes containing historical asset prices using Pandas, and visualising them using a Python plotting library of your choice. The purpose of these visualisations is to help you explore the data and identify any patterns. One robust visualisation library you may want to consider is `Matplotlib`. It is one of the most popular, and certainly the most widely used, multi-platform data visualisation library built on NumPy arrays in Python. It is used to generate simple yet powerful visualisations with just a few lines of code. It can be used in both interactive and non-interactive scripts.Make sure you import the required libraries first. Part 2.1. Raw stock prices (4pt)Plot the adjusted daily close prices for your stocks on the same diagram using a Python data visualisation library of your choice (default is matplotlib). Use the historical price data stored in the `stock_prices` dataframe created earlier.<jupyter_code># step 5: import required data visualisation library
%matplotlib inline
stock_prices.plot(title='Stock Prices', ylabel='Price', figsize=(10, 8))<jupyter_output><empty_output><jupyter_text>Part 2.1. Rebased stock prices (6pt)To make comparing and plotting different asset price series together easier, we often "rebase" all prices to a given initial value - e.g. 100. In this section, you need to rebase the adjusted close prices for your stocks and plot them on the same diagram using a visualisation library of your choice (default is matplotlib). Note that some financial data libraries have handy built-in functions to perform this kind of task. Have a look at the `ffn` library  documentation .<jupyter_code># step 6: import required data visualisation library
stock_prices.rebase().plot(title='Stock Prices', ylabel='Price', figsize=(10, 8))<jupyter_output><empty_output><jupyter_text>**Part 3: Absolute return and risk measures [40pt]**In this part of the assignment, you will work with basic financial calculations and functions, such as computing and compounding investment returns, calculating averages, and computing measures of investment risk.I suggest you use `pandas` dataframes to store all necessary data. Colab includes an extension that renders Pandas dataframes into interactive tables that can be filtered, sorted, and explored dynamically.The extension can be enabled by executing `%load_ext google.colab.data_table` in any code cell and disabled with `%unload_ext google.colab.data_table`.  3.1. Stock returns (6pt)In asset management, we are often interested in the returns of a given time series. Therefore, in this part of the assignment, you need to compute **daily**, **weekly**, and **monthly** **arithmetic and logarithmic** returns for each chosen stock and store them in separate `pandas` dataframe objects named `returns` and `log_returns`, respectively.Make sure to drop any missing values and display the first 5 lines of the resulting dataframes.<jupyter_code># step 7: import required data visualisation library
# A: resample daily stock prices into weekly and monthly
stock_prices_weekly = stock_prices.resample('W').ffill()
stock_prices_monthly = stock_prices.resample('M').ffill()

# B: compute ordinary returns
daily_returns = stock_prices.pct_change().dropna()
weekly_returns = stock_prices_weekly.pct_change().dropna()
monthly_returns = stock_prices_monthly.pct_change().dropna()

# C: compute log returns
daily_log_returns = np.log(stock_prices/stock_prices.shift(1)).dropna()
weekly_log_returns = np.log(stock_prices_weekly/stock_prices_weekly.shift(1)).dropna()
monthly_log_returns = np.log(stock_prices_monthly/stock_prices_monthly.shift(1)).dropna()

# D: report all returns
list_of_returns = [(daily_returns, 'Daily Returns'), (weekly_returns, 'Weekly Returns'), (monthly_returns, 'Monthly Returns'), (daily_log_returns, 'Daily Logarithmic Returns'), (weekly_log_returns, 'Weekly Logarithmic Returns'), (monthly_log_returns, 'Monthly Logarithmic Returns')]

for df, title in list_of_returns:
  print(title)
  print(df.head())<jupyter_output><empty_output><jupyter_text>3.2. Distribution of returns (5pt)Check what the return distributions look like by plotting a histogram of daily returns calculated in the previous section. You can use any Python visualisation library of your choice.Plot returns distributions for both, arithmetic and logarithmic returns. Discuss whether there are significant differences between the two. Also, provide a short explanation on when and why we use log returns, rather than normal returns.<jupyter_code># step 8: import required data visualisation library
for df, title in list_of_returns:
  df.plot(kind='hist', title=title, subplots = True, figsize=(10, 8), legend=True, bins=30, alpha=0.5)<jupyter_output><empty_output><jupyter_text>**Your response/ short explanation:** ________HERE_________  3.3. Correlation matrix (5pt)Using daily arithmetic stock returns, compute pairwise correlations between your 5 assets and plot a correlation matrix. (optional) You may want to have a look at the `heatmap()` method in the `Seaborn` visualisation library. It allows you to create elegant correlation heatmaps easily.<jupyter_code># step 9: import required data visualisation library
daily_returns.corr()<jupyter_output><empty_output><jupyter_text>3.4. Cumulative returns (8pt)Using the arithmetic daily returns, compute cumulative returns for each stock over the last 1–, 3-, and 5- year periods and display them as values. Once done, annualise the resulting cumulative daily returns for each stock and display them as well.<jupyter_code># step 10: import required data library (returns are not annualised in this example)
start_date = [('2016-01-01', '5-year cumulative'), ('2018-01-01', '3-year cumulative'), ('2020-01-01', '1-year cumulative')]

for date, period in start_date:
  comp_returns = (daily_returns[(daily_returns.index>=date)]+1).prod()-1
  print(period)
  print(comp_returns)<jupyter_output><empty_output><jupyter_text>3.5. Arithmetic average returns (8pt)Compute arithmetic average daily returns for each stock, annualise them, and display the resulting values. As there are typically 252 trading days in a year, to annualise a daily return $r_d$ we use:$$ (1+r_d)^{252} - 1$$<jupyter_code># step 11: import required data visualisation library
(1+daily_returns.mean())**252-1<jupyter_output><empty_output><jupyter_text>3.6. Standard deviation (8pt)Using the stock returns calculated earlier, compute standard deviations of daily returns for each stock over the last 1–, 3-, and 5- year periods and display them.Once done, repeat the calculation of standard deviations but using monthly returns instead. Display the resulting values.Explain what the best way to annualise standard deviations is.<jupyter_code># step 12: import required data visualisation library
start_date = [('2016-01-01', '5-year std'), ('2018-01-01', '3-year std'), ('2020-01-01', '1-year std')]

for date, period in start_date:
  print(period)
  print('daily', daily_returns[(daily_returns.index>=date)].std(), sep="\n")
  print('monthly', monthly_returns[(monthly_returns.index>=date)].std(), sep="\n")<jupyter_output><empty_output><jupyter_text>**Your response/ short explanation:** ________HERE_________ **Part 4: Risk-adjusted performance evaluation [40pt]**As part of the course we considered several risk-adjusted performance evaluation measures. In this section of the assignment you are asked to compute one of them - the Sharpe ratio: $$Sharpe\ ratio = \frac{E[{r_p}-{r_f}]}{\sqrt{[{r_p}-{r_f}]}}$$  Part 4.1. Calculating the Sharpe measure [10pt]Using previously calculated monthly stock returns and the corresponding risk-free interest rates, compute Sharpe ratios for your selected stocks for the last 1-, 3-, and 5-years. Annualise the calculated Sharpe measures and report them as values.<jupyter_code># step 13: import required libraries
# See the Sharpe_example.ipynb notebook in the course GitHub repository:
# https://github.com/mscouse/TBS_investment_management/blob/main/1_labs_introduction/Sharpe_example.ipynb<jupyter_output><empty_output><jupyter_text>Part 4.2. Sharpe measure function [30pt]Define a new Python function `sharpe(ticker_1, ticker_2, ticker_3)` which:*  accepts 3 stock tickers as the only arguments;*  fetches historical daily prices for the 3 selected tickers over the last 3 years;*  fetches U.S. treasury bill (1-month T-Bill rates) rates over the corresponding 3 year period;* computes daily returns and excess returns for each stock;* computes daily average excess returns for each stock;* computes standard deviations of excess daily returns for each stock;* compute Sharpe ratios based on the daily average excess returns and standard deviations of excess retunrs;* annualises the resulting Sharpe ratio (by multiplying the daily Sharpe by $\sqrt[2]{252}$);* returns the annualised Sharpe ratios for the 3 stocks.Assume that all libraries required by your function are already preinstalled and imported (i.e. do not include any `import` statements within your function). However, make sure to import all the required libraries in the code cell below, directly before the function.<jupyter_code># step 14: install required libraries and import as needed

def sharpe(ticker_1, ticker_2, ticker_3):
  """ Provide description of what this function does.

  Args:
    ticker_1 (str): ticker for stock 1
    ticker_2 (str): ticker for stock 2
    ticker_3 (str): ticker for stock 3 
  
  Returns:
    This function returns annualised Sharpe 
    ratios for arg tickers using last 3 years
    of data from Yahoo finance

  Notes: provide any required notes/comments here
  """

  # YOUR CODE HERE
  # YOUR CODE HERE
  return # YOUR CODE HERE

# execute your functions using AAPL, MSFT, and JPM as arguments
import datetime as dt
import ffn

def simple_sharpe(num_of_years, ticker='AAPL', *args):
  """ 
  Args:
    num_of_years (int): period to consider relative today 
    ticker (str): ticker for stock 1; default value = 'AAPL'
    *args (str, optional): tickers for further stocks
  
  Returns:
    This function returns annualised Sharpe 
    ratios for arg tickers and specified period.
    All data are from Yahoo finance.
  """
  end_date = dt.datetime.now()
  start_date = dt.datetime(end_date.year-num_of_years, month=end_date.month, day=end_date.day)
  tickers = [ticker, *args]

  df = ffn.get(tickers, start=start_date, end=end_date)
  ret = df.pct_change().dropna()
  sharpe = ret.mean()/ret.std()
  annual_sharpe = sharpe*np.sqrt(252)
  return annual_sharpe
simple_sharpe(5, 'msft', 'jpm', 'gs', 'ko', 'aal')
# Alternative relative date

end_date = dt.datetime.now()
num_of_years = 3
tds = pd.Timedelta(weeks=num_of_years*52)

start_date = end_date-tds
start_date<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08317757009345794, 'fraction_numerical': 0.016606757728253055, 'mean_word_length': 5.546352941176471, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 52, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '322349', 'license': 'MIT', 'n_tokens_mistral': 4118, 'n_tokens_neox': 3837, 'n_words': 1676, 'path': '2_assignment_1/PM_assignment_1_hints.ipynb', 'repo_name': 'CLARAAAAZ/TBS_portfolio_management', 'size': '13910'}