UNPKG

sebit-mcp-public

Version:

> 한국어 설명은 아래 링크에서 확인할 수 있습니다. > 👉 [README.ko.md](./README.ko.md)

78 lines (77 loc) 3.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runOCIM = runOCIM; // src/models/ocim.ts (patched to follow the doc) const shared_1 = require("./shared"); const R = (x, step) => (0, shared_1.roundTo)((0, shared_1._nz)(x), step); function runOCIM(input) { const step = (0, shared_1.toNumberLoose)(input.options?.roundStep, 1e-6); const clampOn = (input.options?.clampToCap ?? true); // --- Step1: 계정과목 비율 --- const shareDirect = (0, shared_1.toFrac)(input.accountSharePct ?? input.ociShare ?? 0); const acct = (0, shared_1._nz)(input.accountOCIAmount ?? 0); const total = (0, shared_1._nz)(input.totalOCIAllItems ?? 0); const shareFromAmounts = total > 0 ? Math.max(0, Math.min(1, acct / total)) : 0; const accountShare = shareDirect > 0 ? Math.max(0, Math.min(1, shareDirect)) : shareFromAmounts || 1; // 기본 1 // --- 잔액/흐름 --- const opening = (0, shared_1._nz)(input.openingOCIBalance ?? 0) * accountShare; const current = (0, shared_1._nz)(input.currentPeriodOCI ?? 0) * accountShare; const reclass = (0, shared_1._nz)(input.reclassificationAdjustments ?? 0) * accountShare; // 베이스(재분류 반영) const baseOCI = opening + current - reclass; // --- Step2: 복리(민감도) --- const years = Math.max(1, (0, shared_1.toNumberLoose)(input.horizonYears ?? 1)); const r = (0, shared_1.toFrac)(input.marketChangeR ?? 0); const beta = (0, shared_1.toFrac)(input.beta ?? 0); const sensitivityFactor = (0, shared_1.calcSensitivity)(r, beta, years, "increment"); const compoundedOCI = baseOCI * sensitivityFactor; // --- Step3: 분기 중간 측정 조정(선택 슬롯) --- const qAdj = (0, shared_1.toFrac)(input.quarterAdjRate ?? 0); // 문서의 전·현 분기 수익/금리식을 외부에서 산정해 입력 const afterQuarterAdj = compoundedOCI * (1 + qAdj); // 추가 보정 const extra = (0, shared_1.toFrac)(input.extraAdjPct ?? 0); let afterExtraAdj = afterQuarterAdj * (1 + extra); // 캡 const minCap = input.minCap === undefined ? undefined : (0, shared_1._nz)(input.minCap); const maxCap = input.maxCap === undefined ? undefined : (0, shared_1._nz)(input.maxCap); const beforeCap = afterExtraAdj; if (clampOn) { if (minCap !== undefined) afterExtraAdj = Math.max(minCap, afterExtraAdj); if (maxCap !== undefined) afterExtraAdj = Math.min(maxCap, afterExtraAdj); } const closing = afterExtraAdj; const capped = beforeCap !== closing; // --- Step4: 복리 증가분 1년치 비율 --- const annualIncreasePct = opening !== 0 ? (closing - opening) / Math.abs(opening) : 0; // --- Step5: 트리거(≥30%) --- const tAnnual30Up = annualIncreasePct >= 0.30; const out = { accountShare: R(accountShare, step), baseOCI: R(baseOCI, step), sensitivityFactor: R(sensitivityFactor, step), compoundedOCI: R(compoundedOCI, step), afterQuarterAdj: R(afterQuarterAdj, step), afterExtraAdj: R(beforeCap, step), // 캡 전 값도 보고 싶으면 유지 closingOCIBalance: R(closing, step), annualIncreasePct: R(annualIncreasePct, step), triggers: { tAnnual30Up, tReclassMove: reclass !== 0, tCapped: capped } }; if (input.options?.debug) { out.debug = { inputs: { opening, current, reclass, r, beta, years, qAdj: qAdj, extra, minCap, maxCap }, notes: { step1: "계정과목 비율(직접 또는 account/total)로 베이스 금액 축소", step3: "분기 중간 조정은 외부 계산된 quarterAdjRate를 곱해 반영", step4: "연간 증가분% = (최종잔액-기초)/|기초|", step5: "30% 이상이면 트리거" } }; } return out; }