<jupyter_start><jupyter_text>Baruch IMG Portfolio Management Risk<jupyter_code>import PortHelp
import json
from pprint import PrettyPrinter, pprint

# Data manipulation 
import numpy as np
import pandas as pd
import time as t

# Plotting
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline 

# Stock Pulling  
from alpha_vantage.timeseries import TimeSeries

# Google Sheet Authorization
import gspread
from oauth2client.service_account import ServiceAccountCredentials<jupyter_output><empty_output><jupyter_text>For more information on the alpha_vantage api or the python wrapper feel free to read the documentation provided- AV API Docs https://www.alphavantage.co/documentation/- Python Wrapper by Romel https://github.com/RomelTorres/alpha_vantage**NOTE that AV API limits call requests to 5 calls to server a minute - an adapter is built in to counter**<jupyter_code>api_key = "API-KEY" #Alpha vantage api-key recieived throguh the service<jupyter_output><empty_output><jupyter_text>Risk Management Helper Functions<jupyter_code># data columns present from timeseries pull by Alpha Vantage API
data_columns = ['1. open', '2. high', '3. low', '4. close', '5. adjusted close', 
                '6. volume', '7. dividend amount', '8. split coefficient']
def stock_puller(ticker_list: list, col: str, outputsize: str = 'compact', length = 252):
    """
    Extracts stock/security data from Alpha Vantage
    :param ticker_list: a list of tickers for data to be extracted eg: ['SPY', 'GOOG', 'AAPL']
    :param col: provided string to extract the desired column type, illustrated in column_desc list
    :param outputsize: 'compact' = 100 most recent, 'full' = historical security list
    :return: returns a dataframe object with relevant timeseries data (index by date, column ticker symbols)
    """
    big_dict = {}
    ts = TimeSeries(key=api_key, output_format='pandas', retries=10) # function call from Python wrapper to extract timeseries 
    
    for ticker in ticker_list:
        # iterates through the security list provided and extracts relevant timeseries information
        data = ts.get_daily_adjusted(symbol=ticker, outputsize=outputsize)[0][col]

        big_dict[ticker] = data[-length:].tolist()  # dictionary storing security time series for faster concatination 
        t.sleep(12)
        
    big_df = pd.DataFrame.from_dict(data=big_dict)  # returns large dataframe for list of securities
    return big_df
def google_api():
    # use creds to create a client to interact with the Google Drive API
    scope = ['https://spreadsheets.google.com/feeds']
    creds = ServiceAccountCredentials.from_json_keyfile_name('GOOGLE-AUTHfile.json', 
                                                             scope)
    client = gspread.authorize(creds)
    
    sheet = client.open("WORRKBOOK NAME").sheet2
    
    result = sheet.get_all_records()
    print(result)
# with open('GOOGLE-AUTHfile.json') as f:
#     data = json.load(f)
#     pprint(data)
def log_returns(price_df: pd.DataFrame):
    """
    Extracts the log returns for relevant price data
    :param price_df: a dataframe object storing price values for a given underlying (index by date, column ticker symbols)
    :return: a dataframe for log returns of select securities
    """
    big_dict = {}

    for ticker in price_df.columns:
        # iterates through the security list provided and extract provided values via dict manipulation
        security_list = price_df[ticker]
        log = np.log(security_list.values) - np.log(np.roll(security_list.values, 1))  # computes log return 
        big_dict[ticker] = log[1:].tolist() # eliminates the first NaN row and returns list from ndarray

    big_df = pd.DataFrame.from_dict(data=big_dict) # dataframe index by data column all ticker symbols
    return big_df
def linear_returns(price_df: pd.DataFrame):
    """
    Extracts the linear returns for relevant price data 
    :param price_df: a dataframe object storing price values for a given underlying (index by date, column ticker symbols)
    :return: a dataframe for linear returns of select securities
    """
    big_dict = {}

    for ticker in price_df.columns:
        # iterates through the security list provided and extract provided values via dict manipulation
        linear_ret = price_df[ticker].pct_change() # pct_change pandas function for linear returns
        big_dict[ticker] = linear_ret[1:].tolist() # eliminates the first NaN row and returns list from ndarray 

    big_df = pd.DataFrame.from_dict(data=big_dict) # dataframe index by data column all ticker symbols
    return big_df
def volatility(price_df: pd.DataFrame, rolling_window: int = 10):
    """
    Extracts the rolling standard deviation of log returns for price data
    :param price_df: a dataframe object storing price values for a given underlying (index by date, column ticker symbols)
    :param rolling_window: the length to which rolling standard deviation is taken 
    :return: a dataframe for linear returns of select securities
    """
    log_ret = log_returns(price_df)
    
    big_dict = {}

    for ticker in price_df.columns:
        # iterates through the security list provided and extract provided values via dict manipulation
        volatility = log_ret[ticker].rolling(rolling_window).std() # rolling standard deviation pandas function for log returns
        big_dict[ticker] = volatility[rolling_window-1:].tolist() # eliminates the NaN rows and returns list from ndarray 

    big_df = pd.DataFrame.from_dict(data=big_dict) # dataframe index by data column all ticker symbols
    return big_df<jupyter_output><empty_output><jupyter_text>======================================================================================================================== ========================================================================================================================  Data Wrangling (Portfolio Selection)<jupyter_code># list of securities you would like to gather information on eg: ['AMZN', 'FB', 'GOOG']
portfolio_list = ['ALB','AMZN','AEP','AWK','BAX','BCE','BX','BP',
                  'CP','CIM','CHD','EFX','EL','HII','LMT','NATI',
                  'OFC','RIO','ROP','RY','STI','WM','WY']
# dataframe storing ticker timeseires, index by time, with tickers for columns
data = stock_puller(ticker_list=portfolio_list, col='5. adjusted close', outputsize='full', length=252*5)
data.head()
exp_ret = pd.DataFrame(linear_returns(data).mean() * 252).transpose() # expected returns dataframe
exp_ret
cov = data.cov() # covariance matrix for calculations later
cov.head()<jupyter_output><empty_output><jupyter_text>Correlation Studies<jupyter_code>lr = log_returns(price_df=data).corr(method='pearson')
plt.figure(figsize=(15,10)) # adjusts the size of the plot for better viewin
plt.title('Log Return Correlation')
sns.heatmap(lr, annot=True) # plots heatmap 
vol = volatility(price_df=data).corr(method='pearson')
plt.figure(figsize=(15,10)) # adjusts the size of the plot for better viewing 
plt.title('Volatility Correlation')
sns.heatmap(vol, annot=True) # plots heatmap<jupyter_output><empty_output><jupyter_text>RIsk Management ModelsRisk is quantifiable both in absolute and in relative terms. A solid understanding of risk in its different forms can help investors to better understand the opportunities, trade-offs, and costs involved with different investment approaches. Our goal here is to quantify systemic risk associated with the portfolio<jupyter_code># Value-at-Risk
def VaR():
    return 1
# Conditional Value-at-Risk
def CVaR():
    return 1
def Beta():
    return 1<jupyter_output><empty_output><jupyter_text>Portfolio Metrics<jupyter_code>def Sharpe():
    return 1
def Sortino():
    return 1
def Treynor():
    return 1<jupyter_output><empty_output><jupyter_text>======================================================================================================================== ========================================================================================================================  Portfolio Optimization ModelsThe following scripts are used for optimizing a given portfolio in a purely quantitative scenario. Our goal is to construct models as to compare current portfolio weights, to help guide portfolio management and decisions regarding whether to sell positions believed to be theoretically overweight.<jupyter_code># Minimum variance portfolio (MVP)
def MVP(cov: np.matrix, mu: np.array):
    """
    Given target return, determine the weights of the portfolio with the smallest variance
    :param cov: provided covariance matrix for the underlying securities (np.matrix object)
    :param mu: expected returns/historical returns for underlying securities (np.array object)
    :return: a dict containing the weights of the provided portfolio
    """
    base = np.ones(len(mu[0]))
    inv = np.linalg.inv(cov.values)
    
    weights = (inv.dot(base)) / (base.dot(inv).dot(base))
    exp_return = (mu.dot(inv).dot(base)) / (base.dot(inv).dot(base))
    
    return weights, exp_return
# Market Portfolio Optimization (MPO)
def MPO(cov: np.matrix, mu: np.array, risk_free: float):
    """
    Given target return, determine the weights of the optimal market portfolio
    :param cov: provided covariance matrix for the underlying securities (np.matrix object)
    :param mu: expected returns/historical returns for underlying securities (np.array object)
    :param risk_free: current risk_free rate in 10 year bonds
    :return: a dict containing the weights of the provided portfolio
    """
    assert 0 < risk_free < 1

    base = np.ones(len(mu[0]))
    inv = np.linalg.inv(cov.values)
    
    weights = ((mu-risk_free*base).dot(inv)) / ((mu-risk_free*base).dot(inv).dot(base))
    
    return weights
# # Portfolio Optimization (Quadratic Programming)
# def port_opt():
#     return 1<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13295030742868663, 'fraction_numerical': 0.005745388569700635, 'mean_word_length': 4.478741027056874, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 33, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '344125', 'license': 'MIT', 'n_tokens_mistral': 2862, 'n_tokens_neox': 2688, 'n_words': 946, 'path': 'IMG_PM.ipynb', 'repo_name': 'PMenes/Baruch_IMG_Risk', 'size': '9921'}