File size: 8,723 Bytes
180d8ec
 
 
 
 
 
a966a42
180d8ec
 
 
 
 
 
 
 
 
 
 
 
53da1d8
180d8ec
 
 
 
 
 
 
4c98e23
 
180d8ec
 
14b59b2
 
53da1d8
180d8ec
 
 
 
04f6a57
 
27c44df
180d8ec
04f6a57
180d8ec
 
9f04c37
 
04f6a57
180d8ec
4c98e23
 
 
 
 
 
04f6a57
 
 
180d8ec
 
07e701b
180d8ec
07e701b
180d8ec
4c98e23
 
07e701b
90c3d4c
07e701b
 
207df97
3612724
c8334c3
4c98e23
 
07e701b
4c98e23
492af17
 
180d8ec
 
07e701b
180d8ec
4c98e23
180d8ec
 
 
07e701b
180d8ec
4c98e23
180d8ec
 
 
 
 
6922363
180d8ec
 
 
 
 
1df9bbe
 
 
 
 
 
 
 
 
 
 
fc2c761
1df9bbe
 
 
 
fc2c761
180d8ec
 
8b1e0d6
180d8ec
 
 
 
 
b127142
ca6a630
c325a6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca6a630
180d8ec
 
8b1e0d6
180d8ec
 
 
 
 
b127142
ca6a630
c325a6d
 
 
 
 
 
 
 
 
 
 
 
 
 
ca6a630
180d8ec
 
 
 
9ca4933
1883c03
180d8ec
 
 
 
 
 
 
 
 
 
 
8408e1a
180d8ec
04f6a57
 
 
1883c03
04f6a57
9f04c37
180d8ec
 
04f6a57
180d8ec
9f04c37
180d8ec
 
 
 
 
38803fd
180d8ec
 
9f04c37
04f6a57
 
 
 
 
fc2c761
9f04c37
 
04f6a57
207df97
04f6a57
 
 
180d8ec
f4a34e2
180d8ec
 
04f6a57
180d8ec
 
 
f4a34e2
04f6a57
f4a34e2
04f6a57
f4a34e2
 
 
180d8ec
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# %%
# imports
import gradio as gr
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import math

# %%
# import data
data = pd.read_excel("graph_data.xlsx",
                     sheet_name = "Sheet1",
                     header = 0
)

# clean data
# rename year column
data = data.rename(columns = {"Unnamed: 0": "Year"})
# drop rows without data
# data = data.drop([0,1,2,3,4,5,6,7,8,9,10,11])
# keep columns of interest
data = data[[
    "Year",
    "Total Revenues",
    "Debt Balance",
    "Revenues ex SS OASDI",
    "Average Rate on Federal Debt", 
    "GDP", 
    "Net Interest"
    ]]

data.set_index("Year", inplace=True)

print(data)


# %%
baseline_interest_rate = 3.67
#baseline_revenues = 15928.73
baseline_cagr_revenues = 4.02
total_revenues_2024 = data.loc[2024, "Total Revenues"]

def plot_interest_coverage(interest_rate, cagr_revenues):

    # calculate the yearly increase in the interest rate based on the projected interest rate in 2054
    interest_rate_yearly_increase = (interest_rate - baseline_interest_rate) / (2054 - 2025) / 100
    # calculate the yearly increase in revenues based on the projected interest rate in 2054
    # revenues_yearly_increase = (revenues - baseline_revenues) / (2054 - 2025)

    # add a baseline net interest / revenues column
    data["Net Interest / Revenues (Baseline)"] = data["Net Interest"] / data["Total Revenues"]

    # add a baseline net interest / revenues ex SS OASDI column
    data["Net Interest / Revenues ex SS OASDI (Baseline)"] = data["Net Interest"] / data["Revenues ex SS OASDI"]

    # add a baseline SS OASDI revenues column
    data["SS OASDI Revenues"] = data["Total Revenues"] - data["Revenues ex SS OASDI"]

    # add a projected average rate on federal debt column
    data["Average Rate on Federal Debt (Projected)"] = np.where(
        data.index.astype(int) < 2025, 
        data["Average Rate on Federal Debt"], 
        data["Average Rate on Federal Debt"] + (interest_rate_yearly_increase * (data.index.astype(int) - 2024)))
    
    # add a projected revenues column
    data["Total Revenues (Projected)"] = np.where(
        data.index.astype(int) < 2025, 
        data["Total Revenues"], 
        total_revenues_2024 * ((1 + (cagr_revenues / 100)) ** (data.index.astype(int) - 2024)))
    # data["Total Revenues"] + (revenues_yearly_increase * (data.index.astype(int) - 2025)))
    
    print(data)
    
    # add a projected revenues ex SS OASDI column
    data["Revenues ex SS OASDI (Projected)"] = np.where(
        data.index.astype(int) < 2025, 
        data["Revenues ex SS OASDI"], 
        data["Total Revenues (Projected)"] - data["SS OASDI Revenues"])
    
    # add a projected interest / revenues column
    data["Net Interest / Revenues (Projected)"] = np.where(
        data.index.astype(int) < 2025, 
        data["Net Interest / Revenues (Baseline)"], 
        data["Average Rate on Federal Debt (Projected)"] * data["Debt Balance"] / data["Total Revenues (Projected)"])
    
    # add a projected interest / revenues ex SS OASDI column
    data["Net Interest / Revenues ex SS OASDI (Projected)"] = np.where(
        data.index.astype(int) < 2025, 
        data["Net Interest / Revenues ex SS OASDI (Baseline)"], 
        data["Average Rate on Federal Debt (Projected)"] * data["Debt Balance"] / data["Revenues ex SS OASDI (Projected)"])

    # Create the plot
    plt.figure(figsize = (10, 4.8))
    # plot average rate on federal debt
    plt.plot(
        data.index, 
        data["Average Rate on Federal Debt"], 
        color = "Green", 
        label = "Average Rate on Federal Debt"
    )
    # plot average rate on federal debt projected
    if cagr_revenues != baseline_cagr_revenues or interest_rate != baseline_interest_rate:
        plt.plot(
            data.index, 
            data["Average Rate on Federal Debt (Projected)"], 
            color = "Green", 
            label = "Average Rate on Federal Debt (Projected)",
            linestyle = "--"
        )
    else:
        plt.plot(
            data.index, 
            data["Average Rate on Federal Debt"], 
            color = "Green", 
            label = "Average Rate on Federal Debt (Projected)",
            linestyle = "--"
        )

    # plot interest / revenues (baseline)
    plt.plot(
        data.index, 
        data["Net Interest / Revenues (Baseline)"], 
        color = "Blue", 
        label = "Net Interest / Revenues (Baseline)"
    )
    # plot interest / revenues (projected)
    if cagr_revenues != baseline_cagr_revenues or interest_rate != baseline_interest_rate:
        plt.plot(
            data.index, 
            data["Net Interest / Revenues (Projected)"], 
            color = "Blue", 
            label = "Net Interest / Revenues (Projected)",
            linestyle = "--"
        )
    else:
        plt.plot(
            data.index, 
            data["Net Interest / Revenues (Baseline)"], 
            color = "Blue", 
            label = "Net Interest / Revenues (Projected)",
            linestyle = "--"
        )

    
    # plot interest / revenues ex ss oasdi (baseline)
    plt.plot(
        data.index, 
        data["Net Interest / Revenues ex SS OASDI (Baseline)"], 
        color = "Orange", 
        label = "Net Interest / Revenues ex SS OASDI (Baseline)"
    )
    # plot interest / revenues ex ss oasdi (projected)
    if cagr_revenues != baseline_cagr_revenues or interest_rate != baseline_interest_rate:
        plt.plot(
            data.index, 
            data["Net Interest / Revenues ex SS OASDI (Projected)"], 
            color = "Orange", 
            label = "Net Interest / Revenues ex SS OASDI (Projected)",
            linestyle = "--"
        )
    else:
        plt.plot(
            data.index, 
            data["Net Interest / Revenues ex SS OASDI (Baseline)"], 
            color = "Orange", 
            label = "Net Interest / Revenues ex SS OASDI (Projected)",
            linestyle = "--"
        )
    
    plt.title("Interest as Share of Revenues Through 2054")
    plt.legend(loc = "upper left")
    plt.ylim(0, 1.05)
    plt.yticks(np.arange(0, 1.1, 0.1))
    plt.xticks(range(1940,2055,4), rotation = 45)
    plt.axvline(x = 2024.5, color = "black", linestyle = '--')
    plt.grid(True, axis = 'y', linestyle = '--', linewidth = 0.7)
    
    # Save the plot to a file
    plt.savefig("interest_coverage.png")
    plt.close()
    
    # Return the path to the image file
    return "interest_coverage.png"

# %%
interest_rate_lowerbound = 0
interest_rate_upperbound = 10

# revenues_lower_bound = 10000
# revenues_upper_bound = 20000

cagr_revenues_lower_bound = 0
cagr_revenues_upper_bound = 8

with gr.Blocks() as interface:
    # Create the image output
    graph = gr.Image(type="filepath", label = "Graph", value = plot_interest_coverage(baseline_interest_rate, baseline_cagr_revenues))
    
    # Create the slider input below the image for projected interest rate
    interest_rate_slider = gr.Slider(
        interest_rate_lowerbound, 
        interest_rate_upperbound, 
        step = .1,
        value = baseline_interest_rate, 
        label = "2054 Projected Average Interest Rate on Federal Debt"
    )

    # Create the slider input below the image for projected revenues
    cagr_revenues_slider = gr.Slider(
        cagr_revenues_lower_bound, 
        cagr_revenues_upper_bound, 
        step = 0.01,
        value = baseline_cagr_revenues, 
        label = "Compound Annual Growth Rate of Revenues through 2054"
    )

    gr.Markdown('<p style="font-size:11px;">Source: CBO June 2024  An Update to the Budget and Economic Outlook: 2024 to 2034, '
    'March 2024 report The Long-Term Budget Outlook: 2024 to 2054, and author\'s calculations. Scenario of higher interest rate and revenues '
    'is author\'s calculations. Data points for 2035-2054 calculated to build on CBO\'s June 2024 10-year update and be consistent '
    'with the March 2024 long-term report. Historical Social Security OASDI payroll tax revenue from Table 4-3 of the SSA\'s '
    'Trust Fund Data, and projections from the CBO\'s August 2024 Long Term Projections for Social Security.</p>')

    # Set up an action that updates the graph when the interest rate slider value changes
    interest_rate_slider.change(
        plot_interest_coverage, 
        inputs = [interest_rate_slider, cagr_revenues_slider], 
        outputs = graph
    )

    # Set up an action that updates the graph when the revenues slider value changes
    cagr_revenues_slider.change(
        plot_interest_coverage, 
        inputs = [interest_rate_slider, cagr_revenues_slider], 
        outputs = graph
    )

# Launch the interface
interface.launch(share = True)