@fintekkers/ledger-models 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/hierarchy.json +2 -2
- package/node/fintekkers/models/security/bond/agency_grpc_pb.js +1 -0
- package/node/fintekkers/models/security/bond/agency_pb.d.ts +14 -0
- package/node/fintekkers/models/security/bond/agency_pb.js +35 -0
- package/node/fintekkers/models/security/product_type_pb.d.ts +1 -0
- package/node/fintekkers/models/security/product_type_pb.js +1 -0
- package/node/fintekkers/models/security/security_pb.d.ts +69 -0
- package/node/fintekkers/models/security/security_pb.js +572 -1
- package/node/wrappers/models/security/MortgageBackedSecurity.d.ts +48 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.d.ts +1 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.js +93 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.js.map +1 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.ts +107 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.js +131 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.js.map +1 -0
- package/node/wrappers/models/security/MortgageBackedSecurity.ts +125 -0
- package/node/wrappers/models/security/security.d.ts +1 -0
- package/node/wrappers/models/security/security.js +6 -1
- package/node/wrappers/models/security/security.js.map +1 -1
- package/node/wrappers/models/security/security.ts +6 -1
- package/package.json +1 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const security_1 = __importDefault(require("./security"));
|
|
7
|
+
const BondSecurity_1 = __importDefault(require("./BondSecurity"));
|
|
8
|
+
const MortgageBackedSecurity_1 = __importDefault(require("./MortgageBackedSecurity"));
|
|
9
|
+
const security_pb_1 = require("../../../fintekkers/models/security/security_pb");
|
|
10
|
+
const product_type_pb_1 = require("../../../fintekkers/models/security/product_type_pb");
|
|
11
|
+
const coupon_type_pb_1 = require("../../../fintekkers/models/security/coupon_type_pb");
|
|
12
|
+
const coupon_frequency_pb_1 = require("../../../fintekkers/models/security/coupon_frequency_pb");
|
|
13
|
+
const agency_pb_1 = require("../../../fintekkers/models/security/bond/agency_pb");
|
|
14
|
+
const date_1 = require("../utils/date");
|
|
15
|
+
const local_date_pb_1 = require("../../../fintekkers/models/util/local_date_pb");
|
|
16
|
+
const decimal_js_1 = require("decimal.js");
|
|
17
|
+
function makeDate(y, m, d) {
|
|
18
|
+
return new date_1.LocalDate(new local_date_pb_1.LocalDateProto().setYear(y).setMonth(m).setDay(d));
|
|
19
|
+
}
|
|
20
|
+
const baseInputs = {
|
|
21
|
+
faceValue: new decimal_js_1.Decimal('250000000'),
|
|
22
|
+
couponRate: new decimal_js_1.Decimal('0.04'),
|
|
23
|
+
couponType: coupon_type_pb_1.CouponTypeProto.FIXED,
|
|
24
|
+
couponFrequency: coupon_frequency_pb_1.CouponFrequencyProto.MONTHLY,
|
|
25
|
+
issueDate: makeDate(2024, 1, 1),
|
|
26
|
+
maturityDate: makeDate(2054, 1, 1),
|
|
27
|
+
};
|
|
28
|
+
const mbsInputs = Object.assign(Object.assign({}, baseInputs), { poolNumber: 'FN AS1234', agency: agency_pb_1.AgencyProto.FNMA, wac: new decimal_js_1.Decimal('0.045'), wam: 358, passThroughRate: new decimal_js_1.Decimal('0.04'), currentFactor: new decimal_js_1.Decimal('0.95'), originalFaceValue: new decimal_js_1.Decimal('250000000'), currentUpb: new decimal_js_1.Decimal('237500000'), psaSpeed: new decimal_js_1.Decimal('150') });
|
|
29
|
+
test('MortgageBackedSecurity.fromPricerInputs populates bond_details and mbs_extension', () => {
|
|
30
|
+
var _a, _b, _c, _d, _e, _f;
|
|
31
|
+
const proto = MortgageBackedSecurity_1.default.fromPricerInputs(mbsInputs);
|
|
32
|
+
expect(proto.getProductType()).toBe(product_type_pb_1.ProductTypeProto.MORTGAGE_BACKED);
|
|
33
|
+
expect(proto.hasBondDetails()).toBe(true);
|
|
34
|
+
expect(proto.hasMbsExtension()).toBe(true);
|
|
35
|
+
const ext = proto.getMbsExtension();
|
|
36
|
+
expect(ext.getPoolNumber()).toBe('FN AS1234');
|
|
37
|
+
expect(ext.getAgency()).toBe(agency_pb_1.AgencyProto.FNMA);
|
|
38
|
+
expect((_a = ext.getWac()) === null || _a === void 0 ? void 0 : _a.getArbitraryPrecisionValue()).toBe('0.045');
|
|
39
|
+
expect(ext.getWam()).toBe(358);
|
|
40
|
+
expect((_b = ext.getPassThroughRate()) === null || _b === void 0 ? void 0 : _b.getArbitraryPrecisionValue()).toBe('0.04');
|
|
41
|
+
expect((_c = ext.getCurrentFactor()) === null || _c === void 0 ? void 0 : _c.getArbitraryPrecisionValue()).toBe('0.95');
|
|
42
|
+
expect((_d = ext.getOriginalFaceValue()) === null || _d === void 0 ? void 0 : _d.getArbitraryPrecisionValue()).toBe('250000000');
|
|
43
|
+
expect((_e = ext.getCurrentUpb()) === null || _e === void 0 ? void 0 : _e.getArbitraryPrecisionValue()).toBe('237500000');
|
|
44
|
+
expect((_f = ext.getPsaSpeed()) === null || _f === void 0 ? void 0 : _f.getArbitraryPrecisionValue()).toBe('150');
|
|
45
|
+
});
|
|
46
|
+
test('MortgageBackedSecurity round-trips via serializeBinary / deserializeBinary preserving all 9 mbs fields', () => {
|
|
47
|
+
var _a, _b, _c, _d, _e, _f;
|
|
48
|
+
const proto = MortgageBackedSecurity_1.default.fromPricerInputs(mbsInputs);
|
|
49
|
+
const bytes = proto.serializeBinary();
|
|
50
|
+
const round = security_pb_1.SecurityProto.deserializeBinary(bytes);
|
|
51
|
+
expect(round.getProductType()).toBe(product_type_pb_1.ProductTypeProto.MORTGAGE_BACKED);
|
|
52
|
+
expect(round.hasBondDetails()).toBe(true);
|
|
53
|
+
expect(round.hasMbsExtension()).toBe(true);
|
|
54
|
+
const ext = round.getMbsExtension();
|
|
55
|
+
expect(ext.getPoolNumber()).toBe('FN AS1234');
|
|
56
|
+
expect(ext.getAgency()).toBe(agency_pb_1.AgencyProto.FNMA);
|
|
57
|
+
expect((_a = ext.getWac()) === null || _a === void 0 ? void 0 : _a.getArbitraryPrecisionValue()).toBe('0.045');
|
|
58
|
+
expect(ext.getWam()).toBe(358);
|
|
59
|
+
expect((_b = ext.getPassThroughRate()) === null || _b === void 0 ? void 0 : _b.getArbitraryPrecisionValue()).toBe('0.04');
|
|
60
|
+
expect((_c = ext.getCurrentFactor()) === null || _c === void 0 ? void 0 : _c.getArbitraryPrecisionValue()).toBe('0.95');
|
|
61
|
+
expect((_d = ext.getOriginalFaceValue()) === null || _d === void 0 ? void 0 : _d.getArbitraryPrecisionValue()).toBe('250000000');
|
|
62
|
+
expect((_e = ext.getCurrentUpb()) === null || _e === void 0 ? void 0 : _e.getArbitraryPrecisionValue()).toBe('237500000');
|
|
63
|
+
expect((_f = ext.getPsaSpeed()) === null || _f === void 0 ? void 0 : _f.getArbitraryPrecisionValue()).toBe('150');
|
|
64
|
+
});
|
|
65
|
+
test('MortgageBackedSecurity wraps via Security.create factory dispatch', () => {
|
|
66
|
+
const proto = MortgageBackedSecurity_1.default.fromPricerInputs(mbsInputs);
|
|
67
|
+
const sec = security_1.default.create(proto);
|
|
68
|
+
expect(sec).toBeInstanceOf(MortgageBackedSecurity_1.default);
|
|
69
|
+
// Inherits BondSecurity behaviour.
|
|
70
|
+
expect(sec).toBeInstanceOf(BondSecurity_1.default);
|
|
71
|
+
expect(sec.isBond()).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
test('MortgageBackedSecurity typed accessors read back the expected values', () => {
|
|
74
|
+
var _a, _b, _c, _d, _e, _f;
|
|
75
|
+
const proto = MortgageBackedSecurity_1.default.fromPricerInputs(mbsInputs);
|
|
76
|
+
const sec = security_1.default.create(proto);
|
|
77
|
+
// Bond-side checks (inherited from BondSecurity).
|
|
78
|
+
expect(sec.getCouponRate().getArbitraryPrecisionValue()).toBe('0.04');
|
|
79
|
+
expect(sec.getFaceValue().getArbitraryPrecisionValue()).toBe('250000000');
|
|
80
|
+
expect(sec.getIssueDate().toDate().getFullYear()).toBe(2024);
|
|
81
|
+
expect(sec.getMaturityDate().toDate().getFullYear()).toBe(2054);
|
|
82
|
+
// MBS-specific accessor checks.
|
|
83
|
+
expect(sec.getPoolNumber()).toBe('FN AS1234');
|
|
84
|
+
expect(sec.getAgency()).toBe(agency_pb_1.AgencyProto.FNMA);
|
|
85
|
+
expect((_a = sec.getWac()) === null || _a === void 0 ? void 0 : _a.toString()).toBe('0.045');
|
|
86
|
+
expect(sec.getWam()).toBe(358);
|
|
87
|
+
expect((_b = sec.getPassThroughRate()) === null || _b === void 0 ? void 0 : _b.toString()).toBe('0.04');
|
|
88
|
+
expect((_c = sec.getCurrentFactor()) === null || _c === void 0 ? void 0 : _c.toString()).toBe('0.95');
|
|
89
|
+
expect((_d = sec.getOriginalFaceValue()) === null || _d === void 0 ? void 0 : _d.toString()).toBe('250000000');
|
|
90
|
+
expect((_e = sec.getCurrentUpb()) === null || _e === void 0 ? void 0 : _e.toString()).toBe('237500000');
|
|
91
|
+
expect((_f = sec.getPsaSpeed()) === null || _f === void 0 ? void 0 : _f.toString()).toBe('150');
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=MortgageBackedSecurity.fromPricerInputs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MortgageBackedSecurity.fromPricerInputs.test.js","sourceRoot":"","sources":["MortgageBackedSecurity.fromPricerInputs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import Security from './security';
|
|
2
|
+
import BondSecurity from './BondSecurity';
|
|
3
|
+
import MortgageBackedSecurity from './MortgageBackedSecurity';
|
|
4
|
+
import { SecurityProto } from '../../../fintekkers/models/security/security_pb';
|
|
5
|
+
import { ProductTypeProto } from '../../../fintekkers/models/security/product_type_pb';
|
|
6
|
+
import { CouponTypeProto } from '../../../fintekkers/models/security/coupon_type_pb';
|
|
7
|
+
import { CouponFrequencyProto } from '../../../fintekkers/models/security/coupon_frequency_pb';
|
|
8
|
+
import { AgencyProto } from '../../../fintekkers/models/security/bond/agency_pb';
|
|
9
|
+
import { LocalDate } from '../utils/date';
|
|
10
|
+
import { LocalDateProto } from '../../../fintekkers/models/util/local_date_pb';
|
|
11
|
+
import { Decimal } from 'decimal.js';
|
|
12
|
+
|
|
13
|
+
function makeDate(y: number, m: number, d: number): LocalDate {
|
|
14
|
+
return new LocalDate(new LocalDateProto().setYear(y).setMonth(m).setDay(d));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const baseInputs = {
|
|
18
|
+
faceValue: new Decimal('250000000'),
|
|
19
|
+
couponRate: new Decimal('0.04'),
|
|
20
|
+
couponType: CouponTypeProto.FIXED,
|
|
21
|
+
couponFrequency: CouponFrequencyProto.MONTHLY,
|
|
22
|
+
issueDate: makeDate(2024, 1, 1),
|
|
23
|
+
maturityDate: makeDate(2054, 1, 1),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const mbsInputs = {
|
|
27
|
+
...baseInputs,
|
|
28
|
+
poolNumber: 'FN AS1234',
|
|
29
|
+
agency: AgencyProto.FNMA,
|
|
30
|
+
wac: new Decimal('0.045'),
|
|
31
|
+
wam: 358,
|
|
32
|
+
passThroughRate: new Decimal('0.04'),
|
|
33
|
+
currentFactor: new Decimal('0.95'),
|
|
34
|
+
originalFaceValue: new Decimal('250000000'),
|
|
35
|
+
currentUpb: new Decimal('237500000'),
|
|
36
|
+
psaSpeed: new Decimal('150'),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
test('MortgageBackedSecurity.fromPricerInputs populates bond_details and mbs_extension', () => {
|
|
40
|
+
const proto = MortgageBackedSecurity.fromPricerInputs(mbsInputs);
|
|
41
|
+
expect(proto.getProductType()).toBe(ProductTypeProto.MORTGAGE_BACKED);
|
|
42
|
+
expect(proto.hasBondDetails()).toBe(true);
|
|
43
|
+
expect(proto.hasMbsExtension()).toBe(true);
|
|
44
|
+
|
|
45
|
+
const ext = proto.getMbsExtension()!;
|
|
46
|
+
expect(ext.getPoolNumber()).toBe('FN AS1234');
|
|
47
|
+
expect(ext.getAgency()).toBe(AgencyProto.FNMA);
|
|
48
|
+
expect(ext.getWac()?.getArbitraryPrecisionValue()).toBe('0.045');
|
|
49
|
+
expect(ext.getWam()).toBe(358);
|
|
50
|
+
expect(ext.getPassThroughRate()?.getArbitraryPrecisionValue()).toBe('0.04');
|
|
51
|
+
expect(ext.getCurrentFactor()?.getArbitraryPrecisionValue()).toBe('0.95');
|
|
52
|
+
expect(ext.getOriginalFaceValue()?.getArbitraryPrecisionValue()).toBe('250000000');
|
|
53
|
+
expect(ext.getCurrentUpb()?.getArbitraryPrecisionValue()).toBe('237500000');
|
|
54
|
+
expect(ext.getPsaSpeed()?.getArbitraryPrecisionValue()).toBe('150');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('MortgageBackedSecurity round-trips via serializeBinary / deserializeBinary preserving all 9 mbs fields', () => {
|
|
58
|
+
const proto = MortgageBackedSecurity.fromPricerInputs(mbsInputs);
|
|
59
|
+
const bytes = proto.serializeBinary();
|
|
60
|
+
const round = SecurityProto.deserializeBinary(bytes);
|
|
61
|
+
|
|
62
|
+
expect(round.getProductType()).toBe(ProductTypeProto.MORTGAGE_BACKED);
|
|
63
|
+
expect(round.hasBondDetails()).toBe(true);
|
|
64
|
+
expect(round.hasMbsExtension()).toBe(true);
|
|
65
|
+
|
|
66
|
+
const ext = round.getMbsExtension()!;
|
|
67
|
+
expect(ext.getPoolNumber()).toBe('FN AS1234');
|
|
68
|
+
expect(ext.getAgency()).toBe(AgencyProto.FNMA);
|
|
69
|
+
expect(ext.getWac()?.getArbitraryPrecisionValue()).toBe('0.045');
|
|
70
|
+
expect(ext.getWam()).toBe(358);
|
|
71
|
+
expect(ext.getPassThroughRate()?.getArbitraryPrecisionValue()).toBe('0.04');
|
|
72
|
+
expect(ext.getCurrentFactor()?.getArbitraryPrecisionValue()).toBe('0.95');
|
|
73
|
+
expect(ext.getOriginalFaceValue()?.getArbitraryPrecisionValue()).toBe('250000000');
|
|
74
|
+
expect(ext.getCurrentUpb()?.getArbitraryPrecisionValue()).toBe('237500000');
|
|
75
|
+
expect(ext.getPsaSpeed()?.getArbitraryPrecisionValue()).toBe('150');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('MortgageBackedSecurity wraps via Security.create factory dispatch', () => {
|
|
79
|
+
const proto = MortgageBackedSecurity.fromPricerInputs(mbsInputs);
|
|
80
|
+
const sec = Security.create(proto);
|
|
81
|
+
expect(sec).toBeInstanceOf(MortgageBackedSecurity);
|
|
82
|
+
// Inherits BondSecurity behaviour.
|
|
83
|
+
expect(sec).toBeInstanceOf(BondSecurity);
|
|
84
|
+
expect(sec.isBond()).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('MortgageBackedSecurity typed accessors read back the expected values', () => {
|
|
88
|
+
const proto = MortgageBackedSecurity.fromPricerInputs(mbsInputs);
|
|
89
|
+
const sec = Security.create(proto) as MortgageBackedSecurity;
|
|
90
|
+
|
|
91
|
+
// Bond-side checks (inherited from BondSecurity).
|
|
92
|
+
expect(sec.getCouponRate().getArbitraryPrecisionValue()).toBe('0.04');
|
|
93
|
+
expect(sec.getFaceValue().getArbitraryPrecisionValue()).toBe('250000000');
|
|
94
|
+
expect(sec.getIssueDate().toDate().getFullYear()).toBe(2024);
|
|
95
|
+
expect(sec.getMaturityDate().toDate().getFullYear()).toBe(2054);
|
|
96
|
+
|
|
97
|
+
// MBS-specific accessor checks.
|
|
98
|
+
expect(sec.getPoolNumber()).toBe('FN AS1234');
|
|
99
|
+
expect(sec.getAgency()).toBe(AgencyProto.FNMA);
|
|
100
|
+
expect(sec.getWac()?.toString()).toBe('0.045');
|
|
101
|
+
expect(sec.getWam()).toBe(358);
|
|
102
|
+
expect(sec.getPassThroughRate()?.toString()).toBe('0.04');
|
|
103
|
+
expect(sec.getCurrentFactor()?.toString()).toBe('0.95');
|
|
104
|
+
expect(sec.getOriginalFaceValue()?.toString()).toBe('250000000');
|
|
105
|
+
expect(sec.getCurrentUpb()?.toString()).toBe('237500000');
|
|
106
|
+
expect(sec.getPsaSpeed()?.toString()).toBe('150');
|
|
107
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const BondSecurity_1 = __importStar(require("./BondSecurity"));
|
|
27
|
+
const security_pb_1 = require("../../../fintekkers/models/security/security_pb");
|
|
28
|
+
const agency_pb_1 = require("../../../fintekkers/models/security/bond/agency_pb");
|
|
29
|
+
const product_type_pb_1 = require("../../../fintekkers/models/security/product_type_pb");
|
|
30
|
+
const decimal_js_1 = require("decimal.js");
|
|
31
|
+
/**
|
|
32
|
+
* MBS-specific accessors layered on top of BondSecurity. Pool-level fields
|
|
33
|
+
* (agency, WAC, WAM, pass-through rate, factors, balances, PSA) live in
|
|
34
|
+
* the parallel mbs_extension sub-message; bond_details still carries the
|
|
35
|
+
* canonical coupon/dates/face value.
|
|
36
|
+
*/
|
|
37
|
+
class MortgageBackedSecurity extends BondSecurity_1.default {
|
|
38
|
+
constructor(proto) {
|
|
39
|
+
super(proto);
|
|
40
|
+
}
|
|
41
|
+
getMbsExtension() {
|
|
42
|
+
var _a;
|
|
43
|
+
return (_a = this.proto.getMbsExtension()) !== null && _a !== void 0 ? _a : undefined;
|
|
44
|
+
}
|
|
45
|
+
/** Pool identifier (e.g. "FN AS1234"). */
|
|
46
|
+
getPoolNumber() {
|
|
47
|
+
const ext = this.getMbsExtension();
|
|
48
|
+
return ext ? ext.getPoolNumber() : '';
|
|
49
|
+
}
|
|
50
|
+
/** Issuing agency (FNMA / FHLMC / GNMA). */
|
|
51
|
+
getAgency() {
|
|
52
|
+
const ext = this.getMbsExtension();
|
|
53
|
+
return ext ? ext.getAgency() : agency_pb_1.AgencyProto.AGENCY_UNKNOWN;
|
|
54
|
+
}
|
|
55
|
+
/** Weighted Average Coupon across underlying loans. */
|
|
56
|
+
getWac() {
|
|
57
|
+
const ext = this.getMbsExtension();
|
|
58
|
+
const v = ext ? ext.getWac() : undefined;
|
|
59
|
+
if (!v)
|
|
60
|
+
return null;
|
|
61
|
+
return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
|
|
62
|
+
}
|
|
63
|
+
/** Weighted Average Maturity, in months. */
|
|
64
|
+
getWam() {
|
|
65
|
+
const ext = this.getMbsExtension();
|
|
66
|
+
return ext ? ext.getWam() : 0;
|
|
67
|
+
}
|
|
68
|
+
/** Pass-through rate paid to investors (net of servicing/guarantee fees). */
|
|
69
|
+
getPassThroughRate() {
|
|
70
|
+
const ext = this.getMbsExtension();
|
|
71
|
+
const v = ext ? ext.getPassThroughRate() : undefined;
|
|
72
|
+
if (!v)
|
|
73
|
+
return null;
|
|
74
|
+
return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
|
|
75
|
+
}
|
|
76
|
+
/** Current pool factor (remaining UPB / original face). */
|
|
77
|
+
getCurrentFactor() {
|
|
78
|
+
const ext = this.getMbsExtension();
|
|
79
|
+
const v = ext ? ext.getCurrentFactor() : undefined;
|
|
80
|
+
if (!v)
|
|
81
|
+
return null;
|
|
82
|
+
return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
|
|
83
|
+
}
|
|
84
|
+
/** Original face value at issuance. */
|
|
85
|
+
getOriginalFaceValue() {
|
|
86
|
+
const ext = this.getMbsExtension();
|
|
87
|
+
const v = ext ? ext.getOriginalFaceValue() : undefined;
|
|
88
|
+
if (!v)
|
|
89
|
+
return null;
|
|
90
|
+
return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
|
|
91
|
+
}
|
|
92
|
+
/** Current Unpaid Principal Balance. */
|
|
93
|
+
getCurrentUpb() {
|
|
94
|
+
const ext = this.getMbsExtension();
|
|
95
|
+
const v = ext ? ext.getCurrentUpb() : undefined;
|
|
96
|
+
if (!v)
|
|
97
|
+
return null;
|
|
98
|
+
return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
|
|
99
|
+
}
|
|
100
|
+
/** PSA prepayment speed assumption. */
|
|
101
|
+
getPsaSpeed() {
|
|
102
|
+
const ext = this.getMbsExtension();
|
|
103
|
+
const v = ext ? ext.getPsaSpeed() : undefined;
|
|
104
|
+
if (!v)
|
|
105
|
+
return null;
|
|
106
|
+
return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build a fresh SecurityProto for an agency MBS pass-through. product_type
|
|
110
|
+
* is set to MORTGAGE_BACKED so Security.create routes back to this wrapper.
|
|
111
|
+
*/
|
|
112
|
+
static fromPricerInputs(args) {
|
|
113
|
+
const bond = (0, BondSecurity_1.buildBondDetails)(args);
|
|
114
|
+
const mbs = new security_pb_1.MbsExtensionProto()
|
|
115
|
+
.setPoolNumber(args.poolNumber)
|
|
116
|
+
.setAgency(args.agency)
|
|
117
|
+
.setWac((0, BondSecurity_1.decimalToProto)(args.wac))
|
|
118
|
+
.setWam(args.wam)
|
|
119
|
+
.setPassThroughRate((0, BondSecurity_1.decimalToProto)(args.passThroughRate))
|
|
120
|
+
.setCurrentFactor((0, BondSecurity_1.decimalToProto)(args.currentFactor))
|
|
121
|
+
.setOriginalFaceValue((0, BondSecurity_1.decimalToProto)(args.originalFaceValue))
|
|
122
|
+
.setCurrentUpb((0, BondSecurity_1.decimalToProto)(args.currentUpb))
|
|
123
|
+
.setPsaSpeed((0, BondSecurity_1.decimalToProto)(args.psaSpeed));
|
|
124
|
+
return new security_pb_1.SecurityProto()
|
|
125
|
+
.setProductType(product_type_pb_1.ProductTypeProto.MORTGAGE_BACKED)
|
|
126
|
+
.setBondDetails(bond)
|
|
127
|
+
.setMbsExtension(mbs);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.default = MortgageBackedSecurity;
|
|
131
|
+
//# sourceMappingURL=MortgageBackedSecurity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MortgageBackedSecurity.js","sourceRoot":"","sources":["MortgageBackedSecurity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import BondSecurity, {
|
|
2
|
+
BondPricerInputs,
|
|
3
|
+
buildBondDetails,
|
|
4
|
+
decimalToProto,
|
|
5
|
+
} from './BondSecurity';
|
|
6
|
+
import { SecurityProto, MbsExtensionProto } from '../../../fintekkers/models/security/security_pb';
|
|
7
|
+
import { AgencyProto } from '../../../fintekkers/models/security/bond/agency_pb';
|
|
8
|
+
import { ProductTypeProto } from '../../../fintekkers/models/security/product_type_pb';
|
|
9
|
+
import { Decimal } from 'decimal.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* MBS-specific accessors layered on top of BondSecurity. Pool-level fields
|
|
13
|
+
* (agency, WAC, WAM, pass-through rate, factors, balances, PSA) live in
|
|
14
|
+
* the parallel mbs_extension sub-message; bond_details still carries the
|
|
15
|
+
* canonical coupon/dates/face value.
|
|
16
|
+
*/
|
|
17
|
+
class MortgageBackedSecurity extends BondSecurity {
|
|
18
|
+
constructor(proto: SecurityProto) {
|
|
19
|
+
super(proto);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private getMbsExtension(): MbsExtensionProto | undefined {
|
|
23
|
+
return this.proto.getMbsExtension() ?? undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Pool identifier (e.g. "FN AS1234"). */
|
|
27
|
+
getPoolNumber(): string {
|
|
28
|
+
const ext = this.getMbsExtension();
|
|
29
|
+
return ext ? ext.getPoolNumber() : '';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Issuing agency (FNMA / FHLMC / GNMA). */
|
|
33
|
+
getAgency(): AgencyProto {
|
|
34
|
+
const ext = this.getMbsExtension();
|
|
35
|
+
return ext ? ext.getAgency() : AgencyProto.AGENCY_UNKNOWN;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Weighted Average Coupon across underlying loans. */
|
|
39
|
+
getWac(): Decimal | null {
|
|
40
|
+
const ext = this.getMbsExtension();
|
|
41
|
+
const v = ext ? ext.getWac() : undefined;
|
|
42
|
+
if (!v) return null;
|
|
43
|
+
return new Decimal(v.getArbitraryPrecisionValue());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Weighted Average Maturity, in months. */
|
|
47
|
+
getWam(): number {
|
|
48
|
+
const ext = this.getMbsExtension();
|
|
49
|
+
return ext ? ext.getWam() : 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Pass-through rate paid to investors (net of servicing/guarantee fees). */
|
|
53
|
+
getPassThroughRate(): Decimal | null {
|
|
54
|
+
const ext = this.getMbsExtension();
|
|
55
|
+
const v = ext ? ext.getPassThroughRate() : undefined;
|
|
56
|
+
if (!v) return null;
|
|
57
|
+
return new Decimal(v.getArbitraryPrecisionValue());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Current pool factor (remaining UPB / original face). */
|
|
61
|
+
getCurrentFactor(): Decimal | null {
|
|
62
|
+
const ext = this.getMbsExtension();
|
|
63
|
+
const v = ext ? ext.getCurrentFactor() : undefined;
|
|
64
|
+
if (!v) return null;
|
|
65
|
+
return new Decimal(v.getArbitraryPrecisionValue());
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Original face value at issuance. */
|
|
69
|
+
getOriginalFaceValue(): Decimal | null {
|
|
70
|
+
const ext = this.getMbsExtension();
|
|
71
|
+
const v = ext ? ext.getOriginalFaceValue() : undefined;
|
|
72
|
+
if (!v) return null;
|
|
73
|
+
return new Decimal(v.getArbitraryPrecisionValue());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Current Unpaid Principal Balance. */
|
|
77
|
+
getCurrentUpb(): Decimal | null {
|
|
78
|
+
const ext = this.getMbsExtension();
|
|
79
|
+
const v = ext ? ext.getCurrentUpb() : undefined;
|
|
80
|
+
if (!v) return null;
|
|
81
|
+
return new Decimal(v.getArbitraryPrecisionValue());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** PSA prepayment speed assumption. */
|
|
85
|
+
getPsaSpeed(): Decimal | null {
|
|
86
|
+
const ext = this.getMbsExtension();
|
|
87
|
+
const v = ext ? ext.getPsaSpeed() : undefined;
|
|
88
|
+
if (!v) return null;
|
|
89
|
+
return new Decimal(v.getArbitraryPrecisionValue());
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build a fresh SecurityProto for an agency MBS pass-through. product_type
|
|
94
|
+
* is set to MORTGAGE_BACKED so Security.create routes back to this wrapper.
|
|
95
|
+
*/
|
|
96
|
+
static fromPricerInputs(args: BondPricerInputs & {
|
|
97
|
+
poolNumber: string;
|
|
98
|
+
agency: AgencyProto;
|
|
99
|
+
wac: Decimal;
|
|
100
|
+
wam: number;
|
|
101
|
+
passThroughRate: Decimal;
|
|
102
|
+
currentFactor: Decimal;
|
|
103
|
+
originalFaceValue: Decimal;
|
|
104
|
+
currentUpb: Decimal;
|
|
105
|
+
psaSpeed: Decimal;
|
|
106
|
+
}): SecurityProto {
|
|
107
|
+
const bond = buildBondDetails(args);
|
|
108
|
+
const mbs = new MbsExtensionProto()
|
|
109
|
+
.setPoolNumber(args.poolNumber)
|
|
110
|
+
.setAgency(args.agency)
|
|
111
|
+
.setWac(decimalToProto(args.wac))
|
|
112
|
+
.setWam(args.wam)
|
|
113
|
+
.setPassThroughRate(decimalToProto(args.passThroughRate))
|
|
114
|
+
.setCurrentFactor(decimalToProto(args.currentFactor))
|
|
115
|
+
.setOriginalFaceValue(decimalToProto(args.originalFaceValue))
|
|
116
|
+
.setCurrentUpb(decimalToProto(args.currentUpb))
|
|
117
|
+
.setPsaSpeed(decimalToProto(args.psaSpeed));
|
|
118
|
+
return new SecurityProto()
|
|
119
|
+
.setProductType(ProductTypeProto.MORTGAGE_BACKED)
|
|
120
|
+
.setBondDetails(bond)
|
|
121
|
+
.setMbsExtension(mbs);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default MortgageBackedSecurity;
|
|
@@ -38,6 +38,7 @@ declare class Security {
|
|
|
38
38
|
* the proto's product_type. Dispatch rules:
|
|
39
39
|
* - TIPS -> TIPSBond
|
|
40
40
|
* - TREASURY_FRN -> FloatingRateNote
|
|
41
|
+
* - MORTGAGE_BACKED -> MortgageBackedSecurity
|
|
41
42
|
* - any other descendant of BOND in hierarchy.json -> BondSecurity
|
|
42
43
|
* - any descendant of INDEX in hierarchy.json -> IndexSecurity
|
|
43
44
|
* - everything else (equity, cash, fx, etc.) -> base Security
|
|
@@ -69,6 +69,7 @@ class Security {
|
|
|
69
69
|
* the proto's product_type. Dispatch rules:
|
|
70
70
|
* - TIPS -> TIPSBond
|
|
71
71
|
* - TREASURY_FRN -> FloatingRateNote
|
|
72
|
+
* - MORTGAGE_BACKED -> MortgageBackedSecurity
|
|
72
73
|
* - any other descendant of BOND in hierarchy.json -> BondSecurity
|
|
73
74
|
* - any descendant of INDEX in hierarchy.json -> IndexSecurity
|
|
74
75
|
* - everything else (equity, cash, fx, etc.) -> base Security
|
|
@@ -77,7 +78,7 @@ class Security {
|
|
|
77
78
|
const productType = proto.getProductType();
|
|
78
79
|
const ptName = Object.keys(product_type_pb_1.ProductTypeProto)
|
|
79
80
|
.find(k => product_type_pb_1.ProductTypeProto[k] === productType);
|
|
80
|
-
// TIPS / FRN have dedicated wrappers with extension-specific accessors.
|
|
81
|
+
// TIPS / FRN / MBS have dedicated wrappers with extension-specific accessors.
|
|
81
82
|
if (productType === product_type_pb_1.ProductTypeProto.TIPS) {
|
|
82
83
|
const TIPSBond = require('./TIPSBond').default;
|
|
83
84
|
return new TIPSBond(proto);
|
|
@@ -86,6 +87,10 @@ class Security {
|
|
|
86
87
|
const FloatingRateNote = require('./FloatingRateNote').default;
|
|
87
88
|
return new FloatingRateNote(proto);
|
|
88
89
|
}
|
|
90
|
+
if (productType === product_type_pb_1.ProductTypeProto.MORTGAGE_BACKED) {
|
|
91
|
+
const MortgageBackedSecurity = require('./MortgageBackedSecurity').default;
|
|
92
|
+
return new MortgageBackedSecurity(proto);
|
|
93
|
+
}
|
|
89
94
|
// Any other BOND descendant -> generic BondSecurity wrapper.
|
|
90
95
|
if (ptName && (0, product_hierarchy_1.isDescendantOf)(ptName, 'BOND')) {
|
|
91
96
|
const BondSecurity = require('./BondSecurity').default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.js","sourceRoot":"","sources":["security.ts"],"names":[],"mappings":";;AAAA,2EAA0E;AAC1E,iFAAgF;AAGhF,gDAAkD;AAClD,wCAAqC;AACrC,wCAA0C;AAC1C,yFAAuF;AAEvF,6CAA0C;AAC1C,2DAAqD;AAErD,MAAM,QAAQ;IAGZ,YAAY,KAAoB;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,CAAC,IAAU,EAAE,IAAmB;QAC3C,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAC;QAC/G,MAAM,KAAK,GAAG,IAAI,2BAAa,EAAE,CAAC;QAClC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,IAAU;QAC5B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,2BAAa,EAAE,CAAC;QAClC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,MAAM,CAAC,YAAY,CAAC,IAAU;QACpC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,IAAmB;QACtD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED;;;OAGG;IACK,aAAa,CAAC,QAAgB;QACpC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE;YAC1B,MAAM,IAAI,KAAK,CACb,eAAe,QAAQ,2CAA2C;kBAChE,8CAA8C;kBAC9C,kCAAkC,CACrC,CAAC;SACH;IACH,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["security.ts"],"names":[],"mappings":"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"}
|
|
@@ -78,6 +78,7 @@ class Security {
|
|
|
78
78
|
* the proto's product_type. Dispatch rules:
|
|
79
79
|
* - TIPS -> TIPSBond
|
|
80
80
|
* - TREASURY_FRN -> FloatingRateNote
|
|
81
|
+
* - MORTGAGE_BACKED -> MortgageBackedSecurity
|
|
81
82
|
* - any other descendant of BOND in hierarchy.json -> BondSecurity
|
|
82
83
|
* - any descendant of INDEX in hierarchy.json -> IndexSecurity
|
|
83
84
|
* - everything else (equity, cash, fx, etc.) -> base Security
|
|
@@ -87,7 +88,7 @@ class Security {
|
|
|
87
88
|
const ptName = (Object.keys(ProductTypeProto) as Array<keyof typeof ProductTypeProto>)
|
|
88
89
|
.find(k => ProductTypeProto[k] === productType);
|
|
89
90
|
|
|
90
|
-
// TIPS / FRN have dedicated wrappers with extension-specific accessors.
|
|
91
|
+
// TIPS / FRN / MBS have dedicated wrappers with extension-specific accessors.
|
|
91
92
|
if (productType === ProductTypeProto.TIPS) {
|
|
92
93
|
const TIPSBond = require('./TIPSBond').default;
|
|
93
94
|
return new TIPSBond(proto);
|
|
@@ -96,6 +97,10 @@ class Security {
|
|
|
96
97
|
const FloatingRateNote = require('./FloatingRateNote').default;
|
|
97
98
|
return new FloatingRateNote(proto);
|
|
98
99
|
}
|
|
100
|
+
if (productType === ProductTypeProto.MORTGAGE_BACKED) {
|
|
101
|
+
const MortgageBackedSecurity = require('./MortgageBackedSecurity').default;
|
|
102
|
+
return new MortgageBackedSecurity(proto);
|
|
103
|
+
}
|
|
99
104
|
|
|
100
105
|
// Any other BOND descendant -> generic BondSecurity wrapper.
|
|
101
106
|
if (ptName && isDescendantOf(ptName as string, 'BOND')) {
|