41 lines
1.7 KiB
TypeScript
41 lines
1.7 KiB
TypeScript
// Unit coverage for sizing/risk product contracts used by tRPC routers.
|
||||
|
|
import { test } from 'node:test';
|
|||
|
|
import { strict as assert } from 'node:assert';
|
|||
|
|
import { sizePosition } from '../../sizing/SizingEngine.ts';
|
|||
|
|
import { assessRisk, ADR_0007_FOOTER } from '../RiskEngine.ts';
|
|||
|
|
|
|||
|
|
test('sizing.compute contract: math implies shares, ADR-0007 footer-ready', () => {
|
|||
|
|
const result = sizePosition(
|
|||
|
|
{ symbol: 'NVDA', tier: 'B', riskFraction: 0.01, stopPerShare: 5 },
|
|||
|
|
{ equity: 100_000, complexity: 'beginner' },
|
|||
|
|
{
|
|||
|
|
holdings: [],
|
|||
|
|
regime: 'trending-up',
|
|||
|
|
clusterCaps: { uncategorized: 25_000 },
|
|||
|
|
aStarUnlocked: false,
|
|||
|
|
},
|
|||
|
|
);
|
|||
|
|
// 100000 * 0.01 / 5 = 200 shares * B(×1) = 200
|
|||
|
|
assert.equal(result.shares, 200);
|
|||
|
|
assert.equal(result.blocked, false);
|
|||
|
|
assert.ok(result.explanations.some((e) => /math implies/i.test(e)));
|
|||
|
|
assert.ok(result.explanations.some((e) => /not investment advice/i.test(e)));
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('risk.posture contract: peak breach yields halt + consideration', () => {
|
|||
|
|
const posture = assessRisk({
|
|||
|
|
portfolio: [
|
|||
|
|
{ symbol: 'NVDA', shares: 100, avgCost: 100, cluster: 'uncategorized', stopPrice: 90, rewardTarget: 130 },
|
|||
|
|
],
|
|||
|
|
account: { equity: 80_000, drawdownTolerancePct: 15, complexity: 'beginner' },
|
|||
|
|
peakEquity: 100_000,
|
|||
|
|
regime: 'trending-down',
|
|||
|
|
sizingContext: { clusterCaps: { uncategorized: 20_000 } },
|
|||
|
|
});
|
|||
|
|
assert.equal(posture.halted, true);
|
|||
|
|
assert.ok(posture.recommendedActions.length > 0);
|
|||
|
|
assert.ok(posture.recommendedActions.every((a) => a.explanation.includes(ADR_0007_FOOTER)
|
|||
|
|
|| a.explanation.toLowerCase().includes('trade-off')));
|
|||
|
|
assert.ok(!JSON.stringify(posture.recommendedActions).toLowerCase().includes('you should sell'));
|
|||
|
|
});
|