GAMS [ Home | Support | Sales | Solvers | Documentation | Model Libraries | Search | Contact Us ]

tba.gms : Financial Optimization: Financial Engineering


The delivery and settlement of mortgage-backed securities is governed
by an extensive set of rules and regulations. Forward delivery
settlements of not yet pooled mortgages are on a to-be-announced
(TPA) basis. Some allowed variance allows to structure the TBAs in
a cost effective manner.

Reference:
Large Model of Type: MIP
$Title Financial Optimization: Financial Engineering (TBA,SEQ=115) $Ontext The delivery and settlement of mortgage-backed securities is governed by an extensive set of rules and regulations. Forward delivery settlements of not yet pooled mortgages are on a to-be-announced (TPA) basis. Some allowed variance allows to structure the TBAs in a cost effective manner. Dahl, H, Meeraus, A, and Zenios, S A, Some Financial Optimization Models: Risk Management. In Zenios, S A, Ed, Financial Optimization. Cambridge University Press, New York, NY, 1993. $Offtext Sets p gnma pools / gn999001*gn999011 / i tbas / 20580252 / l lots / l1*l4 / c3(p) class 3 high risk pools / gn999010*gn999011 / ; * note: * class1 in the box * class2 delivery within 48 hours * class3 delayed delivery Alias (p,pp), (i,ii), (l,ll) ; Table pv(p,*) value of pools original adjusted gn999001 50 50 gn999002 100 100 gn999003 300 300 gn999004 400 400 gn999005 450 450 gn999006 450 450 gn999007 475 475 gn999008 700 700 gn999009 1000 1000 gn999010 1000 1000 gn999011 5000 5000 ; Table tbainfo(i,*) tba information table quantity selling market variation maxpools 20580252 5000 100.88 100 .05 3 ; Parameter o(p) original face value of pools a(p) adjusted face value of pools head first incremental step for allocation steps incremental step size between head and tail tail(p) tail of pools splitcost(p) cost of splitting pools futprice(i) agreed delivery price mktprice(i) market price futamt(i) agreed quantity var(i) agreed upper and lower relative deviation maxpools(i) maximum number of pools in 1 mill dollar tba lots lsize(i,l) tba lot sizes maxp(i,l) maximum number of pools to allocate to each lot m(p,i,l) upper bound on the number of value incremental steps mb(p) upper bound on the number of box incremental steps n total number of lots in the allocation ; o(p) = pv(p,"original") ; a(p) = pv(p,"adjusted") ; head = 25 ; steps = 5 ; tail(p) = mod((o(p)-head$(o(p) gt head)),steps) ; splitcost(p) = .00001 ; futamt(i) = tbainfo(i,"quantity") ; futprice(i) = tbainfo(i,"selling")/100 ; mktprice(i) = tbainfo(i,"market")/100 ; var(i) = tbainfo(i,"variation") ; maxpools(i) = tbainfo(i,"maxpools") ; lsize(i,l) = 0 ; Loop(l, lsize(i,l) = min(1000,futamt(i)-sum(ll$(ord(ll) lt ord(l)), lsize(i,ll)))) ; maxp(i,l) = (maxpools(i)-2) $ (lsize(i,l) lt 500) + (maxpools(i)-1) $ (lsize(i,l) ge 500 and lsize(i,l) lt 1000) + maxpools(i) $ (lsize(i,l) eq 1000) ; m(p,i,l) = floor( max( 0, ((1+var(i))*lsize(i,l)*o(p)/a(p)-head) / steps ) ); mb(p) = floor( max(0,o(p)-head)/steps) ; n = sum((i,l)$lsize(i,l), 1) ; Variable profit total profit ; Positive Variable v(p,i,l) allocated pool values by tba lot b(p) adjusted face value of pools remaining in box ; Binary Variable z(p,i,l) decision whether to allocated pool to tba lot zb1(p) auxiliary binary variable to determine splits zb2(p) auxiliary binary variable to determine splits w(i,l) decision whether to fail tba lot (0=failed) u0(p,i,l) auxiliary binary variable for minimum allocation u0b(p) auxiliary binary variable for minimum boxing ut(p,i,l) auxiliary binary variable for tail allocation ubt(p) auxiliary binary variable for tail boxing s(p) decision whether to split pools f1(i,l) binary variable for one big pool allocation f2(i,l) binary variable for two big pools allocation Integer Variable u(p,i,l) auxiliary integer variable for allocation steps ub(p) auxiliary integer variable for box steps ; Equation loval(i,l) lower limit on allocated value by tba lot upval(i,l) upper limit on allocated value by tba lot supply(p) allocate value and boxed amounts class3con(i,l) constraint on use of class 3 pools splitsize(p,i,l) allocate head step and tail variables stepcon(p,i,l) allocate step only after head allocation tailcon(p,i,l) allocate tail only after head allocation onetail(p) allocate tail only once for each pool boxsize(p) allocate boxed head step and tail variables stepboxcon(p) allocate boxed steps after boxed head boxtailcon(p) allocate boxed tail after boxed head zdet(p,i,l) determination of whether to allocate pool zbox1def(p) definition of zb1 zbox2def(p) definition of zb2 splitdet(p) determination of whether to split f1det(p,i,l) determination of single big allocated pools f2det(p,pp,i,l) determination of two big pools maxpool1(i,l) constraint on maximum pools per lot maxpool2(i,l) constraint on maximum pools per lot maxpool3(i,l) constraint on maximum pools per lot profitdef definition of profits ; $Stitle equations and model definition * * the value of pools assigned to a tba lot must be above the lower limit * given by the agreement on delivery and variance, unless the lot is * failed in which case it must be zero. * loval(i,l)$lsize(i,l).. sum(p, v(p,i,l)) =g= (1-var(i))*lsize(i,l)*w(i,l) ; * * the value of pools assigned to a tba lot must be below the upper limit * given by the agreement on delivery and variance, unless the lot is * failed in which case it must be zero. * upval(i,l)$lsize(i,l).. sum(p, v(p,i,l)) =l= (1+var(i))*lsize(i,l)*w(i,l) ; * * no more than the adjusted face value of a pool can be assigned * or boxed. * supply(p).. sum((i,l)$lsize(i,l), v(p,i,l)) + b(p) =e= a(p) ; * * it is illegal to use only class 3 pools in a lot. * class3con(i,l)$lsize(i,l).. sum(p$(not c3(p)), v(p,i,l)) =g= w(i,l) ; * * pools must be allocated in a minimum amount of head dollars of * original face value and with increments of steps dollars original face * value, except possibly for the tail. * splitsize(p,i,l)$lsize(i,l).. v(p,i,l)*o(p)/a(p) =e= head*u0(p,i,l) + steps*u(p,i,l) + tail(p)*ut(p,i,l) ; * * the steps increments in a split pool only applies after * the head has been allocated for the tba lot. * stepcon(p,i,l)$lsize(i,l).. u(p,i,l) =l= m(p,i,l)*u0(p,i,l) ; * * the tail increment in a split pool only applies after * the head has been allocated for the tba lot. * tailcon(p,i,l)$(lsize(i,l) and tail(p)).. ut(p,i,l) =l= u0(p,i,l) ; * * the tail of a pool can not be split. * onetail(p)$tail(p).. sum((i,l)$lsize(i,l), ut(p,i,l)) + ubt(p) =l= 1 ; * * the above size rules for split pools also apply to what remains in * the box. * boxsize(p).. b(p)*o(p)/a(p) =e= head*u0b(p) + steps*ub(p) + tail(p)*ubt(p) ; * * this also applies to the box. * stepboxcon(p).. ub(p) =l= mb(p)*u0b(p) ; * * the box tail increment in a split pool only applies after * the box head has been allocated for the pool. * boxtailcon(p)$tail(p).. ubt(p) =l= u0b(p) ; * * if a pool is not allocated to tba lot, the value of that allocation * must be zero. * zdet(p,i,l)$lsize(i,l).. v(p,i,l) =l= (1+var(i))*lsize(i,l)*z(p,i,l) ; * * zb1 is 1 if something or nothing - but not everything - of a * pool is boxed. it is zero if everything is boxed. * zbox1def(p).. zb1(p) =g= (a(p) - b(p))/a(p) ; * * zb2 is 1 if something or everything of a pool is boxed. it is zero * if nothing remains in the box. thus zb1 + zb2 equals 1 if * everything or nothing remains in the box and 2 otherwise. * zbox2def(p).. zb2(p) =g= 1 - (a(p) - b(p))/a(p) ; * * a pool is split if it is allocated to more than one lot or - if * allocated to only one lot - if it is not fully allocated, (i.e., * a fraction, but not all original value, remains in the box). * splitdet(p).. sum((i,l)$lsize(i,l), z(p,i,l)) + zb1(p) + zb2(p) - 2 =l= n*s(p) ; * * a single pool allocation is big if it is greater than or equal to * the lower value requirement. * f1det(p,i,l)$lsize(i,l).. 2*var(i)*lsize(i,l)*f1(i,l) =g= v(p,i,l) - (1-var(i))*lsize(i,l) ; * * a two pool allocation is big if the sum of the allocated values for * those two pools is greater than or equal to the minimum allocation * value requirement. * f2det(p,pp,i,l)$(lsize(i,l) and ord(p) lt ord(pp)).. 2*var(i)*lsize(i,l)*f2(i,l) =g= v(p,i,l) + v(pp,i,l) - (1-var(i))*lsize(i,l) ; * * no more than the specified number of pools can be allocated to a * lot. if a big single pool allocation takes place then only that * pool can be allocated, and if a big two pool allocation takes place * for a tba lot, then only those two pools can be allocated to the lot. * maxpool1(i,l)$lsize(i,l).. sum(p, z(p,i,l)) =l= maxp(i,l) ; maxpool2(i,l)$lsize(i,l).. sum(p, z(p,i,l)) =l= 1 + (1 - f1(i,l))*maxp(i,l) ; maxpool3(i,l)$lsize(i,l).. sum(p, z(p,i,l)) =l= 2 + (1 - f2(i,l))*maxp(i,l) ; * * total profit equals margin times delivery minus splitting costs. * profitdef.. profit =e= sum((p,i,l)$lsize(i,l), (futprice(i)-mktprice(i))*v(p,i,l)) - sum(p, splitcost(p)*s(p)) ; Model poolassign pool to tab lot assignment model / all /; u.up(p,i,l) = m(p,i,l) ; ub.up(p) = mb(p) ; * help the mip code along u.prior(p,i,l) = 2; ub.prior(p) = 2; poolassign.prioropt=1; poolassign.optcr = .0001; Solve poolassign maximizing profit using mip ;