Skip to content

SayBGM/kis-streamdeck-plugin

Repository files navigation

KIS StreamDeck 실시간 주식 시세 플러그인

Preview

한국투자증권(KIS) Open API를 사용해 Stream Deck 키에 국내/미국 주식 시세를 표시하는 플러그인입니다. 버튼은 먼저 REST 스냅샷으로 채워지고, 이후 공통 업데이트 모드에 따라 WebSocket 실시간, WebSocket + 쓰로틀, 또는 REST 폴링으로 갱신됩니다.

주요 기능

  • 국내주식 버튼
    • TR_ID: H0UNCNT0
    • 입력값: 종목코드, 종목명
  • 미국주식 버튼
    • TR_ID: HDFSCNT0
    • 입력값: 티커 심볼, 거래소(NAS/NYS/AMS), 종목명
  • 최초 표시 속도 개선
    • 버튼이 나타나면 REST 현재가를 먼저 조회해 바로 표시
    • 이후 공통 업데이트 모드에 따라 실시간 또는 백업 경로로 갱신
  • 단일 WebSocket 연결 공유
    • 모든 버튼 구독을 하나의 연결에서 관리
    • 마지막 구독이 해제되면 연결도 자동 종료
  • 연결 안정성 강화
    • approval_key 30분 자동 갱신
    • 지수 백오프 재연결: 5초 → 10초 → 20초 … 최대 60초, ±10% 지터
  • 렌더링 성능 최적화
    • setImage() 50ms 디바운스
    • SVG Data URI LRU 캐시 500개
  • 카드 상태 표시 강화
    • LIVE / BACKUP / BROKEN 연결 상태를 카드 하단 바와 상태 문구로 표시
    • stale(지연), 수동 새로고침, 연결 회복, 오류 상태를 별도 카드/문구로 구분
  • 전역 인증 재사용
    • access_token을 Global Settings에 저장해 재시작 후 재사용
    • App Key 또는 App Secret이 바뀌면 이전 토큰은 자동 제거

Property Inspector UX

1. 공통 설정: 수동 저장

KIS API 설정 그룹은 모든 버튼이 공유하는 전역 설정입니다.

  • 입력 항목
    • App Key
    • App Secret
    • 업데이트
  • 저장 방식
    • 이 그룹은 자동 저장되지 않습니다.
    • 값을 바꾸면 저장 대기 상태가 되며, 공통 설정 저장 버튼을 눌러야 반영됩니다.
    • 공통 설정 저장 버튼은 변경 사항이 있고 현재 보이는 입력값이 유효할 때만 활성화됩니다.
  • 업데이트 모드
    • 실시간 (WebSocket): REST 스냅샷 후 WebSocket 체결 데이터로 갱신
    • WebSocket + 쓰로틀: WebSocket은 유지하되 카드 렌더링 빈도를 쓰로틀(ms) 값으로 제한
    • 주기적 (폴링): WebSocket을 사용하지 않고 REST만 간격(초)마다 재조회
  • 입력 검증
    • 주기적 (폴링) 선택 시 간격(초) 입력이 나타납니다.
    • 간격(초)1~3600만 허용하며, 비워두면 저장 시 기본값 30이 사용됩니다.
    • WebSocket + 쓰로틀 선택 시 쓰로틀(ms) 입력이 나타납니다.
    • 쓰로틀(ms)200 이상만 허용하며, 비워두면 저장 시 기본값 1000이 사용됩니다.
    • 쓰로틀(ms)200 미만 값을 넣고 포커스를 벗어나면 자동으로 200으로 보정됩니다.
  • 반영 범위
    • 자격증명은 저장 즉시 공용 인증 상태와 WebSocket 인증 갱신에 사용됩니다.
    • 업데이트, 간격(초), 쓰로틀(ms)는 전역 기준값으로 저장되며, 버튼이 다시 초기화되거나 설정을 다시 받을 때 해당 값으로 구성됩니다.

2. 현재 버튼 설정: 자동 저장

국내주식 설정 / 미국주식 설정 그룹은 현재 선택한 버튼에만 저장됩니다.

  • 저장 방식
    • 별도 저장 버튼이 없습니다.
    • 마지막 입력 후 약 350ms 뒤 자동 저장됩니다.
    • 형식이 잘못된 값은 자동 저장되지 않습니다.
    • 빈 값으로 지우는 것도 저장됩니다.
  • 국내 버튼
    • 종목코드: 정확히 6자리 숫자만 허용
    • 종목명: 카드에 표시할 이름, 비워두면 종목코드를 표시
  • 미국 버튼
    • 티커 심볼: 정확히 1~6자 영문(A-Z)만 허용
    • 입력 즉시 대문자로 정규화되어 저장
    • 현재 검증 규칙상 점(.), 하이픈(-), 숫자가 들어간 티커는 저장되지 않습니다.
    • 거래소: NAS / NYS / AMS, 변경 즉시 자동 저장
    • 종목명: 카드에 표시할 이름, 비워두면 티커를 표시
  • 빈 값 저장 후 동작
    • 국내 버튼에서 종목코드를 비우면 버튼은 설정 필요 카드로 돌아갑니다.
    • 미국 버튼에서 티커 심볼을 비우면 버튼은 설정 필요 카드로 돌아갑니다.

카드 UX

1. 초기/보조 카드

카드 표시 조건 화면 문구
설정 필요 버튼 설정에 종목코드 또는 티커가 없을 때 설정 필요 + 종목코드를 설정하세요 또는 티커를 설정하세요
초기화 중 버튼이 나타나거나 설정이 바뀐 직후, 첫 데이터 준비 중 초기화 중 + REST/실시간 연결 준비
데이터 대기 WebSocket 구독은 됐지만 아직 체결 데이터가 없을 때 데이터 대기 + 실시간 연결됨
장 마감 대기 위 상태에서 시장 세션이 CLOSED일 때 장 마감 + 실시간 연결됨
회복 카드 BACKUP 또는 BROKEN에서 LIVE로 회복될 때 2초 동안 실시간 복구 + 연결 회복

2. 시세 카드

실제 시세 카드에는 아래 정보가 표시됩니다.

  • 종목명
  • 종목코드 또는 티커
  • 현재가
  • 전일 대비
  • 등락률
  • 장 상태 pill

장 상태 pill 라벨은 다음과 같습니다.

  • 프리
  • 정규
  • 애프터
  • 마감

3. 연결 상태와 하단 표시

시세 카드 하단에는 상태 문구와 4px 연결 바가 표시됩니다.

연결 상태 하단 문구 하단 바 색상
LIVE 실시간 초록
BACKUP 백업 노랑
BROKEN 연결 끊김 빨강

추가 표시 규칙:

  • 수동 새로고침 중에는 하단 문구가 새로고침 중으로 바뀝니다.
  • stale 상태가 되면 종목명이 노란색으로 바뀝니다.
  • BACKUP 상태에서 stale이면 하단 문구가 백업 · 지연이 됩니다.
  • 연결 상태 문구가 없는 상황에서 stale이면 지연이 표시됩니다.
  • 주기적 (폴링) 모드는 설계상 BACKUP 상태로 표시됩니다.
  • WebSocket + 쓰로틀 모드는 실시간 연결 상태를 유지하되, 화면 갱신만 쓰로틀됩니다.

4. stale(지연) 기준

  • 기본 기준: 마지막 데이터 수신 후 20초 경과
  • 주기적 (폴링) 모드: max(폴링 간격 × 2, 20초)

즉, 폴링 간격이 길수록 stale 판정도 더 늦게 내려갑니다.

5. 오류 카드

오류가 발생하면 시세 카드 대신 오류 카드가 표시됩니다. 오류 카드는 연결 바를 표시하지 않습니다.

에러 타입 카드 레이블 의미
NO_CREDENTIAL 설정 필요 전역 App Key / App Secret 미설정
AUTH_FAIL 인증 실패 인증 실패 또는 토큰/approval_key 발급 실패
NETWORK_ERROR 연결 오류 네트워크 실패 또는 API 연결 오류
INVALID_STOCK 종목 오류 종목코드/티커가 잘못됐거나 현재 시세 응답이 비어 있음

모든 오류 카드는 하단에 Property Inspector를 확인하세요 안내 문구를 표시합니다.

데이터 흐름

  1. 사용자가 공통 설정을 저장하거나 버튼별 설정을 입력합니다.
  2. 버튼이 나타나면 전역 자격증명과 버튼별 종목 설정을 검사합니다.
  3. 자격증명이 없으면 NO_CREDENTIAL 오류 카드, 종목 설정이 없으면 설정 필요 카드를 표시합니다.
  4. 설정이 준비되면 초기화 중 카드를 표시하고 REST 현재가를 먼저 조회합니다.
  5. 이후 공통 업데이트 모드에 따라 동작합니다.
    • websocket: WebSocket 구독
    • hybrid: WebSocket 구독 + 렌더링 쓰로틀
    • poll: REST 주기 조회만 수행
  6. 키를 누르면 REST 기반 수동 새로고침을 실행합니다.
  7. 버튼이 사라지면 구독과 타이머를 정리합니다.

설정 값

  • 전역 설정
    • appKey
    • appSecret
    • accessToken
    • accessTokenExpiry
    • updateMode
    • pollIntervalSec
    • throttleMs
  • 국내 버튼 설정
    • stockCode (예: 005930)
    • stockName (예: 삼성전자)
  • 미국 버튼 설정
    • ticker (예: AAPL)
    • exchange (NAS / NYS / AMS)
    • stockName (예: Apple)

구조

com.kis.streamdeck.sdPlugin/
├── manifest.json
├── src/
│   ├── plugin.ts                     # 진입점, 전역 설정 반영, PI 메시지 처리
│   ├── actions/
│   │   ├── domestic-stock.ts         # 국내 버튼 라이프사이클/구독/폴링/수동 새로고침
│   │   ├── overseas-stock.ts         # 미국 버튼 라이프사이클/구독/폴링/수동 새로고침
│   │   └── __tests__/
│   ├── kis/
│   │   ├── auth.ts                   # approval_key / access_token 발급 및 캐시
│   │   ├── websocket-manager.ts      # 단일 WS 연결, 구독/해제, heartbeat, 재연결
│   │   ├── rest-price.ts             # 초기/수동/폴링 현재가 조회
│   │   ├── domestic-parser.ts
│   │   ├── overseas-parser.ts
│   │   ├── settings-store.ts         # 전역 설정 저장/대기
│   │   └── __tests__/
│   ├── renderer/
│   │   ├── stock-card.ts             # 144x144 SVG 카드 렌더링
│   │   └── __tests__/
│   ├── types/
│   │   └── index.ts
│   └── utils/
│       ├── timezone.ts
│       └── logger.ts
├── ui/
│   ├── domestic-stock-pi.html
│   ├── overseas-stock-pi.html
│   ├── sdpi.css
│   └── sdpi.js
└── imgs/

개발

npm run build           # Rollup 프로덕션 빌드 → bin/plugin.js
npm run watch           # 변경 감지 빌드
npm test                # Vitest 단위 테스트 실행
npm run test:watch      # 테스트 감지 모드
npm run test:coverage   # 커버리지 리포트 (coverage/)
npm run local:install   # 빌드 + Stream Deck 앱에 로컬 설치
npm run package:plugin  # 빌드 + .streamDeckPlugin 패키징

제약 사항

  • 한국투자증권 실전투자 Open API 기준으로 구현되어 있습니다.
  • WebSocket 연결은 단일 인스턴스로 공유합니다.
  • 미국주식 tr_key는 시간대에 따라 주간/야간 접두사가 자동 변경됩니다.
  • src/plugin.ts는 테스트 커버리지에서 제외됩니다.

About

StreamDeck을 활용하여 한국투자증권 실시간 시세 조회

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors