phase-6: typescript introduction

This commit is contained in:
Kazuma
2026-06-04 22:16:48 -04:00
committed by Kazuma
parent de8427d578
commit 2b785aa861
69 changed files with 2323 additions and 1036 deletions
+74
View File
@@ -0,0 +1,74 @@
import { SECTOR, ASSET_TYPE, REGIME } from '../config/constants.js';
import type { MarketContext, AssetType } from '../types.js';
interface InflatedOverrides {
gates: Record<string, number>;
thresholds: Record<string, number>;
}
export class MarketRegime {
private marketPE: number;
private techPE: number;
private reitYield: number;
private igSpread: number;
private rateRegime: string;
private volatilityRegime: string;
constructor(marketContext: Partial<MarketContext>) {
const b = marketContext?.benchmarks ?? ({} as MarketContext['benchmarks']);
this.marketPE = b.marketPE ?? 22;
this.techPE = b.techPE ?? 30;
this.reitYield = b.reitYield ?? 3.5;
this.igSpread = b.igSpread ?? 1.0;
this.rateRegime = marketContext?.rateRegime ?? REGIME.NORMAL;
this.volatilityRegime = marketContext?.volatilityRegime ?? REGIME.NORMAL;
}
getInflatedOverrides(type: AssetType, sector?: string): InflatedOverrides {
if (type === ASSET_TYPE.STOCK) return this._stock(sector);
if (type === ASSET_TYPE.ETF) return this._etf();
if (type === ASSET_TYPE.BOND) return this._bond();
return { gates: {}, thresholds: {} };
}
private _stock(sector?: string): InflatedOverrides {
if (sector === SECTOR.REIT) {
return {
gates: {},
thresholds: {
minYield: +(this.reitYield * (this.rateRegime === REGIME.HIGH ? 0.95 : 0.85)).toFixed(2),
maxPFFO: 20,
},
};
}
if (sector === SECTOR.TECHNOLOGY) {
return {
gates: {
maxPERatio: Math.round(this.techPE * 1.3),
maxPegGate: +(this.techPE / 15).toFixed(1),
},
thresholds: {},
};
}
const peMultiplier = this.rateRegime === REGIME.HIGH ? 1.2 : 1.5;
return {
gates: {
maxPERatio: Math.round(this.marketPE * peMultiplier),
maxPegGate: +(this.marketPE / 12).toFixed(1),
},
thresholds: {},
};
}
private _etf(): InflatedOverrides {
return { gates: { maxExpenseRatio: 0.75 }, thresholds: { minYield: 0.5 } };
}
private _bond(): InflatedOverrides {
const spreadMultiplier = this.rateRegime === REGIME.HIGH ? 0.9 : 0.8;
return {
gates: {},
thresholds: { minSpread: +(this.igSpread * spreadMultiplier).toFixed(2) },
};
}
}