Skip to main content

ledger_models/
fintekkers.models.security.rs

1#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2#[repr(i32)]
3pub enum IdentifierTypeProto {
4    UnknownIdentifierType = 0,
5    ExchTicker = 1,
6    Isin = 2,
7    Cusip = 3,
8    Osi = 4,
9    Figi = 5,
10    SeriesId = 6,
11    /// Identifier for index securities (e.g. 'US Treasury Curve', 'S&P 500',
12    /// 'CDX.NA.IG'). Used when productType is one of the *_INDEX leaves and
13    /// there's no exchange-listed ticker or ISIN that uniquely identifies
14    /// the index. Added per second-brain#268.
15    IndexName = 7,
16    Cash = 50,
17}
18impl IdentifierTypeProto {
19    /// String value of the enum field names used in the ProtoBuf definition.
20    ///
21    /// The values are not transformed in any way and thus are considered stable
22    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
23    pub fn as_str_name(&self) -> &'static str {
24        match self {
25            IdentifierTypeProto::UnknownIdentifierType => "UNKNOWN_IDENTIFIER_TYPE",
26            IdentifierTypeProto::ExchTicker => "EXCH_TICKER",
27            IdentifierTypeProto::Isin => "ISIN",
28            IdentifierTypeProto::Cusip => "CUSIP",
29            IdentifierTypeProto::Osi => "OSI",
30            IdentifierTypeProto::Figi => "FIGI",
31            IdentifierTypeProto::SeriesId => "SERIES_ID",
32            IdentifierTypeProto::IndexName => "INDEX_NAME",
33            IdentifierTypeProto::Cash => "CASH",
34        }
35    }
36    /// Creates an enum from field names used in the ProtoBuf definition.
37    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
38        match value {
39            "UNKNOWN_IDENTIFIER_TYPE" => Some(Self::UnknownIdentifierType),
40            "EXCH_TICKER" => Some(Self::ExchTicker),
41            "ISIN" => Some(Self::Isin),
42            "CUSIP" => Some(Self::Cusip),
43            "OSI" => Some(Self::Osi),
44            "FIGI" => Some(Self::Figi),
45            "SERIES_ID" => Some(Self::SeriesId),
46            "INDEX_NAME" => Some(Self::IndexName),
47            "CASH" => Some(Self::Cash),
48            _ => None,
49        }
50    }
51}
52#[allow(clippy::derive_partial_eq_without_eq)]
53#[derive(Clone, PartialEq, ::prost::Message)]
54pub struct IdentifierProto {
55    #[prost(string, tag = "1")]
56    pub object_class: ::prost::alloc::string::String,
57    #[prost(string, tag = "2")]
58    pub version: ::prost::alloc::string::String,
59    /// Primary Key
60    #[prost(string, tag = "5")]
61    pub identifier_value: ::prost::alloc::string::String,
62    #[prost(enumeration = "IdentifierTypeProto", tag = "6")]
63    pub identifier_type: i32,
64}
65/// Leaf product types — the kind of contract a Security represents.
66///
67/// Authoritative shape lives in ledger-models-protos/hierarchy.json
68/// (single source of truth: parent chain, asset_class, instrument_type,
69/// label, status). Every active leaf in hierarchy.json must have a
70/// matching enum value here; CI guard enforces the round-trip.
71///
72/// Abstract parent nodes (BOND, GOV_BOND, OPTION, EQUITY_OPTION, etc.)
73/// live only in hierarchy.json — they are never assigned to a Security.
74///
75/// Strategies (butterfly, vertical spread, calendar spread, condor,
76/// straddle, ...) are intentionally absent. They are derived from the
77/// SecurityProto.legs field, not from a productType enum value.
78///
79/// Multi-language wrapper helpers (parentOf, descendantsOf,
80/// isDescendantOf, labelOf, assetClassOf, instrumentTypeOf) load
81/// hierarchy.json at startup and dispatch on the leaf identity carried
82/// by ProductTypeProto.
83///
84/// See ../../../hierarchy-examples.md for worked examples and
85/// ../../../registry-versioning.md for compatibility rules on changes
86/// to this enum.
87#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
88#[repr(i32)]
89pub enum ProductTypeProto {
90    ProductTypeUnknown = 0,
91    /// Bonds (1-19)
92    Tbill = 1,
93    TreasuryNote = 2,
94    TreasuryBond = 3,
95    Tips = 4,
96    TreasuryFrn = 5,
97    Strips = 6,
98    SovereignBond = 7,
99    CorpBond = 8,
100    MuniBond = 9,
101    MortgageBacked = 10,
102    /// Stocks (20-29)
103    CommonStock = 20,
104    PreferredStock = 21,
105    Adr = 22,
106    Etf = 23,
107    /// Reference indices and rate series (30-39)
108    EquityIndex = 30,
109    BondIndex = 31,
110    CommodityIndex = 32,
111    VixSpot = 33,
112    CpiSeries = 34,
113    SofrSeries = 35,
114    /// Cash and FX (40-49)
115    Currency = 40,
116    FxSpot = 41,
117    MoneyMarketFund = 42,
118    /// Crypto (50-59)
119    Cryptocurrency = 50,
120    Stablecoin = 51,
121    /// Commodity spot (60-69)
122    Gold = 60,
123    Silver = 61,
124}
125impl ProductTypeProto {
126    /// String value of the enum field names used in the ProtoBuf definition.
127    ///
128    /// The values are not transformed in any way and thus are considered stable
129    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
130    pub fn as_str_name(&self) -> &'static str {
131        match self {
132            ProductTypeProto::ProductTypeUnknown => "PRODUCT_TYPE_UNKNOWN",
133            ProductTypeProto::Tbill => "TBILL",
134            ProductTypeProto::TreasuryNote => "TREASURY_NOTE",
135            ProductTypeProto::TreasuryBond => "TREASURY_BOND",
136            ProductTypeProto::Tips => "TIPS",
137            ProductTypeProto::TreasuryFrn => "TREASURY_FRN",
138            ProductTypeProto::Strips => "STRIPS",
139            ProductTypeProto::SovereignBond => "SOVEREIGN_BOND",
140            ProductTypeProto::CorpBond => "CORP_BOND",
141            ProductTypeProto::MuniBond => "MUNI_BOND",
142            ProductTypeProto::MortgageBacked => "MORTGAGE_BACKED",
143            ProductTypeProto::CommonStock => "COMMON_STOCK",
144            ProductTypeProto::PreferredStock => "PREFERRED_STOCK",
145            ProductTypeProto::Adr => "ADR",
146            ProductTypeProto::Etf => "ETF",
147            ProductTypeProto::EquityIndex => "EQUITY_INDEX",
148            ProductTypeProto::BondIndex => "BOND_INDEX",
149            ProductTypeProto::CommodityIndex => "COMMODITY_INDEX",
150            ProductTypeProto::VixSpot => "VIX_SPOT",
151            ProductTypeProto::CpiSeries => "CPI_SERIES",
152            ProductTypeProto::SofrSeries => "SOFR_SERIES",
153            ProductTypeProto::Currency => "CURRENCY",
154            ProductTypeProto::FxSpot => "FX_SPOT",
155            ProductTypeProto::MoneyMarketFund => "MONEY_MARKET_FUND",
156            ProductTypeProto::Cryptocurrency => "CRYPTOCURRENCY",
157            ProductTypeProto::Stablecoin => "STABLECOIN",
158            ProductTypeProto::Gold => "GOLD",
159            ProductTypeProto::Silver => "SILVER",
160        }
161    }
162    /// Creates an enum from field names used in the ProtoBuf definition.
163    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
164        match value {
165            "PRODUCT_TYPE_UNKNOWN" => Some(Self::ProductTypeUnknown),
166            "TBILL" => Some(Self::Tbill),
167            "TREASURY_NOTE" => Some(Self::TreasuryNote),
168            "TREASURY_BOND" => Some(Self::TreasuryBond),
169            "TIPS" => Some(Self::Tips),
170            "TREASURY_FRN" => Some(Self::TreasuryFrn),
171            "STRIPS" => Some(Self::Strips),
172            "SOVEREIGN_BOND" => Some(Self::SovereignBond),
173            "CORP_BOND" => Some(Self::CorpBond),
174            "MUNI_BOND" => Some(Self::MuniBond),
175            "MORTGAGE_BACKED" => Some(Self::MortgageBacked),
176            "COMMON_STOCK" => Some(Self::CommonStock),
177            "PREFERRED_STOCK" => Some(Self::PreferredStock),
178            "ADR" => Some(Self::Adr),
179            "ETF" => Some(Self::Etf),
180            "EQUITY_INDEX" => Some(Self::EquityIndex),
181            "BOND_INDEX" => Some(Self::BondIndex),
182            "COMMODITY_INDEX" => Some(Self::CommodityIndex),
183            "VIX_SPOT" => Some(Self::VixSpot),
184            "CPI_SERIES" => Some(Self::CpiSeries),
185            "SOFR_SERIES" => Some(Self::SofrSeries),
186            "CURRENCY" => Some(Self::Currency),
187            "FX_SPOT" => Some(Self::FxSpot),
188            "MONEY_MARKET_FUND" => Some(Self::MoneyMarketFund),
189            "CRYPTOCURRENCY" => Some(Self::Cryptocurrency),
190            "STABLECOIN" => Some(Self::Stablecoin),
191            "GOLD" => Some(Self::Gold),
192            "SILVER" => Some(Self::Silver),
193            _ => None,
194        }
195    }
196}
197/// Mechanical structure of a Security — orthogonal to productType.
198///
199/// Three values:
200///
201///    CASH             A tradable underlying that settles to a position.
202///                     T-Bill, common stock, BTC, FX spot, money-market
203///                     fund, ETF.
204///
205///    DERIVATIVE       A contract whose value derives from an underlying.
206///                     Future, option, swap, forward, FX swap, variance
207///                     swap.
208///
209///    REFERENCE_INDEX  Observational only, never positioned. Used as
210///                     fixings for derivatives or as display benchmarks.
211///                     Cash-index values (.SPX, .NDX, .VIX), reference
212///                     rate series (.SOFR, .CPI), and benchmark indices
213///                     (Bloomberg Commodity Index).
214///
215/// The distinction matters because: .SPX (REFERENCE_INDEX) and SPY (CASH
216/// ETF that tracks .SPX) are both "EQUITY index"-flavoured but only SPY
217/// is positionable; ES future (DERIVATIVE) is positionable but isn't the
218/// same instrument as either.
219///
220/// Enum-value names are prefixed INSTRUMENT_TYPE_* because proto3
221/// enforces package-wide uniqueness for enum value names — bare CASH
222/// would collide with IdentifierTypeProto.CASH in this package.
223#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
224#[repr(i32)]
225pub enum InstrumentTypeProto {
226    InstrumentTypeUnknown = 0,
227    InstrumentTypeCash = 1,
228    InstrumentTypeDerivative = 2,
229    InstrumentTypeReferenceIndex = 3,
230}
231impl InstrumentTypeProto {
232    /// String value of the enum field names used in the ProtoBuf definition.
233    ///
234    /// The values are not transformed in any way and thus are considered stable
235    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
236    pub fn as_str_name(&self) -> &'static str {
237        match self {
238            InstrumentTypeProto::InstrumentTypeUnknown => "INSTRUMENT_TYPE_UNKNOWN",
239            InstrumentTypeProto::InstrumentTypeCash => "INSTRUMENT_TYPE_CASH",
240            InstrumentTypeProto::InstrumentTypeDerivative => "INSTRUMENT_TYPE_DERIVATIVE",
241            InstrumentTypeProto::InstrumentTypeReferenceIndex => {
242                "INSTRUMENT_TYPE_REFERENCE_INDEX"
243            }
244        }
245    }
246    /// Creates an enum from field names used in the ProtoBuf definition.
247    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
248        match value {
249            "INSTRUMENT_TYPE_UNKNOWN" => Some(Self::InstrumentTypeUnknown),
250            "INSTRUMENT_TYPE_CASH" => Some(Self::InstrumentTypeCash),
251            "INSTRUMENT_TYPE_DERIVATIVE" => Some(Self::InstrumentTypeDerivative),
252            "INSTRUMENT_TYPE_REFERENCE_INDEX" => Some(Self::InstrumentTypeReferenceIndex),
253            _ => None,
254        }
255    }
256}
257#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
258#[repr(i32)]
259pub enum SecurityQuantityTypeProto {
260    /// Maps to Security
261    UnknownQuantityType = 0,
262    OriginalFaceValue = 1,
263    Notional = 2,
264    Units = 3,
265}
266impl SecurityQuantityTypeProto {
267    /// String value of the enum field names used in the ProtoBuf definition.
268    ///
269    /// The values are not transformed in any way and thus are considered stable
270    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
271    pub fn as_str_name(&self) -> &'static str {
272        match self {
273            SecurityQuantityTypeProto::UnknownQuantityType => "UNKNOWN_QUANTITY_TYPE",
274            SecurityQuantityTypeProto::OriginalFaceValue => "ORIGINAL_FACE_VALUE",
275            SecurityQuantityTypeProto::Notional => "NOTIONAL",
276            SecurityQuantityTypeProto::Units => "UNITS",
277        }
278    }
279    /// Creates an enum from field names used in the ProtoBuf definition.
280    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
281        match value {
282            "UNKNOWN_QUANTITY_TYPE" => Some(Self::UnknownQuantityType),
283            "ORIGINAL_FACE_VALUE" => Some(Self::OriginalFaceValue),
284            "NOTIONAL" => Some(Self::Notional),
285            "UNITS" => Some(Self::Units),
286            _ => None,
287        }
288    }
289}
290#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
291#[repr(i32)]
292pub enum CouponFrequencyProto {
293    /// Maps to Security
294    UnknownCouponFrequency = 0,
295    Annually = 1,
296    Semiannually = 2,
297    Quarterly = 3,
298    Monthly = 4,
299    NoCoupon = 5,
300}
301impl CouponFrequencyProto {
302    /// String value of the enum field names used in the ProtoBuf definition.
303    ///
304    /// The values are not transformed in any way and thus are considered stable
305    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
306    pub fn as_str_name(&self) -> &'static str {
307        match self {
308            CouponFrequencyProto::UnknownCouponFrequency => "UNKNOWN_COUPON_FREQUENCY",
309            CouponFrequencyProto::Annually => "ANNUALLY",
310            CouponFrequencyProto::Semiannually => "SEMIANNUALLY",
311            CouponFrequencyProto::Quarterly => "QUARTERLY",
312            CouponFrequencyProto::Monthly => "MONTHLY",
313            CouponFrequencyProto::NoCoupon => "NO_COUPON",
314        }
315    }
316    /// Creates an enum from field names used in the ProtoBuf definition.
317    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
318        match value {
319            "UNKNOWN_COUPON_FREQUENCY" => Some(Self::UnknownCouponFrequency),
320            "ANNUALLY" => Some(Self::Annually),
321            "SEMIANNUALLY" => Some(Self::Semiannually),
322            "QUARTERLY" => Some(Self::Quarterly),
323            "MONTHLY" => Some(Self::Monthly),
324            "NO_COUPON" => Some(Self::NoCoupon),
325            _ => None,
326        }
327    }
328}
329#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
330#[repr(i32)]
331pub enum CouponTypeProto {
332    /// Maps to Security
333    UnknownCouponType = 0,
334    Fixed = 1,
335    Float = 2,
336    Zero = 3,
337}
338impl CouponTypeProto {
339    /// String value of the enum field names used in the ProtoBuf definition.
340    ///
341    /// The values are not transformed in any way and thus are considered stable
342    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
343    pub fn as_str_name(&self) -> &'static str {
344        match self {
345            CouponTypeProto::UnknownCouponType => "UNKNOWN_COUPON_TYPE",
346            CouponTypeProto::Fixed => "FIXED",
347            CouponTypeProto::Float => "FLOAT",
348            CouponTypeProto::Zero => "ZERO",
349        }
350    }
351    /// Creates an enum from field names used in the ProtoBuf definition.
352    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
353        match value {
354            "UNKNOWN_COUPON_TYPE" => Some(Self::UnknownCouponType),
355            "FIXED" => Some(Self::Fixed),
356            "FLOAT" => Some(Self::Float),
357            "ZERO" => Some(Self::Zero),
358            _ => None,
359        }
360    }
361}
362#[allow(clippy::derive_partial_eq_without_eq)]
363#[derive(Clone, PartialEq, ::prost::Message)]
364pub struct SecurityProto {
365    #[prost(string, tag = "1")]
366    pub object_class: ::prost::alloc::string::String,
367    #[prost(string, tag = "2")]
368    pub version: ::prost::alloc::string::String,
369    /// Primary Key
370    #[prost(message, optional, tag = "5")]
371    pub uuid: ::core::option::Option<super::util::UuidProto>,
372    #[prost(message, optional, tag = "6")]
373    pub as_of: ::core::option::Option<super::util::LocalTimestampProto>,
374    /// When true, this message is a lightweight reference — only uuid is populated.
375    /// The caller must resolve the full entity by calling SecurityService.GetByIds
376    /// with this UUID. Used when embedding a SecurityProto inside another message
377    /// (e.g. PriceProto.security, TransactionProto.security) to avoid duplicating
378    /// the full security data. See docs/adr/is_link_pattern.md for details.
379    #[prost(bool, tag = "7")]
380    pub is_link: bool,
381    #[prost(message, optional, tag = "8")]
382    pub valid_from: ::core::option::Option<super::util::LocalTimestampProto>,
383    #[prost(message, optional, tag = "9")]
384    pub valid_to: ::core::option::Option<super::util::LocalTimestampProto>,
385    #[prost(enumeration = "ProductTypeProto", tag = "10")]
386    pub product_type: i32,
387    /// Orthogonal to product_type — see instrument_type.proto.
388    /// CASH (positionable), DERIVATIVE (value derives from underlying),
389    /// REFERENCE_INDEX (observational only).
390    #[prost(enumeration = "InstrumentTypeProto", tag = "16")]
391    pub instrument_type: i32,
392    /// Multi-leg strategy package legs — each leg is itself a Security
393    /// referenced by UUID using the is_link=true pattern (see
394    /// docs/adr/is_link_pattern.md). See hierarchy-examples.md for the
395    /// pattern: butterflies, calendar spreads, iron condors, etc. are not
396    /// productTypes; they're a Security whose product_type is the
397    /// underlying vanilla type with `legs` populated.
398    ///
399    /// Each leg MUST have is_link=true with uuid and as_of populated.
400    /// Resolve full legs via SecurityService.GetByIds.
401    ///
402    /// WIRE COMPATIBLE with the prior SecurityIdProto type at this tag:
403    /// SecurityIdProto carried uuid at tag 1, identical to SecurityProto.
404    /// Legacy persisted bytes parse correctly under the new type.
405    #[prost(message, repeated, tag = "17")]
406    pub legs: ::prost::alloc::vec::Vec<SecurityProto>,
407    /// Biz fields
408    #[prost(string, tag = "11")]
409    pub asset_class: ::prost::alloc::string::String,
410    #[prost(string, tag = "12")]
411    pub issuer_name: ::prost::alloc::string::String,
412    #[prost(message, optional, boxed, tag = "13")]
413    pub settlement_currency: ::core::option::Option<
414        ::prost::alloc::boxed::Box<SecurityProto>,
415    >,
416    #[prost(enumeration = "SecurityQuantityTypeProto", tag = "14")]
417    pub quantity_type: i32,
418    #[prost(string, tag = "41")]
419    pub description: ::prost::alloc::string::String,
420    /// All known identifiers for this security. The primary identifier (used as
421    /// the human-readable ID) is the first entry. Secondary identifiers follow.
422    /// For Gilts, entry 0 will be {type=ISIN, value="GB..."}; for US Treasuries,
423    /// entry 0 will be {type=CUSIP, value="912828..."}.
424    #[prost(message, repeated, tag = "42")]
425    pub identifiers: ::prost::alloc::vec::Vec<IdentifierProto>,
426    /// Bond-shape details. Populated for any product_type descending from BOND
427    /// in hierarchy.json (TBILL, TREASURY_NOTE, TREASURY_BOND, TIPS,
428    /// TREASURY_FRN, STRIPS, SOVEREIGN_BOND, CORP_BOND, MUNI_BOND, ...).
429    /// Single canonical home for the 8 shared bond fields. Null for non-bonds.
430    #[prost(message, optional, tag = "200")]
431    pub bond_details: ::core::option::Option<BondDetailsProto>,
432    /// TIPS-specific extras. Populated when product_type == TIPS.
433    /// Co-exists with bond_details (does NOT replace it).
434    #[prost(message, optional, tag = "201")]
435    pub tips_extension: ::core::option::Option<TipsExtensionProto>,
436    /// FRN-specific extras. Populated when product_type == TREASURY_FRN.
437    /// Co-exists with bond_details (does NOT replace it).
438    #[prost(message, optional, tag = "202")]
439    pub frn_extension: ::core::option::Option<FrnExtensionProto>,
440    /// Agency MBS pass-through extras. Populated when
441    /// product_type == MORTGAGE_BACKED. Co-exists with bond_details
442    /// (does NOT replace it) — pool-level coupon / face / maturity
443    /// are still on bond_details.
444    #[prost(message, optional, tag = "207")]
445    pub mbs_extension: ::core::option::Option<MbsExtensionProto>,
446    /// Non-bond product details. These ARE mutually exclusive — Cash, Equity,
447    /// Index, FxSpot have no shared shape — so a oneof fits.
448    #[prost(oneof = "security_proto::NonBondDetails", tags = "203, 204, 205, 206")]
449    pub non_bond_details: ::core::option::Option<security_proto::NonBondDetails>,
450}
451/// Nested message and enum types in `SecurityProto`.
452pub mod security_proto {
453    /// Non-bond product details. These ARE mutually exclusive — Cash, Equity,
454    /// Index, FxSpot have no shared shape — so a oneof fits.
455    #[allow(clippy::derive_partial_eq_without_eq)]
456    #[derive(Clone, PartialEq, ::prost::Oneof)]
457    pub enum NonBondDetails {
458        #[prost(message, tag = "203")]
459        IndexDetails(super::IndexDetailsProto),
460        #[prost(message, tag = "204")]
461        EquityDetails(super::EquityDetailsProto),
462        #[prost(message, tag = "205")]
463        CashDetails(super::CashDetailsProto),
464        #[prost(message, tag = "206")]
465        FxSpotDetails(::prost::alloc::boxed::Box<super::FxSpotDetailsProto>),
466    }
467}
468/// Bond security details: fixed-rate coupon bonds (US Treasuries, corporates, etc.)
469#[allow(clippy::derive_partial_eq_without_eq)]
470#[derive(Clone, PartialEq, ::prost::Message)]
471pub struct BondDetailsProto {
472    /// Expressed as a decimal fraction (0.05=5%, 0.0075=0.75%). Do NOT use percentage form (5.0 will be rejected).
473    #[prost(message, optional, tag = "1")]
474    pub coupon_rate: ::core::option::Option<super::util::DecimalValueProto>,
475    #[prost(enumeration = "CouponTypeProto", tag = "2")]
476    pub coupon_type: i32,
477    #[prost(enumeration = "CouponFrequencyProto", tag = "3")]
478    pub coupon_frequency: i32,
479    #[prost(message, optional, tag = "4")]
480    pub dated_date: ::core::option::Option<super::util::LocalDateProto>,
481    #[prost(message, optional, tag = "5")]
482    pub face_value: ::core::option::Option<super::util::DecimalValueProto>,
483    #[prost(message, optional, tag = "6")]
484    pub issue_date: ::core::option::Option<super::util::LocalDateProto>,
485    #[prost(message, optional, tag = "7")]
486    pub maturity_date: ::core::option::Option<super::util::LocalDateProto>,
487    #[prost(message, repeated, tag = "8")]
488    pub issuance_info: ::prost::alloc::vec::Vec<bond::IssuanceProto>,
489}
490/// TIPS (Treasury Inflation-Protected Securities) extras.
491/// Carries ONLY the TIPS-specific fields; shared bond fields live in
492/// SecurityProto.bond_details. Populated when product_type == TIPS.
493#[allow(clippy::derive_partial_eq_without_eq)]
494#[derive(Clone, PartialEq, ::prost::Message)]
495pub struct TipsExtensionProto {
496    /// Reference CPI at bond issuance (e.g. 256.394)
497    #[prost(message, optional, tag = "1")]
498    pub base_cpi: ::core::option::Option<super::util::DecimalValueProto>,
499    /// The date the base CPI was observed
500    #[prost(message, optional, tag = "2")]
501    pub index_date: ::core::option::Option<super::util::LocalDateProto>,
502    /// Which inflation index (e.g. CPI_U)
503    #[prost(enumeration = "index::IndexTypeProto", tag = "3")]
504    pub inflation_index_type: i32,
505}
506/// Floating Rate Note (FRN) extras.
507/// Carries ONLY the FRN-specific fields; shared bond fields live in
508/// SecurityProto.bond_details. Populated when product_type == TREASURY_FRN.
509#[allow(clippy::derive_partial_eq_without_eq)]
510#[derive(Clone, PartialEq, ::prost::Message)]
511pub struct FrnExtensionProto {
512    /// Fixed spread over the reference rate, in basis points
513    #[prost(message, optional, tag = "1")]
514    pub spread: ::core::option::Option<super::util::DecimalValueProto>,
515    /// Which floating rate benchmark (e.g. SOFR)
516    #[prost(enumeration = "index::IndexTypeProto", tag = "2")]
517    pub reference_rate_index: i32,
518    /// How often the floating coupon rate resets
519    #[prost(enumeration = "CouponFrequencyProto", tag = "3")]
520    pub reset_frequency: i32,
521}
522/// Agency MBS pass-through extras (FNMA / FHLMC / GNMA).
523/// Carries pool-level fields beyond what BondDetailsProto already covers
524/// (coupon, face value, maturity date). Populated when
525/// product_type == MORTGAGE_BACKED.
526#[allow(clippy::derive_partial_eq_without_eq)]
527#[derive(Clone, PartialEq, ::prost::Message)]
528pub struct MbsExtensionProto {
529    /// Agency pool identifier (e.g. "FN AS1234")
530    #[prost(string, tag = "1")]
531    pub pool_number: ::prost::alloc::string::String,
532    /// Issuing agency
533    #[prost(enumeration = "bond::AgencyProto", tag = "2")]
534    pub agency: i32,
535    /// Weighted-average coupon (decimal fraction; 0.045 = 4.5%)
536    #[prost(message, optional, tag = "3")]
537    pub wac: ::core::option::Option<super::util::DecimalValueProto>,
538    /// Weighted-average maturity, in months
539    #[prost(int32, tag = "4")]
540    pub wam: i32,
541    /// Pass-through coupon paid to investors (decimal fraction)
542    #[prost(message, optional, tag = "5")]
543    pub pass_through_rate: ::core::option::Option<super::util::DecimalValueProto>,
544    /// Current pool factor (fraction of original principal remaining)
545    #[prost(message, optional, tag = "6")]
546    pub current_factor: ::core::option::Option<super::util::DecimalValueProto>,
547    /// Original face / par at issuance
548    #[prost(message, optional, tag = "7")]
549    pub original_face_value: ::core::option::Option<super::util::DecimalValueProto>,
550    /// Current unpaid principal balance
551    #[prost(message, optional, tag = "8")]
552    pub current_upb: ::core::option::Option<super::util::DecimalValueProto>,
553    /// Prepayment speed assumption (PSA model multiplier)
554    #[prost(message, optional, tag = "9")]
555    pub psa_speed: ::core::option::Option<super::util::DecimalValueProto>,
556}
557/// Index security details (e.g. CPI-U, SOFR index, S&P 500).
558#[allow(clippy::derive_partial_eq_without_eq)]
559#[derive(Clone, PartialEq, ::prost::Message)]
560pub struct IndexDetailsProto {
561    #[prost(enumeration = "index::IndexTypeProto", tag = "1")]
562    pub index_type: i32,
563    /// Populated when QuerySecurityRequestProto.lookthrough=true. Server-side
564    /// resolver computes constituents for the request asOf. Each constituent
565    /// is a SecurityProto with is_link=true (uuid + as_of populated; resolve
566    /// full security via SecurityService.GetByIds).
567    /// See docs/adr/is_link_pattern.md.
568    #[prost(message, repeated, tag = "2")]
569    pub constituents: ::prost::alloc::vec::Vec<SecurityProto>,
570}
571/// Equity security details. Minimal for now — placeholder for future fields
572/// (e.g. shares_outstanding, dividend_yield, sector).
573///
574/// No equity-specific fields exist yet. This message serves as a type marker
575/// in the oneof and a home for future equity-specific fields.
576#[allow(clippy::derive_partial_eq_without_eq)]
577#[derive(Clone, PartialEq, ::prost::Message)]
578pub struct EquityDetailsProto {}
579/// Cash security details.
580#[allow(clippy::derive_partial_eq_without_eq)]
581#[derive(Clone, PartialEq, ::prost::Message)]
582pub struct CashDetailsProto {
583    /// e.g. "USD", "EUR", "GBP"
584    #[prost(string, tag = "1")]
585    pub cash_id: ::prost::alloc::string::String,
586}
587/// FX spot pair details.
588/// Represents a spot foreign exchange rate between two currencies.
589/// The pair is expressed as: price = units of quote_currency per 1 unit of base_currency.
590/// Example: USD/GBP with convention UNITS_OF_QUOTE_PER_BASE means the price is
591/// "how many GBP you receive for 1 USD" (e.g. 0.79).
592#[allow(clippy::derive_partial_eq_without_eq)]
593#[derive(Clone, PartialEq, ::prost::Message)]
594pub struct FxSpotDetailsProto {
595    /// The currency being bought/sold (e.g. USD cash security). Must be a CashDetailsProto with is_link=true.
596    #[prost(message, optional, boxed, tag = "1")]
597    pub base_currency: ::core::option::Option<::prost::alloc::boxed::Box<SecurityProto>>,
598    /// The currency in which the price is expressed (e.g. GBP cash security). Must be a CashDetailsProto with is_link=true.
599    #[prost(message, optional, boxed, tag = "2")]
600    pub quote_currency: ::core::option::Option<
601        ::prost::alloc::boxed::Box<SecurityProto>,
602    >,
603    /// Quoting convention — always "UNITS_OF_QUOTE_PER_BASE" for spot FX (ISO standard)
604    #[prost(string, tag = "3")]
605    pub convention: ::prost::alloc::string::String,
606}
607/// Canonical vocabulary for the asset class of a security.
608///
609/// Note: the SecurityProto.asset_class field is currently `string` (security.proto
610/// field 11). This enum defines the canonical values; the field type stays
611/// string in this release to avoid coordinating a breaking change with
612/// ledger-service / valuation-service / market-data-inputs. A follow-up
613/// will flip the field type after a data-normalization audit.
614///
615/// Initial values are conservative — only those with active usage in the
616/// codebase as of the v0.1.x line:
617///    Cash, Equity, Fixed Income, Index
618/// Add new variants only when there is concrete consumer demand.
619///
620/// Naming note: proto3 enforces package-wide uniqueness for enum value
621/// names (C++ scoping rules — enum values are siblings of their type, not
622/// children of it). `IdentifierTypeProto.CASH` already exists in this
623/// package, so the cash-asset-class value is named `CASH_ASSET_CLASS` to
624/// disambiguate. The other values (FIXED_INCOME, EQUITY, INDEX) are
625/// unique within the package and stay bare.
626#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
627#[repr(i32)]
628pub enum AssetClassProto {
629    UnknownAssetClass = 0,
630    FixedIncome = 1,
631    Equity = 2,
632    CashAssetClass = 3,
633    /// INDEX covers reference instruments like SP500, CMT-derived treasury
634    /// indices, etc. — used in market-data-inputs today. Borderline as an
635    /// "asset class" in finance terminology, but matches in-use data.
636    Index = 4,
637    /// VOLATILITY covers volatility-class reference instruments — VIX
638    /// (CBOE Volatility Index), VVIX, etc. Stored as INDEX_SECURITY at the
639    /// proto type level (these are reference indices, not holdable
640    /// instruments) but distinct asset_class to differentiate from
641    /// equity / fixed-income reference indices like SP500 or CMT yields.
642    /// Added per FinTekkers/second-brain#236.
643    Volatility = 5,
644    /// CRYPTO covers cryptocurrency holdings — BTC, ETH, and other crypto
645    /// assets. Pairs with ProductTypeProto.CRYPTOCURRENCY. Added per
646    /// FinTekkers/second-brain#237.
647    Crypto = 6,
648}
649impl AssetClassProto {
650    /// String value of the enum field names used in the ProtoBuf definition.
651    ///
652    /// The values are not transformed in any way and thus are considered stable
653    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
654    pub fn as_str_name(&self) -> &'static str {
655        match self {
656            AssetClassProto::UnknownAssetClass => "UNKNOWN_ASSET_CLASS",
657            AssetClassProto::FixedIncome => "FIXED_INCOME",
658            AssetClassProto::Equity => "EQUITY",
659            AssetClassProto::CashAssetClass => "CASH_ASSET_CLASS",
660            AssetClassProto::Index => "INDEX",
661            AssetClassProto::Volatility => "VOLATILITY",
662            AssetClassProto::Crypto => "CRYPTO",
663        }
664    }
665    /// Creates an enum from field names used in the ProtoBuf definition.
666    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
667        match value {
668            "UNKNOWN_ASSET_CLASS" => Some(Self::UnknownAssetClass),
669            "FIXED_INCOME" => Some(Self::FixedIncome),
670            "EQUITY" => Some(Self::Equity),
671            "CASH_ASSET_CLASS" => Some(Self::CashAssetClass),
672            "INDEX" => Some(Self::Index),
673            "VOLATILITY" => Some(Self::Volatility),
674            "CRYPTO" => Some(Self::Crypto),
675            _ => None,
676        }
677    }
678}
679/// A point-in-time snapshot of an equity index's constituent securities and weights.
680///
681/// Temporal model (identical to PriceProto):
682///    uuid        — stable identity for this composition record
683///    as_of       — the timestamp this composition was observed / recorded
684///    valid_from  — bitemporal: when this record became system-valid
685///    valid_to    — bitemporal: when this record was superseded
686///    is_link     — if true, only uuid is meaningful; resolve via GetByIds
687///
688/// A new IndexCompositionProto is created whenever the index is rebalanced.
689/// The effective_date field marks the business date the new composition took effect.
690/// To find the composition active on a given date D, query for the most recent
691/// record where effective_date <= D.
692#[allow(clippy::derive_partial_eq_without_eq)]
693#[derive(Clone, PartialEq, ::prost::Message)]
694pub struct IndexCompositionProto {
695    #[prost(string, tag = "1")]
696    pub object_class: ::prost::alloc::string::String,
697    #[prost(string, tag = "2")]
698    pub version: ::prost::alloc::string::String,
699    /// Primary Key (same temporal pattern as SecurityProto and PriceProto)
700    #[prost(message, optional, tag = "5")]
701    pub uuid: ::core::option::Option<super::util::UuidProto>,
702    #[prost(message, optional, tag = "6")]
703    pub as_of: ::core::option::Option<super::util::LocalTimestampProto>,
704    #[prost(bool, tag = "7")]
705    pub is_link: bool,
706    #[prost(message, optional, tag = "8")]
707    pub valid_from: ::core::option::Option<super::util::LocalTimestampProto>,
708    #[prost(message, optional, tag = "9")]
709    pub valid_to: ::core::option::Option<super::util::LocalTimestampProto>,
710    /// The index security this composition belongs to (EQUITY_INDEX_SECURITY type).
711    /// Typically is_link = true; resolve via SecurityService.GetByIds.
712    #[prost(message, optional, tag = "10")]
713    pub index_security: ::core::option::Option<SecurityProto>,
714    /// The calendar date on which this composition became effective (the rebalance date).
715    /// Temporal lookup key: given as_of_date D, return the composition where
716    /// effective_date <= D, ordered by effective_date DESC, LIMIT 1.
717    #[prost(message, optional, tag = "11")]
718    pub effective_date: ::core::option::Option<super::util::LocalDateProto>,
719    /// The full list of constituents at this rebalance point.
720    #[prost(message, repeated, tag = "20")]
721    pub constituents: ::prost::alloc::vec::Vec<IndexConstituentProto>,
722    /// For price-weighted indices (e.g. DJIA), the divisor at this rebalance point.
723    /// Divisors change when constituents change or corporate actions occur.
724    /// index_level = sum(price_i * shares_i) / index_divisor
725    #[prost(message, optional, tag = "21")]
726    pub index_divisor: ::core::option::Option<super::util::DecimalValueProto>,
727    /// Free-form notes (e.g. "Quarterly rebalance — removed XYZ, added ABC").
728    #[prost(string, tag = "31")]
729    pub notes: ::prost::alloc::string::String,
730}
731/// A single constituent within an index at a specific rebalance point.
732#[allow(clippy::derive_partial_eq_without_eq)]
733#[derive(Clone, PartialEq, ::prost::Message)]
734pub struct IndexConstituentProto {
735    /// The constituent equity security.
736    /// Typically is_link = true; resolve via SecurityService.GetByIds.
737    #[prost(message, optional, tag = "1")]
738    pub security: ::core::option::Option<SecurityProto>,
739    /// Weight of this constituent in the index, expressed as a decimal fraction
740    /// (e.g. 0.05 = 5%). Used for market-cap-weighted and equal-weighted indices.
741    /// For price-weighted indices, leave unset; use shares_in_index instead.
742    #[prost(message, optional, tag = "2")]
743    pub weight: ::core::option::Option<super::util::DecimalValueProto>,
744    /// Number of shares used in price-weighted index calculation (e.g. DJIA).
745    /// For non-price-weighted indices, leave unset; use weight instead.
746    #[prost(message, optional, tag = "3")]
747    pub shares_in_index: ::core::option::Option<super::util::DecimalValueProto>,
748    /// The currency of the constituent's price (e.g. "USD"). Needed for multi-currency indices.
749    #[prost(string, tag = "5")]
750    pub currency: ::prost::alloc::string::String,
751}
752#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
753#[repr(i32)]
754pub enum TenorTypeProto {
755    UnknownTenorType = 0,
756    Perpetual = 1,
757    Term = 2,
758}
759impl TenorTypeProto {
760    /// String value of the enum field names used in the ProtoBuf definition.
761    ///
762    /// The values are not transformed in any way and thus are considered stable
763    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
764    pub fn as_str_name(&self) -> &'static str {
765        match self {
766            TenorTypeProto::UnknownTenorType => "UNKNOWN_TENOR_TYPE",
767            TenorTypeProto::Perpetual => "PERPETUAL",
768            TenorTypeProto::Term => "TERM",
769        }
770    }
771    /// Creates an enum from field names used in the ProtoBuf definition.
772    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
773        match value {
774            "UNKNOWN_TENOR_TYPE" => Some(Self::UnknownTenorType),
775            "PERPETUAL" => Some(Self::Perpetual),
776            "TERM" => Some(Self::Term),
777            _ => None,
778        }
779    }
780}
781#[allow(clippy::derive_partial_eq_without_eq)]
782#[derive(Clone, PartialEq, ::prost::Message)]
783pub struct TenorProto {
784    #[prost(string, tag = "1")]
785    pub object_class: ::prost::alloc::string::String,
786    #[prost(string, tag = "2")]
787    pub version: ::prost::alloc::string::String,
788    #[prost(string, tag = "5")]
789    pub term_value: ::prost::alloc::string::String,
790    #[prost(enumeration = "TenorTypeProto", tag = "6")]
791    pub tenor_type: i32,
792}