npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@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) — KRX bldAttendant POST 호출 래퍼(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);

모듈별 메서드 요약

  • Stock
    • getOhlcvByDate(strtDd, endDd, ticker, adjusted=true): 기간별 개별 종목 OHLCV
    • getOhlcvByTicker(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"): 티커 조회
  • Index
    • getOhlcvByDate(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"): 상장일/기본정보
  • Etf
    • getOhlcvByDate(strtDd, endDd, ticker): 기간별 ETF 시세
    • getOhlcvByTicker(date): 일자별 ETF 전 종목 시세
    • getPortfolioDepositFile(date, ticker): 구성 종목
    • getTrackingErrorByDate(strtDd, endDd, ticker): 추적오차
    • getPriceChangeByTicker(strtDd, endDd): 기간별 등락률
    • getTradingVolumeAndValue(strtDd, endDd, ticker): 기간별 거래량/대금
  • Bond
    • getTreasuryYield(strtDd, endDd): 국고채 금리 추이
    • getOtpYieldByDate(strtDd, endDd, ticker): 기간별 장외 채권 수익률
    • getOtpYieldByTicker(date): 일자별 장외 채권 수익률
  • Derivative
    • getFutureOhlcv(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 test

node --test + ts-node/register로 파서 단위 테스트를 실행합니다. 샘플 HTML/JSON 픽스처(096770)를 사용합니다.

로드맵

  • 컨센서스/재무 외 추가 지표 및 다른 Wisereport 탭을 순차적으로 지원 예정.
  • 크롤링 안정성을 높이기 위한 재시도·백오프 옵션, 프록시 지원 계획.
  • API 표면을 점진적으로 확장할 예정이므로 getCompanyOverview 외 함수도 계속 추가될 수 있습니다.