Python Forum
3 Finance Python Exercises
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
3 Finance Python Exercises
#1
Disclaimer: I receive participation credit for obtaining the answers to the following three problems. This is a finance course, not a python course, thus we are allowed to use any medium (including going to the professor's office and asking what the answers are) to solve the following three problems, so long as we find the answers. Thank you in advance!

1. (Use futures_prices.py)Assuming the same realized die rolls, calculate all of the spot market and futures prices in the experiment:

(a) if dividends were selected from {-4,-2,2,4} instead of {-2,-1,1,2}.
(b) if dividends were as in the experiment, but there were 5 periods instead of 4

2. (Use RiskMgmt_p3.py) Calculate (1) the standard deviation and (2) the 5% VaR of an equally weighted portfolio of

(a) American Airlines, United/Continental, Delta Airlines
(b) Exxon, Tesla, McDonalds

3. (Use RiskMgmt_p4.py) (1) Plot the PDF of earnings from the trucking example, and (2) calculate the 5% VaR, if the firm enters into the futures contract for 10 million barrels of oil and purchases the options for 5 barrels of oil.

futures_prices.py:
# -*- coding: utf-8 -*-
"""
Created on Wed Sep 13 10:09:16 2017

@author: LoweryR
"""

import numpy as np

numper = 4 #define number of periods (NOT USED; INCLUDED TO EXTEND TO MORE PERIODS LATER)
div = (-2,-1,1) # Establish 3 of the 4 dividends
div = np.append(div,-np.sum(div)) # Set the 4th dividend so E[d]=0
scrap = 6
persist = 1/2 # probability that the dividend persists


# report the dividend in period 1
p = (4,2,2,3) # ENTER 1, 2, 3, 4, (THE DIE ROLL) NOT THE ACTUAL DIVIDEND
d = np.zeros(numper)
for i in range(0,numper): # This is an inefficient and inelegant way to do this task...
d[i] = div[p[i]-1] # Extract the correct dividend; note that the first element is designated 0

# Define an upper triangular matrix such that the diagonals are the spot prices in each period
# and the remaining elements are the (column) period price during the (row) period

price = np.triu(scrap*np.ones((numper,4))) # Initialize price matrix

# Note first that the first row (indexed by zero) is just the scrap value

# Now, in each period after the first (row, indexed by i), add the expected value of the LAST period dividend, given the dividend in the immediately prior period
for i in range(1,4):
price[i] = price[i] + np.append(np.zeros(i),np.ones(4-i)*np.power(persist,4-i)*d[i-1])

# Now, for all except the last period, add in the expected second to last period (third period) dividend
for i in range(1,3):
price[i] = price[i] + np.append(np.append(np.zeros(i),np.ones(3-i)*np.power(persist,3-i)*d[i-1]),np.zeros(1))

# Now, for all except the last period and second to last period, add in the expected second period dividend
for i in range(1,2):
price[i] = price[i] + np.append(np.append(np.zeros(i),np.ones(2-i)*np.power(persist,2-i)*d[i-1]),np.zeros(2))

print(price)

# We now want to calculate the expected price during period 2 (i.e., what we expect when we are trading during the period 2 market), of the
# period 3 futures price for period 4 delivery.

# What we are trying to calculate can be represented by E[E[scrap+x_4|x_2]|x_1]. That is, given the period 1 dividend, what do we expect the expected price
# for period 4 to be in period 3.

efutprice = 6 + persist*((np.power(persist,2)*d[0]))+(1-persist)*((1/4)*np.power(persist,2)*div[0]+(1/4)*np.power(persist,2)*div[1]+(1/4)*np.power(persist,2)*div[2]+(1/4)*np.power(persist,2)*div[3])
print(efutprice)

RiskMgmt_p3.py:
# -*- coding: utf-8 -*-
"""
created by Nicole Liu on 07/10/2017
updated by Nicole Liu on 07/14/2017
purpose: solve example on slide 22 of Risk Management
"""


import pandas_datareader.data as web
import datetime
import numpy as np
import pandas as pd
from scipy.stats import norm

# change the following specification as you wish
ticker = ["AAPL", "MCD", "BAC"] # remember to change dimension of "weights" if you want to have more than 3 stocks
start = datetime.datetime(2012, 7, 10)
end = datetime.datetime(2017, 7, 10)
weights = np.asarray([0.5,0.2,0.3]) # weights must sum up to 1

# pull data from Google and clean up
rawData = web.DataReader(ticker, 'google', start, end) # pull data
cleanData = rawData['Close'] # select only the column of closing price
prices = pd.DataFrame(cleanData) # convert series to dataframe format for subsequent manipulation

# calculate daily stock return and portfolio return
daily_ret = prices.pct_change(1) # calculate daily return as percentage change
daily_ret = daily_ret[1:] # drop the first row which contains missing values
temp = daily_ret * weights # multiply stock return with portfolio weights
port_ret = temp.sum(axis=1) # sum over rows to obtain daily portfolio return

# the right way to calculate portfolio VAR: resample from the portfolio return series
print('(correct answer) 5% cutoff lose:',np.percentile(port_ret, 5)) # find the 5th percentile
print('(correct answer) 1% cutoff lose:',np.percentile(port_ret, 1)) # find the 1th percentile

# compare: the wrong way to calculate portfolio VAR: resample from the stock return series assuming independence
temp1 = np.percentile(daily_ret, 5, axis=0) * weights
temp2 = np.percentile(daily_ret, 1, axis=0) * weights
print('(wrong answer) 5% cutoff lose:',temp1.sum())
print('(wrong answer) 1% cutoff lose:',temp2.sum())

RiskMgmt_p4.py:
# -*- coding: utf-8 -*-
"""
created by Nicole Liu on 07/10/2017
purpose: reproduce example on slide 23-30 of Risk Management
note: need to revise plot for options hedging
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

rev = 1100 # expected revenue
n = 15 # amount of oil consumed
mean_oil = 70 # mean of oil price per barrel
std_oil = 7 # std of oil price per barrel
call_price = 5 # cost of call option
cutoff = 0.95


# define a function for custom subplots with axes throught the origin
def subplots():
fig, ax = plt.subplots()
for spine in ['left', 'bottom']:
ax.spines[spine].set_position('zero')
for spine in ['right', 'top']:
ax.spines[spine].set_color('none')
return fig, ax


# case 1 - no hedging
plt.close("all") # close any other graph currently open
fig, ax = subplots() # use subplots to line up two graphs on the x-axis
x = np.linspace(-250, 250, 500) # define min and max values on the x-axis
mean_earnings = rev - n*mean_oil
std_earnings = n*std_oil
print('No hedging cutoff lose:',norm.ppf(0.05, loc=mean_earnings, scale=std_earnings)) # cutoff lose using inverse cdf
y1 = norm.pdf(x, loc=mean_earnings, scale=std_earnings) # pdf with the mean and std calculated above
ax.plot(x, y1, linewidth=2, alpha=0.6, label='No Hedging') # plot graph
ax.legend(loc='upper right') # add legend
plt.savefig('slide23NoHedging') # save graph
plt.show() # show graph on screen


# case 2 - forward hedging, covering 10m barrels
plt.close("all") # close any other graph currently open
fig, ax = subplots() # use subplots to line up two graphs on the x-axis
x = np.linspace(-250, 250, 500) # define min and max values on the x-axis
mean_earnings = rev - n*mean_oil
std_earnings = (n-10)*std_oil
print('Forward hedging cutoff lose:',norm.ppf(0.05, loc=mean_earnings, scale=std_earnings)) # cutoff lose using inverse cdf
y2 = norm.pdf(x, loc=mean_earnings, scale=std_earnings) # pdf with the mean and std calculated above
ax.plot(x, y2, linewidth=2, alpha=0.6, label='Forward Hedging') # plot graph
ax.legend(loc='upper right') # add legend
plt.savefig('slide23ForwardHedging') # save graph
plt.show() # show graph on screen


# case 3 - options hedging, covering 10m barrels
plt.close("all") # close any other graph currently open
fig, ax = subplots() # use subplots to line up two graphs on the x-axis
x = np.linspace(-250,250, 500) # define min and max values on the x-axis
mean_earnings = rev - n*mean_oil - 10*call_price # mean earnings is the same no matter oil prices falls or rises
std1_earnings = n*std_oil # if oil price falls below 70
std2_earnings = (n-10)*std_oil # if oil price rises above 70
print('Options hedging cutoff lose:',norm.ppf(0.05, loc=mean_earnings, scale=std2_earnings)) # cutoff lose (left tail hence std2)
y3left = norm.pdf(x, loc=mean_earnings, scale=std2_earnings)
y3right = norm.pdf(x, loc=mean_earnings, scale=std1_earnings)
y3 = y3left * (x<0) + y3right * (x>=0)
ax.plot(x, y3, linewidth=2, alpha=0.6, label='Options Hedging')
ax.legend(loc='upper right') # add legend
plt.savefig('slide23OptionsHedging') # save graph
plt.show() # show graph on screen


# all together
plt.close("all") # close any other graph currently open
fig, ax = subplots() # use subplots to line up all three graphs on the x-axis
x = np.linspace(-250, 250, 500) # define min and max values on the x-axis
ax.plot(x, y1, linewidth=2, alpha=0.6, label='No Hedging') # plot case 1
ax.plot(x, y2, linewidth=2, alpha=0.6, label='Forward Hedging') # plot case 2
ax.plot(x, y3, linewidth=2, alpha=0.6, label='Options Hedging') # plot case 3
ax.legend(loc='upper right') # add legend
plt.savefig('slide23All') # save graph
plt.show() # show graph on screen
Reply
#2
use code tags read: BBCODE
when posting code, use shift-ctrl-v so that indentation is preserved.
Reply
#3
Normally, this is where we say (despite your 'Disclaimer') "We will help and guide you, but we will not write the code for you.", however, it's seems you already have the code, so after you post the code correctly, perhaps you could let us know what exactly you are looking for.
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python for finance Not_skilled_at_all 11 4,883 Aug-03-2022, 04:14 PM
Last Post: deanhystad
  Help me with yahoo finance excel sheet Learner4life 2 2,271 Nov-27-2019, 12:55 PM
Last Post: Learner4life
  Python with Finance - i have no code but don't do it for me give me tips please Akainu 1 2,381 May-30-2019, 07:57 PM
Last Post: nilamo
  Some exercises I need help with. Beginner_coder123 2 2,805 Dec-02-2018, 06:21 PM
Last Post: ichabod801
  Mission Impossible : New to Python and 3 days to do theses exercises Kangaaxx 6 3,718 Aug-16-2018, 05:58 PM
Last Post: Kangaaxx
  One of my exercises is breaking my balls. Jei 14 13,686 Dec-03-2016, 03:35 PM
Last Post: Jei

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020