@mnemopay/sdk 0.9.3 → 1.0.0

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.
@@ -0,0 +1,560 @@
1
+ "use strict";
2
+ /**
3
+ * Behavioral Finance Engine — Psychology-Backed Financial Intelligence
4
+ *
5
+ * Implements Nobel Prize-winning behavioral economics research to help
6
+ * AI agents (and their human principals) make better financial decisions.
7
+ *
8
+ * Core models implemented:
9
+ * 1. Prospect Theory value function (Kahneman & Tversky, 1979/1992)
10
+ * 2. Quasi-hyperbolic discounting (Laibson, 1997)
11
+ * 3. Dynamic cooling-off periods (MnemoPay original)
12
+ * 4. Loss-framed nudges (Tversky & Kahneman, 1981)
13
+ * 5. Commitment devices / Save More Tomorrow (Thaler & Benartzi, 2004)
14
+ * 6. Regret memory + prediction (Zeelenberg & Pieters, 2007)
15
+ * 7. Overconfidence brake (Barber & Odean, 2000)
16
+ * 8. Intelligent expense reframing (Thaler, 1985 mental accounting)
17
+ * 9. Endowed progress effect (Nunes & Dreze, 2006)
18
+ * 10. Anti-herd alerting (Shiller, 2000)
19
+ *
20
+ * All parameters sourced from peer-reviewed publications with exact citations.
21
+ * Zero external dependencies.
22
+ *
23
+ * References (selected):
24
+ * - Tversky & Kahneman (1992). "Advances in Prospect Theory"
25
+ * - Laibson (1997). "Golden Eggs and Hyperbolic Discounting"
26
+ * - Thaler & Benartzi (2004). "Save More Tomorrow"
27
+ * - Barber & Odean (2000). "Trading Is Hazardous to Your Wealth"
28
+ * - Madrian & Shea (2001). "The Power of Suggestion"
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.BehavioralEngine = exports.DEFAULT_BEHAVIORAL_CONFIG = void 0;
32
+ exports.DEFAULT_BEHAVIORAL_CONFIG = {
33
+ lambda: 2.25, // Tversky & Kahneman 1992
34
+ alpha: 0.88, // Tversky & Kahneman 1992
35
+ beta_pt: 0.88, // Tversky & Kahneman 1992
36
+ beta_discount: 0.70, // Laibson 1997
37
+ delta: 0.96, // Laibson 1997
38
+ baseCoolingHours: 2,
39
+ coolingThreshold: 100,
40
+ maxTradesPerMonth: 15,
41
+ excessTradeCostBps: 50, // 50 bps per excess trade (conservative estimate from B&O)
42
+ };
43
+ // ─── Behavioral Finance Engine ──────────────────────────────────────────────
44
+ class BehavioralEngine {
45
+ config;
46
+ regretHistory = [];
47
+ static MAX_REGRET_HISTORY = 500;
48
+ constructor(config) {
49
+ this.config = { ...exports.DEFAULT_BEHAVIORAL_CONFIG, ...config };
50
+ this._validateConfig();
51
+ }
52
+ // ── 1. Prospect Theory Value Function ───────────────────────────────────
53
+ // v(x) = x^alpha for gains (x >= 0)
54
+ // v(x) = -lambda * (-x)^beta for losses (x < 0)
55
+ //
56
+ // Properties:
57
+ // - Concave for gains (diminishing sensitivity)
58
+ // - Convex for losses (risk-seeking in losses)
59
+ // - Steeper for losses than gains (loss aversion)
60
+ prospectValue(amount) {
61
+ if (typeof amount !== "number" || !Number.isFinite(amount)) {
62
+ throw new Error("Amount must be a finite number");
63
+ }
64
+ if (amount >= 0) {
65
+ const value = Math.pow(amount, this.config.alpha);
66
+ return {
67
+ value,
68
+ amount,
69
+ domain: "gain",
70
+ lossAversion: 1,
71
+ explanation: `A $${amount.toFixed(2)} gain feels like ${value.toFixed(2)} units of satisfaction. Diminishing returns: doubling the gain doesn't double the joy.`,
72
+ };
73
+ }
74
+ else {
75
+ const absAmount = Math.abs(amount);
76
+ const value = -this.config.lambda * Math.pow(absAmount, this.config.beta_pt);
77
+ return {
78
+ value,
79
+ amount,
80
+ domain: "loss",
81
+ lossAversion: this.config.lambda,
82
+ explanation: `A $${absAmount.toFixed(2)} loss feels like ${Math.abs(value).toFixed(2)} units of pain — ${this.config.lambda}x worse than an equivalent gain.`,
83
+ };
84
+ }
85
+ }
86
+ /**
87
+ * Compare gain vs loss framing of the same amount.
88
+ * Shows why loss framing is 2.25x more effective for behavior change.
89
+ */
90
+ compareFraming(amount) {
91
+ if (amount <= 0)
92
+ throw new Error("Amount must be positive for framing comparison");
93
+ const gain = this.prospectValue(amount);
94
+ const loss = this.prospectValue(-amount);
95
+ const ratio = Math.abs(loss.value) / gain.value;
96
+ return {
97
+ gainValue: gain.value,
98
+ lossValue: loss.value,
99
+ ratio: Math.round(ratio * 100) / 100,
100
+ insight: `Losing $${amount.toFixed(2)} hurts ${ratio.toFixed(1)}x more than gaining it feels good. Frame savings interventions as loss prevention for ${ratio.toFixed(1)}x effectiveness.`,
101
+ };
102
+ }
103
+ // ── 2. Quasi-Hyperbolic Discounting ─────────────────────────────────────
104
+ // D(0) = 1
105
+ // D(t) = beta * delta^t for t >= 1
106
+ //
107
+ // Models present bias: people overvalue immediate rewards.
108
+ // beta < 1 means "I want it NOW" — the gap between D(0)=1 and D(1)=beta*delta
109
+ discount(periods) {
110
+ if (typeof periods !== "number" || !Number.isFinite(periods) || periods < 0) {
111
+ throw new Error("Periods must be a non-negative number");
112
+ }
113
+ if (periods === 0)
114
+ return 1;
115
+ return this.config.beta_discount * Math.pow(this.config.delta, periods);
116
+ }
117
+ /**
118
+ * Calculate the present-biased value of a future amount.
119
+ * Shows how much a rational agent values $X received in T periods.
120
+ */
121
+ presentValue(futureAmount, periods) {
122
+ if (futureAmount <= 0)
123
+ throw new Error("Future amount must be positive");
124
+ const factor = this.discount(periods);
125
+ const discountedValue = futureAmount * factor;
126
+ return {
127
+ discountedValue: Math.round(discountedValue * 100) / 100,
128
+ discountFactor: Math.round(factor * 10000) / 10000,
129
+ lostValue: Math.round((futureAmount - discountedValue) * 100) / 100,
130
+ explanation: `$${futureAmount.toFixed(2)} in ${periods} period(s) feels worth only $${discountedValue.toFixed(2)} now (${(factor * 100).toFixed(1)}% of face value). Present bias loses $${(futureAmount - discountedValue).toFixed(2)} of perceived value.`,
131
+ };
132
+ }
133
+ // ── 3. Dynamic Cooling-Off Period ───────────────────────────────────────
134
+ // hours = base * (amount / monthly_income) * (1 / user_beta) * regret_ratio
135
+ //
136
+ // Adapted from Thaler's cooling-off concept + our own behavioral calibration.
137
+ // user_beta is estimated from past behavior (high impulsivity = low beta).
138
+ coolingOff(amount, monthlyIncome, userBeta) {
139
+ if (typeof amount !== "number" || !Number.isFinite(amount) || amount < 0) {
140
+ throw new Error("Amount must be a non-negative finite number");
141
+ }
142
+ if (typeof monthlyIncome !== "number" || !Number.isFinite(monthlyIncome) || monthlyIncome <= 0) {
143
+ throw new Error("Monthly income must be a positive number");
144
+ }
145
+ // Below threshold: no cooling needed
146
+ if (amount < this.config.coolingThreshold) {
147
+ return {
148
+ recommended: false,
149
+ hours: 0,
150
+ reason: `Amount ($${amount.toFixed(2)}) below cooling threshold ($${this.config.coolingThreshold})`,
151
+ riskLevel: "low",
152
+ regretProbability: 0,
153
+ };
154
+ }
155
+ const beta = Math.max(0.1, Math.min(1.0, userBeta ?? this.config.beta_discount));
156
+ const regretRatio = this._computeRegretRatio();
157
+ const incomeRatio = amount / monthlyIncome;
158
+ // Core formula
159
+ let hours = this.config.baseCoolingHours * incomeRatio * (1 / beta) * Math.max(0.1, regretRatio);
160
+ // Clamp to reasonable bounds
161
+ hours = Math.max(0.5, Math.min(168, hours)); // 30 min to 1 week
162
+ // Risk level
163
+ let riskLevel;
164
+ if (incomeRatio < 0.05)
165
+ riskLevel = "low";
166
+ else if (incomeRatio < 0.15)
167
+ riskLevel = "medium";
168
+ else if (incomeRatio < 0.50)
169
+ riskLevel = "high";
170
+ else
171
+ riskLevel = "extreme";
172
+ // Regret probability from history
173
+ const regretProbability = Math.min(0.95, regretRatio * 1.2);
174
+ const reason = hours > 0.5
175
+ ? `Purchase is ${(incomeRatio * 100).toFixed(0)}% of monthly income. Historical regret rate: ${(regretRatio * 100).toFixed(0)}%. Wait ${hours.toFixed(1)} hours.`
176
+ : `Low-risk purchase relative to income`;
177
+ return {
178
+ recommended: hours >= 1,
179
+ hours: Math.round(hours * 10) / 10,
180
+ reason,
181
+ riskLevel,
182
+ regretProbability: Math.round(regretProbability * 100) / 100,
183
+ };
184
+ }
185
+ // ── 4. Loss-Framed Nudges ───────────────────────────────────────────────
186
+ // Frame spending as goal delay: "$15/mo delays your home by 4 months"
187
+ // Loss framing is 2.25x more effective than gain framing (T&K 1981)
188
+ lossFrame(spendAmount, goal) {
189
+ if (spendAmount <= 0)
190
+ throw new Error("Spend amount must be positive");
191
+ if (!goal || goal.target <= 0 || goal.monthlySavings <= 0) {
192
+ throw new Error("Goal must have positive target and monthly savings");
193
+ }
194
+ const remaining = goal.target - goal.current;
195
+ const monthsToGoal = remaining > 0 ? remaining / goal.monthlySavings : 0;
196
+ // How much does this spend delay the goal?
197
+ const delayMonths = goal.monthlySavings > 0 ? spendAmount / goal.monthlySavings : 0;
198
+ const delayDays = Math.round(delayMonths * 30);
199
+ const message = delayDays > 0
200
+ ? `This $${spendAmount.toFixed(2)} purchase delays your "${goal.name}" goal by ${delayDays} day(s). You'll reach $${goal.target.toLocaleString()} ${delayDays} day(s) later.`
201
+ : `This purchase has minimal impact on your "${goal.name}" goal.`;
202
+ const gainMessage = `Skipping this purchase saves $${spendAmount.toFixed(2)} toward your "${goal.name}" goal.`;
203
+ return {
204
+ message,
205
+ gainMessage,
206
+ effectivenessMultiplier: this.config.lambda, // 2.25x
207
+ goalDelayDays: delayDays,
208
+ };
209
+ }
210
+ // ── 5. Commitment Devices / Save More Tomorrow ──────────────────────────
211
+ // Pre-commit to save X% of future raises.
212
+ // Thaler & Benartzi 2004: participants went from 3.5% to 13.6% over 4 cycles.
213
+ commitmentDevice(currentSavingsRate, raisePercent, cycles) {
214
+ if (currentSavingsRate < 0 || currentSavingsRate > 1)
215
+ throw new Error("Savings rate must be 0-1");
216
+ if (raisePercent <= 0 || raisePercent > 0.5)
217
+ throw new Error("Raise percent must be 0-0.5");
218
+ if (cycles < 1 || cycles > 20 || !Number.isInteger(cycles))
219
+ throw new Error("Cycles must be integer 1-20");
220
+ // Each raise cycle: allocate a fraction of the raise to savings
221
+ // Default allocation: 50% of each raise goes to savings (SMarT default)
222
+ const allocationRate = 0.5;
223
+ const rates = [currentSavingsRate];
224
+ const savings = [0];
225
+ let rate = currentSavingsRate;
226
+ let cumulativeSavings = 0;
227
+ // Assume $100K salary for projections
228
+ const baseSalary = 100_000;
229
+ for (let i = 0; i < cycles; i++) {
230
+ const raiseAmount = baseSalary * raisePercent;
231
+ const additionalSavings = raiseAmount * allocationRate;
232
+ rate = Math.min(0.50, rate + (additionalSavings / baseSalary)); // Cap at 50%
233
+ cumulativeSavings += baseSalary * rate;
234
+ rates.push(Math.round(rate * 10000) / 10000);
235
+ savings.push(Math.round(cumulativeSavings));
236
+ }
237
+ return {
238
+ projectedRates: rates,
239
+ projectedSavings: savings,
240
+ finalRate: rates[rates.length - 1],
241
+ explanation: `SMarT projection: savings rate grows from ${(currentSavingsRate * 100).toFixed(1)}% to ${(rate * 100).toFixed(1)}% over ${cycles} raise cycle(s). Thaler & Benartzi (2004) observed 3.5% → 13.6% in 4 cycles. Key insight: people don't feel the loss because it comes from future raises, not current income.`,
242
+ };
243
+ }
244
+ // ── 6. Regret Memory & Prediction ───────────────────────────────────────
245
+ // Track past purchase regret to predict future regret.
246
+ recordRegret(entry) {
247
+ if (!entry || typeof entry.amount !== "number" || !Number.isFinite(entry.amount)) {
248
+ throw new Error("Regret entry requires a valid amount");
249
+ }
250
+ if (typeof entry.regretScore !== "number" || entry.regretScore < 0 || entry.regretScore > 10) {
251
+ throw new Error("Regret score must be 0-10");
252
+ }
253
+ this.regretHistory.push({
254
+ amount: entry.amount,
255
+ category: entry.category?.toLowerCase() || "unknown",
256
+ regretScore: entry.regretScore,
257
+ timestamp: entry.timestamp || new Date().toISOString(),
258
+ });
259
+ // Cap history
260
+ if (this.regretHistory.length > BehavioralEngine.MAX_REGRET_HISTORY) {
261
+ this.regretHistory.splice(0, this.regretHistory.length - BehavioralEngine.MAX_REGRET_HISTORY);
262
+ }
263
+ }
264
+ predictRegret(amount, category) {
265
+ if (typeof amount !== "number" || !Number.isFinite(amount) || amount < 0) {
266
+ throw new Error("Amount must be a non-negative finite number");
267
+ }
268
+ const cat = category?.toLowerCase() || "unknown";
269
+ if (this.regretHistory.length < 3) {
270
+ return {
271
+ probability: 0.5, // Unknown, assume 50%
272
+ confidence: 0.1,
273
+ historicalRegretRate: 0,
274
+ categoryRegretRate: 0,
275
+ recommendation: "Not enough purchase history to predict regret. Consider waiting.",
276
+ triggerCoolingOff: amount >= this.config.coolingThreshold,
277
+ };
278
+ }
279
+ // Overall regret rate (regretScore > 5 = regretted)
280
+ const regretted = this.regretHistory.filter(r => r.regretScore > 5).length;
281
+ const historicalRate = regretted / this.regretHistory.length;
282
+ // Category-specific rate
283
+ const catEntries = this.regretHistory.filter(r => r.category === cat);
284
+ const catRegretted = catEntries.filter(r => r.regretScore > 5).length;
285
+ const categoryRate = catEntries.length >= 2 ? catRegretted / catEntries.length : historicalRate;
286
+ // Amount-weighted: larger purchases tend to have higher regret
287
+ const similarAmount = this.regretHistory.filter(r => r.amount >= amount * 0.5 && r.amount <= amount * 2);
288
+ const amountRegretted = similarAmount.filter(r => r.regretScore > 5).length;
289
+ const amountRate = similarAmount.length >= 2 ? amountRegretted / similarAmount.length : historicalRate;
290
+ // Blend: 40% category, 30% amount-similar, 30% overall
291
+ const probability = Math.min(0.95, categoryRate * 0.4 + amountRate * 0.3 + historicalRate * 0.3);
292
+ const confidence = Math.min(0.9, this.regretHistory.length / 50);
293
+ let recommendation;
294
+ if (probability >= 0.7) {
295
+ recommendation = `High regret risk (${(probability * 100).toFixed(0)}%). You've regretted ${(categoryRate * 100).toFixed(0)}% of similar "${cat}" purchases. Strongly consider waiting.`;
296
+ }
297
+ else if (probability >= 0.4) {
298
+ recommendation = `Moderate regret risk (${(probability * 100).toFixed(0)}%). Consider whether this purchase aligns with your goals.`;
299
+ }
300
+ else {
301
+ recommendation = `Low regret risk (${(probability * 100).toFixed(0)}%). This type of purchase has been satisfying historically.`;
302
+ }
303
+ return {
304
+ probability: Math.round(probability * 100) / 100,
305
+ confidence: Math.round(confidence * 100) / 100,
306
+ historicalRegretRate: Math.round(historicalRate * 100) / 100,
307
+ categoryRegretRate: Math.round(categoryRate * 100) / 100,
308
+ recommendation,
309
+ triggerCoolingOff: probability >= 0.5 && amount >= this.config.coolingThreshold,
310
+ };
311
+ }
312
+ // ── 7. Overconfidence Brake ─────────────────────────────────────────────
313
+ // Barber & Odean (2000): highest-turnover quartile underperforms by 6.5pp/year
314
+ // Also checks disposition effect: holding losers, selling winners (Odean 1998)
315
+ overconfidenceBrake(trades, periodDays = 30) {
316
+ if (!Array.isArray(trades))
317
+ throw new Error("Trades must be an array");
318
+ if (periodDays <= 0)
319
+ throw new Error("Period must be positive");
320
+ const now = Date.now();
321
+ const periodMs = periodDays * 86_400_000;
322
+ const recentTrades = trades.filter(t => (now - t.timestamp) < periodMs);
323
+ const frequency = recentTrades.length;
324
+ const optimal = this.config.maxTradesPerMonth * (periodDays / 30);
325
+ // Performance drag: excess trades * cost per trade
326
+ const excessTrades = Math.max(0, frequency - optimal);
327
+ const performanceDrag = excessTrades * (this.config.excessTradeCostBps / 100);
328
+ // Disposition effect: are sells concentrated on winners?
329
+ const sells = recentTrades.filter(t => t.direction === "sell" && t.realizedPL !== undefined);
330
+ const winnerSells = sells.filter(t => (t.realizedPL ?? 0) > 0).length;
331
+ const loserSells = sells.filter(t => (t.realizedPL ?? 0) < 0).length;
332
+ // Odean (1998): investors are 1.5x more likely to sell winners
333
+ const dispositionEffect = sells.length >= 3 && winnerSells > loserSells * 1.3;
334
+ const detected = frequency > optimal || dispositionEffect;
335
+ let recommendation;
336
+ if (frequency > optimal * 2) {
337
+ recommendation = `Trading ${frequency} times in ${periodDays} days is ${(frequency / optimal).toFixed(1)}x the optimal rate. Estimated annual performance drag: ${performanceDrag.toFixed(1)}%. Consider a rules-based approach.`;
338
+ }
339
+ else if (dispositionEffect) {
340
+ recommendation = `Disposition effect detected: selling winners (${winnerSells}) more than losers (${loserSells}). This pattern costs ~4% annually (Odean 1998). Let winners run, cut losers.`;
341
+ }
342
+ else if (frequency > optimal) {
343
+ recommendation = `Slightly above optimal trading frequency. Monitor for escalation.`;
344
+ }
345
+ else {
346
+ recommendation = `Trading frequency is within optimal range.`;
347
+ }
348
+ return {
349
+ detected,
350
+ frequency,
351
+ optimalFrequency: Math.round(optimal),
352
+ performanceDrag: Math.round(performanceDrag * 100) / 100,
353
+ dispositionEffect,
354
+ recommendation,
355
+ };
356
+ }
357
+ // ── 8. Intelligent Expense Reframing ────────────────────────────────────
358
+ // Thaler (1985): mental accounting — how people categorize money matters.
359
+ // Convert subscriptions to annual to reveal true cost.
360
+ // Convert daily habits to annual to show accumulation.
361
+ reframeExpense(amount, frequency) {
362
+ if (typeof amount !== "number" || !Number.isFinite(amount) || amount < 0) {
363
+ throw new Error("Amount must be a non-negative finite number");
364
+ }
365
+ let annual;
366
+ switch (frequency) {
367
+ case "daily":
368
+ annual = amount * 365;
369
+ break;
370
+ case "weekly":
371
+ annual = amount * 52;
372
+ break;
373
+ case "monthly":
374
+ annual = amount * 12;
375
+ break;
376
+ case "annual":
377
+ annual = amount;
378
+ break;
379
+ default: throw new Error("Frequency must be daily, weekly, monthly, or annual");
380
+ }
381
+ const daily = annual / 365;
382
+ const weekly = annual / 52;
383
+ const monthly = annual / 12;
384
+ // Most impactful frame:
385
+ // For subscriptions (monthly), annual is more impactful ($13/mo vs $156/yr)
386
+ // For habits (daily), annual is more impactful ($5/day vs $1,825/yr)
387
+ // For annual costs, daily makes it seem smaller (useful for showing it's affordable)
388
+ let impactFrame;
389
+ if (frequency === "monthly" || frequency === "weekly") {
390
+ impactFrame = `That's $${annual.toFixed(2)}/year. Over 10 years: $${(annual * 10).toFixed(0)}.`;
391
+ }
392
+ else if (frequency === "daily") {
393
+ impactFrame = `That $${amount.toFixed(2)}/day habit costs $${annual.toFixed(0)}/year — $${(annual * 10).toFixed(0)} over a decade.`;
394
+ }
395
+ else {
396
+ impactFrame = `That's $${daily.toFixed(2)}/day or $${monthly.toFixed(2)}/month.`;
397
+ }
398
+ // Opportunity cost: invested at 7% annual return
399
+ const invested10yr = annual * ((Math.pow(1.07, 10) - 1) / 0.07);
400
+ const opportunityCost = `Invested instead at 7% annual return: $${Math.round(invested10yr).toLocaleString()} in 10 years.`;
401
+ return {
402
+ original: { amount, frequency },
403
+ daily: Math.round(daily * 100) / 100,
404
+ weekly: Math.round(weekly * 100) / 100,
405
+ monthly: Math.round(monthly * 100) / 100,
406
+ annual: Math.round(annual * 100) / 100,
407
+ impactFrame,
408
+ opportunityCost,
409
+ };
410
+ }
411
+ // ── 9. Endowed Progress Effect ──────────────────────────────────────────
412
+ // Nunes & Dreze (2006): People given a head start (2/12 stamps vs 0/10)
413
+ // complete loyalty programs 34% vs 19% of the time.
414
+ // Frame progress to make goals feel closer.
415
+ endowedProgress(goal) {
416
+ if (!goal || goal.target <= 0)
417
+ throw new Error("Goal must have positive target");
418
+ const percent = Math.min(100, Math.max(0, (goal.current / goal.target) * 100));
419
+ // Endowed framing: emphasize what's been achieved, not what's left
420
+ let message;
421
+ if (percent >= 80) {
422
+ message = `You're ${percent.toFixed(0)}% there! Only $${(goal.target - goal.current).toFixed(0)} to go for "${goal.name}". The finish line is right there.`;
423
+ }
424
+ else if (percent >= 50) {
425
+ message = `You're past the halfway mark on "${goal.name}" — ${percent.toFixed(0)}% complete! $${goal.current.toFixed(0)} saved so far.`;
426
+ }
427
+ else if (percent >= 20) {
428
+ message = `Great start on "${goal.name}" — ${percent.toFixed(0)}% done! You've already saved $${goal.current.toFixed(0)}.`;
429
+ }
430
+ else if (percent > 0) {
431
+ message = `You've started "${goal.name}" — every dollar counts. ${percent.toFixed(1)}% complete ($${goal.current.toFixed(0)} saved).`;
432
+ }
433
+ else {
434
+ message = `Ready to start "${goal.name}"? Setting aside even $1 today puts you ahead of 80% of people who never start.`;
435
+ }
436
+ // Nunes & Dreze: 34% completion with endowed progress vs 19% without
437
+ const expectedCompletionRate = percent > 0 ? 0.34 : 0.19;
438
+ return {
439
+ percentComplete: Math.round(percent * 100) / 100,
440
+ message,
441
+ expectedCompletionRate,
442
+ };
443
+ }
444
+ // ── 10. Anti-Herd Alert ─────────────────────────────────────────────────
445
+ // Shiller (2000): CAPE hit 44 during dot-com (mean ~16).
446
+ // Alert when valuation exceeds 2 standard deviations from historical mean.
447
+ antiHerdAlert(metrics) {
448
+ if (!metrics || typeof metrics.peRatio !== "number")
449
+ throw new Error("Valid asset metrics required");
450
+ if (metrics.historicalStdPE <= 0)
451
+ throw new Error("Historical std dev must be positive");
452
+ const sigma = (metrics.peRatio - metrics.historicalMeanPE) / metrics.historicalStdPE;
453
+ const absSigma = Math.abs(sigma);
454
+ let detected = false;
455
+ let severity = "low";
456
+ let message = "";
457
+ let recommendation = "";
458
+ if (sigma > 2 && metrics.recentReturn30d > 10) {
459
+ detected = true;
460
+ severity = "high";
461
+ message = `Extreme overvaluation: P/E ${metrics.peRatio.toFixed(1)} is ${sigma.toFixed(1)}σ above mean (${metrics.historicalMeanPE.toFixed(1)}). Recent 30-day return of ${metrics.recentReturn30d.toFixed(1)}% suggests momentum chasing.`;
462
+ recommendation = `Contrarian signal: reduce exposure. Historical mean reversion is strong above 2σ.`;
463
+ }
464
+ else if (sigma > 1.5) {
465
+ detected = true;
466
+ severity = "medium";
467
+ message = `Elevated valuation: P/E ${metrics.peRatio.toFixed(1)} is ${sigma.toFixed(1)}σ above mean. Watch for reversal.`;
468
+ recommendation = `Consider trimming position or tightening stops.`;
469
+ }
470
+ else if (sigma < -1.5) {
471
+ detected = true;
472
+ severity = "medium";
473
+ message = `Potential undervaluation: P/E ${metrics.peRatio.toFixed(1)} is ${Math.abs(sigma).toFixed(1)}σ below mean. Market may be irrationally pessimistic.`;
474
+ recommendation = `Contrarian opportunity: evaluate fundamentals. Beaten-down assets often recover (De Bondt & Thaler 1985: 25% outperformance over 3 years).`;
475
+ }
476
+ else {
477
+ message = `Valuation within normal range (${sigma.toFixed(1)}σ from mean).`;
478
+ recommendation = `No herd-driven distortion detected.`;
479
+ }
480
+ if (metrics.volumeRatio > 2.5) {
481
+ detected = true;
482
+ if (severity === "low")
483
+ severity = "medium";
484
+ message += ` Volume is ${metrics.volumeRatio.toFixed(1)}x normal — unusual activity.`;
485
+ }
486
+ return {
487
+ detected,
488
+ severity,
489
+ valuationSigma: Math.round(sigma * 100) / 100,
490
+ message,
491
+ recommendation,
492
+ };
493
+ }
494
+ // ── Helpers ─────────────────────────────────────────────────────────────
495
+ _computeRegretRatio() {
496
+ if (this.regretHistory.length === 0)
497
+ return 0.5; // Default: assume 50% regret
498
+ const regretted = this.regretHistory.filter(r => r.regretScore > 5).length;
499
+ return regretted / this.regretHistory.length;
500
+ }
501
+ _validateConfig() {
502
+ const c = this.config;
503
+ // Reject NaN/Infinity on all numeric config values
504
+ for (const [key, val] of Object.entries(c)) {
505
+ if (typeof val === "number" && !Number.isFinite(val)) {
506
+ throw new Error(`Config.${key} must be a finite number, got ${val}`);
507
+ }
508
+ }
509
+ if (c.lambda <= 0 || c.lambda > 10)
510
+ throw new Error("Lambda must be in (0, 10]");
511
+ if (c.alpha <= 0 || c.alpha > 1)
512
+ throw new Error("Alpha must be in (0, 1]");
513
+ if (c.beta_pt <= 0 || c.beta_pt > 1)
514
+ throw new Error("Beta (PT) must be in (0, 1]");
515
+ if (c.beta_discount <= 0 || c.beta_discount > 1)
516
+ throw new Error("Beta (discount) must be in (0, 1]");
517
+ if (c.delta <= 0 || c.delta > 1)
518
+ throw new Error("Delta must be in (0, 1]");
519
+ if (c.baseCoolingHours <= 0)
520
+ throw new Error("Base cooling hours must be positive");
521
+ if (c.coolingThreshold < 0)
522
+ throw new Error("Cooling threshold must be non-negative");
523
+ if (c.maxTradesPerMonth < 1)
524
+ throw new Error("maxTradesPerMonth must be at least 1");
525
+ if (c.excessTradeCostBps < 0)
526
+ throw new Error("excessTradeCostBps must be non-negative");
527
+ }
528
+ /** Get regret history for analysis */
529
+ getRegretHistory() {
530
+ return [...this.regretHistory];
531
+ }
532
+ /** Serialize for persistence */
533
+ serialize() {
534
+ return {
535
+ config: { ...this.config },
536
+ regretHistory: [...this.regretHistory],
537
+ };
538
+ }
539
+ /** Deserialize with validation */
540
+ static deserialize(data) {
541
+ const engine = new BehavioralEngine(data.config);
542
+ if (Array.isArray(data.regretHistory)) {
543
+ for (const entry of data.regretHistory) {
544
+ // Validate each entry before adding
545
+ if (typeof entry.amount === "number" && Number.isFinite(entry.amount) &&
546
+ typeof entry.regretScore === "number" && entry.regretScore >= 0 && entry.regretScore <= 10) {
547
+ engine.regretHistory.push({
548
+ amount: entry.amount,
549
+ category: String(entry.category || "unknown"),
550
+ regretScore: entry.regretScore,
551
+ timestamp: String(entry.timestamp || ""),
552
+ });
553
+ }
554
+ }
555
+ }
556
+ return engine;
557
+ }
558
+ }
559
+ exports.BehavioralEngine = BehavioralEngine;
560
+ //# sourceMappingURL=behavioral.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavioral.js","sourceRoot":"","sources":["../src/behavioral.ts"],"names":[],"mappings":"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"}