Overview
See Full code for a complete listing of the code in this example.
Pay Dates
We use the pay dates library to calculate a set of dates for which payments are due. The $group api is used to put the pay dates into a map for easy lookup later.
let dates = pd.dates(start, number, period, endOfMonth);
let dateMap = $group(dates, p=>p).toObject();
Tranches
We construct an array that keeps a list of the tranches. Each tranch has a paymnet amount, which is the contractual payment amount every period to that tranche, and a payments array which will contain a list of the payments to the tranche from the structure after the code has run. The array is ordered so that the first payments go to the first tranche in the list. Each tranche (other than the l)
let tranches = [{
payments:[],
payment:1000
},{
payments:[],
payment:1000
},{
payments:[],
payment:2000
}];
Aggregating Cash Flows and Payments
The asset cash flows and the payments are aggregated into a single array, representing dates where cash flows occur.
flows = [...flows, ...dates.map(p=>({date:p}))];
let cashFlows = $group(flows, p=>p.date).map((keys, values)=>{
let item = {
date:keys[0],
value : $list(values).filter(p=>p.value !== undefined).map(p=>p.value).sum(),
}
return item;
}).values();
Calculate Cash and Tranche Payments
The total cash in the structure is kept in the cash variable. Then the code iterates through the set of cash flows
let cash = 0;
for(let item of st.sort(cashFlows, p=>p.date)){
//increase the cash available by
cash += item.value;
if(item.date in dateMap){
item.fees = 10;
cash -= item.fees;
for(let tranche of tranches){
let payment = {
date:item.date,
value:0
};
if(cash > tranche.payment){
payment.value = tranche.payment;
cash-=payment.value;
}
else if(cash>0){
payment.value = cash;
cash = 0;
}
tranche.payments.push(payment);
}
}
item.cash = cash;
}