한국투자증권(KIS) Open API를 사용해 Stream Deck 키에 국내/미국 주식 시세를 표시하는 플러그인입니다. 버튼은 먼저 REST 스냅샷으로 채워지고, 이후 공통 업데이트 모드에 따라 WebSocket 실시간, WebSocket + 쓰로틀, 또는 REST 폴링으로 갱신됩니다.
- 국내주식 버튼
- TR_ID:
H0UNCNT0 - 입력값:
종목코드,종목명
- TR_ID:
- 미국주식 버튼
- TR_ID:
HDFSCNT0 - 입력값:
티커 심볼,거래소(NAS/NYS/AMS),종목명
- TR_ID:
- 최초 표시 속도 개선
- 버튼이 나타나면 REST 현재가를 먼저 조회해 바로 표시
- 이후 공통 업데이트 모드에 따라 실시간 또는 백업 경로로 갱신
- 단일 WebSocket 연결 공유
- 모든 버튼 구독을 하나의 연결에서 관리
- 마지막 구독이 해제되면 연결도 자동 종료
- 연결 안정성 강화
approval_key30분 자동 갱신- 지수 백오프 재연결: 5초 → 10초 → 20초 … 최대 60초, ±10% 지터
- 렌더링 성능 최적화
setImage()50ms 디바운스- SVG Data URI LRU 캐시 500개
- 카드 상태 표시 강화
LIVE/BACKUP/BROKEN연결 상태를 카드 하단 바와 상태 문구로 표시- stale(지연), 수동 새로고침, 연결 회복, 오류 상태를 별도 카드/문구로 구분
- 전역 인증 재사용
access_token을 Global Settings에 저장해 재시작 후 재사용App Key또는App Secret이 바뀌면 이전 토큰은 자동 제거
KIS API 설정 그룹은 모든 버튼이 공유하는 전역 설정입니다.
- 입력 항목
App KeyApp Secret업데이트
- 저장 방식
- 이 그룹은 자동 저장되지 않습니다.
- 값을 바꾸면 저장 대기 상태가 되며,
공통 설정 저장버튼을 눌러야 반영됩니다. 공통 설정 저장버튼은 변경 사항이 있고 현재 보이는 입력값이 유효할 때만 활성화됩니다.
- 업데이트 모드
실시간 (WebSocket): REST 스냅샷 후 WebSocket 체결 데이터로 갱신WebSocket + 쓰로틀: WebSocket은 유지하되 카드 렌더링 빈도를쓰로틀(ms)값으로 제한주기적 (폴링): WebSocket을 사용하지 않고 REST만간격(초)마다 재조회
- 입력 검증
주기적 (폴링)선택 시간격(초)입력이 나타납니다.간격(초)는1~3600만 허용하며, 비워두면 저장 시 기본값30이 사용됩니다.WebSocket + 쓰로틀선택 시쓰로틀(ms)입력이 나타납니다.쓰로틀(ms)는200이상만 허용하며, 비워두면 저장 시 기본값1000이 사용됩니다.쓰로틀(ms)에200미만 값을 넣고 포커스를 벗어나면 자동으로200으로 보정됩니다.
- 반영 범위
- 자격증명은 저장 즉시 공용 인증 상태와 WebSocket 인증 갱신에 사용됩니다.
업데이트,간격(초),쓰로틀(ms)는 전역 기준값으로 저장되며, 버튼이 다시 초기화되거나 설정을 다시 받을 때 해당 값으로 구성됩니다.
국내주식 설정 / 미국주식 설정 그룹은 현재 선택한 버튼에만 저장됩니다.
- 저장 방식
- 별도 저장 버튼이 없습니다.
- 마지막 입력 후 약
350ms뒤 자동 저장됩니다. - 형식이 잘못된 값은 자동 저장되지 않습니다.
- 빈 값으로 지우는 것도 저장됩니다.
- 국내 버튼
종목코드: 정확히6자리 숫자만 허용종목명: 카드에 표시할 이름, 비워두면종목코드를 표시
- 미국 버튼
티커 심볼: 정확히1~6자 영문(A-Z)만 허용- 입력 즉시 대문자로 정규화되어 저장
- 현재 검증 규칙상 점(
.), 하이픈(-), 숫자가 들어간 티커는 저장되지 않습니다. 거래소:NAS/NYS/AMS, 변경 즉시 자동 저장종목명: 카드에 표시할 이름, 비워두면티커를 표시
- 빈 값 저장 후 동작
- 국내 버튼에서
종목코드를 비우면 버튼은설정 필요카드로 돌아갑니다. - 미국 버튼에서
티커 심볼을 비우면 버튼은설정 필요카드로 돌아갑니다.
- 국내 버튼에서
| 카드 | 표시 조건 | 화면 문구 |
|---|---|---|
| 설정 필요 | 버튼 설정에 종목코드 또는 티커가 없을 때 |
설정 필요 + 종목코드를 설정하세요 또는 티커를 설정하세요 |
| 초기화 중 | 버튼이 나타나거나 설정이 바뀐 직후, 첫 데이터 준비 중 | 초기화 중 + REST/실시간 연결 준비 |
| 데이터 대기 | WebSocket 구독은 됐지만 아직 체결 데이터가 없을 때 | 데이터 대기 + 실시간 연결됨 |
| 장 마감 대기 | 위 상태에서 시장 세션이 CLOSED일 때 |
장 마감 + 실시간 연결됨 |
| 회복 카드 | BACKUP 또는 BROKEN에서 LIVE로 회복될 때 |
2초 동안 실시간 복구 + 연결 회복 |
실제 시세 카드에는 아래 정보가 표시됩니다.
- 종목명
- 종목코드 또는 티커
- 현재가
- 전일 대비
- 등락률
- 장 상태 pill
장 상태 pill 라벨은 다음과 같습니다.
프리정규애프터마감
시세 카드 하단에는 상태 문구와 4px 연결 바가 표시됩니다.
| 연결 상태 | 하단 문구 | 하단 바 색상 |
|---|---|---|
LIVE |
실시간 |
초록 |
BACKUP |
백업 |
노랑 |
BROKEN |
연결 끊김 |
빨강 |
추가 표시 규칙:
- 수동 새로고침 중에는 하단 문구가
새로고침 중으로 바뀝니다. - stale 상태가 되면 종목명이 노란색으로 바뀝니다.
BACKUP상태에서 stale이면 하단 문구가백업 · 지연이 됩니다.- 연결 상태 문구가 없는 상황에서 stale이면
지연이 표시됩니다. 주기적 (폴링)모드는 설계상BACKUP상태로 표시됩니다.WebSocket + 쓰로틀모드는 실시간 연결 상태를 유지하되, 화면 갱신만 쓰로틀됩니다.
- 기본 기준: 마지막 데이터 수신 후
20초경과 주기적 (폴링)모드:max(폴링 간격 × 2, 20초)
즉, 폴링 간격이 길수록 stale 판정도 더 늦게 내려갑니다.
오류가 발생하면 시세 카드 대신 오류 카드가 표시됩니다. 오류 카드는 연결 바를 표시하지 않습니다.
| 에러 타입 | 카드 레이블 | 의미 |
|---|---|---|
NO_CREDENTIAL |
설정 필요 |
전역 App Key / App Secret 미설정 |
AUTH_FAIL |
인증 실패 |
인증 실패 또는 토큰/approval_key 발급 실패 |
NETWORK_ERROR |
연결 오류 |
네트워크 실패 또는 API 연결 오류 |
INVALID_STOCK |
종목 오류 |
종목코드/티커가 잘못됐거나 현재 시세 응답이 비어 있음 |
모든 오류 카드는 하단에 Property Inspector를 확인하세요 안내 문구를 표시합니다.
- 사용자가 공통 설정을 저장하거나 버튼별 설정을 입력합니다.
- 버튼이 나타나면 전역 자격증명과 버튼별 종목 설정을 검사합니다.
- 자격증명이 없으면
NO_CREDENTIAL오류 카드, 종목 설정이 없으면설정 필요카드를 표시합니다. - 설정이 준비되면
초기화 중카드를 표시하고 REST 현재가를 먼저 조회합니다. - 이후 공통 업데이트 모드에 따라 동작합니다.
websocket: WebSocket 구독hybrid: WebSocket 구독 + 렌더링 쓰로틀poll: REST 주기 조회만 수행
- 키를 누르면 REST 기반 수동 새로고침을 실행합니다.
- 버튼이 사라지면 구독과 타이머를 정리합니다.
- 전역 설정
appKeyappSecretaccessTokenaccessTokenExpiryupdateModepollIntervalSecthrottleMs
- 국내 버튼 설정
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는 테스트 커버리지에서 제외됩니다.
