In [1]:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline  

# number of time steps
N = 300

# relative size of rUK to Scotland - this is basically used to define the relative government spends
scaling = 9.0

# fixed spending rate of rUK
G_UK = 50

# fiscal transfer to Scotland
# taken as a fraction of the rUK spend (based on relative size factor) 
# with another fraction for the proportion devolved (with the remainder provided by Sottish tax and spend) 
FT_S = 0.5*(G_UK/(scaling))

# tax rates
theta_UK = 0.25
theta_S  = 0.25

# savings rates (actually spending rates!)
alpha_UK = 0.95
alpha_S  = 0.95

# Scottish (rUK) export rate (relative to GDP) - approximate value from table 6.11 of Active Citizen
EX_S  = 0.31
# Scottish (rUK) import rate (relative to GDP) - approximate value from table 6.11 of Active Citizen
IM_S  = 0.41
# UK import rate (relative to GDP) - simply Scottish export rate scaled by relative sizes of economies
IM_UK = EX_S/scaling

# containers - rUK
C_UK   = np.zeros(N) # consumption
Y_UK   = np.zeros(N) # income
Y_d_UK = np.zeros(N) # disposable income
T_UK   = np.zeros(N) # tax revenue
H_h_UK = np.zeros(N) # private savings
H_g_UK = np.zeros(N) # government debt
CA_UK  = np.zeros(N) # current account

# containers - Scotland
C_S   = np.zeros(N) # consumption
Y_S   = np.zeros(N) # income
Y_d_S = np.zeros(N) # disposable income
T_S   = np.zeros(N) # tax revenue
H_h_S = np.zeros(N) # private savings
H_g_S = np.zeros(N) # government debt
CA_S  = np.zeros(N) # current account
# Scottish G is not a constant
G_S = np.zeros(N) # Scottish government spending


for t in range(1, N):
    
    ### UK ###
    
    # calculate consumer spending
    C_UK[t]   = alpha_UK*Y_d_UK[t-1] 
    
    CA_UK[t] = IM_S*Y_S[t-1] - IM_UK*Y_UK[t-1]
    
    # calculate total income (consumer spending plus constant government spending plus CA)
    Y_UK[t]   = G_UK + C_UK[t] + CA_UK[t]
    
    # calculate the tax take
    T_UK[t] = theta_UK * Y_UK[t]
    
    # calculate disposable income
    Y_d_UK[t] = Y_UK[t] - T_UK[t]
    
    # calculate the change in private savings
    H_h_UK[t] = H_h_UK[t-1] + (1-alpha_UK)*Y_d_UK[t-1] 
    
    # calculate the change in government debt from rUK operations
    H_g_UK[t] = H_g_UK[t-1] + T_UK[t]- G_UK
    
    ### SCOTLAND ###
    
    # calculate consumer spending
    C_S[t]   = alpha_S*Y_d_S[t-1] 
    
    # calculate government spending (tax take plus fiscal transfer)
    G_S[t] = T_S[t-1] + FT_S
    
    # calculate CA
    CA_S[t] = - IM_S*Y_S[t-1] + IM_UK*Y_UK[t-1]
    
    # calculate total income (consumer spending plus constant government spending + CA)
    Y_S[t]   = G_S[t] + C_S[t] + CA_S[t]
    
    # calculate the tax take
    T_S[t] = theta_S * Y_S[t]
    
    # calculate disposable income
    Y_d_S[t] = Y_S[t] - T_S[t]
    
    # calculate the change in private savings
    H_h_S[t] = H_h_S[t-1] + (1-alpha_S)*Y_d_S[t-1] 
    
    # calculate the change in government debt from Scottish operations
    # this has already been modified for rUK operations - just add on Scottish value
    H_g_UK[t] = H_g_UK[t] + T_S[t]- G_S[t]

In [2]:
fig = plt.figure(figsize=(14, 10))

consumption_plot = fig.add_subplot(341, xlim=(0, N), ylim=(0, np.max([np.max(Y_UK),np.max(Y_S)])*1.1))
consumption_plot.plot(range(N), C_UK, lw=3)
consumption_plot.plot(range(N), C_S, lw=3)
consumption_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('consumption')

gov_plot = fig.add_subplot(342, xlim=(0, N), ylim=(0, np.max([np.max(Y_UK), np.max(Y_S)])*1.1))
gov_plot.plot(range(N), np.repeat(G_UK,N), lw=3)
gov_plot.plot(range(N), G_S, lw=3)
gov_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government spending')

ca_plot = fig.add_subplot(343, xlim=(0, N), ylim=(np.min([np.min(CA_UK),np.min(CA_S)])*1.1, np.max([np.max(CA_UK),np.max(CA_S)])*1.1))
ca_plot.plot(range(N), CA_UK, lw=3)
ca_plot.plot(range(N), CA_S, lw=3)
ca_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('trade balance')

income_plot = fig.add_subplot(344, xlim=(0, N), ylim=(0, np.max([np.max(Y_UK),np.max(Y_S)])*1.1))
income_plot.plot(range(N), Y_UK, lw=3)
income_plot.plot(range(N), Y_S, lw=3)
income_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('income')

tax_plot = fig.add_subplot(345, xlim=(0, N), ylim=(0, np.max([np.max(T_UK),np.max(T_S)])*1.1))
tax_plot.plot(range(N), T_UK, lw=3)
tax_plot.plot(range(N), T_S, lw=3)
tax_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('tax revenue')

tax_gdp_plot = fig.add_subplot(346, xlim=(0, N), ylim=(0, 1))
tax_gdp_plot.plot(range(N), T_UK/Y_UK, lw=3)
tax_gdp_plot.plot(range(N), T_S/Y_S, lw=3)
tax_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('tax revenue (% GDP)')

deficit_plot = fig.add_subplot(347, xlim=(0, N), ylim=(np.min([np.min(T_UK-G_UK),np.min(T_S-G_S)])*1.1, np.max([np.max(T_UK-G_UK),np.max(T_S-G_S)])*1.1))
deficit_plot.plot(range(N), T_UK-np.repeat(G_UK,N), lw=3)
deficit_plot.plot(range(N), T_S-G_S, lw=3)
deficit_plot.plot(range(N), ((T_UK-np.repeat(G_UK,N))+(T_S-G_S)), lw=3)
deficit_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government budget')

debt_plot = fig.add_subplot(348, xlim=(0, N), ylim=(np.min(H_g_UK)*1.1,0))
debt_plot.plot(range(N), H_g_UK, lw=3)
debt_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government debt')

gov_balance_gdp_plot = fig.add_subplot(3,4,9, xlim=(0, N), ylim=(-0.2, 0.2))
gov_balance_gdp_plot.plot(range(N-1), (T_UK[1:]-np.repeat(G_UK,N-1))/Y_UK[1:], lw=3)
gov_balance_gdp_plot.plot(range(N-1), (T_S[1:]-G_S[1:])/Y_S[1:], lw=3)
gov_balance_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government balance (% GDP)')

private_balance_gdp_plot = fig.add_subplot(3,4,10, xlim=(0, N), ylim=(-0.2,0.2))
private_balance_gdp_plot.plot(range(N-1), np.diff(H_h_UK)/Y_UK[1:], lw=3)
private_balance_gdp_plot.plot(range(N-1), np.diff(H_h_S)/Y_S[1:], lw=3)
private_balance_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('private balance (% GDP)')

ca_gdp_plot = fig.add_subplot(3,4,11, xlim=(0, N), ylim=(-0.2,0.2))
ca_gdp_plot.plot(range(N-1), np.divide(CA_UK[1:],Y_UK[1:]), lw=3)
ca_gdp_plot.plot(range(N-1), np.divide(CA_S[1:], Y_S[1:]), lw=3)
ca_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('trade balance (% GDP)')

# space subplots neatly
plt.tight_layout()


-c:44: RuntimeWarning: invalid value encountered in divide
-c:45: RuntimeWarning: invalid value encountered in divide

Some thoughts...

  • rUK = blue, Scotland = green, aggregate = red

  • top row of plots shows income identity, first three plots sum to last one

  • middle row is government
  • bottom row is sectoral balances as percent of GDP
  • government has deficit in both regions if private sector are saving (i.e. alpha < 1)
  • in absolute terms rUK has bigger deficit, but relative to GDP it is much smaller
  • government balance equals private balance + trade balance for each regions (bottom row of plots)
  • if alpha = 1, private balance obviously goes to zero (no savings) and trade deficit perfectly balances government deficit (in this case we see the government have a balanced budget on aggregate (red) - the surplus from the rUK exactly matches the fiscal transfer to Scotland)
  • any absolute trade deficit needs to be less than G at the outset otherwise it explodes (i.e. more money being spent than exists, G is only source of funds)
  • basically economies grow until amount flowing out (IM and savings; both function of Y) equals amount flowing in (EX, G and FT)
  • absolute trade balances are obsiously equal and opposite but relative to GDP Scotlands deficit is much larger than rUKs surplus (by factor of 9, again, obviously)

Would be good to

  • add investment
  • use realistic figures for rUK government spend and Scottish block grant (very crude implementation here), spending propensities
  • could add spending out of wealth (Modigliani consumption function) but probably guessing parameters
  • could handle Scottish tax differently (i.e. Scottish rate)
  • could add bonds (and interest rate and liquidity preference) but possibly overkill
  • if modelling as distinct countries need to central banks with reserves (e.g. gold)

In [3]:
### NO SAVING ###

# savings rates (actually spending rates!)
alpha_UK = 1.0
alpha_S  = 1.0


for t in range(1, N):
    
    ### UK ###
    
    # calculate consumer spending
    C_UK[t]   = alpha_UK*Y_d_UK[t-1] 
    
    CA_UK[t] = IM_S*Y_S[t-1] - IM_UK*Y_UK[t-1]
    
    # calculate total income (consumer spending plus constant government spending plus CA)
    Y_UK[t]   = G_UK + C_UK[t] + CA_UK[t]
    
    # calculate the tax take
    T_UK[t] = theta_UK * Y_UK[t]
    
    # calculate disposable income
    Y_d_UK[t] = Y_UK[t] - T_UK[t]
    
    # calculate the change in private savings
    H_h_UK[t] = H_h_UK[t-1] + (1-alpha_UK)*Y_d_UK[t-1] 
    
    # calculate the change in government debt from rUK operations
    H_g_UK[t] = H_g_UK[t-1] + T_UK[t]- G_UK
    
    ### SCOTLAND ###
    
    # calculate consumer spending
    C_S[t]   = alpha_S*Y_d_S[t-1] 
    
    # calculate government spending (tax take plus fiscal transfer)
    G_S[t] = T_S[t-1] + FT_S
    
    # calculate CA
    CA_S[t] = - IM_S*Y_S[t-1] + IM_UK*Y_UK[t-1]
    
    # calculate total income (consumer spending plus constant government spending + CA)
    Y_S[t]   = G_S[t] + C_S[t] + CA_S[t]
    
    # calculate the tax take
    T_S[t] = theta_S * Y_S[t]
    
    # calculate disposable income
    Y_d_S[t] = Y_S[t] - T_S[t]
    
    # calculate the change in private savings
    H_h_S[t] = H_h_S[t-1] + (1-alpha_S)*Y_d_S[t-1] 
    
    # calculate the change in government debt from Scottish operations
    # this has already been modified for rUK operations - just add on Scottish value
    H_g_UK[t] = H_g_UK[t] + T_S[t]- G_S[t]
   

fig = plt.figure(figsize=(14, 10))

consumption_plot = fig.add_subplot(341, xlim=(0, N), ylim=(0, np.max([np.max(Y_UK),np.max(Y_S)])*1.1))
consumption_plot.plot(range(N), C_UK, lw=3)
consumption_plot.plot(range(N), C_S, lw=3)
consumption_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('consumption')

gov_plot = fig.add_subplot(342, xlim=(0, N), ylim=(0, np.max([np.max(Y_UK), np.max(Y_S)])*1.1))
gov_plot.plot(range(N), np.repeat(G_UK,N), lw=3)
gov_plot.plot(range(N), G_S, lw=3)
gov_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government spending')

ca_plot = fig.add_subplot(343, xlim=(0, N), ylim=(np.min([np.min(CA_UK),np.min(CA_S)])*1.1, np.max([np.max(CA_UK),np.max(CA_S)])*1.1))
ca_plot.plot(range(N), CA_UK, lw=3)
ca_plot.plot(range(N), CA_S, lw=3)
ca_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('trade balance')

income_plot = fig.add_subplot(344, xlim=(0, N), ylim=(0, np.max([np.max(Y_UK),np.max(Y_S)])*1.1))
income_plot.plot(range(N), Y_UK, lw=3)
income_plot.plot(range(N), Y_S, lw=3)
income_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('income')

tax_plot = fig.add_subplot(345, xlim=(0, N), ylim=(0, np.max([np.max(T_UK),np.max(T_S)])*1.1))
tax_plot.plot(range(N), T_UK, lw=3)
tax_plot.plot(range(N), T_S, lw=3)
tax_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('tax revenue')

tax_gdp_plot = fig.add_subplot(346, xlim=(0, N), ylim=(0, 1))
tax_gdp_plot.plot(range(N), T_UK/Y_UK, lw=3)
tax_gdp_plot.plot(range(N), T_S/Y_S, lw=3)
tax_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('tax revenue (% GDP)')

deficit_plot = fig.add_subplot(347, xlim=(0, N), ylim=(np.min([np.min(T_UK-G_UK),np.min(T_S-G_S)])*1.1, np.max([np.max(T_UK-G_UK),np.max(T_S-G_S)])*1.1))
deficit_plot.plot(range(N), T_UK-np.repeat(G_UK,N), lw=3)
deficit_plot.plot(range(N), T_S-G_S, lw=3)
deficit_plot.plot(range(N), ((T_UK-np.repeat(G_UK,N))+(T_S-G_S)), lw=3)
deficit_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government budget')

debt_plot = fig.add_subplot(348, xlim=(0, N), ylim=(np.min(H_g_UK)*1.1,0))
debt_plot.plot(range(N), H_g_UK, lw=3)
debt_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government debt')

gov_balance_gdp_plot = fig.add_subplot(3,4,9, xlim=(0, N), ylim=(-0.2, 0.2))
gov_balance_gdp_plot.plot(range(N-1), (T_UK[1:]-np.repeat(G_UK,N-1))/Y_UK[1:], lw=3)
gov_balance_gdp_plot.plot(range(N-1), (T_S[1:]-G_S[1:])/Y_S[1:], lw=3)
gov_balance_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('government balance (% GDP)')

private_balance_gdp_plot = fig.add_subplot(3,4,10, xlim=(0, N), ylim=(-0.2,0.2))
private_balance_gdp_plot.plot(range(N-1), np.diff(H_h_UK)/Y_UK[1:], lw=3)
private_balance_gdp_plot.plot(range(N-1), np.diff(H_h_S)/Y_S[1:], lw=3)
private_balance_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('private balance (% GDP)')

ca_gdp_plot = fig.add_subplot(3,4,11, xlim=(0, N), ylim=(-0.2,0.2))
ca_gdp_plot.plot(range(N-1), np.divide(CA_UK[1:],Y_UK[1:]), lw=3)
ca_gdp_plot.plot(range(N-1), np.divide(CA_S[1:], Y_S[1:]), lw=3)
ca_gdp_plot.grid()
# label axes
plt.xlabel('time')
plt.ylabel('trade balance (% GDP)')

# space subplots neatly
plt.tight_layout()


-c:103: RuntimeWarning: invalid value encountered in divide
-c:104: RuntimeWarning: invalid value encountered in divide

In [ ]: