@npmc_5/krxjs
v2.0.8
Published
krx data api
Readme
krxjs
국내 주식 종목 개요/컨센서스 정보를 크롤·파싱하는 Node.js 라이브러리입니다.
설치
npm install @npmc_5/krxjs
# 또는
pnpm add @npmc_5/krxjs
# 또는
yarn add @npmc_5/krxjs주요 API
모든 함수는 비동기이며 Promise를 반환합니다. 기본 사용법은 (1) Krxjs 클래스의 정적 메서드, (2) 함수형 export(예: Stock.getOhlcvByTicker) 두 가지 방식을 모두 지원합니다.
사용 예제 (Krxjs 클래스)
import Krxjs from "@npmc_5/krxjs";
const overview = await Krxjs.getCompanyOverview("005930");
const profile = await Krxjs.getCompanyProfile("005930");
const rivals = await Krxjs.getRivalCompany("096770"); // RivalAnalysis 반환 (경쟁사 지표 파싱 완료)CommonJS 예시
const Krxjs = require("@npmc_5/krxjs").default;
Krxjs.getCompanyOverview("005930").then((data) => {
console.log(data.company);
});
Krxjs.getCompanyProfile("005930").then((data) => {
console.log(data.basicInfo);
});KRX 시세/거래 데이터 API (v1 호환)
Stock: 주식 시세/펀더멘털/거래량·대금/순매수/티커 조회Index: 지수 시세/펀더멘털/등락률/상장일Etf: ETF/ETN/ELW 시세, 구성, 추적오차, 거래량/대금Bond: 국고채 금리, 장외채권 수익률Derivative: 선물 시세, 선물 상품 리스트- 공통 클라이언트:
fetchKrx(bld, params)— KRXbldAttendantPOST 호출 래퍼(POST, URLSearchParams, JSON 파싱)
사용 예시 (함수형 export)
import { Stock, Index, Etf, Bond, Derivative } from "@npmc_5/krxjs";
const date = "20240102";
const stocks = await Stock.getOhlcvByTicker(date, "STK");
const idx = await Index.getOhlcvByTicker(date, "01");
const etf = await Etf.getOhlcvByTicker(date);
const bond = await Bond.getOtpYieldByTicker(date);
const drv = await Derivative.getFutureTickerList("ALL");추가 예시: 기간별 개별 종목 시세
// 시작일, 종료일, 표준코드/단축코드, 수정주가 여부
const ohlcv = await Stock.getOhlcvByDate("20240102", "20240105", "KR7005930003", true);모듈별 메서드 요약
StockgetOhlcvByDate(strtDd, endDd, ticker, adjusted=true): 기간별 개별 종목 OHLCVgetOhlcvByTicker(date, marketId="STK", adjusted=true): 단일 일자 전 종목 시세getFundamentalByDate(strtDd, endDd, ticker): 기간별 펀더멘털getFundamentalByTicker(date, marketId="STK"): 일자별 전 종목 펀더멘털getMarketCapByDate(strtDd, endDd, ticker): 기간별 시가총액 추이getTradingVolumeByDate(strtDd, endDd, marketId="STK"): 기간별 투자자별 거래량getTradingValueByDate(strtDd, endDd, marketId="STK"): 기간별 투자자별 거래대금getNetPurchasesOfEquities(strtDd, endDd, marketId="STK", investorCode="9000"): 순매수 상위getTickerName(marketId="STK"),getTickerList(marketId="STK"): 티커 조회
IndexgetOhlcvByDate(strtDd, endDd, ticker): 기간별 지수 시세getOhlcvByTicker(date, marketCode="01"): 일자별 전체 지수 시세getFundamentalByDate(strtDd, endDd, ticker): 기간별 지수 펀더멘털getFundamentalByTicker(date, marketCode="01"): 일자별 지수 펀더멘털getPortfolioDepositFile(date, ticker): 지수 구성(동일 bld 사용)getPriceChangeByTicker(strtDd, endDd, marketCode="01"): 기간별 등락률getListingDate(date, marketCode="01"): 상장일/기본정보
EtfgetOhlcvByDate(strtDd, endDd, ticker): 기간별 ETF 시세getOhlcvByTicker(date): 일자별 ETF 전 종목 시세getPortfolioDepositFile(date, ticker): 구성 종목getTrackingErrorByDate(strtDd, endDd, ticker): 추적오차getPriceChangeByTicker(strtDd, endDd): 기간별 등락률getTradingVolumeAndValue(strtDd, endDd, ticker): 기간별 거래량/대금
BondgetTreasuryYield(strtDd, endDd): 국고채 금리 추이getOtpYieldByDate(strtDd, endDd, ticker): 기간별 장외 채권 수익률getOtpYieldByTicker(date): 일자별 장외 채권 수익률
DerivativegetFutureOhlcv(date, ticker): 선물 상품 기간별 시세getFutureTickerList(marketCode="ALL"): 선물 상품 리스트
반환 타입 (KRX 모듈)
모든 메서드는 Promise<KrxResponse<T>>를 반환합니다. KRX 응답은 output / OutBlock_1 / block1 / result 등 다양한 키로 내려오므로 KrxResponse<T>가 이를 모두 허용합니다.
export type StringNumber = string;
export interface KrxResponse<T> {
output?: T[];
OutBlock_1?: T[];
block1?: T[];
result?: T[];
CURRENT_DATETIME?: string;
[key: string]: unknown;
}Stock 반환 타입
// 기간별 개별 종목 OHLCV (getOhlcvByDate / getMarketCapByDate)
interface MarketOhlcvByDateRow {
TRD_DD: StringNumber; // 일자
TDD_CLSPRC: StringNumber; // 종가
FLUC_TP_CD: StringNumber; // 등락 코드
CMPPREVDD_PRC: StringNumber; // 전일 대비
FLUC_RT: StringNumber; // 등락률
TDD_OPNPRC: StringNumber; // 시가
TDD_HGPRC: StringNumber; // 고가
TDD_LWPRC: StringNumber; // 저가
ACC_TRDVOL: StringNumber; // 거래량
ACC_TRDVAL: StringNumber; // 거래대금
MKTCAP: StringNumber; // 시가총액
LIST_SHRS: StringNumber; // 상장주식수
}
// 단일 일자 전 종목 시세 (getOhlcvByTicker)
interface MarketOhlcvByTickerRow {
ISU_SRT_CD: StringNumber; // 종목코드(단축)
ISU_CD: StringNumber; // 표준코드
ISU_ABBRV: StringNumber; // 종목명
MKT_NM: StringNumber; // 시장명
SECT_TP_NM: StringNumber; // 업종
TDD_CLSPRC: StringNumber; // 종가
FLUC_TP_CD: StringNumber; // 등락 코드
CMPPREVDD_PRC: StringNumber; // 전일 대비
FLUC_RT: StringNumber; // 등락률
TDD_OPNPRC: StringNumber; // 시가
TDD_HGPRC: StringNumber; // 고가
TDD_LWPRC: StringNumber; // 저가
ACC_TRDVOL: StringNumber; // 거래량
ACC_TRDVAL: StringNumber; // 거래대금
MKTCAP: StringNumber; // 시총
LIST_SHRS: StringNumber; // 상장주식수
MKT_ID: StringNumber; // 시장코드
}
// 펀더멘털 (getFundamentalByDate / getFundamentalByTicker)
interface MarketFundamentalRow {
ISU_SRT_CD: StringNumber;
ISU_CD: StringNumber;
MKT_ID: StringNumber;
ISU_ABBRV: StringNumber;
ISU_ABBRV_STR?: StringNumber;
TDD_CLSPRC: StringNumber;
FLUC_TP_CD: StringNumber;
CMPPREVDD_PRC: StringNumber;
FLUC_RT: StringNumber;
EPS: StringNumber;
PER: StringNumber;
FWD_EPS: StringNumber;
FWD_PER: StringNumber;
BPS: StringNumber;
PBR: StringNumber;
DPS: StringNumber;
DVD_YLD: StringNumber;
}
// 투자자별 거래량/대금 (getTradingVolumeByDate / getTradingValueByDate)
interface InvestorTradingRow {
INVST_TP_NM: StringNumber; // 투자자 구분
ASK_TRDVOL: StringNumber; // 매도량
BID_TRDVOL: StringNumber; // 매수량
NETBID_TRDVOL: StringNumber; // 순매수량
ASK_TRDVAL: StringNumber; // 매도대금
BID_TRDVAL: StringNumber; // 매수대금
NETBID_TRDVAL: StringNumber; // 순매수대금
CONV_OBJ_TP_CD: StringNumber;
}
// 순매수 상위 (getNetPurchasesOfEquities)
interface NetPurchaseRow {
ISU_SRT_CD: StringNumber;
ISU_NM: StringNumber;
ASK_TRDVOL: StringNumber;
BID_TRDVOL: StringNumber;
NETBID_TRDVOL: StringNumber;
ASK_TRDVAL: StringNumber;
BID_TRDVAL: StringNumber;
NETBID_TRDVAL: StringNumber;
}
// 티커 조회 (getTickerList / getTickerName)
interface TickerSearchRow {
full_code: StringNumber; // 표준코드
short_code: StringNumber; // 단축코드
codeName: StringNumber; // 종목명
marketCode: StringNumber; // 시장코드
marketName: StringNumber; // 시장명(KOR)
marketEngName: StringNumber; // 시장명(ENG)
ord1: StringNumber;
ord2: StringNumber;
}Index 반환 타입
interface IndexOhlcvByTickerRow {
IDX_NM: StringNumber; // 지수명
CLSPRC_IDX: StringNumber; // 종가
FLUC_TP_CD: StringNumber;
CMPPREVDD_IDX: StringNumber;
FLUC_RT: StringNumber;
OPNPRC_IDX: StringNumber;
HGPRC_IDX: StringNumber;
LWPRC_IDX: StringNumber;
ACC_TRDVOL: StringNumber;
ACC_TRDVAL: StringNumber;
MKTCAP: StringNumber;
}
interface IndexFundamentalRow {
IDX_NM: StringNumber;
CLSPRC_IDX: StringNumber;
FLUC_TP_CD: StringNumber;
PRV_DD_CMPR: StringNumber;
FLUC_RT: StringNumber;
WT_PER: StringNumber;
WT_STKPRC_NETASST_RTO: StringNumber;
DIV_YD: StringNumber;
}
interface IndexPriceChangeRow {
IDX_IND_NM: StringNumber;
OPN_DD_INDX: StringNumber;
END_DD_INDX: StringNumber;
FLUC_TP: StringNumber;
PRV_DD_CMPR: StringNumber;
FLUC_RT: StringNumber;
ACC_TRDVOL: StringNumber;
ACC_TRDVAL: StringNumber;
}
interface IndexListingRow {
IDX_NM: StringNumber;
IDX_ENG_NM: StringNumber;
BAS_TM_CONTN: StringNumber;
ANNC_TM_CONTN: StringNumber;
BAS_IDX_CONTN: StringNumber;
CALC_CYCLE_CONTN: StringNumber;
CALC_TM_CONTN: StringNumber;
COMPST_ISU_CNT: StringNumber;
IND_TP_CD: StringNumber;
IDX_IND_CD: StringNumber;
}ETF 반환 타입
interface EtfInfoRow {
ISU_CD: StringNumber;
ISU_SRT_CD: StringNumber;
ISU_NM: StringNumber;
ISU_ABBRV: StringNumber;
ISU_ENG_NM: StringNumber;
LIST_DD: StringNumber;
ETF_OBJ_IDX_NM: StringNumber;
IDX_CALC_INST_NM1: StringNumber;
IDX_CALC_INST_NM2: StringNumber;
ETF_REPLICA_METHD_TP_CD: StringNumber;
IDX_MKT_CLSS_NM: StringNumber;
IDX_ASST_CLSS_NM: StringNumber;
LIST_SHRS: StringNumber;
COM_ABBRV: StringNumber;
CU_QTY: StringNumber;
ETF_TOT_FEE: StringNumber;
TAX_TP_CD: StringNumber;
}
interface EtfTrackingErrorRow {
TRD_DD: StringNumber;
LST_NAV: StringNumber;
NAV_CHG_RT: StringNumber;
OBJ_STKPRC_IDX: StringNumber;
IDX_CHG_RTO: StringNumber;
TRACE_YD_MULT: StringNumber;
TRACE_ERR_RT: StringNumber;
}
interface EtfPriceChangeRow {
ISU_ABBRV: StringNumber;
ISU_CD: StringNumber;
SECUGRP_NM: StringNumber;
TDD_CLSPRC: StringNumber;
FLUC_TP_CD1: StringNumber;
CMPPREVDD_PRC: StringNumber;
FLUC_RT1: StringNumber;
TDD_OPNPRC: StringNumber;
TDD_HGPRC: StringNumber;
TDD_LWPRC: StringNumber;
LST_NAV: StringNumber;
WK52_HGST_PRC: StringNumber;
WK52_LWST_PRC: StringNumber;
ACC_TRDVOL: StringNumber;
ACC_TRDVAL: StringNumber;
MKTCAP: StringNumber;
IDX_ASST_CLSS_NM: StringNumber;
IDX_ASST_CLSS_ID: StringNumber;
ETF_TOT_FEE: StringNumber;
TRACE_IDX_NM: StringNumber;
OBJ_STKPRC_IDX: StringNumber;
CMPPREVDD_IDX: StringNumber;
FLUC_TP_CD2: StringNumber;
FLUC_RT2: StringNumber;
CURRENT_DATETIME?: StringNumber;
}Bond / Derivative 반환 타입
// Bond 계열은 구조가 유동적이라 GenericRow 사용
type GenericRow = Record<string, string>;
interface DerivativeTickerRow {
value: StringNumber; // 상품 코드
name: StringNumber; // 상품명
}testkrx 스크립트
로컬에서 대표 엔드포인트를 호출해 JSON으로 저장합니다.
npx ts-node testkrx.ts생성물: testkrx-result.json (기본 날짜 20240102, KRX_DATE 환경변수로 변경 가능)
경쟁사 분석 (비동기 크롤 + 파싱)
경쟁사 페이지(c1060001)는 AJAX와 iframe으로 핵심 데이터를 내려보냅니다. Krxjs.getRivalCompany는 내부에서 customAsyncCrawl로 응답을 캡처하고 parseRival로 회사별 지표를 매핑한 RivalAnalysis를 반환합니다.
import Krxjs from "@npmc_5/krxjs";
const rival = await Krxjs.getRivalCompany("096770");직접 캡처/파싱 흐름이 필요하다면:
import { customAsyncCrawl } from "@npmc_5/krxjs/customAsyncCraler";
import { parseRival } from "@npmc_5/krxjs/parseEngine/rival-parse";
const asyncResult = await customAsyncCrawl(
"https://comp.wisereport.co.kr/company/c1060001.aspx?cmp_cd=096770&cn=&menuType=block"
);
const rival = parseRival(asyncResult);반환 구조 (RivalAnalysis)
companies: 회사별 헤더 + 지표 맵labels: 파싱된 지표명 목록(순서 유지)groups: 섹션명 → 지표명 배열
회사 객체(RivalCompany) 예시:
{
"code": "096770",
"name": "SK이노베이션",
"finGubun": "IFRS연결",
"yymm": "202412",
"marketCap": 195932.181292,
"metrics": {
"전일종가(원)": "115,900",
"시가총액(억원)": "195,932.2",
"자산총계(억원)": "1,105,301.0",
"PBR": "0.68",
"목표주가(원)": "142,944"
},
"groupedMetrics": {
"주가데이터": { "전일종가(원)": "115,900" },
"재무상태표": { "자산총계(억원)": "1,105,301.0" }
}
}샘플 크롤/파싱 결과: rival-096770.json(생데이터), rival-096770-parsed.json(회사별 지표 구조)
타입 요약
TypeScript 타입이 dist/index.d.ts로 제공됩니다. 주요 타입은 아래와 같습니다.
CompanyOverviewType
Wisereport HTML을 파싱한 결과입니다.
interface CompanyOverviewType {
company: { name: string | null; code: string | null };
priceShareholders: Record<string, string> | null; // 시세/주주현황
credit: { agency: string; bond: string; cp: string }[] | null;
holders: { name: string; shares: string; ratio: string }[] | null;
overview: { paragraphs: string[] } | null;
resultsCommentary: { metrics: Record<string, string | undefined> } | null;
fundamentals: { period: string; metrics: Record<string, string | undefined> }[] | null;
earningsSurprise: {
period: string;
metrics: Record<string, { 컨센서스?: string; 잠정치?: string; Surprise?: string; 전년동기대비?: string } | undefined>;
}[] | null;
consensusHeadline: Record<string, string | undefined> | null;
brokerTargets: Record<string, string | undefined>[] | null;
estimateConsensus: {
period: string;
revenue: string; revenueYoY: string;
operatingIncome: string; operatingIncomeYoY: string;
netIncome: string; netIncomeYoY: string;
eps: string; per: string; pbr: string; roe: string;
evEbitda: string; netDebtRatio: string; accounting: string;
}[] | null;
financialSummary: { period: string; metrics: Record<string, string | undefined> }[] | null;
}CompanyProfileType
기업개요 탭에 대한 파싱 결과입니다.
interface CompanyProfileType {
company: { name: string | null; code: string | null };
basicInfo: Record<string, string | undefined> | null; // 주소/전화/설립일 등
recentHistory: { date: string; event: string }[] | null;
productSales: { name: string; ratio: string }[] | null;
marketShare: { name: string; share: string }[] | null;
rndSpending: {
period: string; total: string; ratioOfSales: string;
capitalized: string; capitalizedRatio: string;
expensed: string; expensedRatio: string; basis: string;
}[] | null;
workforce: {
period: string; category: string;
male: string; female: string; total: string;
payroll: string; avgTenure: string; avgSalary: string;
}[] | null;
domesticExport: {
type: string; product: string;
domestic2022: string; export2022: string;
domestic2023: string; export2023: string;
domestic2024: string; export2024: string;
}[] | null;
creditChanges: { bondDate: string; bond: string; cpDate: string; cp: string }[] | null;
capitalChanges: { date: string; type: string; changeShares: string; capitalAfter: string }[] | null;
affiliates: { name: string; stake: string }[] | null;
subsidiaries: { name: string; business: string; founded: string; assets: string }[] | null;
}동작 흐름
getCompanyOverview('code')가 Wisereport 기업 개요 페이지를 크롤링해 필요한 테이블을 파싱한 뒤 CompanyOverviewType를 반환합니다.
getCompanyProfile('code')는 기업개요(프로필) 탭을 크롤링·파싱해 CompanyProfileType를 반환합니다.
주의사항
- 공개 페이지를 수집하므로 대상 사이트의 응답 지연/차단 가능성을 고려해 백오프나 재시도 로직을 상위 레이어에서 추가하세요.
테스트
npm testnode --test + ts-node/register로 파서 단위 테스트를 실행합니다. 샘플 HTML/JSON 픽스처(096770)를 사용합니다.
로드맵
- 컨센서스/재무 외 추가 지표 및 다른 Wisereport 탭을 순차적으로 지원 예정.
- 크롤링 안정성을 높이기 위한 재시도·백오프 옵션, 프록시 지원 계획.
- API 표면을 점진적으로 확장할 예정이므로
getCompanyOverview외 함수도 계속 추가될 수 있습니다.
