// 4.4.js // 2024-09-25 // $Id: 4.4.js 1.1 2024/11/01 22:01:26 s Exp $ 'use strict' const math = require("./math.js"); // https://mathjs.org // An extensive math library for JavaScript and Node.js //# input const face_value = 1000 const coupon_rate = [6 + 5/8, 9 + 1/8, 7 + 7/8, 8 + 1/4, 8 + 1/4, 8 + 3/8, 8, 8 + 3/4, 6 + 7/8, 8 + 7/8, 6 + 7/8, 8 + 5/8, 7 + 3/4, 11 + 1/4, 8 + 1/2, 10 + 1/2, 7 + 7/8, 8 + 7/8]; const ask_price = [100+ 0/32, 100+22/32, 100+24/32, 101+1/32, 101+ 7/32, 101+12/32, 100+26/32, 102+ 1/32, 98+5/32, 102+ 9/32, 97+13/32, 101+23/32, 99+ 5/32, 109+4/32, 101+13/32, 107+27/32, 99+13/32, 103+ 0/32]; const today = new Date("2011-11-05"); const last_coupon = new Date("2011-08-15"); const next_coupon = new Date("2012-02-15"); // calculating const coupon = coupon_rate.map(x => face_value * x / 100 / 2); const t = [(new Date("2012-02-15") - today) /1000/60/60/24 / 365, (new Date("2012-08-15") - today) /1000/60/60/24 / 365, (new Date("2013-02-15") - today) /1000/60/60/24 / 365, (new Date("2013-08-15") - today) /1000/60/60/24 / 365, (new Date("2014-02-15") - today) /1000/60/60/24 / 365, (new Date("2014-08-15") - today) /1000/60/60/24 / 365, (new Date("2015-02-15") - today) /1000/60/60/24 / 365, (new Date("2015-08-15") - today) /1000/60/60/24 / 365, (new Date("2016-02-15") - today) /1000/60/60/24 / 365]; const number_of_days_since_last_coupon = (today - last_coupon) /1000/60/60/24; //.days const number_of_days_in_current_coupon_period = (next_coupon - last_coupon) /1000/60/60/24;//.days const accrued_interest = coupon.map(x => number_of_days_since_last_coupon / number_of_days_in_current_coupon_period * x); const total_price = ask_price.map((_, i) => face_value * ask_price[i] / 100 + accrued_interest[i]); const cf0 = [coupon[ 0]+face_value,0,0,0,0,0,0,0,0]; const cf1 = [coupon[ 1]+face_value,0,0,0,0,0,0,0,0]; const cf2 = [coupon[ 2],coupon[ 2]+face_value,0,0,0,0,0,0,0]; const cf3 = [coupon[ 3],coupon[ 3]+face_value,0,0,0,0,0,0,0]; const cf4 = [coupon[ 4],coupon[ 4],coupon[ 4]+face_value,0,0,0,0,0,0]; const cf5 = [coupon[ 5],coupon[ 5],coupon[ 5]+face_value,0,0,0,0,0,0]; const cf6 = [coupon[ 6],coupon[ 6],coupon[ 6],coupon[ 6]+face_value, 0,0,0,0,0]; const cf7 = [coupon[ 7],coupon[ 7],coupon[ 7],coupon[ 7]+face_value, 0,0,0,0,0]; const cf8 = [coupon[ 8],coupon[ 8],coupon[ 8],coupon[ 8],coupon[ 8]+ face_value,0,0,0,0]; const cf9 = [coupon[ 9],coupon[ 9],coupon[ 9],coupon[ 9],coupon[ 9]+ face_value,0,0,0,0]; const cf10= [coupon[10],coupon[10],coupon[10],coupon[10],coupon[10], coupon[10]+face_value,0,0,0]; const cf11= [coupon[11],coupon[11],coupon[11],coupon[11],coupon[11], coupon[11]+face_value,0,0,0]; const cf12= [coupon[12],coupon[12],coupon[12],coupon[12],coupon[12], coupon[12],coupon[12]+face_value,0,0]; const cf13= [coupon[13],coupon[13],coupon[13],coupon[13],coupon[13], coupon[13],coupon[13]+face_value,0,0]; const cf14= [coupon[14],coupon[14],coupon[14],coupon[14],coupon[14], coupon[14],coupon[14],coupon[14]+face_value,0]; const cf15= [coupon[15],coupon[15],coupon[15],coupon[15],coupon[15], coupon[15],coupon[15],coupon[15]+face_value,0]; const cf16= [coupon[16],coupon[16],coupon[16],coupon[16],coupon[16], coupon[16],coupon[16],coupon[16],coupon[16]+face_value]; const cf17= [coupon[17],coupon[17],coupon[17],coupon[17],coupon[17], coupon[17],coupon[17],coupon[17],coupon[17]+face_value]; const w1 = [cf0, cf1, cf2, cf3, cf4, cf5, cf6, cf7, cf8, cf9, cf10, cf11, cf12, cf13, cf14, cf15, cf16, cf17]; const y1 = total_price; // least suquare method // [w1]{beta1} = {y1} // [w1]^T [w1]{beta1} = [w1]^T {y1} // {beta1} = ([w1]^T [w1])^-1 [w1]^T]{y1} const A1 = math.multiply(math.transpose(w1), w1); const b1 = math.multiply(math.transpose(w1), y1); const beta1 = math.lusolve(A1, b1).flat(); const d = beta1; const r = d.map((_, i) => - Math.log(d[i]) / t[i]); const w2 = [[0,1,2,3,4].map(x => t[0] ** x), [0,1,2,3,4].map(x => t[1] ** x), [0,1,2,3,4].map(x => t[2] ** x), [0,1,2,3,4].map(x => t[3] ** x), [0,1,2,3,4].map(x => t[4] ** x), [0,1,2,3,4].map(x => t[5] ** x), [0,1,2,3,4].map(x => t[6] ** x), [0,1,2,3,4].map(x => t[7] ** x), [0,1,2,3,4].map(x => t[8] ** x)]; const y2 = r; const A2 = math.multiply(math.transpose(w2), w2); const b2 = math.multiply(math.transpose(w2), y2); const beta2 = math.lusolve(A2, b2).flat(); // output console.log('4.4.js'); console.log('face value', face_value); console.log('last_coupon', last_coupon.toISOString().substring(0,10)); console.log('today ', today.toISOString().substring(0,10)); console.log('next coupon', next_coupon.toISOString().substring(0,10)); console.log('number_of_days_since_last_coupon= ', number_of_days_since_last_coupon); console.log('number_of_days_in_current_coupon_period= ', number_of_days_in_current_coupon_period); console.log(); console.log('i'.padStart(10), 'a_price'.padStart(10), 'coupon'.padStart(10), 'a.interest'.padStart(10), 'total_price'.padStart(10)) console.log("-".repeat(54)); for(let i = 0; i < ask_price.length; i++){ console.log(i.toFixed(0).padStart(10), ask_price[i].toFixed(1).padStart(10), coupon[i].toFixed(2).padStart(10), accrued_interest[i].toFixed(2).padStart(10), total_price[i].toFixed(2).padStart(10)); } console.log("-".repeat(54)); console.log('a_price = ask price'); console.log('a.interest = accrued interest'); console.log(); // print t console.log('i'.padStart(10), 't'.padStart(10)); console.log('-'.repeat(21)); for(let i = 0; i < t.length; i++){ console.log(i.toFixed(0).padStart(10), t[i].toFixed(3).padStart(10)); } console.log('-'.repeat(21));console.log(); // print y1 console.log('i'.padStart(10), 'y1'.padStart(10)); console.log('-'.repeat(21)); for(let i = 0; i < y1.length; i++){ console.log(i.toFixed(0).padStart(10), y1[i].toFixed(0).padStart(10)); } console.log('-'.repeat(21));console.log(); // print w1 console.log('w1, matrix of cf(in integer) in row'); let nn = 5; console.log( 'i'.padStart(nn), "t0".padStart(nn), "t1".padStart(nn), "t2".padStart(nn), "t3".padStart(nn), "t4".padStart(nn), "t5".padStart(nn), "t6".padStart(nn), "t7".padStart(nn), "t8".padStart(nn)); console.log("-".repeat(60)); for(let i = 0; i < w1.length; i++){ console.log(i.toFixed(0).padStart(nn), w1[i][0].toFixed(0).padStart(nn), w1[i][1].toFixed(0).padStart(nn), w1[i][2].toFixed(0).padStart(nn), w1[i][3].toFixed(0).padStart(nn), w1[i][4].toFixed(0).padStart(nn), w1[i][5].toFixed(0).padStart(nn), w1[i][6].toFixed(0).padStart(nn), w1[i][7].toFixed(0).padStart(nn), w1[i][8].toFixed(0).padStart(nn)); } console.log("-".repeat(60));console.log(); // print beta1 console.log('estimated beta1, d(t[i])'); console.log('i'.padStart(10), 'beta1[i]'.padStart(10)); console.log('-'.repeat(20+1)); for(let i = 0; i < beta1.length; i++){ console.log(i.toFixed(0).padStart(10), beta1[i].toFixed(3).padStart(10)); } console.log('-'.repeat(20 + 1));console.log(); // print r console.log('estimated r(t[i])'); console.log('i'.padStart(10), 'r(t[i])'.padStart(10)); console.log('-'.repeat(20 +1)); for(let i = 0; i < r.length; i++){ console.log(i.toFixed(0).padStart(10), r[i].toFixed(4).padStart(10)); } console.log('-'.repeat(20 + 1));console.log(); // print w2 nn = 8; console.log('w2, coefficent matrix'); console.log('i'.padStart(nn), '1'.padStart(nn), 't'.padStart(nn), 't^2'.padStart(nn), 't^3'.padStart(nn), 't^4'.padStart(nn)); console.log('-'.repeat(6 *(nn + 1))); for(let i = 0; i < w2.length; i++){ console.log(i.toFixed(0).padStart(nn), w2[i][0].toFixed(3).padStart(nn), w2[i][1].toFixed(3).padStart(nn), w2[i][2].toFixed(3).padStart(nn), w2[i][3].toFixed(3).padStart(nn), w2[i][4].toFixed(3).padStart(nn)); } console.log('-'.repeat(6 * (nn + 1)));console.log(); // print beta2 console.log('beta2, estimated a[i] for r(t)'); console.log('i'.padStart(10), 'a[i]'.padStart(15)); console.log('-'.repeat(30)); for(let i = 0; i < beta2.length; i++){ console.log(i.toFixed(0).padStart(10), beta2[i].toFixed(5).padStart(15)); } console.log('-'.repeat(30));console.log(); // print r equation estimated const a = beta2.flat(); console.log('estimated r(t)='); console.log(a[0].toFixed(5), '+', a[1].toFixed(5), 't +', a[2].toFixed(5), 't^2 +', a[3].toFixed(5), 't^3 +', a[4].toFixed(5), 't^4'); // end