Spot rate curve
Awaiting user inputHello Gurobi community!
I'd like to ask you for help with the following problem. I am trying to get the spot rate curve (r[t]) from set of coupon bonds with prices P[i] generating cashflows F[t,i] (having more bonds with the same maturity) using the discrete discounting accoarding to the following minimization formula.

My code as far is as follows.
import gurobipy as gp
from gurobipy import GRB
maturity = [2023, 2024, 2025, ...]
time = [i + 1 for i in range(len(maturity))]
bonds = ["TB-1-24", "TB-2-24", "TB-3-24", ...]
data = {
"TB-1-24": {"price": 95.172, "maturity": 2024, "coupon": 0.125, "ytm": 0.0520415},
"TB-2-24": {"price": 96.034, "maturity": 2024, "coupon": 0.750, "ytm": 0.0491065},
...
}
for i, value in enumerate(data):
data[value]["coupon"] = data[value]["coupon"] / 100
F = np.zeros((len(maturity), len(bonds))) # np.array for storing cashflows
m = gp.Model("Spot rate curve")
r = m.addVars(len(time), lb=-100, name="r")
S = m.addVar(lb=0, name="S") # expression under sqrt
SS = m.addVar(lb=0, name="SS")
m.addConstr(
gp.quicksum(
(
data[bonds[i]]["price"]
- gp.quicksum(F[t, i] / ((1 + r[t]) ^ t) for t in time)
)
for i in range(len(bonds))
)
== S
)
m.addGenConstrPow(SS, S, 2, "gf", "FuncPieces=1000") # SS^2 = S
obj = SS
m.setObjective(obj, GRB.MINIMIZE)
m.optimize()
I think my solution of the sqrt part might be correct, but i was struggeling with the second sum expression. I can also provide full input data if needed. Thank you for any advice.
-
Hi Daniel,
Indeed, formulating this function in a Gurobi model is a bit involved.
First, you do not need addGenConstrPow() for quadratic terms, those are directly supported in the constraint formulation. In your case, you can remove variable SS, just state "... = S * S" in your sum constraints, and minimize S.
Regarding the fraction in the sum, as far as I can see from your code only the r(t) are variables, correct?
If yes, then you could create additional helper variables x(i,t) that are equivalent to the fraction for i and t, variables y(t) that correspond to (1+r(t)), and variables z(t) that correspond to y(t) ^ t. This leads to constraintsS*S = sum_{i=1 to N} [ P(0,i) - sum_{t=1 to T} x(i,t) ]
x(i,t) * z(t) = F(t,i)
z(t) = y(t)^t (implemented via addGenConstrPow())
y(t) = 1 + r(t)Except for the 3rd constraints, you can write every constraint in a straightforward way with addConstr().
Did I miss something?
Best regards,
Mario0
Please sign in to leave a comment.
Comments
1 comment