import { test } from 'node:test'; import assert from 'node:assert/strict'; import { MarketRegime } from '../src/market/MarketRegime.js'; import { SECTOR, ASSET_TYPE } from '../src/config/constants.js'; const regime = (benchmarks) => new MarketRegime({ benchmarks }); test('stock inflated P/E = marketPE × 1.5', () => { const { gates } = regime({ marketPE: 24 }).getInflatedOverrides(ASSET_TYPE.STOCK, SECTOR.GENERAL); assert.equal(gates.maxPERatio, Math.round(24 * 1.5)); // 36 }); test('tech inflated P/E = techPE × 1.3', () => { const { gates } = regime({ techPE: 40 }).getInflatedOverrides( ASSET_TYPE.STOCK, SECTOR.TECHNOLOGY, ); assert.equal(gates.maxPERatio, Math.round(40 * 1.3)); // 52 }); test('REIT inflated minYield = reitYield × 0.85', () => { const { thresholds } = regime({ reitYield: 4.0 }).getInflatedOverrides( ASSET_TYPE.STOCK, SECTOR.REIT, ); assert.equal(thresholds.minYield, +(4.0 * 0.85).toFixed(2)); // 3.40 }); test('bond inflated minSpread = igSpread × 0.80', () => { const { thresholds } = regime({ igSpread: 1.5 }).getInflatedOverrides( ASSET_TYPE.BOND, SECTOR.GENERAL, ); assert.equal(thresholds.minSpread, +(1.5 * 0.8).toFixed(2)); // 1.20 }); test('ETF inflated loosens expense gate to 0.75', () => { const { gates } = regime({}).getInflatedOverrides(ASSET_TYPE.ETF); assert.equal(gates.maxExpenseRatio, 0.75); }); test('falls back to defaults when benchmarks missing', () => { const { gates } = new MarketRegime({}).getInflatedOverrides(ASSET_TYPE.STOCK, SECTOR.GENERAL); assert.equal(gates.maxPERatio, Math.round(22 * 1.5)); // default marketPE = 22 });