86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
/**
|
|
* 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<string, number>;
|
|
}): 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<string, number>;
|
|
} {
|
|
return {
|
|
suggestedPrice: this.suggestedPrice,
|
|
confidence: this.confidence,
|
|
factors: { ...this.factors },
|
|
};
|
|
}
|
|
}
|
|
|
|
export interface PricingFactors {
|
|
timeDecay: number;
|
|
redemptionCredit: number;
|
|
liquidityPremium: number;
|
|
}
|