-
Basics Part 1 2
-
Lecture1.1
-
Lecture1.2
-
-
Basics Part 2 1
-
Lecture2.1
-
-
Credit Migration 2
-
Lecture3.1
-
Lecture3.2
-
-
Vasicek Model 2
-
Lecture4.1
-
Lecture4.2
-
-
Payments 2
-
Lecture5.1
-
Lecture5.2
-
-
Complete System 2
-
Lecture6.1
-
Lecture6.2
-
Basic Simulation
Now, let’s begin using cadCAD. Documentation found here that will explain the ideas of policies, state variables and more.
The first thing we want to do is assign an interest rate that will be used as our initial state. We do this with a dictionary where r is our variable.
#Set an initial interest rate
initial_state = {'r': .08}
Next, we can build out first policy. A policy will take the parameters _params, substep, sH, s and return a dictionary of values. For now, we only need to understand what the input s is. It is the current state, so it will give us at the current time step what the state of r is. We will get the current state of r, apply the random rate change, then return a dictionary with the key r containing the value for the updated r.
#Policy for updating
def vasicek_policy(_params, substep, sH, s):
r = rate_change(s['r'])
return {'r': r}
The variables update takes the parameters _params, substep, sH, s, _input. In this case, you have to return a tuple with the first value as the variable name and the second as the value. We also can use the _input parameter to get the values passed from policies. In this simulation, the variable r is going to be passed from the policy we created above. This function we define below is really simple and will just assign the value to r.
#Simple state update
def update_rate(_params, substep, sH, s, _input):
return ('r', _input['r'])
Now, we create the sub-steps. The sub-steps are a list of nested dictionaries which have policies and variables as the keys. For this basic simulation we only will need to do one dictionary in the list and the policies and the variables will be just one policy and variable updates.
#Partial updates
PSUBs = [
{
"policies": {
"rate_policy": vasicek_policy,
},
"variables": {
"r": update_rate,
}
}
]
Every simulation needs configuration options. We need a dictionary with keys T for number of time steps, N for number of runs, and optionally M if we want parameters. In this first simulation we do not need M because there are no parameters we are working with. This dictionary is passed to config_sim from cadCAD.
#Set simulation parameters
from cadCAD.configuration.utils import config_sim
sim_config_dict = {
'T': range(360),
'N': 100}
c = config_sim(sim_config_dict)
Now that we have the partial update steps, the initial configuration, as well as the simulation configuration we make an experiment. First you create an instance of the class Experiment, and then use the append_configs function passing the initial state, partial_state_update_blocks and sim_configs.
from cadCAD.configuration import Experiment
#Build the experiment
exp = Experiment()
exp.append_configs(
initial_state = initial_state,
partial_state_update_blocks = PSUBs,
sim_configs = c
)
The following will execute the simulation.
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
from cadCAD import configs
#Create the simulation
exec_mode = ExecutionMode()
local_mode_ctx = ExecutionContext(context=exec_mode.single_mode)
simulation = Executor(exec_context=local_mode_ctx, configs=configs)
#Execute the simulation
raw_result, tensor_field, sessions = simulation.execute()
result = pd.DataFrame(raw_result)
print(result)
Now we can plot the first 3 paths as well as the average of the 100 paths!
import matplotlib.pyplot as plt
#Plot 3 paths
result.pivot("timestep", "run", 'r').iloc[:,:3].plot(kind='line')
plt.xlabel("Month")
plt.ylabel("Rate")
plt.title("Vasicek Rates")
plt.show()
#Visualize average path of the 100 simulations
result.groupby('timestep')['r'].mean().plot(kind='line')
plt.xlabel("Month")
plt.ylabel("Rate")
plt.title("Vasicek Rates")
plt.show()