feat(stocks): 판정 기준 정밀화 — 레버리지 가드·실측 YoY·PER 기둥 (v2.2.212)
퀀트 실증 근거(F-Score 류 품질+가격 결합) 기반 기준 강화: - ROE: 부채비율 ≤150% 레버리지 가드 — 빚으로 부풀린 ROE 배제 (듀폰분해). - 성장성: Naver 연간 다년치에서 매출/영업이익 YoY 실측 계산을 1순위로 (매출 ≥10% 또는 영업이익 ≥15%). 마진 수준·상장연차는 YoY 미확보 시 폴백. - 안정성: 부채비율 ≤100% 가드 추가 — 유보율은 자본금 왜곡되는 약한 지표. - PER ≤12배 키워드 신설(보유 데이터인데 미사용이던 가격 매력 축), 저평가우량주 우선순위에 PBR 다음으로 편입. - naverFundamentals: revenueGrowthYoY/opProfitGrowthYoY 추출 추가. - 테스트 12건 (기존 사용자 패턴 8건 유지 + 신규 규칙 4건). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,9 @@ export interface Fundamentals {
|
||||
operatingMargin?: number; // % (영업이익률)
|
||||
retentionRatio?: number; // % (유보율)
|
||||
debtRatio?: number; // % (부채비율)
|
||||
/** 최근 확정 2개 연도 기준 YoY 성장률 (%). '성장성' 기준의 실측치 — 마진 수준이 아닌 진짜 성장. */
|
||||
revenueGrowthYoY?: number; // 매출액 YoY %
|
||||
opProfitGrowthYoY?: number; // 영업이익 YoY %
|
||||
/** integration API 의 현재가 + 평가지표. */
|
||||
per?: number;
|
||||
pbr?: number;
|
||||
@@ -125,18 +128,32 @@ export async function fetchFundamentals(symbol: string, timeoutMs = 10000): Prom
|
||||
|
||||
// finance/annual — rowList 에서 최근 확정 연도 컬럼 값.
|
||||
if (fin?.financeInfo?.rowList && fin.financeInfo.rowList.length > 0) {
|
||||
const latestKey = pickLatestConfirmedKey(fin.financeInfo.trTitleList);
|
||||
const confirmedKeys = (fin.financeInfo.trTitleList || [])
|
||||
.filter(t => t.isConsensus === 'N').map(t => t.key).sort().reverse();
|
||||
const latestKey = confirmedKeys[0] ?? null;
|
||||
const prevKey = confirmedKeys[1] ?? null;
|
||||
if (latestKey) {
|
||||
const rowByTitle = new Map(fin.financeInfo.rowList.map(r => [r.title, r]));
|
||||
const valueOf = (title: string): number | undefined => {
|
||||
const valueOf = (title: string, key: string = latestKey): number | undefined => {
|
||||
const row = rowByTitle.get(title);
|
||||
if (!row) return undefined;
|
||||
return parseNumber(row.columns[latestKey]?.value);
|
||||
return parseNumber(row.columns[key]?.value);
|
||||
};
|
||||
out.roe = valueOf('ROE');
|
||||
out.operatingMargin = valueOf('영업이익률');
|
||||
out.retentionRatio = valueOf('유보율');
|
||||
out.debtRatio = valueOf('부채비율');
|
||||
// YoY 성장률 — 최근 확정 2개 연도. '성장성'을 마진 수준이 아닌 실측 성장으로 판정.
|
||||
if (prevKey) {
|
||||
const yoy = (title: string): number | undefined => {
|
||||
const a = valueOf(title, latestKey);
|
||||
const b = valueOf(title, prevKey);
|
||||
if (a === undefined || b === undefined || b === 0) return undefined;
|
||||
return ((a - b) / Math.abs(b)) * 100;
|
||||
};
|
||||
out.revenueGrowthYoY = yoy('매출액');
|
||||
out.opProfitGrowthYoY = yoy('영업이익');
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
||||
Reference in New Issue
Block a user