@fintekkers/ledger-models 0.4.0 → 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.
Files changed (63) hide show
  1. package/hierarchy.json +2 -2
  2. package/node/fintekkers/models/security/bond/agency_grpc_pb.js +1 -0
  3. package/node/fintekkers/models/security/bond/agency_pb.d.ts +14 -0
  4. package/node/fintekkers/models/security/bond/agency_pb.js +35 -0
  5. package/node/fintekkers/models/security/product_type_pb.d.ts +1 -0
  6. package/node/fintekkers/models/security/product_type_pb.js +1 -0
  7. package/node/fintekkers/models/security/security_pb.d.ts +69 -0
  8. package/node/fintekkers/models/security/security_pb.js +572 -1
  9. package/node/wrappers/models/security/BondSecurity.d.ts +41 -3
  10. package/node/wrappers/models/security/BondSecurity.fromPricerInputs.test.d.ts +1 -0
  11. package/node/wrappers/models/security/BondSecurity.fromPricerInputs.test.js +75 -0
  12. package/node/wrappers/models/security/BondSecurity.fromPricerInputs.test.js.map +1 -0
  13. package/node/wrappers/models/security/BondSecurity.fromPricerInputs.test.ts +95 -0
  14. package/node/wrappers/models/security/BondSecurity.js +50 -2
  15. package/node/wrappers/models/security/BondSecurity.js.map +1 -1
  16. package/node/wrappers/models/security/BondSecurity.ts +65 -3
  17. package/node/wrappers/models/security/FloatingRateNote.d.ts +30 -0
  18. package/node/wrappers/models/security/FloatingRateNote.js +80 -0
  19. package/node/wrappers/models/security/FloatingRateNote.js.map +1 -0
  20. package/node/wrappers/models/security/FloatingRateNote.ts +67 -0
  21. package/node/wrappers/models/security/IndexSecurity.d.ts +16 -0
  22. package/node/wrappers/models/security/IndexSecurity.js +26 -0
  23. package/node/wrappers/models/security/IndexSecurity.js.map +1 -0
  24. package/node/wrappers/models/security/IndexSecurity.test.d.ts +1 -0
  25. package/node/wrappers/models/security/IndexSecurity.test.js +60 -0
  26. package/node/wrappers/models/security/IndexSecurity.test.js.map +1 -0
  27. package/node/wrappers/models/security/IndexSecurity.test.ts +60 -0
  28. package/node/wrappers/models/security/IndexSecurity.ts +24 -0
  29. package/node/wrappers/models/security/Issuance.d.ts +35 -0
  30. package/node/wrappers/models/security/Issuance.js +64 -0
  31. package/node/wrappers/models/security/Issuance.js.map +1 -0
  32. package/node/wrappers/models/security/Issuance.test.d.ts +1 -0
  33. package/node/wrappers/models/security/Issuance.test.js +55 -0
  34. package/node/wrappers/models/security/Issuance.test.js.map +1 -0
  35. package/node/wrappers/models/security/Issuance.test.ts +52 -0
  36. package/node/wrappers/models/security/Issuance.ts +74 -0
  37. package/node/wrappers/models/security/MortgageBackedSecurity.d.ts +48 -0
  38. package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.d.ts +1 -0
  39. package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.js +93 -0
  40. package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.js.map +1 -0
  41. package/node/wrappers/models/security/MortgageBackedSecurity.fromPricerInputs.test.ts +107 -0
  42. package/node/wrappers/models/security/MortgageBackedSecurity.js +131 -0
  43. package/node/wrappers/models/security/MortgageBackedSecurity.js.map +1 -0
  44. package/node/wrappers/models/security/MortgageBackedSecurity.ts +125 -0
  45. package/node/wrappers/models/security/TIPSBond.d.ts +30 -0
  46. package/node/wrappers/models/security/TIPSBond.js +83 -0
  47. package/node/wrappers/models/security/TIPSBond.js.map +1 -0
  48. package/node/wrappers/models/security/TIPSBond.ts +70 -0
  49. package/node/wrappers/models/security/security.d.ts +20 -3
  50. package/node/wrappers/models/security/security.identifiers.test.d.ts +1 -0
  51. package/node/wrappers/models/security/security.identifiers.test.js +67 -0
  52. package/node/wrappers/models/security/security.identifiers.test.js.map +1 -0
  53. package/node/wrappers/models/security/security.identifiers.test.ts +67 -0
  54. package/node/wrappers/models/security/security.js +72 -22
  55. package/node/wrappers/models/security/security.js.map +1 -1
  56. package/node/wrappers/models/security/security.ts +75 -22
  57. package/node/wrappers/models/transaction/transaction.js +4 -2
  58. package/node/wrappers/models/transaction/transaction.js.map +1 -1
  59. package/node/wrappers/models/transaction/transaction.ts +4 -2
  60. package/node/wrappers/services/security-service/security.maturityLadder.test.js +3 -2
  61. package/node/wrappers/services/security-service/security.maturityLadder.test.js.map +1 -1
  62. package/node/wrappers/services/security-service/security.maturityLadder.test.ts +3 -2
  63. package/package.json +1 -1
@@ -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;
@@ -0,0 +1,30 @@
1
+ import BondSecurity, { BondPricerInputs } from './BondSecurity';
2
+ import { SecurityProto } from '../../../fintekkers/models/security/security_pb';
3
+ import { IndexTypeProto } from '../../../fintekkers/models/security/index/index_type_pb';
4
+ import { LocalDate } from '../utils/date';
5
+ import { Decimal } from 'decimal.js';
6
+ /**
7
+ * TIPS-specific accessors layered on top of BondSecurity. The inflation
8
+ * fields live in the parallel tips_extension sub-message; bond_details
9
+ * (coupon, maturity, etc.) still carries the rest.
10
+ */
11
+ declare class TIPSBond extends BondSecurity {
12
+ constructor(proto: SecurityProto);
13
+ private getTipsExtension;
14
+ /** Base CPI value at issue, used to scale inflation-adjusted principal. */
15
+ getBaseCpi(): Decimal | null;
16
+ /** Reference date for the base CPI fixing. */
17
+ getIndexDate(): LocalDate | null;
18
+ /** Which inflation index drives accruals (CPI_U on US TIPS). */
19
+ getInflationIndexType(): IndexTypeProto;
20
+ /**
21
+ * Build a fresh SecurityProto for a TIPS bond. product_type is set to
22
+ * TIPS so Security.create routes back to this wrapper.
23
+ */
24
+ static fromPricerInputs(args: BondPricerInputs & {
25
+ baseCpi: Decimal;
26
+ indexDate: LocalDate;
27
+ inflationIndexType: IndexTypeProto;
28
+ }): SecurityProto;
29
+ }
30
+ export default TIPSBond;
@@ -0,0 +1,83 @@
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 product_type_pb_1 = require("../../../fintekkers/models/security/product_type_pb");
29
+ const index_type_pb_1 = require("../../../fintekkers/models/security/index/index_type_pb");
30
+ const date_1 = require("../utils/date");
31
+ const decimal_js_1 = require("decimal.js");
32
+ /**
33
+ * TIPS-specific accessors layered on top of BondSecurity. The inflation
34
+ * fields live in the parallel tips_extension sub-message; bond_details
35
+ * (coupon, maturity, etc.) still carries the rest.
36
+ */
37
+ class TIPSBond extends BondSecurity_1.default {
38
+ constructor(proto) {
39
+ super(proto);
40
+ }
41
+ getTipsExtension() {
42
+ var _a;
43
+ return (_a = this.proto.getTipsExtension()) !== null && _a !== void 0 ? _a : undefined;
44
+ }
45
+ /** Base CPI value at issue, used to scale inflation-adjusted principal. */
46
+ getBaseCpi() {
47
+ const ext = this.getTipsExtension();
48
+ const v = ext ? ext.getBaseCpi() : undefined;
49
+ if (!v)
50
+ return null;
51
+ return new decimal_js_1.Decimal(v.getArbitraryPrecisionValue());
52
+ }
53
+ /** Reference date for the base CPI fixing. */
54
+ getIndexDate() {
55
+ const ext = this.getTipsExtension();
56
+ const d = ext ? ext.getIndexDate() : undefined;
57
+ if (!d)
58
+ return null;
59
+ return new date_1.LocalDate(d);
60
+ }
61
+ /** Which inflation index drives accruals (CPI_U on US TIPS). */
62
+ getInflationIndexType() {
63
+ const ext = this.getTipsExtension();
64
+ return ext ? ext.getInflationIndexType() : index_type_pb_1.IndexTypeProto.UNKNOWN_INDEX_TYPE;
65
+ }
66
+ /**
67
+ * Build a fresh SecurityProto for a TIPS bond. product_type is set to
68
+ * TIPS so Security.create routes back to this wrapper.
69
+ */
70
+ static fromPricerInputs(args) {
71
+ const bond = (0, BondSecurity_1.buildBondDetails)(args);
72
+ const tips = new security_pb_1.TipsExtensionProto()
73
+ .setBaseCpi((0, BondSecurity_1.decimalToProto)(args.baseCpi))
74
+ .setIndexDate((0, BondSecurity_1.localDateToProto)(args.indexDate))
75
+ .setInflationIndexType(args.inflationIndexType);
76
+ return new security_pb_1.SecurityProto()
77
+ .setProductType(product_type_pb_1.ProductTypeProto.TIPS)
78
+ .setBondDetails(bond)
79
+ .setTipsExtension(tips);
80
+ }
81
+ }
82
+ exports.default = TIPSBond;
83
+ //# sourceMappingURL=TIPSBond.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TIPSBond.js","sourceRoot":"","sources":["TIPSBond.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+DAKwB;AACxB,iFAAoG;AACpG,yFAAuF;AACvF,2FAAyF;AACzF,wCAA0C;AAC1C,2CAAqC;AAErC;;;;GAIG;AACH,MAAM,QAAS,SAAQ,sBAAY;IACjC,YAAY,KAAoB;QAC9B,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;IAEO,gBAAgB;;QACtB,OAAO,MAAA,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,mCAAI,SAAS,CAAC;IACpD,CAAC;IAED,2EAA2E;IAC3E,UAAU;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7C,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,OAAO,IAAI,oBAAO,CAAC,CAAC,CAAC,0BAA0B,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,8CAA8C;IAC9C,YAAY;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/C,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,OAAO,IAAI,gBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,gEAAgE;IAChE,qBAAqB;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACpC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,8BAAc,CAAC,kBAAkB,CAAC;IAC/E,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAIvB;QACC,MAAM,IAAI,GAAG,IAAA,+BAAgB,EAAC,IAAI,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,gCAAkB,EAAE;aAClC,UAAU,CAAC,IAAA,6BAAc,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aACxC,YAAY,CAAC,IAAA,+BAAgB,EAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aAC9C,qBAAqB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClD,OAAO,IAAI,2BAAa,EAAE;aACvB,cAAc,CAAC,kCAAgB,CAAC,IAAI,CAAC;aACrC,cAAc,CAAC,IAAI,CAAC;aACpB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CACF;AAED,kBAAe,QAAQ,CAAC"}
@@ -0,0 +1,70 @@
1
+ import BondSecurity, {
2
+ BondPricerInputs,
3
+ buildBondDetails,
4
+ decimalToProto,
5
+ localDateToProto,
6
+ } from './BondSecurity';
7
+ import { SecurityProto, TipsExtensionProto } from '../../../fintekkers/models/security/security_pb';
8
+ import { ProductTypeProto } from '../../../fintekkers/models/security/product_type_pb';
9
+ import { IndexTypeProto } from '../../../fintekkers/models/security/index/index_type_pb';
10
+ import { LocalDate } from '../utils/date';
11
+ import { Decimal } from 'decimal.js';
12
+
13
+ /**
14
+ * TIPS-specific accessors layered on top of BondSecurity. The inflation
15
+ * fields live in the parallel tips_extension sub-message; bond_details
16
+ * (coupon, maturity, etc.) still carries the rest.
17
+ */
18
+ class TIPSBond extends BondSecurity {
19
+ constructor(proto: SecurityProto) {
20
+ super(proto);
21
+ }
22
+
23
+ private getTipsExtension(): TipsExtensionProto | undefined {
24
+ return this.proto.getTipsExtension() ?? undefined;
25
+ }
26
+
27
+ /** Base CPI value at issue, used to scale inflation-adjusted principal. */
28
+ getBaseCpi(): Decimal | null {
29
+ const ext = this.getTipsExtension();
30
+ const v = ext ? ext.getBaseCpi() : undefined;
31
+ if (!v) return null;
32
+ return new Decimal(v.getArbitraryPrecisionValue());
33
+ }
34
+
35
+ /** Reference date for the base CPI fixing. */
36
+ getIndexDate(): LocalDate | null {
37
+ const ext = this.getTipsExtension();
38
+ const d = ext ? ext.getIndexDate() : undefined;
39
+ if (!d) return null;
40
+ return new LocalDate(d);
41
+ }
42
+
43
+ /** Which inflation index drives accruals (CPI_U on US TIPS). */
44
+ getInflationIndexType(): IndexTypeProto {
45
+ const ext = this.getTipsExtension();
46
+ return ext ? ext.getInflationIndexType() : IndexTypeProto.UNKNOWN_INDEX_TYPE;
47
+ }
48
+
49
+ /**
50
+ * Build a fresh SecurityProto for a TIPS bond. product_type is set to
51
+ * TIPS so Security.create routes back to this wrapper.
52
+ */
53
+ static fromPricerInputs(args: BondPricerInputs & {
54
+ baseCpi: Decimal;
55
+ indexDate: LocalDate;
56
+ inflationIndexType: IndexTypeProto;
57
+ }): SecurityProto {
58
+ const bond = buildBondDetails(args);
59
+ const tips = new TipsExtensionProto()
60
+ .setBaseCpi(decimalToProto(args.baseCpi))
61
+ .setIndexDate(localDateToProto(args.indexDate))
62
+ .setInflationIndexType(args.inflationIndexType);
63
+ return new SecurityProto()
64
+ .setProductType(ProductTypeProto.TIPS)
65
+ .setBondDetails(bond)
66
+ .setTipsExtension(tips);
67
+ }
68
+ }
69
+
70
+ export default TIPSBond;
@@ -1,9 +1,10 @@
1
1
  import { FieldProto } from "../../../fintekkers/models/position/field_pb";
2
- import { IdentifierProto } from "../../../fintekkers/models/security/identifier/identifier_pb";
3
2
  import { SecurityProto } from "../../../fintekkers/models/security/security_pb";
4
3
  import { ZonedDateTime } from "../utils/datetime";
5
4
  import { UUID } from "../utils/uuid";
6
5
  import { LocalDate } from "../utils/date";
6
+ import { IdentifierTypeProto } from "../../../fintekkers/models/security/identifier/identifier_type_pb";
7
+ import { Identifier } from "./identifier";
7
8
  declare class Security {
8
9
  proto: SecurityProto;
9
10
  constructor(proto: SecurityProto);
@@ -33,7 +34,14 @@ declare class Security {
33
34
  */
34
35
  private assertNotLink;
35
36
  /**
36
- * Factory method to create the appropriate Security subclass based on security type
37
+ * Factory method to create the appropriate Security subclass based on
38
+ * the proto's product_type. Dispatch rules:
39
+ * - TIPS -> TIPSBond
40
+ * - TREASURY_FRN -> FloatingRateNote
41
+ * - MORTGAGE_BACKED -> MortgageBackedSecurity
42
+ * - any other descendant of BOND in hierarchy.json -> BondSecurity
43
+ * - any descendant of INDEX in hierarchy.json -> IndexSecurity
44
+ * - everything else (equity, cash, fx, etc.) -> base Security
37
45
  */
38
46
  static create(proto: SecurityProto): Security;
39
47
  /**
@@ -63,7 +71,16 @@ declare class Security {
63
71
  getAssetClass(): string;
64
72
  getProductClass(): string;
65
73
  getProductType(): string;
66
- getSecurityID(): IdentifierProto;
74
+ /**
75
+ * Returns every Identifier attached to this security as typed wrappers.
76
+ * Empty list if none are set. Throws on a link-mode Security.
77
+ */
78
+ getIdentifiers(): Identifier[];
79
+ /**
80
+ * Returns the first Identifier matching the given IdentifierTypeProto,
81
+ * or undefined if none is present. Throws on a link-mode Security.
82
+ */
83
+ getIdentifierByType(type: IdentifierTypeProto): Identifier | undefined;
67
84
  /**
68
85
  * Returns the issue date if set, else null. Per-type semantic:
69
86
  * - Bond / TIPS / FRN: auction date.