-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b2e60e2
Showing
10 changed files
with
3,032 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
code/modeling_language | ||
*.pyc | ||
*.xlsx | ||
*.svg | ||
*.png | ||
*ipynb_checkpoints* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
This code replicates the graphs from the paper *Managing Capital Outflows: The Role of Foreign. Exchange Intervention.* by Suman S. Basu, Atish R. Ghosh, Jonathan D. Ostry and Pablo E. Winant. | ||
|
||
The code requires Python 3.6 and depends on two libraries: | ||
|
||
- [dolo](https://github.com/EconForge/dolo) | ||
- [backtothetrees](https://github.com/albop/backtothetrees) | ||
|
||
An up-to-date version of the code can be found on [github](https://github.com/albop/managing_capital_outflows_with_limited_reserves | ||
|
||
|
||
To generate the results run: | ||
|
||
- `python compute_simulations.py` : creates files with various simulation results | ||
- `precomputed_decision_rules.pickle` | ||
- `precomputed_moving_target.pickle` | ||
- `precomputed_simulations.pickle` | ||
|
||
- `python compute_welfares.py`: create welfare comparison files: | ||
- `simple_rules_welfare.xlsx` (p=1.0) | ||
- `simple_rules_welfare_9.xlsx` (p=0.9) | ||
- `simple_rules_welfare_8.xlsx` (p=0.8) | ||
|
||
|
||
The graphs are then created in the notebooke `gen_graphs.ipynb` which can be opened and run using Jupyter. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
|
||
import copy | ||
from collections import OrderedDict | ||
|
||
params = dict( | ||
beta=0.8/(0.8+0.15), | ||
a=0.8, | ||
c=0.15, | ||
estar=-0.0, | ||
Rbar=0.5, | ||
min_f=0, | ||
kappa=1.0, | ||
N=40, | ||
zbar=0.1, | ||
p=1, | ||
model='optimal' | ||
) | ||
|
||
|
||
reserve_levels = [0.01, 0.5, 1.0, 1.5, 2.0, 3.0] | ||
policies = ['volume','peg','optimal','time-consistent'] | ||
cases = { | ||
'baseline': {}, | ||
'accumulation': {'min_f': -10000}, | ||
'low_beta': {'beta': 0.8}, | ||
'high_beta': {'beta': 0.9}, | ||
'super_low_a': {'a': 0.01}, | ||
'low_a': {'a': 0.4}, | ||
'high_a': {'a': 1.6}, | ||
'low_c': {'c': 0.075}, | ||
'high_c': {'c': 0.30}, | ||
'p_8': {'p': 0.8}, | ||
'p_85': {'p': 0.85}, | ||
'p_9': {'p': 0.9}, | ||
'p_95': {'p': 0.95}, | ||
} | ||
|
||
list_of_calibrations = OrderedDict() | ||
for case in cases.keys(): | ||
for pol in policies: | ||
for r in reserve_levels: | ||
calib = copy.copy(params) | ||
calib.update(cases[case]) | ||
calib['Rbar'] = r | ||
calib['model'] = pol | ||
list_of_calibrations[(case,pol,r)] = calib.copy() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
######## Solve | ||
import pandas | ||
import numpy | ||
from collections import OrderedDict | ||
# from solution import * | ||
from calibrations import * | ||
from time_consistent import solve as solve_time_consistent | ||
from time_consistent import simulate | ||
from bttt.trees import DeterministicTree, get_ts | ||
from matplotlib import pyplot as plt | ||
from bttt.trees import DeathTree | ||
from bttt.model import import_tree_model | ||
from matplotlib import pyplot as plt | ||
from numpy import * | ||
|
||
|
||
|
||
N = 25 | ||
T = 25 | ||
|
||
|
||
calib0 = calib.copy() | ||
beta = calib0['beta'] | ||
a = calib0['a'] | ||
p = calib0['p'] | ||
zbar = calib0['zbar'] | ||
max_R=5 | ||
|
||
|
||
tree = DeterministicTree(N) | ||
for s in tree.nodes: | ||
tree.values[s] = zbar | ||
model = import_tree_model('models.yaml', key='stochastic', tree=tree) | ||
|
||
def solve_it(**cc): | ||
tree = DeterministicTree(N) | ||
for s in tree.nodes: | ||
tree.values[s] = zbar | ||
model = import_tree_model('models.yaml', key='optimal', tree=tree) | ||
model.calibration.update(cc) | ||
sol = model.solve(verbose=True) | ||
df = numpy.concatenate( [get_ts(tree, sol, varname)[:,None] for varname in ['e','f', 'Gamma']], axis=1 ) | ||
df = pandas.DataFrame(df, columns=['e','f','Gamma']) | ||
return df | ||
|
||
from collections import OrderedDict | ||
|
||
|
||
Rvec0 = linspace(0.01, 3.0, 20) | ||
|
||
|
||
|
||
pvec = [0.8, 0.85, 0.9, 0.95, 1.0] | ||
|
||
# Unconstrained solutions | ||
|
||
unconstrained_sols = OrderedDict() | ||
for p in pvec: | ||
dfs = [solve_it(Rbar=i, min_f=0, p=p) for i in Rvec0] | ||
unconstrained_sols[p] = dfs | ||
|
||
all_gammas = OrderedDict() | ||
for p in pvec: | ||
dfs = unconstrained_sols[p] | ||
max_gammas = numpy.array([dfs[i]['Gamma'].max() for i,r in enumerate(Rvec0)]) | ||
all_gammas[p] = max_gammas | ||
|
||
for p in pvec: | ||
plt.plot(Rvec0, all_gammas[p]) | ||
|
||
alpha = 0.5 | ||
|
||
Rlimit = OrderedDict() | ||
|
||
for p in pvec: | ||
dfs = unconstrained_sols[p] | ||
max_gammas = numpy.array([dfs[i]['Gamma'].max() for i,r in enumerate(Rvec0)]) | ||
j = numpy.where(max_gammas<alpha)[0][0] | ||
a0 = max_gammas[j-1] | ||
a1 = max_gammas[j] | ||
r0 = Rvec0[j-1] | ||
r1 = Rvec0[j] | ||
rmax = r0 + (r1-r0)*(alpha-a0)/(a1-a0) | ||
Rlimit[p] = rmax | ||
|
||
# Constrained solutions | ||
|
||
R0 = 0.8 | ||
|
||
constrained_solutions = OrderedDict() | ||
|
||
for p in pvec: | ||
Rm = Rlimit[p] | ||
R1 = min([R0, Rm]) | ||
if Rm>0: | ||
df = solve_it(p=p, Rbar=R1) | ||
elif Rm<=0: | ||
df = solve_it(p=p, Rbar=0.001) | ||
df['R'] = R0 - df['f'].cumsum().shift() | ||
df['R'][0] = R0 | ||
constrained_solutions[p] = df | ||
|
||
d = {'dfs':constrained_solutions} | ||
|
||
import pickle | ||
with open("precomputed_alpha_p.pickle",'wb') as f: | ||
pickle.dump(d,f) | ||
|
||
### | ||
## | ||
### | ||
|
||
|
||
Rmax = 0.998 | ||
nRvec0 = numpy.array([0.01, 0.5, 0.9, Rmax, 2.0, 3.0]) | ||
ndfs = [solve_it(Rbar=i, min_f=0) for i in nRvec0] | ||
for i in [4,5]: | ||
df = ndfs[3].copy() | ||
ndfs[i] = df | ||
for i,df in enumerate(ndfs): | ||
df['R'] = nRvec0[i] - df['f'].cumsum() | ||
# | ||
# | ||
# # In[43]: | ||
# | ||
# | ||
# def plot_dfs(dfs, labels): | ||
# attributes = ['b', 'g', 'r'] | ||
# if not isinstance(dfs, list): | ||
# dfs = [dfs] | ||
# fig = plt.figure(figsize=(15,10)) | ||
# # plt.clear() | ||
# plt.subplot(131) | ||
# plt.plot(dfs[0].index,dfs[0].index*0+0.5,color='black', linestyle='--') | ||
# for i,df in enumerate(dfs): | ||
# plt.plot(df["Gamma"]) | ||
# | ||
# plt.grid() | ||
# plt.title("Marginal Value of Intervention") | ||
# # plt.figure() | ||
# plt.subplot(132) | ||
# for i,df in enumerate(dfs): | ||
# plt.plot(df["e"], label=labels[i]) | ||
# plt.legend(loc='lower right') | ||
# plt.grid() | ||
# plt.title("Exchange Rate") | ||
# plt.subplot(133) | ||
# for i,df in enumerate(dfs): | ||
# plt.plot(df["R"], label=labels[i]) | ||
# plt.grid() | ||
# plt.title("Reserves") | ||
# return fig | ||
# | ||
# | ||
# # In[44]: | ||
|
||
|
||
import pickle | ||
with open("precomputed_option_value.pickle","wb") as f: | ||
pickle.dump({"commitment":ndfs},f) | ||
|
||
# | ||
# # In[82]: | ||
# | ||
# | ||
# f = plot_dfs(ndfs, labels=['$R_0={}$'.format(i) for i in Rvec0]) | ||
# plt.savefig("optimal_choice_noconstraint.png", bbox_inches="tight") | ||
# plt.savefig("optimal_choice_noconstraint.pdf", bbox_inches="tight") | ||
# f | ||
# | ||
# | ||
# # In[11]: | ||
# | ||
# | ||
# Rvec0 = linspace(0.3, 3.0, 10) | ||
# dfs = [solve_it(Rbar=i) for i in Rvec0] | ||
# | ||
# | ||
# # In[12]: | ||
# | ||
# | ||
# f = plot_dfs(dfs, labels=['$R_0={}$'.format(i) for i in Rvec0]) | ||
# plt.savefig("optimal_choice_constraint.png", bbox_inches="tight") | ||
# plt.savefig("optimal_choice_constraint.pdf", bbox_inches="tight") | ||
# f |
Oops, something went wrong.