my-markdown-library 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/F24LS_md/ Lecture 4 - Public.md +347 -0
- data/F24LS_md/Lecture 1 - Introduction and Overview.md +327 -0
- data/F24LS_md/Lecture 10 - Development_.md +631 -0
- data/F24LS_md/Lecture 11 - Econometrics.md +345 -0
- data/F24LS_md/Lecture 12 - Finance.md +692 -0
- data/F24LS_md/Lecture 13 - Environmental Economics.md +299 -0
- data/F24LS_md/Lecture 15 - Conclusion.md +272 -0
- data/F24LS_md/Lecture 2 - Demand.md +349 -0
- data/F24LS_md/Lecture 3 - Supply.md +329 -0
- data/F24LS_md/Lecture 5 - Production C-D.md +291 -0
- data/F24LS_md/Lecture 6 - Utility and Latex.md +440 -0
- data/F24LS_md/Lecture 7 - Inequality.md +607 -0
- data/F24LS_md/Lecture 8 - Macroeconomics.md +704 -0
- data/F24LS_md/Lecture 8 - Macro.md +700 -0
- data/F24LS_md/Lecture 9 - Game Theory_.md +436 -0
- data/F24LS_md/summary.yaml +105 -0
- data/F24Lec_MD/LecNB_summary.yaml +206 -0
- data/F24Lec_MD/lec01/lec01.md +267 -0
- data/F24Lec_MD/lec02/Avocados_demand.md +425 -0
- data/F24Lec_MD/lec02/Demand_Steps_24.md +126 -0
- data/F24Lec_MD/lec02/PriceElasticity.md +83 -0
- data/F24Lec_MD/lec02/ScannerData_Beer.md +171 -0
- data/F24Lec_MD/lec02/demand-curve-Fa24.md +213 -0
- data/F24Lec_MD/lec03/3.0-CubicCostCurve.md +239 -0
- data/F24Lec_MD/lec03/3.1-Supply.md +274 -0
- data/F24Lec_MD/lec03/3.2-sympy.md +332 -0
- data/F24Lec_MD/lec03/3.3a-california-energy.md +120 -0
- data/F24Lec_MD/lec03/3.3b-a-really-hot-tuesday.md +121 -0
- data/F24Lec_MD/lec04/lec04-CSfromSurvey-closed.md +335 -0
- data/F24Lec_MD/lec04/lec04-CSfromSurvey.md +331 -0
- data/F24Lec_MD/lec04/lec04-Supply-Demand-closed.md +519 -0
- data/F24Lec_MD/lec04/lec04-Supply-Demand.md +514 -0
- data/F24Lec_MD/lec04/lec04-four-plot-24.md +34 -0
- data/F24Lec_MD/lec04/lec04-four-plot.md +34 -0
- data/F24Lec_MD/lec05/Lec5-Cobb-Douglas.md +131 -0
- data/F24Lec_MD/lec05/Lec5-CobbD-AER1928.md +283 -0
- data/F24Lec_MD/lec06/6.1-Sympy-Differentiation.md +253 -0
- data/F24Lec_MD/lec06/6.2-3D-utility.md +287 -0
- data/F24Lec_MD/lec06/6.3-QuantEcon-Optimization.md +399 -0
- data/F24Lec_MD/lec06/6.4-latex.md +138 -0
- data/F24Lec_MD/lec06/6.5-Edgeworth.md +269 -0
- data/F24Lec_MD/lec07/7.1-inequality.md +283 -0
- data/F24Lec_MD/lec07/7.2-historical-inequality.md +237 -0
- data/F24Lec_MD/lec08/macro-fred-api.md +313 -0
- data/F24Lec_MD/lec09/lecNB-prisoners-dilemma.md +88 -0
- data/F24Lec_MD/lec10/Lec10.2-waterguard.md +401 -0
- data/F24Lec_MD/lec10/lec10.1-mapping.md +199 -0
- data/F24Lec_MD/lec11/11.1-slr.md +305 -0
- data/F24Lec_MD/lec11/11.2-mlr.md +171 -0
- data/F24Lec_MD/lec12/Lec12-4-PersonalFinance.md +590 -0
- data/F24Lec_MD/lec12/lec12-1_Interest_Payments.md +267 -0
- data/F24Lec_MD/lec12/lec12-2-stocks-options.md +235 -0
- data/F24Lec_MD/lec13/Co2_ClimateChange.md +139 -0
- data/F24Lec_MD/lec13/ConstructingMAC.md +213 -0
- data/F24Lec_MD/lec13/EmissionsTracker.md +170 -0
- data/F24Lec_MD/lec13/KuznetsHypothesis.md +219 -0
- data/F24Lec_MD/lec13/RoslingPlots.md +217 -0
- data/F24Lec_MD/lec15/vibecession.md +485 -0
- data/F24Textbook_MD/00-intro/index.md +292 -0
- data/F24Textbook_MD/01-demand/01-demand.md +152 -0
- data/F24Textbook_MD/01-demand/02-example.md +131 -0
- data/F24Textbook_MD/01-demand/03-log-log.md +284 -0
- data/F24Textbook_MD/01-demand/04-elasticity.md +248 -0
- data/F24Textbook_MD/01-demand/index.md +15 -0
- data/F24Textbook_MD/02-supply/01-supply.md +203 -0
- data/F24Textbook_MD/02-supply/02-eep147-example.md +86 -0
- data/F24Textbook_MD/02-supply/03-sympy.md +138 -0
- data/F24Textbook_MD/02-supply/04-market-equilibria.md +204 -0
- data/F24Textbook_MD/02-supply/index.md +16 -0
- data/F24Textbook_MD/03-public/govt-intervention.md +73 -0
- data/F24Textbook_MD/03-public/index.md +10 -0
- data/F24Textbook_MD/03-public/surplus.md +351 -0
- data/F24Textbook_MD/03-public/taxes-subsidies.md +282 -0
- data/F24Textbook_MD/04-production/index.md +15 -0
- data/F24Textbook_MD/04-production/production.md +178 -0
- data/F24Textbook_MD/04-production/shifts.md +296 -0
- data/F24Textbook_MD/05-utility/budget-constraints.md +166 -0
- data/F24Textbook_MD/05-utility/index.md +15 -0
- data/F24Textbook_MD/05-utility/utility.md +136 -0
- data/F24Textbook_MD/06-inequality/historical-inequality.md +253 -0
- data/F24Textbook_MD/06-inequality/index.md +15 -0
- data/F24Textbook_MD/06-inequality/inequality.md +226 -0
- data/F24Textbook_MD/07-game-theory/bertrand.md +257 -0
- data/F24Textbook_MD/07-game-theory/cournot.md +333 -0
- data/F24Textbook_MD/07-game-theory/equilibria-oligopolies.md +96 -0
- data/F24Textbook_MD/07-game-theory/expected-utility.md +61 -0
- data/F24Textbook_MD/07-game-theory/index.md +19 -0
- data/F24Textbook_MD/07-game-theory/python-classes.md +340 -0
- data/F24Textbook_MD/08-development/index.md +35 -0
- data/F24Textbook_MD/09-macro/CentralBanks.md +101 -0
- data/F24Textbook_MD/09-macro/Indicators.md +77 -0
- data/F24Textbook_MD/09-macro/fiscal_policy.md +36 -0
- data/F24Textbook_MD/09-macro/index.md +14 -0
- data/F24Textbook_MD/09-macro/is_curve.md +76 -0
- data/F24Textbook_MD/09-macro/phillips_curve.md +70 -0
- data/F24Textbook_MD/10-finance/index.md +10 -0
- data/F24Textbook_MD/10-finance/options.md +178 -0
- data/F24Textbook_MD/10-finance/value-interest.md +60 -0
- data/F24Textbook_MD/11-econometrics/index.md +16 -0
- data/F24Textbook_MD/11-econometrics/multivariable.md +218 -0
- data/F24Textbook_MD/11-econometrics/reading-econ-papers.md +25 -0
- data/F24Textbook_MD/11-econometrics/single-variable.md +483 -0
- data/F24Textbook_MD/11-econometrics/statsmodels.md +58 -0
- data/F24Textbook_MD/12-environmental/KuznetsHypothesis-Copy1.md +187 -0
- data/F24Textbook_MD/12-environmental/KuznetsHypothesis.md +187 -0
- data/F24Textbook_MD/12-environmental/MAC.md +254 -0
- data/F24Textbook_MD/12-environmental/index.md +36 -0
- data/F24Textbook_MD/LICENSE.md +11 -0
- data/F24Textbook_MD/intro.md +26 -0
- data/F24Textbook_MD/references.md +25 -0
- data/F24Textbook_MD/summary.yaml +414 -0
- metadata +155 -0
@@ -0,0 +1,267 @@
|
|
1
|
+
---
|
2
|
+
title: "lec12-1_Interest_Payments"
|
3
|
+
type: lecture-notebook
|
4
|
+
week: 12
|
5
|
+
source_path: "/Users/ericvandusen/Documents/Data88E-ForTraining/F24Lec_NBs/lec12/lec12-1_Interest_Payments.ipynb"
|
6
|
+
---
|
7
|
+
|
8
|
+
<table style="width: 100%;">
|
9
|
+
<tr style="background-color: transparent;"><td>
|
10
|
+
<img src="https://data-88e.github.io/assets/images/blue_text.png" width="250px" style="margin-left: 0;" />
|
11
|
+
</td><td>
|
12
|
+
<p style="text-align: right; font-size: 10pt;"><strong>Economic Models</strong>, Fall 2024<br>
|
13
|
+
Dr. Eric Van Dusen <br>
|
14
|
+
</p></td></tr>
|
15
|
+
</table>
|
16
|
+
|
17
|
+
```python
|
18
|
+
import numpy as np
|
19
|
+
import matplotlib.pyplot as plt
|
20
|
+
import ipywidgets as widgets
|
21
|
+
from IPython.display import display
|
22
|
+
import plotly.graph_objects as go
|
23
|
+
```
|
24
|
+
|
25
|
+
## Mortgage Calculator
|
26
|
+
|
27
|
+
Lets build some widgets to allow you to select the
|
28
|
+
- Principal - amount of loan
|
29
|
+
- Interestes Rate - annual interest rate
|
30
|
+
- Years: - Years of Loan term ( usually 30 or 15)
|
31
|
+
|
32
|
+
You can consult BankRate to look up resonable rates
|
33
|
+
https://www.bankrate.com/mortgages/mortgage-rates/
|
34
|
+
|
35
|
+
```python
|
36
|
+
|
37
|
+
principal_widget = widgets.FloatSlider( value=200000, min=0, max=1000000, step=100, description='Principal:', readout_format='.0f', )
|
38
|
+
annual_interest_rate_widget = widgets.FloatSlider( value=0.05, min=0, max=0.25, step=0.001, description='Interest Rate:', readout_format='.2f', )
|
39
|
+
years_widget = widgets.IntSlider( value=30, min=1, max=50, step=1, description='Years:', readout_format='.0f', )
|
40
|
+
|
41
|
+
display(principal_widget, annual_interest_rate_widget, years_widget)
|
42
|
+
```
|
43
|
+
|
44
|
+
```python
|
45
|
+
#principal = 200000
|
46
|
+
#annual_interest_rate = 0.04
|
47
|
+
#years = 30
|
48
|
+
|
49
|
+
principal = principal_widget.value
|
50
|
+
annual_interest_rate = annual_interest_rate_widget.value
|
51
|
+
years = years_widget.value
|
52
|
+
```
|
53
|
+
|
54
|
+
# Formula for Mortgage Payment
|
55
|
+
|
56
|
+
$$ \text{Monthly Payment} = \frac{{\text{Principal} \cdot \left(\text{Monthly Interest Rate} \cdot \left(1 + \text{Monthly Interest Rate}\right)^{\text{Number of Payments}}\right)}}{{\left(1 + \text{Monthly Interest Rate}\right)^{\text{Number of Payments}} - 1}}
|
57
|
+
$$
|
58
|
+
|
59
|
+
## This is what we need to program into Python
|
60
|
+
|
61
|
+
```python
|
62
|
+
# Calculate monthly interest rate and number of payments
|
63
|
+
monthly_interest_rate = annual_interest_rate / 12
|
64
|
+
num_payments = years * 12
|
65
|
+
|
66
|
+
#Calculate monthly mortgage payment
|
67
|
+
monthly_payment = principal * (monthly_interest_rate * (1 + monthly_interest_rate)**num_payments) / ((1 + monthly_interest_rate)**num_payments - 1)
|
68
|
+
print('Monthly payment: $%.2f' % monthly_payment)
|
69
|
+
print('Total payment: $%.2f' % (monthly_payment * num_payments))
|
70
|
+
print('Total interest: $%.2f' % (monthly_payment * num_payments - principal))
|
71
|
+
print('Total Principal: $%.2f' % principal)
|
72
|
+
print('Interest to principal ratio: %.2f' % ((monthly_payment * num_payments - principal) / principal))
|
73
|
+
```
|
74
|
+
|
75
|
+
## Lets Build a dataset of the payments over time
|
76
|
+
- Each Monthly Payment has a share
|
77
|
+
- Principal paid each month
|
78
|
+
- Interest Payement eah month
|
79
|
+
|
80
|
+
### if we build this right we can graph the payments over the life of the loan
|
81
|
+
|
82
|
+
```python
|
83
|
+
payment_schedule = []
|
84
|
+
principal_schedule = []
|
85
|
+
interest_schedule = []
|
86
|
+
|
87
|
+
|
88
|
+
remaining_balance = principal
|
89
|
+
|
90
|
+
# This function will calculate the payments and share of interest and pricipal paid
|
91
|
+
for month in range(1, num_payments + 1):
|
92
|
+
interest_payment = remaining_balance * monthly_interest_rate
|
93
|
+
principal_payment = monthly_payment - interest_payment
|
94
|
+
remaining_balance -= principal_payment
|
95
|
+
payment_schedule.append(monthly_payment)
|
96
|
+
principal_schedule.append(principal_payment)
|
97
|
+
interest_schedule.append(interest_payment)
|
98
|
+
```
|
99
|
+
|
100
|
+
## Let's look at the composition of the first 5 and last 5 payments
|
101
|
+
|
102
|
+
```python
|
103
|
+
print("\nPayment Schedule for the first 5 months:")
|
104
|
+
for month in range(5):
|
105
|
+
print(f"Month {month + 1}: Payment ${payment_schedule[month]:.2f} (Principal ${principal_schedule[month]:.2f}, Interest ${interest_schedule[month]:.2f})")
|
106
|
+
print("\nPayment Schedule for the last 5 months:")
|
107
|
+
for month in range(num_payments - 5, num_payments):
|
108
|
+
print(f"Month {month + 1}: Payment ${payment_schedule[month]:.2f} (Principal ${principal_schedule[month]:.2f}, Interest ${interest_schedule[month]:.2f})")
|
109
|
+
```
|
110
|
+
|
111
|
+
## Now we will plot these payments over the 360 months of payback
|
112
|
+
|
113
|
+
```python
|
114
|
+
plot = go.Figure()
|
115
|
+
plot.add_trace(go.Scatter(y=principal_schedule, name="Principal"))
|
116
|
+
plot.add_trace(go.Scatter(y=interest_schedule, name="Interest"))
|
117
|
+
plot.add_trace(go.Scatter(y=payment_schedule, name="Payment"))
|
118
|
+
plot.update_layout(title="Mortgage Amortization Schedule", xaxis_title="Payment Number", yaxis_title="Payment")
|
119
|
+
plot.show()
|
120
|
+
```
|
121
|
+
|
122
|
+
## Let's do this for an investment instead of a mortgage
|
123
|
+
### We will calculate the future value of an investment
|
124
|
+
### Create widgets to specify the rates
|
125
|
+
### Slightly different than the Lab
|
126
|
+
|
127
|
+
```python
|
128
|
+
|
129
|
+
principal_widget = widgets.FloatSlider(value=1000, min=1, max=10000, step=1, description='Principal')
|
130
|
+
rate_widget = widgets.FloatSlider(value=0.05, min=0.01, max=0.2, step=0.01, description='Interest Rate')
|
131
|
+
time_widget = widgets.IntSlider(value=10, min=1, max=30, step=1, description='Time (Years)')
|
132
|
+
n_widget = widgets.IntSlider(value=12, min=1, max=365, step=1, description='Compounding Frequency')
|
133
|
+
display(principal_widget, rate_widget, time_widget, n_widget)
|
134
|
+
```
|
135
|
+
|
136
|
+
# Define a function to calculate future value
|
137
|
+
|
138
|
+
```python
|
139
|
+
def calculate_future_value(principal, rate, time, n):
|
140
|
+
years = np.arange(0, time + 1)
|
141
|
+
future_values = principal * (1 + rate / n) ** (n * years)
|
142
|
+
return years, future_values
|
143
|
+
|
144
|
+
# Calculate and plot the future value of the investment
|
145
|
+
years, future_values = calculate_future_value(principal_widget.value, rate_widget.value, time_widget.value, n_widget.value)
|
146
|
+
|
147
|
+
print("At time = %d years, the future value of the investment is $%.2f" % (time_widget.value, future_values[-1]))
|
148
|
+
```
|
149
|
+
|
150
|
+
```python
|
151
|
+
# Plot the future value of the investment over time
|
152
|
+
|
153
|
+
fig = go.Figure()
|
154
|
+
fig.add_trace(go.Scatter(x=years, y=future_values, mode='lines'))
|
155
|
+
fig.update_layout(title="Future Value Over Time", xaxis_title="Years", yaxis_title="Future Value")
|
156
|
+
fig.show()
|
157
|
+
```
|
158
|
+
|
159
|
+
## Here is a couple more functions to compare mortgage terms
|
160
|
+
|
161
|
+
### First to compare two different interest rates
|
162
|
+
|
163
|
+
You can consult BankRate to look up resonable rates
|
164
|
+
https://www.bankrate.com/mortgages/mortgage-rates/
|
165
|
+
|
166
|
+
```python
|
167
|
+
principal_amount = 200000 # Principal amount of the loan
|
168
|
+
loan_term_years = 30 # Loan term in years
|
169
|
+
interest_rates_to_compare = [0.04, 0.08] # Two different interest rates
|
170
|
+
```
|
171
|
+
|
172
|
+
```python
|
173
|
+
def compare_interest_rates(principal, years, interest_rates):
|
174
|
+
results = []
|
175
|
+
|
176
|
+
for rate in interest_rates:
|
177
|
+
monthly_interest_rate = rate / 12
|
178
|
+
num_payments = years * 12
|
179
|
+
monthly_payment = principal * (monthly_interest_rate * (1 + monthly_interest_rate)**num_payments) / ((1 + monthly_interest_rate)**num_payments - 1)
|
180
|
+
total_payment = monthly_payment * num_payments
|
181
|
+
total_interest_paid = total_payment - principal
|
182
|
+
interest_as_percent_of_payment = (total_interest_paid / total_payment) * 100
|
183
|
+
|
184
|
+
results.append({
|
185
|
+
"interest_rate": rate,
|
186
|
+
"monthly_payment": monthly_payment,
|
187
|
+
"total_payment": total_payment,
|
188
|
+
"total_interest_paid": total_interest_paid,
|
189
|
+
"interest_as_percent_of_payment": interest_as_percent_of_payment
|
190
|
+
})
|
191
|
+
|
192
|
+
return results
|
193
|
+
|
194
|
+
results = compare_interest_rates(principal_amount, loan_term_years, interest_rates_to_compare)
|
195
|
+
|
196
|
+
for result in results:
|
197
|
+
print(f"Interest Rate: {result['interest_rate'] * 100}%")
|
198
|
+
print(f"Monthly Payment: ${result['monthly_payment']:.2f}")
|
199
|
+
print(f"Total Payment: ${result['total_payment']:.2f}")
|
200
|
+
print(f"Total Interest Paid: ${result['total_interest_paid']:.2f}")
|
201
|
+
print(f"Interest as % of Payment: {result['interest_as_percent_of_payment']:.2f}%")
|
202
|
+
print()
|
203
|
+
```
|
204
|
+
|
205
|
+
## Redo to can compare two different loan terms
|
206
|
+
|
207
|
+
```python
|
208
|
+
principal_amount = 200000 # Principal amount of the loan
|
209
|
+
interest_rate = 0.05 # Annual interest rate (5%)
|
210
|
+
loan_terms_to_compare = [15, 30] # Two most typical loan terms ( lengths)
|
211
|
+
```
|
212
|
+
|
213
|
+
```python
|
214
|
+
def compare_loan_terms(principal, years, interest_rate):
|
215
|
+
results = []
|
216
|
+
|
217
|
+
for loan_term in years:
|
218
|
+
# Calculate monthly interest rate and number of payments
|
219
|
+
monthly_interest_rate = interest_rate / 12
|
220
|
+
num_payments = loan_term * 12
|
221
|
+
|
222
|
+
# Calculate monthly mortgage payment
|
223
|
+
monthly_payment = principal * (monthly_interest_rate * (1 + monthly_interest_rate)**num_payments) / ((1 + monthly_interest_rate)**num_payments - 1)
|
224
|
+
|
225
|
+
# Calculate total payment and total interest paid
|
226
|
+
total_payment = monthly_payment * num_payments
|
227
|
+
total_interest_paid = total_payment - principal
|
228
|
+
|
229
|
+
# Calculate the total interest as a percentage of the total payment
|
230
|
+
interest_as_percent_of_payment = (total_interest_paid / total_payment) * 100
|
231
|
+
|
232
|
+
results.append({
|
233
|
+
"loan_term": loan_term,
|
234
|
+
"monthly_payment": monthly_payment,
|
235
|
+
"total_payment": total_payment,
|
236
|
+
"total_interest_paid": total_interest_paid,
|
237
|
+
"interest_as_percent_of_payment": interest_as_percent_of_payment
|
238
|
+
})
|
239
|
+
|
240
|
+
return results
|
241
|
+
|
242
|
+
# Example usage
|
243
|
+
|
244
|
+
|
245
|
+
results = compare_loan_terms(principal_amount, loan_terms_to_compare, interest_rate)
|
246
|
+
|
247
|
+
for result in results:
|
248
|
+
print(f"Loan Term: {result['loan_term']} years")
|
249
|
+
print(f"Monthly Payment: ${result['monthly_payment']:.2f}")
|
250
|
+
print(f"Total Payment: ${result['total_payment']:.2f}")
|
251
|
+
print(f"Total Interest Paid: ${result['total_interest_paid']:.2f}")
|
252
|
+
print(f"Interest as % of Payment: {result['interest_as_percent_of_payment']:.2f}%")
|
253
|
+
print()
|
254
|
+
```
|
255
|
+
|
256
|
+
```python
|
257
|
+
|
258
|
+
```
|
259
|
+
|
260
|
+
```python
|
261
|
+
|
262
|
+
```
|
263
|
+
|
264
|
+
```python
|
265
|
+
|
266
|
+
```
|
267
|
+
|
@@ -0,0 +1,235 @@
|
|
1
|
+
---
|
2
|
+
title: "lec12-2-stocks-options"
|
3
|
+
type: lecture-notebook
|
4
|
+
week: 12
|
5
|
+
source_path: "/Users/ericvandusen/Documents/Data88E-ForTraining/F24Lec_NBs/lec12/lec12-2-stocks-options.ipynb"
|
6
|
+
---
|
7
|
+
|
8
|
+
<table style="width: 100%;">
|
9
|
+
<tr style="background-color: transparent;"><td>
|
10
|
+
<img src="https://data-88e.github.io/assets/images/blue_text.png" width="250px" style="margin-left: 0;" />
|
11
|
+
</td><td>
|
12
|
+
<p style="text-align: right; font-size: 10pt;"><strong>Economic Models</strong>, Fall 2024<br>
|
13
|
+
Dr. Eric Van Dusen <br>
|
14
|
+
Sreeja Apparaju <br>
|
15
|
+
Kidong Kim</p></td></tr>
|
16
|
+
</table>
|
17
|
+
|
18
|
+
# Lecture 12: Finance
|
19
|
+
|
20
|
+
## This notebook takes a look at some simple tools for looking at the stock market
|
21
|
+
- Previously Yahooo finance had a free API for reading in historical data on stocks
|
22
|
+
- However the Yahoo API got discontiued
|
23
|
+
- An awesome quant made a python package that recreated this functionality by scraping the information
|
24
|
+
|
25
|
+
Check out the documentation for [Yfinance package](https://pypi.org/project/yfinance/)
|
26
|
+
|
27
|
+
The package - called yfinance is not on the datahub so first we need to install it
|
28
|
+
|
29
|
+
```python
|
30
|
+
try:
|
31
|
+
import yfinance as yf
|
32
|
+
except:
|
33
|
+
!pip install yfinance
|
34
|
+
import yfinance as yf
|
35
|
+
```
|
36
|
+
|
37
|
+
```python
|
38
|
+
import numpy as np
|
39
|
+
import pandas as pd
|
40
|
+
import matplotlib
|
41
|
+
import matplotlib.pyplot as plt
|
42
|
+
from datetime import timedelta, date, datetime
|
43
|
+
from ipywidgets import interact, interactive, fixed, interact_manual
|
44
|
+
import ipywidgets as widgets
|
45
|
+
from IPython.display import display
|
46
|
+
import warnings
|
47
|
+
from datascience import *
|
48
|
+
warnings.filterwarnings('ignore')
|
49
|
+
%matplotlib inline
|
50
|
+
```
|
51
|
+
|
52
|
+
## S&P 500 and the Nasdaq
|
53
|
+
|
54
|
+
The yfinance package allows us to download by stock ticker and make a Pandas Dataframe - here we will pull in by the market-wide tickers for the S&P 500 and the Nasdaq
|
55
|
+
|
56
|
+
```python
|
57
|
+
data_SPNQ = yf.download(("^GSPC", '^IXIC'), start="1993-01-29", end="2022-04-05")
|
58
|
+
```
|
59
|
+
|
60
|
+
The following section uses the dataframe to build out a new dataframe with returns - the amount earned each day on the previous days close
|
61
|
+
|
62
|
+
```python
|
63
|
+
data_SN = data_SPNQ.iloc[:, [2,3]]
|
64
|
+
data_SP =data_SPNQ.iloc[:, 0]
|
65
|
+
data_NQ = data_SPNQ.iloc[:, 1]
|
66
|
+
dSP = np.array(len(data_SP)-1)
|
67
|
+
for i in range(len(data_SP)-1):
|
68
|
+
dat = ((data_SP[i] - data_SP[i+1])/data_SP[i])*100
|
69
|
+
dSP = np.append(dSP,dat)
|
70
|
+
dNQ = np.array(len(data_NQ)-1)
|
71
|
+
for i in range(len(data_NQ)-1):
|
72
|
+
dat = ((data_NQ[i] - data_NQ[i+1])/data_NQ[i])*100
|
73
|
+
dNQ = np.append(dNQ,dat)
|
74
|
+
data_SN['SP Returns'] = dSP
|
75
|
+
data_SN['NQ Returns'] = dNQ
|
76
|
+
```
|
77
|
+
|
78
|
+
```python
|
79
|
+
data_SN.iloc[:,[0,1]].plot(color = ('blue', 'red'), figsize=(10,8), alpha =0.3);
|
80
|
+
```
|
81
|
+
|
82
|
+
```python
|
83
|
+
data_SN[['SP Returns', 'NQ Returns']].iloc[1:].plot(color = ('blue', 'red'), figsize=(10,8), alpha = 0.3);
|
84
|
+
```
|
85
|
+
|
86
|
+
```python
|
87
|
+
data_SN.iloc[:,[0,1]].plot(color = ('blue', 'red'), figsize=(10,8), alpha =0.3);
|
88
|
+
```
|
89
|
+
|
90
|
+
```python
|
91
|
+
data_SN[['SP Returns', 'NQ Returns']].iloc[1:].plot(color = ('blue', 'red'), figsize=(10,8), alpha = 0.3);
|
92
|
+
```
|
93
|
+
|
94
|
+
## Let's dive deeper into the Yfinance API and and work with the data
|
95
|
+
|
96
|
+
First we will define three stocks that we want to look at more closely, and examine what sort of information we can get for each stock.
|
97
|
+
|
98
|
+
Lets look at
|
99
|
+
- Twitter
|
100
|
+
- Tesla
|
101
|
+
- USO - an ETF (exchange traded fund) that tracks the price of oil
|
102
|
+
|
103
|
+
```python
|
104
|
+
twitter_ticker = yf.Ticker("twtr")
|
105
|
+
tesla_ticker = yf.Ticker("tsla")
|
106
|
+
uso_ticker = yf.Ticker("uso")
|
107
|
+
```
|
108
|
+
|
109
|
+
There is actually a lot of information that yfinance API can provide for any equity. In the example above we only downloaded the closing price for each of the indexes.
|
110
|
+
|
111
|
+
```python
|
112
|
+
#tesla_ticker.info
|
113
|
+
```
|
114
|
+
|
115
|
+
## Out of all this info - let's extract the stock prices
|
116
|
+
|
117
|
+
This will put the dates, prices, and volumes into a *Pandas* dataframe with the name of the stock
|
118
|
+
|
119
|
+
```python
|
120
|
+
#twitter = twitter_ticker.history(period="max")
|
121
|
+
tesla = tesla_ticker.history(period="max")
|
122
|
+
uso = uso_ticker.history(period="max")
|
123
|
+
```
|
124
|
+
|
125
|
+
```python
|
126
|
+
tesla
|
127
|
+
```
|
128
|
+
|
129
|
+
## Lets look at the market for Options for Twitter
|
130
|
+
- This will show us the possible strike dates for different options
|
131
|
+
- From short term - this week - to long term - in two years
|
132
|
+
|
133
|
+
```python
|
134
|
+
tesla_ticker.options
|
135
|
+
```
|
136
|
+
|
137
|
+
## Downloading Calls and Puts
|
138
|
+
Let's download all of the Calls and Puts for Tesla into two tables
|
139
|
+
|
140
|
+
```python
|
141
|
+
tesla_options = tesla_ticker.option_chain(tesla_ticker.options[0])
|
142
|
+
```
|
143
|
+
|
144
|
+
```python
|
145
|
+
tesla_options.calls
|
146
|
+
```
|
147
|
+
|
148
|
+
```python
|
149
|
+
# Returns two table 0 : calls, 1 : puts
|
150
|
+
tesla_options = tesla_ticker.option_chain(tesla_ticker.options[0])
|
151
|
+
tesla_put , tesla_call = tesla_options.puts, tesla_options.calls
|
152
|
+
relevant_columns = ['lastPrice', 'change', 'percentChange', 'volume', 'strike']
|
153
|
+
tesla_put, tesla_call = tesla_put[relevant_columns], tesla_call[relevant_columns]
|
154
|
+
tesla_put.describe(), tesla_call.describe()
|
155
|
+
```
|
156
|
+
|
157
|
+
## Let's put these together into a joint table that are joined by the strike price
|
158
|
+
|
159
|
+
```python
|
160
|
+
tesla_option = pd.merge(tesla_put, tesla_call, how='inner', on = "strike")
|
161
|
+
#tesla_option = pd.merge(tesla_put, tesla_call, how='outer', on = "strike")
|
162
|
+
tesla_option[12:32]
|
163
|
+
```
|
164
|
+
|
165
|
+
## Now lets code up a graph of the puts and calls for Tesla
|
166
|
+
|
167
|
+
```python
|
168
|
+
current_tesla_p = tesla.iloc[-1]['Close']
|
169
|
+
current_tesla_p
|
170
|
+
|
171
|
+
plt.figure().set_size_inches(15, 5)
|
172
|
+
|
173
|
+
plt.title("Tesla calls vs puts", fontsize=15)
|
174
|
+
|
175
|
+
plt.plot(tesla_option['strike'], tesla_option['lastPrice_x'], color='r', label='call', linewidth=3)
|
176
|
+
plt.plot(tesla_option['strike'], tesla_option['lastPrice_y'], color='b', label='put', linewidth=3)
|
177
|
+
plt.axvline(x = current_tesla_p, color = 'g', label = 'Current Price', linewidth=4) #Current Price
|
178
|
+
|
179
|
+
plt.axis([tesla_option['strike'].iloc[0], tesla_option['strike'].iloc[-1], 0, max(max(tesla_option['lastPrice_x']), max(tesla_option['lastPrice_y']))])
|
180
|
+
plt.legend()
|
181
|
+
```
|
182
|
+
|
183
|
+
```python
|
184
|
+
def option(ticker):
|
185
|
+
options_obj = ticker.option_chain(ticker.options[0])
|
186
|
+
put, call = options_obj.puts, options_obj.calls
|
187
|
+
relevant_columns = ['lastPrice', 'change', 'percentChange', 'volume', 'strike']
|
188
|
+
put, call = put[relevant_columns], call[relevant_columns]
|
189
|
+
option_sheet = pd.merge(put, call, how='inner', on = "strike")
|
190
|
+
return option_sheet
|
191
|
+
|
192
|
+
option(uso_ticker)
|
193
|
+
```
|
194
|
+
|
195
|
+
## QuantStats Package
|
196
|
+
The same developer made a more recent package that draws on Yfinance but makes a whole set of summary tables
|
197
|
+
|
198
|
+
Check out the documentation for the [QuantStats Package](https://pypi.org/project/QuantStats/)
|
199
|
+
|
200
|
+
```python
|
201
|
+
try:
|
202
|
+
import quantstats as qs
|
203
|
+
except:
|
204
|
+
!pip install quantstats
|
205
|
+
import quantstats as qs
|
206
|
+
```
|
207
|
+
|
208
|
+
```python
|
209
|
+
import quantstats as qs
|
210
|
+
|
211
|
+
# extend pandas functionality with metrics, etc.
|
212
|
+
qs.extend_pandas()
|
213
|
+
|
214
|
+
# fetch the daily returns for a stock
|
215
|
+
stock = qs.utils.download_returns('TSLA')
|
216
|
+
|
217
|
+
# show sharpe ratio
|
218
|
+
qs.stats.sharpe(stock)
|
219
|
+
|
220
|
+
# or using extend_pandas() :)
|
221
|
+
stock.sharpe()
|
222
|
+
```
|
223
|
+
|
224
|
+
### QuantStats can make a "Snapshot" of stock performance
|
225
|
+
|
226
|
+
```python
|
227
|
+
qs.plots.snapshot(stock, title='Tesla Performance')
|
228
|
+
```
|
229
|
+
|
230
|
+
## Relevant materials and sources
|
231
|
+
|
232
|
+
https://algotrading101.com/learn/yfinance-guide/ <br>
|
233
|
+
https://pypi.org/ <br>
|
234
|
+
https://pypi.org/project/QuantStats/
|
235
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
---
|
2
|
+
title: "Co2_ClimateChange"
|
3
|
+
type: lecture-notebook
|
4
|
+
week: 13
|
5
|
+
source_path: "/Users/ericvandusen/Documents/Data88E-ForTraining/F24Lec_NBs/lec13/Co2_ClimateChange.ipynb"
|
6
|
+
---
|
7
|
+
|
8
|
+
## Carbon Dioxide Emissions and Global Climate Change
|
9
|
+
|
10
|
+
This notebook is a very simple analysis of global carbon emissons and global temperature change.
|
11
|
+
|
12
|
+
- The first point is to load the data directly from the government agencies that manage it.
|
13
|
+
- The second is to plot the data and see that we are at the hightest levels of carbon emissions in history.
|
14
|
+
- The third is to plot the data and see that we are at the highest levels of global temperature in history.
|
15
|
+
- The fourth is to plot the two data series and see that there is a correlation between the two.
|
16
|
+
|
17
|
+
```python
|
18
|
+
import pandas as pd
|
19
|
+
import plotly.express as px
|
20
|
+
```
|
21
|
+
|
22
|
+
## Global Atmospheric Carbon Levels
|
23
|
+
|
24
|
+
The CO2 data is from the Global Monitoring Laboratory of the National Oceanic and Atmospheric Administration (NOAA). The most frequently cited data is the Mauna Loa Observatory in Hawaii.
|
25
|
+
|
26
|
+

|
27
|
+
|
28
|
+
The data is available at https://www.esrl.noaa.gov/gmd/ccgg/trends/data.html.
|
29
|
+
|
30
|
+
There are many data series, but we have selected monthly mean data, which are available as a csv.
|
31
|
+
|
32
|
+
Mauna Loa Obervatory is at the top of a volcano in the middle of the Pacific Ocean. It is a good place to measure CO2 because it is far from any major sources of CO2. The data is available from 1958 to the present. The data is in parts per million (ppm) of CO2 in the atmosphere.
|
33
|
+
|
34
|
+
```python
|
35
|
+
url_mlo_co2="https://gml.noaa.gov/webdata/ccgg/trends/co2/co2_mm_mlo.csv"
|
36
|
+
|
37
|
+
df_mlo_co2 = pd.read_csv(url_mlo_co2, comment='#')
|
38
|
+
|
39
|
+
df_mlo_co2
|
40
|
+
```
|
41
|
+
|
42
|
+
### Let's graph the monthly level of Co2 over time to see the trend.
|
43
|
+
|
44
|
+
This is potentially one of the most famous graphs in the world. It is called the Keeling Curve, after Charles David Keeling, who started the measurements in 1958. The graph shows the monthly mean level of CO2 in the atmosphere.
|
45
|
+
|
46
|
+
```python
|
47
|
+
|
48
|
+
|
49
|
+
fig = px.line(df_mlo_co2, x='decimal date', y='average', title='Mauna Loa CO₂ daily means')
|
50
|
+
fig.show()
|
51
|
+
```
|
52
|
+
|
53
|
+
## GISS Surface Temperature Analysis (GISTEMP v4) ##
|
54
|
+
|
55
|
+
This dataset is the GISS Surface Temperature Analysis (GISTEMP v4) provided by NASA's Goddard Institute for Space Studies. The dataset is updated on a monthly basis and is available from 1880 to the present. The dataset is a combination of land-surface air temperatures and sea-surface water temperatures. The data is provided in tabular format and is available for global, hemispheric, and zonal means. The data is provided as temperature anomalies, which are deviations from the 1951-1980 means. The data is available in csv files and is updated through the most recent month.
|
56
|
+
|
57
|
+

|
58
|
+
|
59
|
+
The data is available from the following URL:
|
60
|
+
https://data.giss.nasa.gov/gistemp/
|
61
|
+
|
62
|
+
We have chosen the following datasets for this analysis:
|
63
|
+
|
64
|
+
**Global-mean monthly, seasonal, and annual means, 1880-present, updated through most recent month**
|
65
|
+
|
66
|
+
```python
|
67
|
+
url_giss_temp = 'https://data.giss.nasa.gov/gistemp/tabledata_v4/GLB.Ts+dSST.csv'
|
68
|
+
|
69
|
+
giss_temp = pd.read_csv(url_giss_temp, skiprows=1)
|
70
|
+
|
71
|
+
giss_temp
|
72
|
+
```
|
73
|
+
|
74
|
+
Lets plot the data to see the trend in global temperature over time.
|
75
|
+
|
76
|
+
MAM is the variable name for Monthly Anomaly Means. The data is in degrees Celsius.
|
77
|
+
|
78
|
+
```python
|
79
|
+
fig = px.line(giss_temp, x='Year', y='MAM', title='Global temperature anomaly')
|
80
|
+
fig.show()
|
81
|
+
```
|
82
|
+
|
83
|
+
## Correlation between CO2 and Global Temperature ##
|
84
|
+
|
85
|
+
Let's check the correlation between the two datasets.
|
86
|
+
|
87
|
+
First we need to cut the temperatture anomoly data to match the CO2 data. The CO2 data is from 1958 to the present. The temperature data is from 1880 to the present. We will cut the temperature data to match the CO2 data.
|
88
|
+
|
89
|
+
Then we will make an annual CO2 dataset by taking the average of the monthly data.
|
90
|
+
|
91
|
+
Finally we will merge the two datasets on the year.
|
92
|
+
|
93
|
+
```python
|
94
|
+
# cut temp data to 1958
|
95
|
+
giss_temp = giss_temp[giss_temp['Year'] >= 1958]
|
96
|
+
```
|
97
|
+
|
98
|
+
```python
|
99
|
+
# make an annual graph for the Co2 data
|
100
|
+
#df_mlo_co2['year'] = df_mlo_co2['decimal date'].apply(lambda x: int(x))
|
101
|
+
annual_co2 = df_mlo_co2.groupby('year').mean().reset_index()
|
102
|
+
annual_co2
|
103
|
+
```
|
104
|
+
|
105
|
+
```python
|
106
|
+
#merge with co2 data
|
107
|
+
merged_co2_temp = pd.merge(annual_co2, giss_temp, left_on='year', right_on='Year')
|
108
|
+
```
|
109
|
+
|
110
|
+
```python
|
111
|
+
merged_co2_temp
|
112
|
+
```
|
113
|
+
|
114
|
+
```python
|
115
|
+
#graph over time using plotly for the merged data
|
116
|
+
fig = px.scatter(merged_co2_temp, x='average', y='MAM',
|
117
|
+
title='CO₂ vs global temperature anomaly',
|
118
|
+
labels={'average':'CO₂ (ppm)', 'MAM':'Temperature anomaly (°C)'},
|
119
|
+
trendline='ols')
|
120
|
+
# add a trendline
|
121
|
+
|
122
|
+
|
123
|
+
fig.show()
|
124
|
+
```
|
125
|
+
|
126
|
+
```python
|
127
|
+
#calculate the correlation
|
128
|
+
correlation = merged_co2_temp['average'].corr(merged_co2_temp['MAM'])
|
129
|
+
print(correlation)
|
130
|
+
```
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
```python
|
137
|
+
|
138
|
+
```
|
139
|
+
|