Files
auto-trade/lib/kis/config.ts
2026-02-06 17:50:35 +09:00

123 lines
3.5 KiB
TypeScript

/**
* @file lib/kis/config.ts
* @description KIS 거래 환경(real/mock) 설정과 키/도메인 로딩
*/
export type KisTradingEnv = "real" | "mock";
export interface KisCredentialInput {
tradingEnv?: KisTradingEnv;
appKey?: string;
appSecret?: string;
baseUrl?: string;
}
export interface KisConfig {
tradingEnv: KisTradingEnv;
appKey: string;
appSecret: string;
baseUrl: string;
}
const DEFAULT_KIS_REAL_BASE_URL = "https://openapi.koreainvestment.com:9443";
const DEFAULT_KIS_MOCK_BASE_URL = "https://openapivts.koreainvestment.com:29443";
const DEFAULT_KIS_REAL_WS_URL = "ws://ops.koreainvestment.com:21000";
const DEFAULT_KIS_MOCK_WS_URL = "ws://ops.koreainvestment.com:31000";
/**
* 거래 환경 문자열을 정규화합니다.
* @param value 환경값
* @returns real | mock
*/
export function normalizeTradingEnv(value?: string): KisTradingEnv {
return (value ?? "mock").toLowerCase() === "real" ? "real" : "mock";
}
/**
* 현재 거래 환경을 반환합니다.
* @returns real | mock
*/
export function getKisTradingEnv() {
return normalizeTradingEnv(process.env.KIS_TRADING_ENV);
}
/**
* KIS 웹소켓 URL을 반환합니다.
* @param tradingEnvInput 거래 모드(real/mock)
* @returns websocket base url
*/
export function getKisWebSocketUrl(tradingEnvInput?: KisTradingEnv) {
const tradingEnv = normalizeTradingEnv(tradingEnvInput);
if (tradingEnv === "real") {
return process.env.KIS_WS_URL_REAL ?? DEFAULT_KIS_REAL_WS_URL;
}
return process.env.KIS_WS_URL_MOCK ?? DEFAULT_KIS_MOCK_WS_URL;
}
/**
* 설정 준비 여부를 확인합니다.
* @param input 외부(사용자 입력) 키가 있으면 우선 사용
* @returns 사용 가능 여부
*/
export function hasKisConfig(input?: KisCredentialInput) {
if (input?.appKey && input?.appSecret) return true;
const env = getKisTradingEnv();
if (env === "real") {
return Boolean(process.env.KIS_APP_KEY_REAL && process.env.KIS_APP_SECRET_REAL);
}
return Boolean(process.env.KIS_APP_KEY_MOCK && process.env.KIS_APP_SECRET_MOCK);
}
/**
* KIS 호출에 필요한 설정을 반환합니다.
* @param input 사용자 입력 키(선택)
* @returns tradingEnv/appKey/appSecret/baseUrl
*/
export function getKisConfig(input?: KisCredentialInput): KisConfig {
if (input?.appKey && input?.appSecret) {
const tradingEnv = normalizeTradingEnv(input.tradingEnv);
const baseUrl =
input.baseUrl ??
(tradingEnv === "real" ? DEFAULT_KIS_REAL_BASE_URL : DEFAULT_KIS_MOCK_BASE_URL);
return {
tradingEnv,
appKey: input.appKey,
appSecret: input.appSecret,
baseUrl,
};
}
const tradingEnv = getKisTradingEnv();
if (tradingEnv === "real") {
const appKey = process.env.KIS_APP_KEY_REAL;
const appSecret = process.env.KIS_APP_SECRET_REAL;
const baseUrl = process.env.KIS_BASE_URL_REAL ?? DEFAULT_KIS_REAL_BASE_URL;
if (!appKey || !appSecret) {
throw new Error(
"KIS 실전투자 키가 없습니다. KIS_APP_KEY_REAL, KIS_APP_SECRET_REAL 환경변수를 설정하세요.",
);
}
return { tradingEnv, appKey, appSecret, baseUrl };
}
const appKey = process.env.KIS_APP_KEY_MOCK;
const appSecret = process.env.KIS_APP_SECRET_MOCK;
const baseUrl = process.env.KIS_BASE_URL_MOCK ?? DEFAULT_KIS_MOCK_BASE_URL;
if (!appKey || !appSecret) {
throw new Error(
"KIS 모의투자 키가 없습니다. KIS_APP_KEY_MOCK, KIS_APP_SECRET_MOCK 환경변수를 설정하세요.",
);
}
return { tradingEnv, appKey, appSecret, baseUrl };
}