Stochastic Dedication model with borrowing and lending variables#
StochDedicationBL.py
StochDedicationBL.gdx
"""
## GAMSSOURCE: https://www.gams.com/latest/finlib_ml/libhtml/finlib_StochDedicationBL.html
## LICENSETYPE: Community
## MODELTYPE: LP
## DATAFILES: StochDedicationBL.gdx
Stochastic Dedication model with borrowing and lending variables
* StochDedicationBL.gms: Stochastic Dedication model with borrowing
* and lending variables.
* Consiglio, Nielsen and Zenios.
* PRACTICAL FINANCIAL OPTIMIZATION: A Library of GAMS Models, Section 6.2.2
* Last modified: Apr 2008.
"""
from __future__ import annotations
import os
from pathlib import Path
from gamspy import Container, Equation, Model, Sense, Sum, Variable
def main():
# Define container
m = Container(
system_directory=os.getenv("SYSTEM_DIRECTORY", None),
load_from=str(Path(__file__).parent.absolute())
+ "/StochDedicationBL.gdx",
)
# Aliases
l, t = m.getSymbols(["l", "t"])
# Scalars
Horizon = m.getSymbols(["Horizon"])[0]
# Parameters
tau = m.getSymbols(["tau"])[0]
# Aliases
i = m.getSymbols(["i"])[0]
# Scalars
spread = m.getSymbols(["spread"])[0]
# Parameters
Price = m.getSymbols(["Price"])[0]
# Parameters
Srf, SF, SLiability = m.getSymbols(
[
"Srf",
"SF",
"SLiability",
]
)
# Variables
x = Variable(
m, "x", domain=i, type="Positive", description="Face value purchased"
)
surplus = Variable(
m,
"surplus",
domain=[t, l],
type="Positive",
description="Amount of money reinvested",
)
borrow = Variable(
m,
"borrow",
domain=[t, l],
type="Positive",
description="Amount of money borrowed",
)
v0 = Variable(m, "v0", description="Upfront investment")
# Equations
CashFlowCon = Equation(
m,
"CashFlowCon",
domain=[t, l],
description="Equations defining the cashflow balance",
)
CashFlowCon[t, l] = (
Sum(i, SF[t, i, l] * x[i]).where[tau[t] > 0]
+ (v0 - Sum(i, Price[i] * x[i])).where[tau[t] == 0]
+ ((1 + Srf[t.lag(1), l]) * surplus[t.lag(1), l]).where[tau[t] > 0]
+ borrow[t, l].where[tau[t] < Horizon]
== surplus[t, l]
+ SLiability[t, l].where[tau[t] > 0]
+ ((1 + Srf[t.lag(1), l] + spread) * borrow[t.lag(1), l]).where[
tau[t] > 0
]
)
StochDedicationBL = Model(
m,
name="StochDedicationBL",
equations=[CashFlowCon],
problem="LP",
sense=Sense.MIN,
objective=v0,
)
StochDedicationBL.solve()
print(
"Objective Function Value: ",
round(StochDedicationBL.objective_value, 3),
)
print(x.description, ": \n", x.records.loc[:, ["i", "level"]])
if __name__ == "__main__":
main()