/** * Pricing Suggestion Value Object * * Encapsulates a suggested price with confidence level and contributing factors. * Immutable once created; all validation happens at construction time. */ export class PricingSuggestion { readonly suggestedPrice: number; readonly confidence: number; readonly factors: PricingFactors; private constructor(props: { suggestedPrice: number; confidence: number; factors: PricingFactors; }) { this.suggestedPrice = props.suggestedPrice; this.confidence = props.confidence; this.factors = props.factors; } /** * Create a PricingSuggestion using the local 3-factor pricing model. * Formula: P = F x (1 - dt - rc - lp) */ static fromLocalModel(params: { faceValue: number; daysToExpiry: number; totalDays: number; redemptionRate: number; liquidityPremium: number; }): PricingSuggestion { const dt = params.totalDays > 0 ? Math.max(0, 1 - params.daysToExpiry / params.totalDays) * 0.3 : 0; const rc = (1 - params.redemptionRate) * 0.2; const lp = params.liquidityPremium; const discount = dt + rc + lp; const price = Math.max(params.faceValue * 0.1, params.faceValue * (1 - discount)); return new PricingSuggestion({ suggestedPrice: Math.round(price * 100) / 100, confidence: 0.7, factors: { timeDecay: dt, redemptionCredit: rc, liquidityPremium: lp }, }); } /** * Reconstitute from external AI agent response data. */ static fromResponse(data: { suggestedPrice: number; confidence: number; factors: Record; }): PricingSuggestion { return new PricingSuggestion({ suggestedPrice: data.suggestedPrice, confidence: data.confidence, factors: { timeDecay: data.factors.timeDecay ?? 0, redemptionCredit: data.factors.redemptionCredit ?? 0, liquidityPremium: data.factors.liquidityPremium ?? 0, }, }); } toPlain(): { suggestedPrice: number; confidence: number; factors: Record; } { return { suggestedPrice: this.suggestedPrice, confidence: this.confidence, factors: { ...this.factors }, }; } } export interface PricingFactors { timeDecay: number; redemptionCredit: number; liquidityPremium: number; }