@2oolkit/kiwoom-cli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/config.ts","../src/config/store.ts","../src/config/constants.ts","../src/output/error.ts","../src/utils/helpers.ts","../src/client/api-client.ts","../src/output/formatter.ts","../src/commands/_helpers.ts","../src/utils/format.ts","../src/commands/auth.ts","../src/client/endpoints.ts","../src/utils/orderbook.ts","../src/commands/market.ts","../src/commands/stock.ts","../src/commands/chart.ts","../src/commands/account.ts","../src/commands/order.ts","../src/commands/ranking.ts","../src/commands/sector.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerConfigCommands } from './commands/config';\nimport { registerAuthCommands } from './commands/auth';\nimport { registerStockCommands } from './commands/stock';\nimport { registerMarketCommands } from './commands/market';\nimport { registerChartCommands } from './commands/chart';\nimport { registerAccountCommands } from './commands/account';\nimport { registerOrderCommands } from './commands/order';\nimport { registerRankingCommands } from './commands/ranking';\nimport { registerSectorCommands } from './commands/sector';\n\nconst program = new Command();\n\nprogram\n .name('kiwoom-cli')\n .description('CLI for Kiwoom Securities (키움증권) — quotes, charts, account, and orders')\n .version('0.1.0');\n\nprogram.exitOverride((err) => {\n if (err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {\n process.exit(0);\n }\n process.exit(1);\n});\n\nregisterConfigCommands(program);\nregisterAuthCommands(program);\nregisterStockCommands(program);\nregisterMarketCommands(program);\nregisterChartCommands(program);\nregisterAccountCommands(program);\nregisterOrderCommands(program);\nregisterRankingCommands(program);\nregisterSectorCommands(program);\n\nprogram.parseAsync(process.argv).catch(() => {\n // Command actions handle their own errors via handleError().\n process.exit(1);\n});\n","import { Command } from 'commander';\nimport * as readline from 'readline';\nimport { CliConfig, saveConfig, getEffectiveConfig, maskSecret } from '../config/store';\nimport { ENV_ALIASES, Environment } from '../config/constants';\nimport { KiwoomClient } from '../client/api-client';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\n\n/** Read a line from stdin, optionally masking the echoed characters. */\nexport function prompt(question: string, hidden = false): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n if (hidden) {\n process.stdout.write(question);\n const stdin = process.stdin;\n const wasRaw = stdin.isRaw;\n if (stdin.isTTY) stdin.setRawMode(true);\n let input = '';\n const onData = (char: Buffer) => {\n const c = char.toString();\n const code = char[0];\n if (c === '\\n' || c === '\\r') {\n stdin.removeListener('data', onData);\n if (stdin.isTTY) stdin.setRawMode(wasRaw ?? false);\n process.stdout.write('\\n');\n rl.close();\n resolve(input);\n } else if (code === 3) {\n // Ctrl-C\n process.exit(0);\n } else if (code === 127 || code === 8) {\n // Backspace / DEL\n if (input.length > 0) {\n input = input.slice(0, -1);\n process.stdout.write('\\b \\b');\n }\n } else {\n input += c;\n process.stdout.write('*');\n }\n };\n stdin.on('data', onData);\n } else {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n }\n });\n}\n\nasync function verifyAndCacheToken(env: Environment, appkey: string, secretkey: string): Promise<void> {\n try {\n const client = new KiwoomClient({ env, appkey, secretkey });\n await client.authenticate();\n console.log('Access token issued and cached.');\n } catch (err) {\n console.error(\n `\\nKeys saved, but token issuance failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n console.error('Double-check the app key / secret key and environment.');\n }\n}\n\nexport function registerConfigCommands(program: Command): void {\n const configCmd = program.command('config').description('Manage CLI configuration (keys, environment)');\n\n configCmd\n .command('init')\n .description('Interactive setup wizard')\n .action(async () => {\n try {\n console.log('Kiwoom CLI Setup\\n');\n const envInput = await prompt('Environment (real/mock) [real]: ');\n const env = ENV_ALIASES[envInput.toLowerCase()] ?? 'real';\n const appkey = await prompt('App key: ');\n if (!appkey) {\n console.error('App key is required.');\n process.exit(1);\n }\n const secretkey = await prompt('Secret key: ', true);\n if (!secretkey) {\n console.error('Secret key is required.');\n process.exit(1);\n }\n saveConfig({ env, appkey, secretkey });\n console.log('\\nConfiguration saved to ~/.kiwoom-cli/config.json');\n if (env === 'real') {\n console.log('NOTE: \"real\" places live orders with real money. Use \"mock\" to practice.');\n }\n await verifyAndCacheToken(env, appkey, secretkey);\n } catch (err) {\n handleError(err);\n }\n });\n\n configCmd\n .command('set')\n .description('Set configuration values')\n .option('--env <environment>', 'Environment (real/mock)')\n .option('--appkey <key>', 'Kiwoom app key')\n .option('--secretkey <key>', 'Kiwoom secret key')\n .action(async (options) => {\n try {\n const updates: Partial<CliConfig> = {};\n if (options.env) {\n const resolved = ENV_ALIASES[options.env.toLowerCase()];\n if (!resolved) {\n console.error(`Unknown environment: ${options.env}. Use: real, mock`);\n process.exit(1);\n }\n updates.env = resolved;\n }\n if (options.appkey) updates.appkey = options.appkey;\n if (options.secretkey) updates.secretkey = options.secretkey;\n if (Object.keys(updates).length === 0) {\n console.log('No values to set. Use --env, --appkey, or --secretkey');\n return;\n }\n saveConfig(updates);\n console.log('Configuration updated.');\n const cfg = getEffectiveConfig();\n if ((updates.appkey || updates.secretkey) && cfg.appkey && cfg.secretkey) {\n await verifyAndCacheToken(cfg.env, cfg.appkey, cfg.secretkey);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n configCmd\n .command('get <key>')\n .description('Get a configuration value (env, appkey, secretkey)')\n .action((key: string) => {\n try {\n const config = getEffectiveConfig();\n const value = (config as unknown as Record<string, unknown>)[key];\n if (value === undefined) {\n console.log(`Key \"${key}\" not found. Available: env, appkey, secretkey`);\n } else if (key === 'secretkey' || key === 'appkey') {\n console.log(maskSecret(value as string));\n } else {\n console.log(String(value));\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n configCmd\n .command('list')\n .description('Show all configuration')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((options) => {\n try {\n const config = getEffectiveConfig();\n output(\n {\n env: config.env,\n appkey: maskSecret(config.appkey),\n secretkey: maskSecret(config.secretkey),\n },\n getOutputFormat(options),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n CONFIG_DIR_NAME,\n CONFIG_FILE_NAME,\n TOKEN_FILE_NAME,\n ENV_VARS,\n ENV_ALIASES,\n Environment,\n} from './constants';\n\nexport interface CliConfig {\n env: Environment;\n appkey?: string;\n secretkey?: string;\n}\n\nexport interface CachedToken {\n token: string;\n /** Kiwoom expiry stamp, \"YYYYMMDDHHmmss\" in KST. */\n expiresDt: string;\n /** First 6 chars of the appkey the token was issued for (cache-invalidation guard). */\n appkeyHint: string;\n}\n\n/** token.json holds one cached token per environment. */\ntype TokenCache = Partial<Record<Environment, CachedToken>>;\n\nconst DEFAULT_CONFIG: CliConfig = { env: 'real' };\n\nfunction getConfigDir(): string {\n return path.join(os.homedir(), CONFIG_DIR_NAME);\n}\n\nfunction getConfigPath(): string {\n return path.join(getConfigDir(), CONFIG_FILE_NAME);\n}\n\nfunction getTokenPath(): string {\n return path.join(getConfigDir(), TOKEN_FILE_NAME);\n}\n\nfunction ensureConfigDir(): void {\n const dir = getConfigDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { mode: 0o700, recursive: true });\n } else {\n // Tighten perms even if the dir pre-existed with looser permissions.\n try {\n fs.chmodSync(dir, 0o700);\n } catch {\n /* best effort */\n }\n }\n}\n\n/**\n * Write a secrets file with 0600 perms. `writeFileSync`'s mode only applies when\n * the file is newly created, so chmod afterward to tighten a pre-existing file\n * that may have looser permissions.\n */\nfunction writeSecure(filePath: string, data: string): void {\n fs.writeFileSync(filePath, data, { mode: 0o600 });\n try {\n fs.chmodSync(filePath, 0o600);\n } catch {\n /* best effort */\n }\n}\n\n// ─── Config ───────────────────────────────────────────────────────────────\n\nexport function loadConfig(): CliConfig {\n try {\n const raw = fs.readFileSync(getConfigPath(), 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(partial: Partial<CliConfig>): void {\n ensureConfigDir();\n const current = loadConfig();\n const merged = { ...current, ...partial };\n writeSecure(getConfigPath(), JSON.stringify(merged, null, 2));\n}\n\n/**\n * Resolve the effective config: config file first, environment variables as a\n * fallback for any unset secret.\n */\nexport function getEffectiveConfig(): CliConfig {\n const disk = loadConfig();\n const envVal = process.env[ENV_VARS.env];\n const env: Environment =\n envVal && ENV_ALIASES[envVal.toLowerCase()]\n ? ENV_ALIASES[envVal.toLowerCase()]\n : disk.env;\n return {\n env,\n appkey: disk.appkey ?? process.env[ENV_VARS.appkey],\n secretkey: disk.secretkey ?? process.env[ENV_VARS.secretkey],\n };\n}\n\nexport function maskSecret(value: string | undefined): string {\n if (!value) return '(not set)';\n if (value.length <= 10) return '****';\n return value.slice(0, 6) + '...' + value.slice(-4);\n}\n\n// ─── Token cache ────────────────────────────────────────────────────────────\n\nfunction loadTokenCache(): TokenCache {\n try {\n return JSON.parse(fs.readFileSync(getTokenPath(), 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function getCachedToken(env: Environment): CachedToken | undefined {\n return loadTokenCache()[env];\n}\n\nexport function saveCachedToken(env: Environment, token: CachedToken): void {\n ensureConfigDir();\n const cache = loadTokenCache();\n cache[env] = token;\n writeSecure(getTokenPath(), JSON.stringify(cache, null, 2));\n}\n\nexport function clearCachedToken(env?: Environment): void {\n if (!env) {\n try {\n fs.rmSync(getTokenPath());\n } catch {\n /* nothing to clear */\n }\n return;\n }\n const cache = loadTokenCache();\n delete cache[env];\n try {\n ensureConfigDir();\n writeSecure(getTokenPath(), JSON.stringify(cache, null, 2));\n } catch {\n /* ignore */\n }\n}\n\n/** Expose paths for diagnostics/tests. */\nexport const _paths = { getConfigDir, getConfigPath, getTokenPath };\n","export type Environment = 'real' | 'mock';\n\n/** API host per environment. */\nexport const BASE_URLS: Record<Environment, string> = {\n real: 'https://api.kiwoom.com',\n mock: 'https://mockapi.kiwoom.com',\n};\n\n/** Accepted aliases for the environment, including Korean labels. */\nexport const ENV_ALIASES: Record<string, Environment> = {\n real: 'real',\n prod: 'real',\n production: 'real',\n live: 'real',\n 실전: 'real',\n 실전투자: 'real',\n mock: 'mock',\n test: 'mock',\n paper: 'mock',\n demo: 'mock',\n 모의: 'mock',\n 모의투자: 'mock',\n};\n\n/** OAuth2 endpoints (relative to the environment base URL). */\nexport const TOKEN_PATH = '/oauth2/token';\nexport const REVOKE_PATH = '/oauth2/revoke';\n\n/** Config + token-cache storage. */\nexport const CONFIG_DIR_NAME = '.kiwoom-cli';\nexport const CONFIG_FILE_NAME = 'config.json';\nexport const TOKEN_FILE_NAME = 'token.json';\n\n/** Environment variables used as a fallback when the config file is unset. */\nexport const ENV_VARS = {\n appkey: 'KIWOOM_APPKEY',\n secretkey: 'KIWOOM_SECRETKEY',\n env: 'KIWOOM_ENV',\n} as const;\n\n/** Re-issue a cached token if it expires within this many milliseconds. */\nexport const TOKEN_REFRESH_BUFFER_MS = 60_000;\n\n/** HTTP request timeout. */\nexport const REQUEST_TIMEOUT_MS = 30_000;\n\n/**\n * `return_code` values that signal \"no matching data\" rather than a real error.\n * The API returns 20 ([2000] 관련자료가없습니다) for empty result sets; callers\n * should receive the (empty) payload, not an exception.\n */\nexport const SOFT_EMPTY_RETURN_CODES = new Set<number>([20]);\n\n/** Exchange routing for ORDER TRs (dmst_stex_tp): best-execution SOR allowed. */\nexport const ORDER_EXCHANGE_TYPES = ['KRX', 'NXT', 'SOR'] as const;\nexport type OrderExchangeType = (typeof ORDER_EXCHANGE_TYPES)[number];\n\n/** Exchange filter for ACCOUNT query TRs (dmst_stex_tp): % = all exchanges. */\nexport const ACCOUNT_EXCHANGE_TYPES = ['KRX', 'NXT', '%'] as const;\nexport type AccountExchangeType = (typeof ACCOUNT_EXCHANGE_TYPES)[number];\n\n/**\n * trde_tp (매매구분 / order-type) codes for buy/sell orders, from the Kiwoom\n * spec. NOTE: 7 = 최우선지정가 (the assignment's \"8\" is wrong). Market types\n * (3/13/23) must be sent with an empty ord_uv.\n */\nexport const ORDER_TYPES: Record<string, string> = {\n '0': '보통(지정가/limit)',\n '3': '시장가(market)',\n '5': '조건부지정가',\n '6': '최유리지정가',\n '7': '최우선지정가',\n '10': '보통(IOC)',\n '13': '시장가(IOC)',\n '16': '최유리(IOC)',\n '20': '보통(FOK)',\n '23': '시장가(FOK)',\n '26': '최유리(FOK)',\n '28': '스톱지정가(stop-limit)',\n '29': '중간가',\n '30': '중간가(IOC)',\n '31': '중간가(FOK)',\n '61': '장시작전시간외',\n '62': '시간외단일가',\n '81': '장마감후시간외',\n};\n\n/** trde_tp codes that are market-style (price must be empty). */\nexport const MARKET_ORDER_TYPES = new Set(['3', '13', '23']);\n\n/**\n * Maximum candles a single chart TR returns (one page). Larger `--count` /\n * `count` values are satisfied by paging on the response `cont-yn` / `next-key`\n * headers (handled by KiwoomClient.requestAll). Verified against the official\n * spec: tick/minute 900, day 600, week 300, month 240, year 30.\n */\nexport const CHART_PER_PAGE_CAP = {\n tick: 900,\n minute: 900,\n day: 600,\n week: 300,\n month: 240,\n year: 30,\n} as const;\n\nexport type ChartType = keyof typeof CHART_PER_PAGE_CAP;\n\n/**\n * Upper bound on the candle count a single command/tool invocation may request,\n * so a typo can't trigger an unbounded paginate loop. Counts above this are\n * clamped (CLI) or rejected by the schema (MCP).\n */\nexport const CHART_MAX_COUNT = 100000;\n","/**\n * An error that carries a suggested recovery command, surfaced to the user as\n * a \"Try: ...\" hint.\n */\nexport class ActionableError extends Error {\n suggestedCommand?: string;\n\n constructor(message: string, suggestedCommand?: string) {\n super(message);\n this.name = 'ActionableError';\n this.suggestedCommand = suggestedCommand;\n }\n}\n\n/**\n * An error raised when the Kiwoom API returns a non-zero return_code.\n */\nexport class KiwoomApiError extends Error {\n returnCode: number;\n returnMsg: string;\n apiId?: string;\n\n constructor(returnCode: number, returnMsg: string, apiId?: string) {\n super(`[${returnCode}] ${returnMsg}`);\n this.name = 'KiwoomApiError';\n this.returnCode = returnCode;\n this.returnMsg = returnMsg;\n this.apiId = apiId;\n }\n}\n\nexport function handleError(err: unknown): never {\n if (err instanceof ActionableError) {\n console.error(`\\nError: ${err.message}`);\n if (err.suggestedCommand) {\n console.error(`\\nTry: ${err.suggestedCommand}`);\n }\n process.exit(1);\n }\n\n if (err instanceof KiwoomApiError) {\n console.error(`\\nError: ${err.returnMsg} (code ${err.returnCode})`);\n if (isAuthError(err.returnMsg) || err.returnCode === 3) {\n console.error(`\\nTry: kiwoom-cli config init`);\n }\n process.exit(1);\n }\n\n if (err instanceof Error) {\n let message = err.message;\n if (message.length > 500) {\n message = message.slice(0, 500) + '...';\n }\n if (isAuthError(message)) {\n console.error(`\\nError: ${message}`);\n console.error(`\\nTry: kiwoom-cli config init`);\n process.exit(1);\n }\n console.error(`\\nError: ${message}`);\n process.exit(1);\n }\n\n console.error(`\\nUnknown error:`, err);\n process.exit(1);\n}\n\nfunction isAuthError(message: string): boolean {\n return /unauthorized|forbidden|not authenticated|토큰|인증|appkey|access token|만료/i.test(\n message,\n );\n}\n\nexport function requireConfig(\n value: string | undefined,\n name: string,\n setCommand: string,\n): asserts value is string {\n if (!value) {\n throw new ActionableError(\n `${name} is not configured.`,\n `kiwoom-cli config set ${setCommand}`,\n );\n }\n}\n","import { ActionableError } from '../output/error';\n\n/** Parse an integer strictly, throwing on failure. */\nexport function parseIntStrict(value: string, name: string): number {\n const n = parseInt(value, 10);\n if (Number.isNaN(n)) {\n throw new Error(`Invalid ${name}: \"${value}\" is not a valid integer`);\n }\n return n;\n}\n\n/** Parse a float strictly, throwing on failure. */\nexport function parseFloatStrict(value: string, name: string): number {\n const n = parseFloat(value);\n if (Number.isNaN(n)) {\n throw new Error(`Invalid ${name}: \"${value}\" is not a valid number`);\n }\n return n;\n}\n\n/**\n * Normalize a Korean stock code to the 6-digit form the API expects.\n * Accepts \"005930\", \"A005930\" (response form), or \"005930_AL\" style suffixes.\n */\nexport function normalizeStockCode(code: string): string {\n const trimmed = code.trim().toUpperCase();\n const stripped = trimmed.replace(/^A(?=\\d)/, '');\n const base = stripped.split('_')[0];\n if (!/^\\d{6}$/.test(base)) {\n throw new ActionableError(\n `Invalid stock code \"${code}\". Expected a 6-digit code like 005930 (삼성전자).`,\n );\n }\n return base;\n}\n\n/**\n * Parse a Kiwoom expiry stamp (\"YYYYMMDDHHmmss\", Korea Standard Time) into\n * epoch milliseconds.\n */\nexport function parseKiwoomExpiry(expiresDt: string): number {\n const m = expiresDt.match(/^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})$/);\n if (!m) return NaN;\n const [, y, mo, d, h, mi, s] = m;\n // KST is UTC+9, no DST.\n return Date.parse(`${y}-${mo}-${d}T${h}:${mi}:${s}+09:00`);\n}\n\n/** True if the token is expired or will expire within `bufferMs`. */\nexport function isTokenExpired(expiresDt: string, bufferMs = 0): boolean {\n const expiry = parseKiwoomExpiry(expiresDt);\n if (Number.isNaN(expiry)) return true;\n return Date.now() + bufferMs >= expiry;\n}\n\n/** Today's date in KST as \"YYYYMMDD\". */\nexport function todayKst(): string {\n const now = new Date(Date.now() + 9 * 3600 * 1000);\n return now.toISOString().slice(0, 10).replace(/-/g, '');\n}\n","import {\n BASE_URLS,\n TOKEN_PATH,\n REVOKE_PATH,\n TOKEN_REFRESH_BUFFER_MS,\n REQUEST_TIMEOUT_MS,\n SOFT_EMPTY_RETURN_CODES,\n Environment,\n} from '../config/constants';\nimport {\n getCachedToken,\n saveCachedToken,\n clearCachedToken,\n} from '../config/store';\nimport { isTokenExpired } from '../utils/helpers';\nimport { KiwoomApiError, ActionableError } from '../output/error';\nimport { EndpointDef } from './endpoints';\n\n/** Result of a TR request, with pagination metadata from the response headers. */\nexport interface TrResponse<T = Record<string, any>> {\n data: T;\n /** True when more pages are available (response header `cont-yn` === 'Y'). */\n contYn: boolean;\n /** Cursor to pass back as `next-key` to fetch the next page. */\n nextKey: string;\n}\n\nexport interface RequestOptions {\n /** Pass 'Y' (with nextKey) to continue a paginated query. */\n contYn?: string;\n nextKey?: string;\n /** Override the api-id header (defaults to the one in the registry call). */\n apiId?: string;\n}\n\nexport interface ClientOptions {\n env: Environment;\n appkey?: string;\n secretkey?: string;\n /** Explicit token; bypasses issuance/caching when provided. */\n token?: string;\n}\n\nfunction fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timeoutId),\n );\n}\n\n/**\n * Kiwoom Securities REST API client.\n *\n * Handles OAuth2 token issuance + caching and routes every TR through a single\n * POST with the api-id header. Tokens are cached per environment on disk so\n * separate CLI invocations reuse them until expiry.\n */\nexport class KiwoomClient {\n private env: Environment;\n private baseUrl: string;\n private appkey?: string;\n private secretkey?: string;\n private tokenOverride?: string;\n private memoToken?: string;\n\n constructor(opts: ClientOptions) {\n this.env = opts.env;\n this.baseUrl = BASE_URLS[opts.env];\n if (!this.baseUrl) {\n throw new Error(`Invalid environment: ${opts.env}. Use: real, mock`);\n }\n this.appkey = opts.appkey;\n this.secretkey = opts.secretkey;\n this.tokenOverride = opts.token;\n }\n\n getEnv(): Environment {\n return this.env;\n }\n\n /** Ensure a valid token exists (issuing + caching as needed) and return it. */\n async authenticate(): Promise<string> {\n return this.getToken();\n }\n\n // ─── OAuth2 ───────────────────────────────────────────────────────────────\n\n /** Issue a fresh access token from the app key + secret key. */\n async issueToken(): Promise<{ token: string; expiresDt: string }> {\n if (!this.appkey || !this.secretkey) {\n throw new ActionableError(\n 'App key and secret key are required to issue a token.',\n 'kiwoom-cli config init',\n );\n }\n const res = await fetchWithTimeout(`${this.baseUrl}${TOKEN_PATH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json;charset=UTF-8' },\n body: JSON.stringify({\n grant_type: 'client_credentials',\n appkey: this.appkey,\n secretkey: this.secretkey,\n }),\n });\n const body = (await res.json().catch(() => ({}))) as Record<string, any>;\n if (!res.ok || body.return_code !== 0 || !body.token) {\n throw new KiwoomApiError(\n body.return_code ?? res.status,\n body.return_msg ?? `Token request failed (HTTP ${res.status})`,\n );\n }\n return { token: body.token, expiresDt: body.expires_dt };\n }\n\n /** Revoke an access token (defaults to the cached/override token). */\n async revokeToken(token?: string): Promise<Record<string, any>> {\n if (!this.appkey || !this.secretkey) {\n throw new ActionableError(\n 'App key and secret key are required to revoke a token.',\n 'kiwoom-cli config init',\n );\n }\n const target = token ?? this.tokenOverride ?? getCachedToken(this.env)?.token;\n if (!target) {\n throw new ActionableError('No token to revoke.');\n }\n const res = await fetchWithTimeout(`${this.baseUrl}${REVOKE_PATH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json;charset=UTF-8' },\n body: JSON.stringify({\n appkey: this.appkey,\n secretkey: this.secretkey,\n token: target,\n }),\n });\n const body = (await res.json().catch(() => ({}))) as Record<string, any>;\n if (!res.ok || body.return_code !== 0) {\n throw new KiwoomApiError(\n body.return_code ?? res.status,\n body.return_msg ?? `Token revoke failed (HTTP ${res.status})`,\n );\n }\n clearCachedToken(this.env);\n return body;\n }\n\n /**\n * Return a valid token, reusing the cache when possible and issuing+caching a\n * new one when missing or near expiry.\n */\n private async getToken(): Promise<string> {\n if (this.tokenOverride) return this.tokenOverride;\n if (this.memoToken) return this.memoToken;\n\n const cached = getCachedToken(this.env);\n const hint = this.appkey?.slice(0, 6);\n if (\n cached &&\n cached.appkeyHint === hint &&\n !isTokenExpired(cached.expiresDt, TOKEN_REFRESH_BUFFER_MS)\n ) {\n this.memoToken = cached.token;\n return cached.token;\n }\n\n const { token, expiresDt } = await this.issueToken();\n this.memoToken = token;\n if (hint) {\n saveCachedToken(this.env, { token, expiresDt, appkeyHint: hint });\n }\n return token;\n }\n\n // ─── Generic TR request ──────────────────────────────────────────────────\n\n /**\n * Execute a TR. `apiId` is sent in the api-id header; `path` is the category\n * route (e.g. /api/dostk/stkinfo). Returns the parsed body plus pagination.\n */\n async request<T = Record<string, any>>(\n apiId: string,\n path: string,\n body: Record<string, unknown> = {},\n options: RequestOptions = {},\n ): Promise<TrResponse<T>> {\n const send = async (token: string): Promise<Response> =>\n fetchWithTimeout(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json;charset=UTF-8',\n authorization: `Bearer ${token}`,\n 'api-id': options.apiId ?? apiId,\n 'cont-yn': options.contYn ?? 'N',\n 'next-key': options.nextKey ?? '',\n },\n body: JSON.stringify(body),\n });\n\n let res = await send(await this.getToken());\n\n // Token might have been revoked/expired server-side: clear and retry once.\n if (res.status === 401 && !this.tokenOverride) {\n clearCachedToken(this.env);\n this.memoToken = undefined;\n res = await send(await this.getToken());\n }\n\n const payload = (await res.json().catch(() => ({}))) as Record<string, any>;\n if (!res.ok) {\n throw new KiwoomApiError(\n payload.return_code ?? res.status,\n payload.return_msg ?? `Request failed (HTTP ${res.status})`,\n apiId,\n );\n }\n if (\n typeof payload.return_code === 'number' &&\n payload.return_code !== 0 &&\n !SOFT_EMPTY_RETURN_CODES.has(payload.return_code)\n ) {\n throw new KiwoomApiError(payload.return_code, payload.return_msg ?? 'Error', apiId);\n }\n\n return {\n data: payload as T,\n contYn: res.headers.get('cont-yn') === 'Y',\n nextKey: res.headers.get('next-key') ?? '',\n };\n }\n\n /**\n * Execute an endpoint from the registry. When `paginate` is set and the\n * endpoint declares a listKey, all pages are fetched and concatenated.\n */\n async callEndpoint<T = Record<string, any>>(\n def: EndpointDef,\n body: Record<string, unknown> = {},\n opts: { paginate?: boolean; contYn?: string; nextKey?: string; maxPages?: number } = {},\n ): Promise<TrResponse<T>> {\n if (opts.paginate && def.listKey) {\n const data = await this.requestAll<T>(def.apiId, def.path, body, def.listKey, opts.maxPages);\n return { data, contYn: false, nextKey: '' };\n }\n return this.request<T>(def.apiId, def.path, body, {\n contYn: opts.contYn,\n nextKey: opts.nextKey,\n });\n }\n\n /**\n * Fetch all pages of a TR, concatenating the array under `listKey`.\n * Caps at `maxPages` to avoid runaway loops (default 100 — high enough for\n * large chart pulls; callers pass a tighter bound when they know how many\n * pages a target row count needs).\n */\n async requestAll<T = Record<string, any>>(\n apiId: string,\n path: string,\n body: Record<string, unknown>,\n listKey: string,\n maxPages = 100,\n ): Promise<T> {\n let page = await this.request<Record<string, any>>(apiId, path, body);\n const acc = Array.isArray(page.data[listKey]) ? [...page.data[listKey]] : [];\n let pages = 1;\n while (page.contYn && page.nextKey && pages < maxPages) {\n page = await this.request<Record<string, any>>(apiId, path, body, {\n contYn: 'Y',\n nextKey: page.nextKey,\n });\n if (Array.isArray(page.data[listKey])) acc.push(...page.data[listKey]);\n pages += 1;\n }\n return { ...page.data, [listKey]: acc } as T;\n }\n}\n","export type OutputFormat = 'json' | 'table';\n\nexport function getOutputFormat(options: { output?: string }): OutputFormat {\n return options.output === 'json' ? 'json' : 'table';\n}\n\n/**\n * Render data to stdout. `json` prints the raw payload; `table` prints arrays\n * via console.table and objects as aligned key/value pairs.\n */\nexport function output(data: unknown, format: OutputFormat = 'table'): void {\n if (format === 'json') {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log('No data');\n return;\n }\n if (typeof data[0] === 'object' && data[0] !== null) {\n console.table(data);\n } else {\n for (const item of data) console.log(` ${String(item)}`);\n }\n return;\n }\n\n if (data !== null && typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) {\n console.log('No data');\n return;\n }\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n for (const [key, value] of entries) {\n const displayValue =\n value !== null && typeof value === 'object'\n ? JSON.stringify(value)\n : String(value);\n console.log(` ${key.padEnd(maxKeyLen + 2)} ${displayValue}`);\n }\n return;\n }\n\n console.log(String(data));\n}\n\n/** Print a list of objects as a table, or \"No data\" when empty. */\nexport function outputTable(rows: Record<string, unknown>[], format: OutputFormat): void {\n if (format === 'json') {\n output(rows, 'json');\n return;\n }\n output(rows, 'table');\n}\n","import { KiwoomClient } from '../client/api-client';\nimport { getEffectiveConfig } from '../config/store';\nimport { ActionableError } from '../output/error';\n\n/**\n * Build a client from the effective config. Every Kiwoom call needs a token, so\n * app key + secret key are always required (there is no anonymous endpoint).\n */\nexport function createClient(): KiwoomClient {\n const config = getEffectiveConfig();\n if (!config.appkey || !config.secretkey) {\n throw new ActionableError(\n 'App key / secret key are not configured.',\n 'kiwoom-cli config init',\n );\n }\n return new KiwoomClient({\n env: config.env,\n appkey: config.appkey,\n secretkey: config.secretkey,\n });\n}\n","/**\n * Kiwoom value normalization.\n *\n * The REST API returns numbers as strings: integers are often zero-padded to a\n * fixed width (\"000000019471143\"), and price/percent fields carry a leading\n * sign that encodes direction (\"+0.39\", \"-350000\"). These helpers turn those\n * wire values into something readable without losing the sign.\n */\n\n// Kiwoom occasionally double-signs delta fields, e.g. \"--3405260\" (negative\n// delta) or \"++100\"; treat a leading run of signs as one effective sign where\n// any '-' makes it negative.\nconst NUMERIC_RE = /^([+-]*)0*(\\d+)(\\.\\d+)?$/;\n\n/**\n * Strip zero-padding while preserving sign and decimals.\n * \"000000019471143\" -> \"19471143\", \"-00000001485445\" -> \"-1485445\",\n * \"+0.39\" -> \"+0.39\", \"--3405260\" -> \"-3405260\", \"000000000000000\" -> \"0\".\n * Non-numeric strings (codes, dates-as-text, \"KRX\") are returned unchanged.\n */\nexport function unpad(value: string | number | null | undefined): string {\n if (value === null || value === undefined) return '';\n const str = String(value).trim();\n const m = str.match(NUMERIC_RE);\n if (!m) return str;\n const sign = m[1].includes('-') ? '-' : m[1].includes('+') ? '+' : '';\n const intPart = m[2].replace(/^0+(?=\\d)/, '');\n return `${sign}${intPart}${m[3] ?? ''}`;\n}\n\n/** Parse a Kiwoom numeric string into a JS number (sign + padding aware). */\nexport function toNumber(value: string | number | null | undefined): number {\n if (value === null || value === undefined || value === '') return NaN;\n const cleaned = unpad(value).replace(/^\\+/, '');\n // Guard sign-only/empty results so \"+\" doesn't coerce to 0.\n if (cleaned === '' || cleaned === '-' || cleaned === '+') return NaN;\n const n = Number(cleaned);\n return Number.isNaN(n) ? NaN : n;\n}\n\n/** Group an integer/decimal string with thousands separators, keeping sign. */\nexport function withCommas(value: string): string {\n const m = value.match(/^([+-]?)(\\d+)(\\.\\d+)?$/);\n if (!m) return value;\n const grouped = m[2].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n return `${m[1]}${grouped}${m[3] ?? ''}`;\n}\n\n/** Format a (possibly zero-padded) won amount as \"19,471,143\". */\nexport function won(value: string | number | null | undefined): string {\n return withCommas(unpad(value));\n}\n\n/**\n * Format a market price. Kiwoom prefixes quote/chart prices with a direction\n * sign (e.g. \"-353750\" = price 353,750, trading below prior close); that sign\n * is NOT part of the value, so it is dropped and the magnitude is grouped.\n */\nexport function price(value: string | number | null | undefined): string {\n return withCommas(unpad(value).replace(/^[+-]/, ''));\n}\n\n/**\n * Format a Kiwoom date/time stamp for display.\n * \"20260622135400\" -> \"2026-06-22 13:54:00\"\n * \"20260622\" -> \"2026-06-22\"\n * \"135400\" -> \"13:54:00\"\n */\nexport function formatStamp(value: string | null | undefined): string {\n if (!value) return '';\n const s = String(value).trim();\n if (/^\\d{14}$/.test(s)) {\n return `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)} ${s.slice(8, 10)}:${s.slice(10, 12)}:${s.slice(12, 14)}`;\n }\n if (/^\\d{8}$/.test(s)) {\n return `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)}`;\n }\n if (/^\\d{6}$/.test(s)) {\n return `${s.slice(0, 2)}:${s.slice(2, 4)}:${s.slice(4, 6)}`;\n }\n return s;\n}\n\n/**\n * Apply a set of formatters to selected keys of an object (shallow).\n * Used by table commands to pretty-print known numeric fields.\n */\nexport function formatFields<T extends Record<string, unknown>>(\n row: T,\n formatters: Partial<Record<keyof T | string, (v: string) => string>>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...row };\n for (const [key, fn] of Object.entries(formatters)) {\n if (fn && out[key] !== undefined && out[key] !== null) {\n out[key] = fn(String(out[key]));\n }\n }\n return out;\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { getEffectiveConfig, getCachedToken, clearCachedToken, maskSecret } from '../config/store';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError, ActionableError } from '../output/error';\nimport { formatStamp } from '../utils/format';\nimport { isTokenExpired } from '../utils/helpers';\n\nexport function registerAuthCommands(program: Command): void {\n const authCmd = program.command('auth').description('Access-token management (OAuth2)');\n\n authCmd\n .command('token')\n .description('Issue (or reuse) an access token and cache it')\n .option('--force', 'Force a fresh token even if a valid one is cached')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const cfg = getEffectiveConfig();\n const client = createClient();\n if (options.force) clearCachedToken(cfg.env);\n await client.authenticate();\n const cached = getCachedToken(cfg.env);\n output(\n {\n env: cfg.env,\n token: maskSecret(cached?.token),\n expiresAt: formatStamp(cached?.expiresDt),\n valid: cached ? !isTokenExpired(cached.expiresDt) : false,\n },\n getOutputFormat(options),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n authCmd\n .command('status')\n .description('Show the cached token status')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((options) => {\n try {\n const cfg = getEffectiveConfig();\n const cached = getCachedToken(cfg.env);\n if (!cached) {\n output({ env: cfg.env, cached: false }, getOutputFormat(options));\n return;\n }\n output(\n {\n env: cfg.env,\n cached: true,\n token: maskSecret(cached.token),\n expiresAt: formatStamp(cached.expiresDt),\n valid: !isTokenExpired(cached.expiresDt),\n },\n getOutputFormat(options),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n authCmd\n .command('revoke')\n .description('Revoke the cached access token')\n .action(async () => {\n try {\n const cfg = getEffectiveConfig();\n const cached = getCachedToken(cfg.env);\n if (!cached) {\n throw new ActionableError('No cached token to revoke.', 'kiwoom-cli auth token');\n }\n const client = createClient();\n await client.revokeToken(cached.token);\n console.log('Token revoked and cache cleared.');\n } catch (err) {\n handleError(err);\n }\n });\n}\n","/**\n * Registry of every Kiwoom TR this CLI exposes — the single source of truth for\n * api-id, route, response list key, and whether the call places/modifies orders.\n *\n * All specs were live-verified against https://api.kiwoom.com (read TRs) or\n * taken from the official spec + typed community wrappers (order TRs, which are\n * never called live for safety).\n */\n\nexport const PATHS = {\n stkinfo: '/api/dostk/stkinfo',\n mrkcond: '/api/dostk/mrkcond',\n chart: '/api/dostk/chart',\n acnt: '/api/dostk/acnt',\n ordr: '/api/dostk/ordr',\n crdordr: '/api/dostk/crdordr',\n rkinfo: '/api/dostk/rkinfo',\n sect: '/api/dostk/sect',\n} as const;\n\nexport interface EndpointDef {\n /** api-id header value, e.g. \"ka10001\". */\n apiId: string;\n /** Category route. */\n path: string;\n /** Korean TR name. */\n korean: string;\n /** Array field in the response payload, if the TR returns a list. */\n listKey?: string;\n /** True for order place/modify/cancel TRs (real-money writes). */\n isWrite?: boolean;\n}\n\nexport const ENDPOINTS = {\n // ── Stock info (종목정보) ──────────────────────────────────────────────────\n stockInfo: { apiId: 'ka10001', path: PATHS.stkinfo, korean: '주식기본정보요청' },\n tradingMembers: { apiId: 'ka10002', path: PATHS.stkinfo, korean: '주식거래원요청' },\n stockTrades: { apiId: 'ka10003', path: PATHS.stkinfo, korean: '체결정보요청', listKey: 'cntr_infr' },\n watchlist: { apiId: 'ka10095', path: PATHS.stkinfo, korean: '관심종목정보요청', listKey: 'atn_stk_infr' },\n stockList: { apiId: 'ka10099', path: PATHS.stkinfo, korean: '종목정보 리스트', listKey: 'list' },\n stockInfoSingle: { apiId: 'ka10100', path: PATHS.stkinfo, korean: '종목정보 조회' },\n sectorCodeList: { apiId: 'ka10101', path: PATHS.stkinfo, korean: '업종코드 리스트', listKey: 'list' },\n creditTrend: { apiId: 'ka10013', path: PATHS.stkinfo, korean: '신용매매동향요청', listKey: 'crd_trde_trend' },\n\n // ── Market quote (시세) ────────────────────────────────────────────────────\n orderbook: { apiId: 'ka10004', path: PATHS.mrkcond, korean: '주식호가요청' },\n quoteSnapshot: { apiId: 'ka10006', path: PATHS.mrkcond, korean: '주식시분요청' },\n priceTableInfo: { apiId: 'ka10007', path: PATHS.mrkcond, korean: '시세표성정보요청' },\n dailyPrice: { apiId: 'ka10086', path: PATHS.mrkcond, korean: '일별주가요청', listKey: 'daly_stkpc' },\n instTradedStocks: { apiId: 'ka10044', path: PATHS.mrkcond, korean: '일별기관매매종목요청', listKey: 'daly_orgn_trde_stk' },\n instForeignTrend: { apiId: 'ka10045', path: PATHS.mrkcond, korean: '종목별기관매매추이요청', listKey: 'stk_orgn_trde_trnsn' },\n strengthByTime: { apiId: 'ka10046', path: PATHS.mrkcond, korean: '체결강도시간별요청', listKey: 'cntr_str_tm' },\n strengthByDay: { apiId: 'ka10047', path: PATHS.mrkcond, korean: '체결강도일별요청', listKey: 'cntr_str_daly' },\n afterHoursOrderbook: { apiId: 'ka10087', path: PATHS.mrkcond, korean: '시간외단일가요청' },\n\n // ── Chart (차트) ───────────────────────────────────────────────────────────\n tickChart: { apiId: 'ka10079', path: PATHS.chart, korean: '주식틱차트조회', listKey: 'stk_tic_chart_qry' },\n minuteChart: { apiId: 'ka10080', path: PATHS.chart, korean: '주식분봉차트조회', listKey: 'stk_min_pole_chart_qry' },\n dailyChart: { apiId: 'ka10081', path: PATHS.chart, korean: '주식일봉차트조회', listKey: 'stk_dt_pole_chart_qry' },\n // NOTE: weekly list key is the doubled \"stk_stk_...\" — verified live, not a typo.\n weeklyChart: { apiId: 'ka10082', path: PATHS.chart, korean: '주식주봉차트조회', listKey: 'stk_stk_pole_chart_qry' },\n monthlyChart: { apiId: 'ka10083', path: PATHS.chart, korean: '주식월봉차트조회', listKey: 'stk_mth_pole_chart_qry' },\n yearlyChart: { apiId: 'ka10094', path: PATHS.chart, korean: '주식년봉차트조회', listKey: 'stk_yr_pole_chart_qry' },\n\n // ── Account (계좌) ─────────────────────────────────────────────────────────\n balance: { apiId: 'kt00018', path: PATHS.acnt, korean: '계좌평가잔고내역요청', listKey: 'acnt_evlt_remn_indv_tot' },\n deposit: { apiId: 'kt00001', path: PATHS.acnt, korean: '예수금상세현황요청', listKey: 'stk_entr_prst' },\n evalStatus: { apiId: 'kt00004', path: PATHS.acnt, korean: '계좌평가현황요청', listKey: 'stk_acnt_evlt_prst' },\n settledBalance: { apiId: 'kt00005', path: PATHS.acnt, korean: '체결잔고요청', listKey: 'stk_cntr_remn' },\n orderDetail: { apiId: 'kt00007', path: PATHS.acnt, korean: '계좌별주문체결내역상세요청', listKey: 'acnt_ord_cntr_prps_dtl' },\n orderStatus: { apiId: 'kt00009', path: PATHS.acnt, korean: '계좌별주문체결현황요청', listKey: 'acnt_ord_cntr_prst' },\n openOrders: { apiId: 'ka10075', path: PATHS.acnt, korean: '미체결요청', listKey: 'oso' },\n executions: { apiId: 'ka10076', path: PATHS.acnt, korean: '체결요청', listKey: 'cntr' },\n realizedPlByDate: { apiId: 'ka10072', path: PATHS.acnt, korean: '일자별종목별실현손익요청_일자', listKey: 'dt_stk_div_rlzt_pl' },\n realizedPlByPeriod: { apiId: 'ka10073', path: PATHS.acnt, korean: '일자별종목별실현손익요청_기간', listKey: 'dt_stk_rlzt_pl' },\n tradeJournal: { apiId: 'ka10170', path: PATHS.acnt, korean: '당일매매일지요청', listKey: 'tdy_trde_diary' },\n dailyReturn: { apiId: 'kt00016', path: PATHS.acnt, korean: '일별계좌수익률상세현황요청' },\n\n // ── Order (주문) — WRITE, real money ──────────────────────────────────────\n buy: { apiId: 'kt10000', path: PATHS.ordr, korean: '주식 매수주문', isWrite: true },\n sell: { apiId: 'kt10001', path: PATHS.ordr, korean: '주식 매도주문', isWrite: true },\n modify: { apiId: 'kt10002', path: PATHS.ordr, korean: '주식 정정주문', isWrite: true },\n cancel: { apiId: 'kt10003', path: PATHS.ordr, korean: '주식 취소주문', isWrite: true },\n creditBuy: { apiId: 'kt10006', path: PATHS.crdordr, korean: '신용 매수주문', isWrite: true },\n creditSell: { apiId: 'kt10007', path: PATHS.crdordr, korean: '신용 매도주문', isWrite: true },\n creditModify: { apiId: 'kt10008', path: PATHS.crdordr, korean: '신용 정정주문', isWrite: true },\n creditCancel: { apiId: 'kt10009', path: PATHS.crdordr, korean: '신용 취소주문', isWrite: true },\n\n // ── Ranking (순위정보) ─────────────────────────────────────────────────────\n rankFluctuation: { apiId: 'ka10027', path: PATHS.rkinfo, korean: '전일대비등락률순위요청', listKey: 'pred_pre_flu_rt_upper' },\n rankVolume: { apiId: 'ka10030', path: PATHS.rkinfo, korean: '당일거래량상위요청', listKey: 'tdy_trde_qty_upper' },\n rankTradeAmount: { apiId: 'ka10032', path: PATHS.rkinfo, korean: '거래대금상위요청', listKey: 'trde_prica_upper' },\n rankVolumeSurge: { apiId: 'ka10023', path: PATHS.rkinfo, korean: '거래량급증요청', listKey: 'trde_qty_sdnin' },\n rankPrevVolume: { apiId: 'ka10031', path: PATHS.rkinfo, korean: '전일거래량상위요청', listKey: 'pred_trde_qty_upper' },\n\n // ── Sector / industry (업종) ───────────────────────────────────────────────\n sectorPrice: { apiId: 'ka20001', path: PATHS.sect, korean: '업종현재가요청', listKey: 'inds_cur_prc_tm' },\n sectorStocks: { apiId: 'ka20002', path: PATHS.sect, korean: '업종별주가요청', listKey: 'inds_stkpc' },\n sectorAllIndex: { apiId: 'ka20003', path: PATHS.sect, korean: '전업종지수요청', listKey: 'all_inds_idex' },\n sectorDaily: { apiId: 'ka20009', path: PATHS.sect, korean: '업종현재가 일별요청', listKey: 'inds_cur_prc_daly_rept' },\n} satisfies Record<string, EndpointDef>;\n\nexport type EndpointKey = keyof typeof ENDPOINTS;\n","import { unpad, formatStamp } from './format';\n\nexport interface BookLevel {\n level: number;\n price: string;\n qty: string;\n}\n\nexport interface ParsedBook {\n baseTime: string;\n asks: BookLevel[]; // highest ask first (level 10 → 1)\n bids: BookLevel[]; // best bid first (level 1 → 10)\n totalAskQty: string;\n totalBidQty: string;\n}\n\n/**\n * Parse a ka10004 (주식호가요청) payload into ordered bid/ask levels.\n *\n * The field naming is irregular: level-1 quotes use the `*_fpr_*` (최우선)\n * keys, while levels 2–10 use `*_{N}th_pre_*`.\n */\nexport function parseOrderbook(d: Record<string, any>): ParsedBook {\n const asks: BookLevel[] = [];\n for (let n = 10; n >= 2; n--) {\n asks.push({\n level: n,\n price: unpad(d[`sel_${n}th_pre_bid`]),\n qty: unpad(d[`sel_${n}th_pre_req`]),\n });\n }\n asks.push({ level: 1, price: unpad(d.sel_fpr_bid), qty: unpad(d.sel_fpr_req) });\n\n const bids: BookLevel[] = [];\n bids.push({ level: 1, price: unpad(d.buy_fpr_bid), qty: unpad(d.buy_fpr_req) });\n for (let n = 2; n <= 10; n++) {\n bids.push({\n level: n,\n price: unpad(d[`buy_${n}th_pre_bid`]),\n qty: unpad(d[`buy_${n}th_pre_req`]),\n });\n }\n\n return {\n baseTime: formatStamp(d.bid_req_base_tm),\n asks,\n bids,\n totalAskQty: unpad(d.tot_sel_req),\n totalBidQty: unpad(d.tot_buy_req),\n };\n}\n\n/** Render a parsed book as a compact two-sided ladder for the terminal. */\nexport function renderOrderbook(book: ParsedBook, title: string): string {\n const lines: string[] = [];\n lines.push(`\\n Order Book: ${title} (${book.baseTime})\\n`);\n lines.push(' ── Asks ──');\n for (const a of book.asks) {\n lines.push(` ${a.price.padStart(12)} ${a.qty.padStart(12)}`);\n }\n lines.push(' ─────────');\n for (const b of book.bids) {\n lines.push(` ${b.price.padStart(12)} ${b.qty.padStart(12)}`);\n }\n lines.push(' ── Bids ──');\n lines.push(`\\n Total ask qty: ${book.totalAskQty} Total bid qty: ${book.totalBidQty}\\n`);\n return lines.join('\\n');\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat, OutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst } from '../utils/helpers';\nimport { unpad, won, price, formatStamp, formatFields, toNumber } from '../utils/format';\nimport { parseOrderbook, renderOrderbook } from '../utils/orderbook';\n\nexport function registerMarketCommands(program: Command): void {\n const market = program.command('market').description('Market data — prices, quotes, order book, trades');\n\n // market price <code>\n market\n .command('price <code>')\n .description('Current price snapshot (ka10007)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.priceTableInfo, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n const chg =\n Math.abs(toNumber(data.cur_prc)) - Math.abs(toNumber(data.pred_close_pric));\n output(\n {\n name: data.stk_nm,\n code: data.stk_cd,\n price: price(data.cur_prc),\n change: Number.isNaN(chg) ? '' : `${chg > 0 ? '+' : ''}${chg}`,\n changeRate: `${unpad(data.flu_rt)}%`,\n open: price(data.open_pric),\n high: price(data.high_pric),\n low: price(data.low_pric),\n volume: won(data.trde_qty),\n bestAsk: price(data.sel_1bid),\n bestBid: price(data.buy_1bid),\n prevClose: price(data.pred_close_pric),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market orderbook <code>\n market\n .command('orderbook <code>')\n .alias('book')\n .description('10-level bid/ask order book (ka10004)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.orderbook, { stk_cd: stk });\n if (getOutputFormat(options) === 'json') {\n output(data, 'json');\n return;\n }\n console.log(renderOrderbook(parseOrderbook(data), stk));\n } catch (err) {\n handleError(err);\n }\n });\n\n // market after-hours <code>\n market\n .command('after-hours <code>')\n .description('After-hours single-price quotes (ka10087)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.afterHoursOrderbook, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n price: unpad(data.ovt_sigpric_cur_prc),\n change: unpad(data.ovt_sigpric_pred_pre),\n changeRate: `${unpad(data.ovt_sigpric_flu_rt)}%`,\n volume: won(data.ovt_sigpric_acc_trde_qty),\n askTotal: won(data.ovt_sigpric_sel_bid_tot_req),\n bidTotal: won(data.ovt_sigpric_buy_bid_tot_req),\n baseTime: formatStamp(data.bid_req_base_tm),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market daily <code>\n market\n .command('daily <code>')\n .description('Daily price history (ka10086)')\n .option('-d, --date <yyyymmdd>', 'Base date (most recent day)', todayKst())\n .option('-t, --type <0|1>', 'Display type: 0=quantity, 1=amount', '0')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.dailyPrice, {\n stk_cd: stk,\n qry_dt: options.date,\n indc_tp: options.type,\n });\n emitList(data, ENDPOINTS.dailyPrice.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n date: formatStamp,\n open_pric: unpad,\n high_pric: unpad,\n low_pric: unpad,\n close_pric: unpad,\n flu_rt: unpad,\n trde_qty: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market trades <code>\n market\n .command('trades <code>')\n .description('Recent tick-by-tick executions (ka10003)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.stockTrades, { stk_cd: stk });\n emitList(data, ENDPOINTS.stockTrades.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n tm: formatStamp,\n cur_prc: unpad,\n pred_pre: unpad,\n pre_rt: unpad,\n cntr_trde_qty: unpad,\n acc_trde_qty: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market strength <code>\n market\n .command('strength <code>')\n .description('Trade strength (체결강도) time series (ka10046 / ka10047)')\n .option('--daily', 'Daily series instead of intraday')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const ep = options.daily ? ENDPOINTS.strengthByDay : ENDPOINTS.strengthByTime;\n const { data } = await client.callEndpoint(ep, { stk_cd: stk });\n emitList(data, ep.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n cntr_tm: formatStamp,\n dt: formatStamp,\n cur_prc: unpad,\n flu_rt: unpad,\n cntr_str: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market inst-foreign <code>\n market\n .command('inst-foreign <code>')\n .description('Per-stock institution/foreigner trading trend (ka10045)')\n .option('-s, --start <yyyymmdd>', 'Start date')\n .option('-e, --end <yyyymmdd>', 'End date', todayKst())\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.instForeignTrend, {\n stk_cd: stk,\n strt_dt: options.start ?? options.end,\n end_dt: options.end,\n orgn_prsm_unp_tp: '0',\n for_prsm_unp_tp: '0',\n });\n emitList(data, ENDPOINTS.instForeignTrend.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n dt: formatStamp,\n close_pric: unpad,\n flu_rt: unpad,\n orgn_daly_nettrde_qty: unpad,\n for_daly_nettrde_qty: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n\n/** Shared helper: emit a list payload as JSON (raw) or a formatted table. */\nexport function emitList(\n data: Record<string, any>,\n listKey: string,\n fmt: OutputFormat,\n rowFormatter?: (row: Record<string, unknown>) => Record<string, unknown>,\n): void {\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n const rows: Record<string, unknown>[] = Array.isArray(data[listKey]) ? data[listKey] : [];\n if (rows.length === 0) {\n console.log('No data');\n return;\n }\n output(rowFormatter ? rows.map(rowFormatter) : rows, 'table');\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst, parseIntStrict } from '../utils/helpers';\nimport { unpad, won, price, formatStamp, formatFields } from '../utils/format';\nimport { emitList } from './market';\n\nexport function registerStockCommands(program: Command): void {\n const stock = program.command('stock').description('Stock information — fundamentals, search, members');\n\n // stock info <code>\n stock\n .command('info <code>')\n .description('Stock fundamentals snapshot (ka10001)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.stockInfo, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n name: data.stk_nm,\n code: data.stk_cd,\n price: price(data.cur_prc),\n change: unpad(data.pred_pre),\n changeRate: `${unpad(data.flu_rt)}%`,\n open: price(data.open_pric),\n high: price(data.high_pric),\n low: price(data.low_pric),\n upperLimit: price(data.upl_pric),\n lowerLimit: price(data.lst_pric),\n volume: won(data.trde_qty),\n per: data.per,\n eps: data.eps,\n roe: data.roe,\n pbr: data.pbr,\n bps: data.bps,\n marketCap: won(data.mac),\n foreignRate: `${unpad(data.for_exh_rt)}%`,\n high52w: price(data['250hgst']),\n low52w: price(data['250lwst']),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock search <keyword>\n stock\n .command('search <keyword>')\n .description('Search the stock list by name or code (ka10099)')\n .option('-m, --market <0|10>', 'Market: 0=KOSPI, 10=KOSDAQ', '0')\n .option('-n, --limit <n>', 'Maximum rows to return', '30')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (keyword: string, options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(\n ENDPOINTS.stockList,\n { mrkt_tp: options.market },\n { paginate: true },\n );\n const fmt = getOutputFormat(options);\n const limit = parseIntStrict(options.limit, 'limit');\n const needle = keyword.toLowerCase();\n const list: Record<string, any>[] = Array.isArray(data[ENDPOINTS.stockList.listKey!])\n ? data[ENDPOINTS.stockList.listKey!]\n : [];\n const filtered = list\n .filter(\n (item) =>\n String(item.name ?? '').toLowerCase().includes(needle) ||\n String(item.code ?? '').startsWith(keyword),\n )\n .slice(0, limit);\n if (filtered.length === 0) {\n console.log('No matches');\n return;\n }\n if (fmt === 'json') {\n output(filtered, 'json');\n return;\n }\n const rows = filtered.map((item) => ({\n code: item.code,\n name: item.name,\n market: item.marketName,\n sector: item.upName,\n lastPrice: unpad(item.lastPrice),\n }));\n output(rows, 'table');\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock resolve <code>\n stock\n .command('resolve <code>')\n .description('Resolve a single stock\\'s listing metadata (ka10100)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.stockInfoSingle, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n code: data.code,\n name: data.name,\n market: data.marketName,\n sector: data.upName,\n sizeTier: data.upSizeName,\n listedShares: won(data.listCount),\n lastPrice: unpad(data.lastPrice),\n state: data.state,\n nxtEnable: data.nxtEnable,\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock members <code>\n stock\n .command('members <code>')\n .description('Top 5 buy/sell trading members (ka10002)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.tradingMembers, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n const rows = [];\n for (let i = 1; i <= 5; i++) {\n rows.push({\n rank: i,\n sellMember: data['sel_trde_ori_nm_' + i],\n sellQty: unpad(data['sel_trde_qty_' + i]),\n buyMember: data['buy_trde_ori_nm_' + i],\n buyQty: unpad(data['buy_trde_qty_' + i]),\n });\n }\n output(rows, 'table');\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock credit-trend <code>\n stock\n .command('credit-trend <code>')\n .description('Credit trading trend (신용매매동향) (ka10013)')\n .option('-d, --date <yyyymmdd>', 'Base date', todayKst())\n .option('-t, --type <1|2>', 'Query type: 1=융자, 2=대주', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.creditTrend, {\n stk_cd: stk,\n dt: options.date ?? todayKst(),\n qry_tp: options.type ?? '1',\n });\n emitList(data, ENDPOINTS.creditTrend.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n dt: formatStamp,\n cur_prc: unpad,\n trde_qty: won,\n new: won,\n rpya: won,\n remn: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS, EndpointDef } from '../client/endpoints';\nimport { output, getOutputFormat, OutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst, parseIntStrict } from '../utils/helpers';\nimport { unpad, won, formatStamp, formatFields } from '../utils/format';\nimport { CHART_PER_PAGE_CAP, CHART_MAX_COUNT, ChartType } from '../config/constants';\nimport { ActionableError } from '../output/error';\n\n/** Per-row formatters shared by every chart TR (fields overlap across types). */\nconst CHART_ROW_FORMATTERS: Record<string, (v: string) => string> = {\n cntr_tm: formatStamp,\n dt: formatStamp,\n open_pric: unpad,\n high_pric: unpad,\n low_pric: unpad,\n cur_prc: unpad,\n trde_qty: won,\n acc_trde_qty: won,\n trde_prica: won,\n pred_pre: unpad,\n trde_tern_rt: unpad,\n};\n\n/**\n * Per-request row cap for each chart TR (rows returned by a single API call).\n * Kiwoom returns at most this many candles per page; larger `--count` values are\n * served by paging on the `cont-yn` / `next-key` headers (see runIntraday/runPeriod).\n * Sourced from the shared constants registry.\n */\nexport const PER_PAGE_CAP = CHART_PER_PAGE_CAP;\n\n/**\n * Parse + validate the `--count` flag locally so a bad value fails clearly here\n * instead of leaking a raw server 400. Must be a positive integer; clamps to\n * CHART_MAX_COUNT to bound auto-pagination.\n */\nfunction parseCount(raw: string): number {\n const n = parseIntStrict(raw, 'count');\n if (n < 1) {\n throw new ActionableError(`--count must be a positive integer (got ${n}).`);\n }\n return Math.min(n, CHART_MAX_COUNT);\n}\n\n/**\n * Render a chart payload: raw JSON, or a formatted table of the first `count`\n * candles under the endpoint's listKey. The list is always sliced to `count` so\n * the output never exceeds the requested number, whether one page or many pages\n * (auto-pagination) were fetched.\n */\nfunction emitChart(data: Record<string, any>, ep: EndpointDef, fmt: OutputFormat, count: number): void {\n const all: Record<string, unknown>[] = Array.isArray(data[ep.listKey!]) ? data[ep.listKey!] : [];\n const sliced = all.slice(0, count);\n if (fmt === 'json') {\n output({ ...data, [ep.listKey!]: sliced }, 'json');\n return;\n }\n if (sliced.length === 0) {\n console.log('No data');\n return;\n }\n output(\n sliced.map((row) => formatFields(row, CHART_ROW_FORMATTERS)),\n 'table',\n );\n}\n\nexport function registerChartCommands(program: Command): void {\n const chart = program\n .command('chart')\n .description(\n 'OHLC charts — tick / minute / daily / weekly / monthly / yearly. ' +\n 'Per-request caps: tick/min 900, day 600, week 300, month 240, year 30. ' +\n '--count beyond the cap auto-paginates via cont-yn/next-key.',\n );\n\n /**\n * Decide whether to auto-paginate: explicitly requested via `--paginate`, or\n * implied because `--count` exceeds the per-page cap for this chart type.\n * Returns the max pages needed so we never over-fetch.\n */\n function planFetch(type: ChartType, count: number, paginate: boolean): { paginate: boolean; maxPages: number } {\n const cap = PER_PAGE_CAP[type];\n const active = paginate || count > cap;\n // Pages needed to reach `count` rows, capped only by data availability.\n const maxPages = active ? Math.max(1, Math.ceil(count / cap)) : 1;\n return { paginate: active, maxPages };\n }\n\n /** Intraday family (tick, min): body keyed on tic_scope. */\n async function runIntraday(\n ep: EndpointDef,\n type: ChartType,\n code: string,\n ticScope: string,\n options: any,\n ): Promise<void> {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const count = parseCount(options.count);\n const plan = planFetch(type, count, !!options.paginate);\n const { data } = await client.callEndpoint(\n ep,\n { stk_cd: stk, tic_scope: ticScope, upd_stkpc_tp: options.raw ? '0' : '1' },\n { paginate: plan.paginate, maxPages: plan.maxPages },\n );\n emitChart(data, ep, getOutputFormat(options), count);\n }\n\n /** Period family (day, week, month, year): body keyed on base_dt. */\n async function runPeriod(\n ep: EndpointDef,\n type: ChartType,\n code: string,\n baseDt: string,\n options: any,\n ): Promise<void> {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const count = parseCount(options.count);\n const plan = planFetch(type, count, !!options.paginate);\n const { data } = await client.callEndpoint(\n ep,\n { stk_cd: stk, base_dt: baseDt, upd_stkpc_tp: options.raw ? '0' : '1' },\n { paginate: plan.paginate, maxPages: plan.maxPages },\n );\n emitChart(data, ep, getOutputFormat(options), count);\n }\n\n // chart tick <code>\n chart\n .command('tick <code>')\n .description(`Tick chart (ka10079) — up to ${PER_PAGE_CAP.tick} candles/request, auto-paginates beyond that`)\n .option('-s, --scope <n>', 'Ticks per candle (1/3/5/10/30)', '1')\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 900)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runIntraday(ENDPOINTS.tickChart, 'tick', code, options.scope, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart min <code>\n chart\n .command('min <code>')\n .alias('minute')\n .description(`Minute chart (ka10080) — up to ${PER_PAGE_CAP.minute} candles/request, auto-paginates beyond that`)\n .option('-i, --interval <n>', 'Minutes per candle (1/3/5/10/15/30/45/60)', '1')\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 900)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runIntraday(ENDPOINTS.minuteChart, 'minute', code, options.interval, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart day <code>\n chart\n .command('day <code>')\n .alias('daily')\n .description(`Daily chart (ka10081) — up to ${PER_PAGE_CAP.day} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 600)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.dailyChart, 'day', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart week <code>\n chart\n .command('week <code>')\n .description(`Weekly chart (ka10082) — up to ${PER_PAGE_CAP.week} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 300)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.weeklyChart, 'week', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart month <code>\n chart\n .command('month <code>')\n .description(`Monthly chart (ka10083) — up to ${PER_PAGE_CAP.month} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 240)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.monthlyChart, 'month', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart year <code>\n chart\n .command('year <code>')\n .description(`Yearly chart (ka10094) — up to ${PER_PAGE_CAP.year} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 30)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.yearlyChart, 'year', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst } from '../utils/helpers';\nimport { unpad, won, formatStamp, formatFields } from '../utils/format';\n\n/** Format a value as \"<n>%\" using unpad to strip padding/sign artifacts. */\nconst pct = (v: unknown) => `${unpad(v as string)}%`;\nimport { ACCOUNT_EXCHANGE_TYPES } from '../config/constants';\nimport { emitList } from './market';\n\nexport function registerAccountCommands(program: Command): void {\n const account = program\n .command('account')\n .alias('acct')\n .description('Account — balance, deposit, orders, executions, P/L');\n\n const exchangeHint = `Exchange filter (${ACCOUNT_EXCHANGE_TYPES.join('/')})`;\n\n // account balance\n account\n .command('balance')\n .description('Account evaluation balance with holdings (kt00018)')\n .option('-x, --exchange <KRX|NXT|%>', exchangeHint, 'KRX')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.balance, {\n qry_tp: '1',\n dmst_stex_tp: options.exchange || 'KRX',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n totalPurchase: won(data.tot_pur_amt),\n totalEval: won(data.tot_evlt_amt),\n evalPnl: won(data.tot_evlt_pl),\n profitRate: `${unpad(data.tot_prft_rt)}%`,\n estDepositAsset: won(data.prsm_dpst_aset_amt),\n },\n 'table',\n );\n emitList(data, ENDPOINTS.balance.listKey!, 'table', (row: any) => ({\n code: row.stk_cd,\n name: row.stk_nm,\n qty: won(row.rmnd_qty),\n avgPrice: won(row.pur_pric),\n curPrice: won(row.cur_prc),\n evalAmt: won(row.evlt_amt),\n pnl: won(row.evltv_prft),\n pnlRate: pct(row.prft_rt),\n weight: pct(row.poss_rt),\n }));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account deposit\n account\n .command('deposit')\n .description('Deposit detail — cash, orderable, withdrawable (kt00001)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.deposit, { qry_tp: '3' });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n cash: won(data.entr),\n orderable: won(data.ord_alow_amt),\n withdrawable: won(data.pymn_alow_amt),\n d2Deposit: won(data.d2_entra),\n substitute: won(data.repl_amt),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account eval\n account\n .command('eval')\n .description('Account evaluation status with holdings (kt00004)')\n .option('-x, --exchange <KRX|NXT|%>', exchangeHint, 'KRX')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.evalStatus, {\n qry_tp: '0',\n dmst_stex_tp: options.exchange || 'KRX',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n accountName: data.acnt_nm,\n branch: data.brch_nm,\n deposit: won(data.entr),\n totalEstimate: won(data.tot_est_amt),\n assetEval: won(data.aset_evlt_amt),\n totalPurchase: won(data.tot_pur_amt),\n },\n 'table',\n );\n emitList(data, ENDPOINTS.evalStatus.listKey!, 'table', (row: any) => ({\n code: row.stk_cd,\n name: row.stk_nm,\n qty: won(row.rmnd_qty),\n avgPrice: won(row.avg_prc),\n curPrice: won(row.cur_prc),\n evalAmt: won(row.evlt_amt),\n pnl: won(row.pl_amt),\n pnlRate: pct(row.pl_rt),\n }));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account settled\n account\n .command('settled')\n .description('Settled (executed) balance (kt00005)')\n .option('-x, --exchange <KRX|NXT|%>', exchangeHint, 'KRX')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.settledBalance, {\n dmst_stex_tp: options.exchange || 'KRX',\n });\n emitList(data, 'stk_cntr_remn', getOutputFormat(options), (row: any) => ({\n code: row.stk_cd,\n name: row.stk_nm,\n qty: won(row.cur_qty),\n avgPrice: won(row.buy_uv),\n curPrice: won(row.cur_prc),\n evalAmt: won(row.evlt_amt),\n pnl: won(row.evltv_prft),\n pnlRate: pct(row.pl_rt),\n }));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account open-orders\n account\n .command('open-orders')\n .description('Unfilled (open) orders (ka10075)')\n .option('-c, --code <code>', 'Filter by stock code')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const body = options.code\n ? {\n all_stk_tp: '0',\n trde_tp: '0',\n stk_cd: normalizeStockCode(options.code),\n stex_tp: '0',\n }\n : { all_stk_tp: '1', trde_tp: '0', stk_cd: '', stex_tp: '0' };\n const { data } = await client.callEndpoint(ENDPOINTS.openOrders, body);\n emitList(data, 'oso', getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_nm: (v) => v,\n ord_no: (v) => v,\n ord_qty: won,\n ord_pric: won,\n oso_qty: won,\n cur_prc: unpad,\n tm: formatStamp,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account executions\n account\n .command('executions')\n .description('Filled executions (ka10076)')\n .option('-c, --code <code>', 'Filter by stock code')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.executions, {\n stk_cd: options.code ? normalizeStockCode(options.code) : '',\n qry_tp: options.code ? '1' : '0',\n sell_tp: '0',\n ord_no: '',\n stex_tp: '0',\n });\n emitList(data, 'cntr', getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_nm: (v) => v,\n ord_no: (v) => v,\n cntr_qty: won,\n cntr_uv: won,\n ord_uv: won,\n cnfm_tm: formatStamp,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account order-detail\n account\n .command('order-detail')\n .description('Detailed order/execution history (kt00007)')\n .option('-d, --date <yyyymmdd>', 'Order date', '')\n .option('-c, --code <code>', 'Filter by stock code')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.orderDetail, {\n ord_dt: options.date || '',\n qry_tp: '1',\n stk_bond_tp: '0',\n sell_tp: '0',\n stk_cd: options.code ? normalizeStockCode(options.code) : '',\n fr_ord_no: '',\n dmst_stex_tp: '%',\n });\n emitList(data, 'acnt_ord_cntr_prps_dtl', getOutputFormat(options));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account pnl <code>\n account\n .command('pnl <code>')\n .description('Realized profit/loss by date or period (ka10072 / ka10073)')\n .option('-s, --start <yyyymmdd>', 'Start date')\n .option('-e, --end <yyyymmdd>', 'End date (enables period query, max 3 months)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const ep = options.end ? ENDPOINTS.realizedPlByPeriod : ENDPOINTS.realizedPlByDate;\n const body = options.end\n ? { stk_cd: stk, strt_dt: options.start || options.end, end_dt: options.end }\n : { stk_cd: stk, strt_dt: options.start || todayKst() };\n const { data } = await client.callEndpoint(ep, body);\n emitList(data, ep.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n dt: formatStamp,\n stk_nm: (v) => v,\n cntr_qty: won,\n buy_uv: won,\n cntr_pric: won,\n tdy_sel_pl: won,\n pl_rt: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account journal\n account\n .command('journal')\n .description(\"Today's trading journal with totals (ka10170)\")\n .option('-d, --date <yyyymmdd>', 'Base date', '')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.tradeJournal, {\n base_dt: options.date || '',\n ottks_tp: '1',\n ch_crd_tp: '0',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n totalSell: won(data.tot_sell_amt),\n totalBuy: won(data.tot_buy_amt),\n commissionTax: won(data.tot_cmsn_tax),\n pnl: won(data.tot_pl_amt),\n profitRate: `${unpad(data.tot_prft_rt)}%`,\n },\n 'table',\n );\n emitList(data, 'tdy_trde_diary', 'table');\n } catch (err) {\n handleError(err);\n }\n });\n\n // account returns\n account\n .command('returns')\n .description('Daily account return detail over a period (kt00016)')\n .option('-s, --start <yyyymmdd>', 'Start date (defaults to first of this month)')\n .option('-e, --end <yyyymmdd>', 'End date', todayKst())\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.dailyReturn, {\n fr_dt: options.start || `${todayKst().slice(0, 6)}01`,\n to_dt: options.end || todayKst(),\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n investBase: won(data.invt_bsamt),\n evalProfit: won(data.evltv_prft),\n profitRate: `${unpad(data.prft_rt)}%`,\n turnoverRate: `${unpad(data.tern_rt)}%`,\n totalFrom: won(data.tot_amt_fr),\n totalTo: won(data.tot_amt_to),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { prompt } from './config';\nimport { ENDPOINTS, EndpointDef } from '../client/endpoints';\nimport {\n ORDER_TYPES,\n MARKET_ORDER_TYPES,\n ORDER_EXCHANGE_TYPES,\n OrderExchangeType,\n} from '../config/constants';\nimport { getEffectiveConfig } from '../config/store';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError, ActionableError } from '../output/error';\nimport { normalizeStockCode, parseIntStrict } from '../utils/helpers';\n\nfunction resolveExchange(value: string | undefined): OrderExchangeType {\n const ex = (value ?? 'KRX').toUpperCase();\n if (!ORDER_EXCHANGE_TYPES.includes(ex as OrderExchangeType)) {\n throw new ActionableError(\n `Invalid exchange \"${value}\". Use one of: ${ORDER_EXCHANGE_TYPES.join(', ')}`,\n );\n }\n return ex as OrderExchangeType;\n}\n\n/**\n * Resolve trde_tp + ord_uv from --type/--price:\n * - explicit --type wins;\n * - else a --price implies limit (0), no price implies market (3).\n * Market types must carry an empty ord_uv; limit types require a price.\n */\nfunction resolveOrderType(\n typeOpt: string | undefined,\n priceOpt: string | undefined,\n): { trde_tp: string; ord_uv: string } {\n let trde_tp = typeOpt ?? (priceOpt ? '0' : '3');\n if (!ORDER_TYPES[trde_tp]) {\n throw new ActionableError(\n `Invalid order type \"${trde_tp}\". Known types: ${Object.entries(ORDER_TYPES)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ')}`,\n );\n }\n const isMarket = MARKET_ORDER_TYPES.has(trde_tp);\n if (isMarket) {\n if (priceOpt) {\n throw new ActionableError('Market orders must not specify a price (--price).');\n }\n return { trde_tp, ord_uv: '' };\n }\n if (!priceOpt) {\n throw new ActionableError(\n `Order type ${trde_tp} (${ORDER_TYPES[trde_tp]}) requires --price.`,\n );\n }\n return { trde_tp, ord_uv: priceOpt };\n}\n\nasync function confirm(summary: string, skip: boolean): Promise<boolean> {\n console.log(summary);\n if (skip) return true;\n const answer = await prompt('Proceed? (y/N): ');\n return /^y(es)?$/i.test(answer.trim());\n}\n\nasync function submit(\n def: EndpointDef,\n body: Record<string, unknown>,\n outputFmt: { output?: string },\n): Promise<void> {\n const client = createClient();\n const { data } = await client.callEndpoint(def, body);\n output(\n {\n orderNo: data.ord_no,\n exchange: data.dmst_stex_tp,\n message: data.return_msg,\n },\n getOutputFormat(outputFmt),\n );\n}\n\nexport function registerOrderCommands(program: Command): void {\n const order = program\n .command('order')\n .description('Place / modify / cancel orders (REAL money on the \"real\" environment)');\n\n // order buy <code> <qty>\n order\n .command('buy <code> <qty>')\n .description('Place a buy order')\n .option('-p, --price <won>', 'Limit price; omit for a market order')\n .option('-t, --type <code>', 'Order type code (trde_tp); default 0=limit / 3=market')\n .option('--cond-price <won>', 'Trigger price for conditional/stop types (e.g. type 28)')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing', 'KRX')\n .option('--credit', 'Use a credit (margin) order')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((code, qty, options) => placeOrder('buy', code, qty, options).catch(handleError));\n\n // order sell <code> <qty>\n order\n .command('sell <code> <qty>')\n .description('Place a sell order')\n .option('-p, --price <won>', 'Limit price; omit for a market order')\n .option('-t, --type <code>', 'Order type code (trde_tp); default 0=limit / 3=market')\n .option('--cond-price <won>', 'Trigger price for conditional/stop types (e.g. type 28)')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing', 'KRX')\n .option('--credit', 'Use a credit (margin) order')\n .option('--credit-deal <code>', 'Credit deal type (신용거래구분): 33=융자, 99=융자합', '33')\n .option('--loan-date <yyyymmdd>', 'Credit loan date (required for some credit sells)')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((code, qty, options) => placeOrder('sell', code, qty, options).catch(handleError));\n\n // order modify <orderNo> <code> <qty> <price>\n order\n .command('modify <orderNo> <code> <qty> <price>')\n .description('Modify a resting order (new qty + price)')\n .option('--cond-price <won>', 'New trigger price for conditional/stop orders')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing (must match original)', 'KRX')\n .option('--credit', 'Modify a credit order')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (orderNo, code, qty, price, options) => {\n try {\n const stk = normalizeStockCode(code);\n parseIntStrict(qty, 'qty');\n parseIntStrict(price, 'price');\n const exchange = resolveExchange(options.exchange);\n const def = options.credit ? ENDPOINTS.creditModify : ENDPOINTS.modify;\n const body = {\n dmst_stex_tp: exchange,\n orig_ord_no: orderNo,\n stk_cd: stk,\n mdfy_qty: qty,\n mdfy_uv: price,\n mdfy_cond_uv: options.condPrice ?? '',\n };\n const ok = await confirm(\n `\\nMODIFY ${options.credit ? '(credit) ' : ''}order ${orderNo} ${stk} → qty ${qty} @ ${price} [${exchange}] on ${getEffectiveConfig().env.toUpperCase()}`,\n options.yes,\n );\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n await submit(def, body, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // order cancel <orderNo> <code>\n order\n .command('cancel <orderNo> <code>')\n .description('Cancel a resting order')\n .option('-q, --qty <qty>', 'Quantity to cancel; 0 = all remaining', '0')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing (must match original)', 'KRX')\n .option('--credit', 'Cancel a credit order')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (orderNo, code, options) => {\n try {\n const stk = normalizeStockCode(code);\n parseIntStrict(options.qty, 'qty'); // '0' = all remaining\n const exchange = resolveExchange(options.exchange);\n const def = options.credit ? ENDPOINTS.creditCancel : ENDPOINTS.cancel;\n const body = {\n dmst_stex_tp: exchange,\n orig_ord_no: orderNo,\n stk_cd: stk,\n cncl_qty: options.qty,\n };\n const qtyLabel = options.qty === '0' ? 'ALL remaining' : options.qty;\n const ok = await confirm(\n `\\nCANCEL ${options.credit ? '(credit) ' : ''}order ${orderNo} ${stk} → ${qtyLabel} [${exchange}] on ${getEffectiveConfig().env.toUpperCase()}`,\n options.yes,\n );\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n await submit(def, body, options);\n } catch (err) {\n handleError(err);\n }\n });\n}\n\nasync function placeOrder(\n side: 'buy' | 'sell',\n code: string,\n qty: string,\n options: Record<string, any>,\n): Promise<void> {\n const stk = normalizeStockCode(code);\n parseIntStrict(qty, 'qty');\n const exchange = resolveExchange(options.exchange);\n const { trde_tp, ord_uv } = resolveOrderType(options.type, options.price);\n\n const credit = Boolean(options.credit);\n const def = credit\n ? side === 'buy'\n ? ENDPOINTS.creditBuy\n : ENDPOINTS.creditSell\n : side === 'buy'\n ? ENDPOINTS.buy\n : ENDPOINTS.sell;\n\n const cond_uv = options.condPrice ?? '';\n // Stop-limit (type 28) requires a trigger price; cond_uv is otherwise optional.\n if (trde_tp === '28' && !cond_uv) {\n throw new ActionableError('Stop-limit orders (type 28) require --cond-price <trigger>.');\n }\n const body: Record<string, unknown> = {\n dmst_stex_tp: exchange,\n stk_cd: stk,\n ord_qty: qty,\n ord_uv,\n trde_tp,\n cond_uv,\n };\n if (credit && side === 'sell') {\n body.crd_deal_tp = options.creditDeal ?? '33';\n if (options.loanDate) body.crd_loan_dt = options.loanDate;\n }\n\n const priceLabel = MARKET_ORDER_TYPES.has(trde_tp) ? 'MARKET' : `@ ${ord_uv}`;\n const env = getEffectiveConfig().env;\n const summary =\n `\\n${side.toUpperCase()} ${credit ? '(credit) ' : ''}${stk} qty ${qty} ${priceLabel}` +\n ` type ${trde_tp}(${ORDER_TYPES[trde_tp]}) [${exchange}] on ${env.toUpperCase()}` +\n (env === 'real' ? ' ⚠ REAL MONEY' : '');\n\n const ok = await confirm(summary, options.yes);\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n await submit(def, body, options);\n}\n\n// Exposed for unit testing the body-construction logic without network calls.\nexport const _internal = { resolveExchange, resolveOrderType };\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { unpad, won, formatFields } from '../utils/format';\nimport { emitList } from './market';\n\n/** Shared row formatter for ranking tables (signed prices/rates unpadded, quantities/amounts comma-grouped). */\nfunction formatRankRow(row: Record<string, unknown>): Record<string, unknown> {\n return formatFields(row, {\n stk_cd: (v) => v,\n stk_nm: (v) => v,\n cur_prc: unpad,\n flu_rt: unpad,\n pred_pre: unpad,\n trde_qty: won,\n now_trde_qty: won,\n trde_prica: won,\n trde_amt: won,\n sdnin_rt: unpad,\n });\n}\n\nexport function registerRankingCommands(program: Command): void {\n const ranking = program\n .command('ranking')\n .alias('rank')\n .description('Ranking lists — gainers, volume, value');\n\n // ranking fluctuation\n ranking\n .command('fluctuation')\n .alias('gainers')\n .description('Price change rate ranking (ka10027)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-s, --sort <1-5>', 'Sort: 1=상승률, 2=상승폭, 3=하락률, 4=하락폭, 5=보합', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankFluctuation, {\n mrkt_tp: options.market,\n sort_tp: options.sort || '1',\n trde_qty_cnd: '0000',\n stk_cnd: '0',\n crd_cnd: '0',\n updown_incls: '1',\n pric_cnd: '0',\n trde_prica_cnd: '0',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankFluctuation.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking volume\n ranking\n .command('volume')\n .description('Today volume ranking (ka10030)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-s, --sort <1-3>', 'Sort: 1=거래량, 2=거래회전율, 3=거래대금', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankVolume, {\n mrkt_tp: options.market,\n sort_tp: options.sort || '1',\n mang_stk_incls: '0',\n crd_tp: '0',\n trde_qty_tp: '0',\n pric_tp: '0',\n trde_prica_tp: '0',\n mrkt_open_tp: '0',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankVolume.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking amount\n ranking\n .command('amount')\n .alias('value')\n .description('Trade value (거래대금) ranking (ka10032)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankTradeAmount, {\n mrkt_tp: options.market,\n mang_stk_incls: '1',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankTradeAmount.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking surge\n ranking\n .command('surge')\n .description('Volume surge (거래량급증) ranking (ka10023)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-s, --sort <1-4>', 'Sort type', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankVolumeSurge, {\n mrkt_tp: options.market,\n sort_tp: options.sort || '1',\n tm_tp: '2',\n trde_qty_tp: '5',\n tm: '',\n stk_cnd: '0',\n pric_tp: '0',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankVolumeSurge.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking prev-volume\n ranking\n .command('prev-volume')\n .description('Previous-day volume ranking (ka10031)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('--query <1|2>', 'Query type', '1')\n .option('--from <n>', 'Rank start', '0')\n .option('--to <n>', 'Rank end', '100')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankPrevVolume, {\n mrkt_tp: options.market,\n qry_tp: options.query || '1',\n rank_strt: options.from || '0',\n rank_end: options.to || '100',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankPrevVolume.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { unpad, won, formatStamp, formatFields } from '../utils/format';\nimport { emitList } from './market';\n\nexport function registerSectorCommands(program: Command): void {\n const sector = program\n .command('sector')\n .alias('industry')\n .description('Sector / industry indices');\n\n const withSharedOptions = (cmd: Command): Command =>\n cmd\n .option('-m, --market <0|1|2>', 'Market: 0=KOSPI, 1=KOSDAQ, 2=KOSPI200', '0')\n .option('-c, --code <inds_cd>', 'Industry code (001=종합KOSPI, 101=종합KOSDAQ)', '001')\n .option('-o, --output <format>', 'Output format (table/json)', 'table');\n\n // sector price\n withSharedOptions(sector.command('price').description('Sector index snapshot (ka20001)')).action(\n async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorPrice, {\n mrkt_tp: options.market || '0',\n inds_cd: options.code || '001',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n price: unpad(data.cur_prc),\n change: unpad(data.pred_pre),\n changeRate: `${unpad(data.flu_rt)}%`,\n open: unpad(data.open_pric),\n high: unpad(data.high_pric),\n low: unpad(data.low_pric),\n volume: won(data.trde_qty),\n rising: data.rising,\n falling: data.fall,\n },\n 'table',\n );\n emitList(data, ENDPOINTS.sectorPrice.listKey!, 'table', (row) =>\n formatFields(row, {\n tm_n: formatStamp,\n cur_prc_n: unpad,\n trde_qty_n: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n },\n );\n\n // sector stocks\n withSharedOptions(\n sector.command('stocks').description('Stock prices within a sector (ka20002)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorStocks, {\n mrkt_tp: options.market || '0',\n inds_cd: options.code || '001',\n stex_tp: '1',\n });\n emitList(data, ENDPOINTS.sectorStocks.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_cd: (v) => v,\n stk_nm: (v) => v,\n cur_prc: unpad,\n flu_rt: unpad,\n now_trde_qty: won,\n open_pric: unpad,\n high_pric: unpad,\n low_pric: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // sector all\n withSharedOptions(\n sector.command('all').description('All sector indices (ka20003)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorAllIndex, {\n inds_cd: options.code || '001',\n });\n emitList(data, ENDPOINTS.sectorAllIndex.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_cd: (v) => v,\n stk_nm: (v) => v,\n cur_prc: unpad,\n flu_rt: unpad,\n trde_qty: won,\n trde_prica: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // sector daily\n withSharedOptions(\n sector.command('daily').description('Sector index daily history (ka20009)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorDaily, {\n mrkt_tp: options.market || '0',\n inds_cd: options.code || '001',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n price: unpad(data.cur_prc),\n changeRate: `${unpad(data.flu_rt)}%`,\n open: unpad(data.open_pric),\n high: unpad(data.high_pric),\n low: unpad(data.low_pric),\n },\n 'table',\n );\n emitList(data, ENDPOINTS.sectorDaily.listKey!, 'table', (row) =>\n formatFields(row, {\n dt_n: formatStamp,\n cur_prc_n: unpad,\n flu_rt_n: unpad,\n acc_trde_qty_n: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // sector codes\n withSharedOptions(\n sector.command('codes').description('Valid industry codes per market (ka10101)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(\n ENDPOINTS.sectorCodeList,\n { mrkt_tp: options.market || '0' },\n { paginate: true },\n );\n emitList(data, ENDPOINTS.sectorCodeList.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n marketCode: (v) => v,\n code: (v) => v,\n name: (v) => v,\n group: (v) => v,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n"],"mappings":"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","names":["path","program","program","program","program","program","program","program","price","program","program"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/config.ts","../src/config/store.ts","../src/config/constants.ts","../src/output/error.ts","../src/utils/helpers.ts","../src/client/api-client.ts","../src/output/formatter.ts","../src/commands/_helpers.ts","../src/utils/format.ts","../src/commands/auth.ts","../src/client/endpoints.ts","../src/utils/orderbook.ts","../src/commands/market.ts","../src/commands/stock.ts","../src/commands/chart.ts","../src/commands/account.ts","../src/commands/order.ts","../src/utils/ranking.ts","../src/commands/ranking.ts","../src/commands/sector.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerConfigCommands } from './commands/config';\nimport { registerAuthCommands } from './commands/auth';\nimport { registerStockCommands } from './commands/stock';\nimport { registerMarketCommands } from './commands/market';\nimport { registerChartCommands } from './commands/chart';\nimport { registerAccountCommands } from './commands/account';\nimport { registerOrderCommands } from './commands/order';\nimport { registerRankingCommands } from './commands/ranking';\nimport { registerSectorCommands } from './commands/sector';\n\nconst program = new Command();\n\nprogram\n .name('kiwoom-cli')\n .description('CLI for Kiwoom Securities (키움증권) — quotes, charts, account, and orders')\n .version('0.1.0');\n\nprogram.exitOverride((err) => {\n if (err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {\n process.exit(0);\n }\n process.exit(1);\n});\n\nregisterConfigCommands(program);\nregisterAuthCommands(program);\nregisterStockCommands(program);\nregisterMarketCommands(program);\nregisterChartCommands(program);\nregisterAccountCommands(program);\nregisterOrderCommands(program);\nregisterRankingCommands(program);\nregisterSectorCommands(program);\n\nprogram.parseAsync(process.argv).catch(() => {\n // Command actions handle their own errors via handleError().\n process.exit(1);\n});\n","import { Command } from 'commander';\nimport * as readline from 'readline';\nimport { CliConfig, saveConfig, getEffectiveConfig, maskSecret } from '../config/store';\nimport { ENV_ALIASES, Environment } from '../config/constants';\nimport { KiwoomClient } from '../client/api-client';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\n\n/** Read a line from stdin, optionally masking the echoed characters. */\nexport function prompt(question: string, hidden = false): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n if (hidden) {\n process.stdout.write(question);\n const stdin = process.stdin;\n const wasRaw = stdin.isRaw;\n if (stdin.isTTY) stdin.setRawMode(true);\n let input = '';\n const onData = (char: Buffer) => {\n const c = char.toString();\n const code = char[0];\n if (c === '\\n' || c === '\\r') {\n stdin.removeListener('data', onData);\n if (stdin.isTTY) stdin.setRawMode(wasRaw ?? false);\n process.stdout.write('\\n');\n rl.close();\n resolve(input);\n } else if (code === 3) {\n // Ctrl-C\n process.exit(0);\n } else if (code === 127 || code === 8) {\n // Backspace / DEL\n if (input.length > 0) {\n input = input.slice(0, -1);\n process.stdout.write('\\b \\b');\n }\n } else {\n input += c;\n process.stdout.write('*');\n }\n };\n stdin.on('data', onData);\n } else {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n }\n });\n}\n\nasync function verifyAndCacheToken(env: Environment, appkey: string, secretkey: string): Promise<void> {\n try {\n const client = new KiwoomClient({ env, appkey, secretkey });\n await client.authenticate();\n console.log('Access token issued and cached.');\n } catch (err) {\n console.error(\n `\\nKeys saved, but token issuance failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n console.error('Double-check the app key / secret key and environment.');\n }\n}\n\nexport function registerConfigCommands(program: Command): void {\n const configCmd = program.command('config').description('Manage CLI configuration (keys, environment)');\n\n configCmd\n .command('init')\n .description('Interactive setup wizard')\n .action(async () => {\n try {\n console.log('Kiwoom CLI Setup\\n');\n const envInput = await prompt('Environment (real/mock) [real]: ');\n const env = ENV_ALIASES[envInput.toLowerCase()] ?? 'real';\n const appkey = await prompt('App key: ');\n if (!appkey) {\n console.error('App key is required.');\n process.exit(1);\n }\n const secretkey = await prompt('Secret key: ', true);\n if (!secretkey) {\n console.error('Secret key is required.');\n process.exit(1);\n }\n saveConfig({ env, appkey, secretkey });\n console.log('\\nConfiguration saved to ~/.kiwoom-cli/config.json');\n if (env === 'real') {\n console.log('NOTE: \"real\" places live orders with real money. Use \"mock\" to practice.');\n }\n await verifyAndCacheToken(env, appkey, secretkey);\n } catch (err) {\n handleError(err);\n }\n });\n\n configCmd\n .command('set')\n .description('Set configuration values')\n .option('--env <environment>', 'Environment (real/mock)')\n .option('--appkey <key>', 'Kiwoom app key')\n .option('--secretkey <key>', 'Kiwoom secret key')\n .action(async (options) => {\n try {\n const updates: Partial<CliConfig> = {};\n if (options.env) {\n const resolved = ENV_ALIASES[options.env.toLowerCase()];\n if (!resolved) {\n console.error(`Unknown environment: ${options.env}. Use: real, mock`);\n process.exit(1);\n }\n updates.env = resolved;\n }\n if (options.appkey) updates.appkey = options.appkey;\n if (options.secretkey) updates.secretkey = options.secretkey;\n if (Object.keys(updates).length === 0) {\n console.log('No values to set. Use --env, --appkey, or --secretkey');\n return;\n }\n saveConfig(updates);\n console.log('Configuration updated.');\n const cfg = getEffectiveConfig();\n if ((updates.appkey || updates.secretkey) && cfg.appkey && cfg.secretkey) {\n await verifyAndCacheToken(cfg.env, cfg.appkey, cfg.secretkey);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n configCmd\n .command('get <key>')\n .description('Get a configuration value (env, appkey, secretkey)')\n .action((key: string) => {\n try {\n const config = getEffectiveConfig();\n const value = (config as unknown as Record<string, unknown>)[key];\n if (value === undefined) {\n console.log(`Key \"${key}\" not found. Available: env, appkey, secretkey`);\n } else if (key === 'secretkey' || key === 'appkey') {\n console.log(maskSecret(value as string));\n } else {\n console.log(String(value));\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n configCmd\n .command('list')\n .description('Show all configuration')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((options) => {\n try {\n const config = getEffectiveConfig();\n output(\n {\n env: config.env,\n appkey: maskSecret(config.appkey),\n secretkey: maskSecret(config.secretkey),\n },\n getOutputFormat(options),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n CONFIG_DIR_NAME,\n CONFIG_FILE_NAME,\n TOKEN_FILE_NAME,\n ENV_VARS,\n ENV_ALIASES,\n Environment,\n} from './constants';\n\nexport interface CliConfig {\n env: Environment;\n appkey?: string;\n secretkey?: string;\n}\n\nexport interface CachedToken {\n token: string;\n /** Kiwoom expiry stamp, \"YYYYMMDDHHmmss\" in KST. */\n expiresDt: string;\n /** First 6 chars of the appkey the token was issued for (cache-invalidation guard). */\n appkeyHint: string;\n}\n\n/** token.json holds one cached token per environment. */\ntype TokenCache = Partial<Record<Environment, CachedToken>>;\n\nconst DEFAULT_CONFIG: CliConfig = { env: 'real' };\n\nfunction getConfigDir(): string {\n return path.join(os.homedir(), CONFIG_DIR_NAME);\n}\n\nfunction getConfigPath(): string {\n return path.join(getConfigDir(), CONFIG_FILE_NAME);\n}\n\nfunction getTokenPath(): string {\n return path.join(getConfigDir(), TOKEN_FILE_NAME);\n}\n\nfunction ensureConfigDir(): void {\n const dir = getConfigDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { mode: 0o700, recursive: true });\n } else {\n // Tighten perms even if the dir pre-existed with looser permissions.\n try {\n fs.chmodSync(dir, 0o700);\n } catch {\n /* best effort */\n }\n }\n}\n\n/**\n * Write a secrets file with 0600 perms. `writeFileSync`'s mode only applies when\n * the file is newly created, so chmod afterward to tighten a pre-existing file\n * that may have looser permissions.\n */\nfunction writeSecure(filePath: string, data: string): void {\n fs.writeFileSync(filePath, data, { mode: 0o600 });\n try {\n fs.chmodSync(filePath, 0o600);\n } catch {\n /* best effort */\n }\n}\n\n// ─── Config ───────────────────────────────────────────────────────────────\n\nexport function loadConfig(): CliConfig {\n try {\n const raw = fs.readFileSync(getConfigPath(), 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(partial: Partial<CliConfig>): void {\n ensureConfigDir();\n const current = loadConfig();\n const merged = { ...current, ...partial };\n writeSecure(getConfigPath(), JSON.stringify(merged, null, 2));\n}\n\n/**\n * Resolve the effective config: config file first, environment variables as a\n * fallback for any unset secret.\n */\nexport function getEffectiveConfig(): CliConfig {\n const disk = loadConfig();\n const envVal = process.env[ENV_VARS.env];\n const env: Environment =\n envVal && ENV_ALIASES[envVal.toLowerCase()]\n ? ENV_ALIASES[envVal.toLowerCase()]\n : disk.env;\n return {\n env,\n appkey: disk.appkey ?? process.env[ENV_VARS.appkey],\n secretkey: disk.secretkey ?? process.env[ENV_VARS.secretkey],\n };\n}\n\nexport function maskSecret(value: string | undefined): string {\n if (!value) return '(not set)';\n if (value.length <= 10) return '****';\n return value.slice(0, 6) + '...' + value.slice(-4);\n}\n\n// ─── Token cache ────────────────────────────────────────────────────────────\n\nfunction loadTokenCache(): TokenCache {\n try {\n return JSON.parse(fs.readFileSync(getTokenPath(), 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function getCachedToken(env: Environment): CachedToken | undefined {\n return loadTokenCache()[env];\n}\n\nexport function saveCachedToken(env: Environment, token: CachedToken): void {\n ensureConfigDir();\n const cache = loadTokenCache();\n cache[env] = token;\n writeSecure(getTokenPath(), JSON.stringify(cache, null, 2));\n}\n\nexport function clearCachedToken(env?: Environment): void {\n if (!env) {\n try {\n fs.rmSync(getTokenPath());\n } catch {\n /* nothing to clear */\n }\n return;\n }\n const cache = loadTokenCache();\n delete cache[env];\n try {\n ensureConfigDir();\n writeSecure(getTokenPath(), JSON.stringify(cache, null, 2));\n } catch {\n /* ignore */\n }\n}\n\n/** Expose paths for diagnostics/tests. */\nexport const _paths = { getConfigDir, getConfigPath, getTokenPath };\n","export type Environment = 'real' | 'mock';\n\n/** API host per environment. */\nexport const BASE_URLS: Record<Environment, string> = {\n real: 'https://api.kiwoom.com',\n mock: 'https://mockapi.kiwoom.com',\n};\n\n/** Accepted aliases for the environment, including Korean labels. */\nexport const ENV_ALIASES: Record<string, Environment> = {\n real: 'real',\n prod: 'real',\n production: 'real',\n live: 'real',\n 실전: 'real',\n 실전투자: 'real',\n mock: 'mock',\n test: 'mock',\n paper: 'mock',\n demo: 'mock',\n 모의: 'mock',\n 모의투자: 'mock',\n};\n\n/** OAuth2 endpoints (relative to the environment base URL). */\nexport const TOKEN_PATH = '/oauth2/token';\nexport const REVOKE_PATH = '/oauth2/revoke';\n\n/** Config + token-cache storage. */\nexport const CONFIG_DIR_NAME = '.kiwoom-cli';\nexport const CONFIG_FILE_NAME = 'config.json';\nexport const TOKEN_FILE_NAME = 'token.json';\n\n/** Environment variables used as a fallback when the config file is unset. */\nexport const ENV_VARS = {\n appkey: 'KIWOOM_APPKEY',\n secretkey: 'KIWOOM_SECRETKEY',\n env: 'KIWOOM_ENV',\n} as const;\n\n/** Re-issue a cached token if it expires within this many milliseconds. */\nexport const TOKEN_REFRESH_BUFFER_MS = 60_000;\n\n/** HTTP request timeout. */\nexport const REQUEST_TIMEOUT_MS = 30_000;\n\n/**\n * `return_code` values that signal \"no matching data\" rather than a real error.\n * The API returns 20 ([2000] 관련자료가없습니다) for empty result sets; callers\n * should receive the (empty) payload, not an exception.\n */\nexport const SOFT_EMPTY_RETURN_CODES = new Set<number>([20]);\n\n/** Exchange routing for ORDER TRs (dmst_stex_tp): best-execution SOR allowed. */\nexport const ORDER_EXCHANGE_TYPES = ['KRX', 'NXT', 'SOR'] as const;\nexport type OrderExchangeType = (typeof ORDER_EXCHANGE_TYPES)[number];\n\n/** Exchange filter for ACCOUNT query TRs (dmst_stex_tp): % = all exchanges. */\nexport const ACCOUNT_EXCHANGE_TYPES = ['KRX', 'NXT', '%'] as const;\nexport type AccountExchangeType = (typeof ACCOUNT_EXCHANGE_TYPES)[number];\n\n/**\n * trde_tp (매매구분 / order-type) codes for buy/sell orders, from the Kiwoom\n * spec. NOTE: 7 = 최우선지정가 (the assignment's \"8\" is wrong). Market types\n * (3/13/23) must be sent with an empty ord_uv.\n */\nexport const ORDER_TYPES: Record<string, string> = {\n '0': '보통(지정가/limit)',\n '3': '시장가(market)',\n '5': '조건부지정가',\n '6': '최유리지정가',\n '7': '최우선지정가',\n '10': '보통(IOC)',\n '13': '시장가(IOC)',\n '16': '최유리(IOC)',\n '20': '보통(FOK)',\n '23': '시장가(FOK)',\n '26': '최유리(FOK)',\n '28': '스톱지정가(stop-limit)',\n '29': '중간가',\n '30': '중간가(IOC)',\n '31': '중간가(FOK)',\n '61': '장시작전시간외',\n '62': '시간외단일가',\n '81': '장마감후시간외',\n};\n\n/** trde_tp codes that are market-style (price must be empty). */\nexport const MARKET_ORDER_TYPES = new Set(['3', '13', '23']);\n\n/**\n * Maximum candles a single chart TR returns (one page). Larger `--count` /\n * `count` values are satisfied by paging on the response `cont-yn` / `next-key`\n * headers (handled by KiwoomClient.requestAll). Verified against the official\n * spec: tick/minute 900, day 600, week 300, month 240, year 30.\n */\nexport const CHART_PER_PAGE_CAP = {\n tick: 900,\n minute: 900,\n day: 600,\n week: 300,\n month: 240,\n year: 30,\n} as const;\n\nexport type ChartType = keyof typeof CHART_PER_PAGE_CAP;\n\n/**\n * Upper bound on the candle count a single command/tool invocation may request,\n * so a typo can't trigger an unbounded paginate loop. Counts above this are\n * clamped (CLI) or rejected by the schema (MCP).\n */\nexport const CHART_MAX_COUNT = 100000;\n","/**\n * An error that carries a suggested recovery command, surfaced to the user as\n * a \"Try: ...\" hint.\n */\nexport class ActionableError extends Error {\n suggestedCommand?: string;\n\n constructor(message: string, suggestedCommand?: string) {\n super(message);\n this.name = 'ActionableError';\n this.suggestedCommand = suggestedCommand;\n }\n}\n\n/**\n * An error raised when the Kiwoom API returns a non-zero return_code.\n */\nexport class KiwoomApiError extends Error {\n returnCode: number;\n returnMsg: string;\n apiId?: string;\n\n constructor(returnCode: number, returnMsg: string, apiId?: string) {\n super(`[${returnCode}] ${returnMsg}`);\n this.name = 'KiwoomApiError';\n this.returnCode = returnCode;\n this.returnMsg = returnMsg;\n this.apiId = apiId;\n }\n}\n\nexport function handleError(err: unknown): never {\n if (err instanceof ActionableError) {\n console.error(`\\nError: ${err.message}`);\n if (err.suggestedCommand) {\n console.error(`\\nTry: ${err.suggestedCommand}`);\n }\n process.exit(1);\n }\n\n if (err instanceof KiwoomApiError) {\n console.error(`\\nError: ${err.returnMsg} (code ${err.returnCode})`);\n if (isAuthError(err.returnMsg) || err.returnCode === 3) {\n console.error(`\\nTry: kiwoom-cli config init`);\n }\n process.exit(1);\n }\n\n if (err instanceof Error) {\n let message = err.message;\n if (message.length > 500) {\n message = message.slice(0, 500) + '...';\n }\n if (isAuthError(message)) {\n console.error(`\\nError: ${message}`);\n console.error(`\\nTry: kiwoom-cli config init`);\n process.exit(1);\n }\n console.error(`\\nError: ${message}`);\n process.exit(1);\n }\n\n console.error(`\\nUnknown error:`, err);\n process.exit(1);\n}\n\nfunction isAuthError(message: string): boolean {\n return /unauthorized|forbidden|not authenticated|토큰|인증|appkey|access token|만료/i.test(\n message,\n );\n}\n\nexport function requireConfig(\n value: string | undefined,\n name: string,\n setCommand: string,\n): asserts value is string {\n if (!value) {\n throw new ActionableError(\n `${name} is not configured.`,\n `kiwoom-cli config set ${setCommand}`,\n );\n }\n}\n","import { ActionableError } from '../output/error';\n\n/** Parse an integer strictly, throwing on failure. */\nexport function parseIntStrict(value: string, name: string): number {\n const n = parseInt(value, 10);\n if (Number.isNaN(n)) {\n throw new Error(`Invalid ${name}: \"${value}\" is not a valid integer`);\n }\n return n;\n}\n\n/** Parse a float strictly, throwing on failure. */\nexport function parseFloatStrict(value: string, name: string): number {\n const n = parseFloat(value);\n if (Number.isNaN(n)) {\n throw new Error(`Invalid ${name}: \"${value}\" is not a valid number`);\n }\n return n;\n}\n\n/**\n * Normalize a Korean stock code to the 6-digit form the API expects.\n * Accepts \"005930\", \"A005930\" (response form), or \"005930_AL\" style suffixes.\n */\nexport function normalizeStockCode(code: string): string {\n const trimmed = code.trim().toUpperCase();\n const stripped = trimmed.replace(/^A(?=\\d)/, '');\n const base = stripped.split('_')[0];\n if (!/^\\d{6}$/.test(base)) {\n throw new ActionableError(\n `Invalid stock code \"${code}\". Expected a 6-digit code like 005930 (삼성전자).`,\n );\n }\n return base;\n}\n\n/**\n * Parse a Kiwoom expiry stamp (\"YYYYMMDDHHmmss\", Korea Standard Time) into\n * epoch milliseconds.\n */\nexport function parseKiwoomExpiry(expiresDt: string): number {\n const m = expiresDt.match(/^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})$/);\n if (!m) return NaN;\n const [, y, mo, d, h, mi, s] = m;\n // KST is UTC+9, no DST.\n return Date.parse(`${y}-${mo}-${d}T${h}:${mi}:${s}+09:00`);\n}\n\n/** True if the token is expired or will expire within `bufferMs`. */\nexport function isTokenExpired(expiresDt: string, bufferMs = 0): boolean {\n const expiry = parseKiwoomExpiry(expiresDt);\n if (Number.isNaN(expiry)) return true;\n return Date.now() + bufferMs >= expiry;\n}\n\n/** Today's date in KST as \"YYYYMMDD\". */\nexport function todayKst(): string {\n const now = new Date(Date.now() + 9 * 3600 * 1000);\n return now.toISOString().slice(0, 10).replace(/-/g, '');\n}\n","import {\n BASE_URLS,\n TOKEN_PATH,\n REVOKE_PATH,\n TOKEN_REFRESH_BUFFER_MS,\n REQUEST_TIMEOUT_MS,\n SOFT_EMPTY_RETURN_CODES,\n Environment,\n} from '../config/constants';\nimport {\n getCachedToken,\n saveCachedToken,\n clearCachedToken,\n} from '../config/store';\nimport { isTokenExpired } from '../utils/helpers';\nimport { KiwoomApiError, ActionableError } from '../output/error';\nimport { EndpointDef } from './endpoints';\n\n/** Result of a TR request, with pagination metadata from the response headers. */\nexport interface TrResponse<T = Record<string, any>> {\n data: T;\n /** True when more pages are available (response header `cont-yn` === 'Y'). */\n contYn: boolean;\n /** Cursor to pass back as `next-key` to fetch the next page. */\n nextKey: string;\n}\n\nexport interface RequestOptions {\n /** Pass 'Y' (with nextKey) to continue a paginated query. */\n contYn?: string;\n nextKey?: string;\n /** Override the api-id header (defaults to the one in the registry call). */\n apiId?: string;\n}\n\nexport interface ClientOptions {\n env: Environment;\n appkey?: string;\n secretkey?: string;\n /** Explicit token; bypasses issuance/caching when provided. */\n token?: string;\n}\n\nfunction fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timeoutId),\n );\n}\n\n/**\n * Kiwoom Securities REST API client.\n *\n * Handles OAuth2 token issuance + caching and routes every TR through a single\n * POST with the api-id header. Tokens are cached per environment on disk so\n * separate CLI invocations reuse them until expiry.\n */\nexport class KiwoomClient {\n private env: Environment;\n private baseUrl: string;\n private appkey?: string;\n private secretkey?: string;\n private tokenOverride?: string;\n private memoToken?: string;\n\n constructor(opts: ClientOptions) {\n this.env = opts.env;\n this.baseUrl = BASE_URLS[opts.env];\n if (!this.baseUrl) {\n throw new Error(`Invalid environment: ${opts.env}. Use: real, mock`);\n }\n this.appkey = opts.appkey;\n this.secretkey = opts.secretkey;\n this.tokenOverride = opts.token;\n }\n\n getEnv(): Environment {\n return this.env;\n }\n\n /** Ensure a valid token exists (issuing + caching as needed) and return it. */\n async authenticate(): Promise<string> {\n return this.getToken();\n }\n\n // ─── OAuth2 ───────────────────────────────────────────────────────────────\n\n /** Issue a fresh access token from the app key + secret key. */\n async issueToken(): Promise<{ token: string; expiresDt: string }> {\n if (!this.appkey || !this.secretkey) {\n throw new ActionableError(\n 'App key and secret key are required to issue a token.',\n 'kiwoom-cli config init',\n );\n }\n const res = await fetchWithTimeout(`${this.baseUrl}${TOKEN_PATH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json;charset=UTF-8' },\n body: JSON.stringify({\n grant_type: 'client_credentials',\n appkey: this.appkey,\n secretkey: this.secretkey,\n }),\n });\n const body = (await res.json().catch(() => ({}))) as Record<string, any>;\n if (!res.ok || body.return_code !== 0 || !body.token) {\n throw new KiwoomApiError(\n body.return_code ?? res.status,\n body.return_msg ?? `Token request failed (HTTP ${res.status})`,\n );\n }\n return { token: body.token, expiresDt: body.expires_dt };\n }\n\n /** Revoke an access token (defaults to the cached/override token). */\n async revokeToken(token?: string): Promise<Record<string, any>> {\n if (!this.appkey || !this.secretkey) {\n throw new ActionableError(\n 'App key and secret key are required to revoke a token.',\n 'kiwoom-cli config init',\n );\n }\n const target = token ?? this.tokenOverride ?? getCachedToken(this.env)?.token;\n if (!target) {\n throw new ActionableError('No token to revoke.');\n }\n const res = await fetchWithTimeout(`${this.baseUrl}${REVOKE_PATH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json;charset=UTF-8' },\n body: JSON.stringify({\n appkey: this.appkey,\n secretkey: this.secretkey,\n token: target,\n }),\n });\n const body = (await res.json().catch(() => ({}))) as Record<string, any>;\n if (!res.ok || body.return_code !== 0) {\n throw new KiwoomApiError(\n body.return_code ?? res.status,\n body.return_msg ?? `Token revoke failed (HTTP ${res.status})`,\n );\n }\n clearCachedToken(this.env);\n return body;\n }\n\n /**\n * Return a valid token, reusing the cache when possible and issuing+caching a\n * new one when missing or near expiry.\n */\n private async getToken(): Promise<string> {\n if (this.tokenOverride) return this.tokenOverride;\n if (this.memoToken) return this.memoToken;\n\n const cached = getCachedToken(this.env);\n const hint = this.appkey?.slice(0, 6);\n if (\n cached &&\n cached.appkeyHint === hint &&\n !isTokenExpired(cached.expiresDt, TOKEN_REFRESH_BUFFER_MS)\n ) {\n this.memoToken = cached.token;\n return cached.token;\n }\n\n const { token, expiresDt } = await this.issueToken();\n this.memoToken = token;\n if (hint) {\n saveCachedToken(this.env, { token, expiresDt, appkeyHint: hint });\n }\n return token;\n }\n\n // ─── Generic TR request ──────────────────────────────────────────────────\n\n /**\n * Execute a TR. `apiId` is sent in the api-id header; `path` is the category\n * route (e.g. /api/dostk/stkinfo). Returns the parsed body plus pagination.\n */\n async request<T = Record<string, any>>(\n apiId: string,\n path: string,\n body: Record<string, unknown> = {},\n options: RequestOptions = {},\n ): Promise<TrResponse<T>> {\n const send = async (token: string): Promise<Response> =>\n fetchWithTimeout(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json;charset=UTF-8',\n authorization: `Bearer ${token}`,\n 'api-id': options.apiId ?? apiId,\n 'cont-yn': options.contYn ?? 'N',\n 'next-key': options.nextKey ?? '',\n },\n body: JSON.stringify(body),\n });\n\n let res = await send(await this.getToken());\n\n // Token might have been revoked/expired server-side: clear and retry once.\n if (res.status === 401 && !this.tokenOverride) {\n clearCachedToken(this.env);\n this.memoToken = undefined;\n res = await send(await this.getToken());\n }\n\n const payload = (await res.json().catch(() => ({}))) as Record<string, any>;\n if (!res.ok) {\n throw new KiwoomApiError(\n payload.return_code ?? res.status,\n payload.return_msg ?? `Request failed (HTTP ${res.status})`,\n apiId,\n );\n }\n if (\n typeof payload.return_code === 'number' &&\n payload.return_code !== 0 &&\n !SOFT_EMPTY_RETURN_CODES.has(payload.return_code)\n ) {\n throw new KiwoomApiError(payload.return_code, payload.return_msg ?? 'Error', apiId);\n }\n\n return {\n data: payload as T,\n contYn: res.headers.get('cont-yn') === 'Y',\n nextKey: res.headers.get('next-key') ?? '',\n };\n }\n\n /**\n * Execute an endpoint from the registry. When `paginate` is set and the\n * endpoint declares a listKey, all pages are fetched and concatenated.\n */\n async callEndpoint<T = Record<string, any>>(\n def: EndpointDef,\n body: Record<string, unknown> = {},\n opts: { paginate?: boolean; contYn?: string; nextKey?: string; maxPages?: number } = {},\n ): Promise<TrResponse<T>> {\n if (opts.paginate && def.listKey) {\n const data = await this.requestAll<T>(def.apiId, def.path, body, def.listKey, opts.maxPages);\n return { data, contYn: false, nextKey: '' };\n }\n return this.request<T>(def.apiId, def.path, body, {\n contYn: opts.contYn,\n nextKey: opts.nextKey,\n });\n }\n\n /**\n * Fetch all pages of a TR, concatenating the array under `listKey`.\n * Caps at `maxPages` to avoid runaway loops (default 100 — high enough for\n * large chart pulls; callers pass a tighter bound when they know how many\n * pages a target row count needs).\n */\n async requestAll<T = Record<string, any>>(\n apiId: string,\n path: string,\n body: Record<string, unknown>,\n listKey: string,\n maxPages = 100,\n ): Promise<T> {\n let page = await this.request<Record<string, any>>(apiId, path, body);\n const acc = Array.isArray(page.data[listKey]) ? [...page.data[listKey]] : [];\n let pages = 1;\n while (page.contYn && page.nextKey && pages < maxPages) {\n page = await this.request<Record<string, any>>(apiId, path, body, {\n contYn: 'Y',\n nextKey: page.nextKey,\n });\n if (Array.isArray(page.data[listKey])) acc.push(...page.data[listKey]);\n pages += 1;\n }\n return { ...page.data, [listKey]: acc } as T;\n }\n}\n","export type OutputFormat = 'json' | 'table';\n\nexport function getOutputFormat(options: { output?: string }): OutputFormat {\n return options.output === 'json' ? 'json' : 'table';\n}\n\n/**\n * Render data to stdout. `json` prints the raw payload; `table` prints arrays\n * via console.table and objects as aligned key/value pairs.\n */\nexport function output(data: unknown, format: OutputFormat = 'table'): void {\n if (format === 'json') {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log('No data');\n return;\n }\n if (typeof data[0] === 'object' && data[0] !== null) {\n console.table(data);\n } else {\n for (const item of data) console.log(` ${String(item)}`);\n }\n return;\n }\n\n if (data !== null && typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) {\n console.log('No data');\n return;\n }\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n for (const [key, value] of entries) {\n const displayValue =\n value !== null && typeof value === 'object'\n ? JSON.stringify(value)\n : String(value);\n console.log(` ${key.padEnd(maxKeyLen + 2)} ${displayValue}`);\n }\n return;\n }\n\n console.log(String(data));\n}\n\n/** Print a list of objects as a table, or \"No data\" when empty. */\nexport function outputTable(rows: Record<string, unknown>[], format: OutputFormat): void {\n if (format === 'json') {\n output(rows, 'json');\n return;\n }\n output(rows, 'table');\n}\n","import { KiwoomClient } from '../client/api-client';\nimport { getEffectiveConfig } from '../config/store';\nimport { ActionableError } from '../output/error';\n\n/**\n * Build a client from the effective config. Every Kiwoom call needs a token, so\n * app key + secret key are always required (there is no anonymous endpoint).\n */\nexport function createClient(): KiwoomClient {\n const config = getEffectiveConfig();\n if (!config.appkey || !config.secretkey) {\n throw new ActionableError(\n 'App key / secret key are not configured.',\n 'kiwoom-cli config init',\n );\n }\n return new KiwoomClient({\n env: config.env,\n appkey: config.appkey,\n secretkey: config.secretkey,\n });\n}\n","/**\n * Kiwoom value normalization.\n *\n * The REST API returns numbers as strings: integers are often zero-padded to a\n * fixed width (\"000000019471143\"), and price/percent fields carry a leading\n * sign that encodes direction (\"+0.39\", \"-350000\"). These helpers turn those\n * wire values into something readable without losing the sign.\n */\n\n// Kiwoom occasionally double-signs delta fields, e.g. \"--3405260\" (negative\n// delta) or \"++100\"; treat a leading run of signs as one effective sign where\n// any '-' makes it negative.\nconst NUMERIC_RE = /^([+-]*)0*(\\d+)(\\.\\d+)?$/;\n\n/**\n * Strip zero-padding while preserving sign and decimals.\n * \"000000019471143\" -> \"19471143\", \"-00000001485445\" -> \"-1485445\",\n * \"+0.39\" -> \"+0.39\", \"--3405260\" -> \"-3405260\", \"000000000000000\" -> \"0\".\n * Non-numeric strings (codes, dates-as-text, \"KRX\") are returned unchanged.\n */\nexport function unpad(value: string | number | null | undefined): string {\n if (value === null || value === undefined) return '';\n const str = String(value).trim();\n const m = str.match(NUMERIC_RE);\n if (!m) return str;\n const sign = m[1].includes('-') ? '-' : m[1].includes('+') ? '+' : '';\n const intPart = m[2].replace(/^0+(?=\\d)/, '');\n return `${sign}${intPart}${m[3] ?? ''}`;\n}\n\n/** Parse a Kiwoom numeric string into a JS number (sign + padding aware). */\nexport function toNumber(value: string | number | null | undefined): number {\n if (value === null || value === undefined || value === '') return NaN;\n const cleaned = unpad(value).replace(/^\\+/, '');\n // Guard sign-only/empty results so \"+\" doesn't coerce to 0.\n if (cleaned === '' || cleaned === '-' || cleaned === '+') return NaN;\n const n = Number(cleaned);\n return Number.isNaN(n) ? NaN : n;\n}\n\n/** Group an integer/decimal string with thousands separators, keeping sign. */\nexport function withCommas(value: string): string {\n const m = value.match(/^([+-]?)(\\d+)(\\.\\d+)?$/);\n if (!m) return value;\n const grouped = m[2].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n return `${m[1]}${grouped}${m[3] ?? ''}`;\n}\n\n/** Format a (possibly zero-padded) won amount as \"19,471,143\". */\nexport function won(value: string | number | null | undefined): string {\n return withCommas(unpad(value));\n}\n\n/**\n * Format a market price. Kiwoom prefixes quote/chart prices with a direction\n * sign (e.g. \"-353750\" = price 353,750, trading below prior close); that sign\n * is NOT part of the value, so it is dropped and the magnitude is grouped.\n */\nexport function price(value: string | number | null | undefined): string {\n return withCommas(unpad(value).replace(/^[+-]/, ''));\n}\n\n/**\n * Format a Kiwoom date/time stamp for display.\n * \"20260622135400\" -> \"2026-06-22 13:54:00\"\n * \"20260622\" -> \"2026-06-22\"\n * \"135400\" -> \"13:54:00\"\n */\nexport function formatStamp(value: string | null | undefined): string {\n if (!value) return '';\n const s = String(value).trim();\n if (/^\\d{14}$/.test(s)) {\n return `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)} ${s.slice(8, 10)}:${s.slice(10, 12)}:${s.slice(12, 14)}`;\n }\n if (/^\\d{8}$/.test(s)) {\n return `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)}`;\n }\n if (/^\\d{6}$/.test(s)) {\n return `${s.slice(0, 2)}:${s.slice(2, 4)}:${s.slice(4, 6)}`;\n }\n return s;\n}\n\n/**\n * Apply a set of formatters to selected keys of an object (shallow).\n * Used by table commands to pretty-print known numeric fields.\n */\nexport function formatFields<T extends Record<string, unknown>>(\n row: T,\n formatters: Partial<Record<keyof T | string, (v: string) => string>>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...row };\n for (const [key, fn] of Object.entries(formatters)) {\n if (fn && out[key] !== undefined && out[key] !== null) {\n out[key] = fn(String(out[key]));\n }\n }\n return out;\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { getEffectiveConfig, getCachedToken, clearCachedToken, maskSecret } from '../config/store';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError, ActionableError } from '../output/error';\nimport { formatStamp } from '../utils/format';\nimport { isTokenExpired } from '../utils/helpers';\n\nexport function registerAuthCommands(program: Command): void {\n const authCmd = program.command('auth').description('Access-token management (OAuth2)');\n\n authCmd\n .command('token')\n .description('Issue (or reuse) an access token and cache it')\n .option('--force', 'Force a fresh token even if a valid one is cached')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const cfg = getEffectiveConfig();\n const client = createClient();\n if (options.force) clearCachedToken(cfg.env);\n await client.authenticate();\n const cached = getCachedToken(cfg.env);\n output(\n {\n env: cfg.env,\n token: maskSecret(cached?.token),\n expiresAt: formatStamp(cached?.expiresDt),\n valid: cached ? !isTokenExpired(cached.expiresDt) : false,\n },\n getOutputFormat(options),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n authCmd\n .command('status')\n .description('Show the cached token status')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((options) => {\n try {\n const cfg = getEffectiveConfig();\n const cached = getCachedToken(cfg.env);\n if (!cached) {\n output({ env: cfg.env, cached: false }, getOutputFormat(options));\n return;\n }\n output(\n {\n env: cfg.env,\n cached: true,\n token: maskSecret(cached.token),\n expiresAt: formatStamp(cached.expiresDt),\n valid: !isTokenExpired(cached.expiresDt),\n },\n getOutputFormat(options),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n authCmd\n .command('revoke')\n .description('Revoke the cached access token')\n .action(async () => {\n try {\n const cfg = getEffectiveConfig();\n const cached = getCachedToken(cfg.env);\n if (!cached) {\n throw new ActionableError('No cached token to revoke.', 'kiwoom-cli auth token');\n }\n const client = createClient();\n await client.revokeToken(cached.token);\n console.log('Token revoked and cache cleared.');\n } catch (err) {\n handleError(err);\n }\n });\n}\n","/**\n * Registry of every Kiwoom TR this CLI exposes — the single source of truth for\n * api-id, route, response list key, and whether the call places/modifies orders.\n *\n * All specs were live-verified against https://api.kiwoom.com (read TRs) or\n * taken from the official spec + typed community wrappers (order TRs, which are\n * never called live for safety).\n */\n\nexport const PATHS = {\n stkinfo: '/api/dostk/stkinfo',\n mrkcond: '/api/dostk/mrkcond',\n chart: '/api/dostk/chart',\n acnt: '/api/dostk/acnt',\n ordr: '/api/dostk/ordr',\n crdordr: '/api/dostk/crdordr',\n rkinfo: '/api/dostk/rkinfo',\n sect: '/api/dostk/sect',\n} as const;\n\nexport interface EndpointDef {\n /** api-id header value, e.g. \"ka10001\". */\n apiId: string;\n /** Category route. */\n path: string;\n /** Korean TR name. */\n korean: string;\n /** Array field in the response payload, if the TR returns a list. */\n listKey?: string;\n /** True for order place/modify/cancel TRs (real-money writes). */\n isWrite?: boolean;\n}\n\nexport const ENDPOINTS = {\n // ── Stock info (종목정보) ──────────────────────────────────────────────────\n stockInfo: { apiId: 'ka10001', path: PATHS.stkinfo, korean: '주식기본정보요청' },\n tradingMembers: { apiId: 'ka10002', path: PATHS.stkinfo, korean: '주식거래원요청' },\n stockTrades: { apiId: 'ka10003', path: PATHS.stkinfo, korean: '체결정보요청', listKey: 'cntr_infr' },\n watchlist: { apiId: 'ka10095', path: PATHS.stkinfo, korean: '관심종목정보요청', listKey: 'atn_stk_infr' },\n stockList: { apiId: 'ka10099', path: PATHS.stkinfo, korean: '종목정보 리스트', listKey: 'list' },\n stockInfoSingle: { apiId: 'ka10100', path: PATHS.stkinfo, korean: '종목정보 조회' },\n sectorCodeList: { apiId: 'ka10101', path: PATHS.stkinfo, korean: '업종코드 리스트', listKey: 'list' },\n creditTrend: { apiId: 'ka10013', path: PATHS.stkinfo, korean: '신용매매동향요청', listKey: 'crd_trde_trend' },\n\n // ── Market quote (시세) ────────────────────────────────────────────────────\n orderbook: { apiId: 'ka10004', path: PATHS.mrkcond, korean: '주식호가요청' },\n quoteSnapshot: { apiId: 'ka10006', path: PATHS.mrkcond, korean: '주식시분요청' },\n priceTableInfo: { apiId: 'ka10007', path: PATHS.mrkcond, korean: '시세표성정보요청' },\n dailyPrice: { apiId: 'ka10086', path: PATHS.mrkcond, korean: '일별주가요청', listKey: 'daly_stkpc' },\n instTradedStocks: { apiId: 'ka10044', path: PATHS.mrkcond, korean: '일별기관매매종목요청', listKey: 'daly_orgn_trde_stk' },\n instForeignTrend: { apiId: 'ka10045', path: PATHS.mrkcond, korean: '종목별기관매매추이요청', listKey: 'stk_orgn_trde_trnsn' },\n strengthByTime: { apiId: 'ka10046', path: PATHS.mrkcond, korean: '체결강도시간별요청', listKey: 'cntr_str_tm' },\n strengthByDay: { apiId: 'ka10047', path: PATHS.mrkcond, korean: '체결강도일별요청', listKey: 'cntr_str_daly' },\n afterHoursOrderbook: { apiId: 'ka10087', path: PATHS.mrkcond, korean: '시간외단일가요청' },\n\n // ── Chart (차트) ───────────────────────────────────────────────────────────\n tickChart: { apiId: 'ka10079', path: PATHS.chart, korean: '주식틱차트조회', listKey: 'stk_tic_chart_qry' },\n minuteChart: { apiId: 'ka10080', path: PATHS.chart, korean: '주식분봉차트조회', listKey: 'stk_min_pole_chart_qry' },\n dailyChart: { apiId: 'ka10081', path: PATHS.chart, korean: '주식일봉차트조회', listKey: 'stk_dt_pole_chart_qry' },\n // NOTE: weekly list key is the doubled \"stk_stk_...\" — verified live, not a typo.\n weeklyChart: { apiId: 'ka10082', path: PATHS.chart, korean: '주식주봉차트조회', listKey: 'stk_stk_pole_chart_qry' },\n monthlyChart: { apiId: 'ka10083', path: PATHS.chart, korean: '주식월봉차트조회', listKey: 'stk_mth_pole_chart_qry' },\n yearlyChart: { apiId: 'ka10094', path: PATHS.chart, korean: '주식년봉차트조회', listKey: 'stk_yr_pole_chart_qry' },\n\n // ── Account (계좌) ─────────────────────────────────────────────────────────\n balance: { apiId: 'kt00018', path: PATHS.acnt, korean: '계좌평가잔고내역요청', listKey: 'acnt_evlt_remn_indv_tot' },\n deposit: { apiId: 'kt00001', path: PATHS.acnt, korean: '예수금상세현황요청', listKey: 'stk_entr_prst' },\n evalStatus: { apiId: 'kt00004', path: PATHS.acnt, korean: '계좌평가현황요청', listKey: 'stk_acnt_evlt_prst' },\n settledBalance: { apiId: 'kt00005', path: PATHS.acnt, korean: '체결잔고요청', listKey: 'stk_cntr_remn' },\n orderDetail: { apiId: 'kt00007', path: PATHS.acnt, korean: '계좌별주문체결내역상세요청', listKey: 'acnt_ord_cntr_prps_dtl' },\n orderStatus: { apiId: 'kt00009', path: PATHS.acnt, korean: '계좌별주문체결현황요청', listKey: 'acnt_ord_cntr_prst' },\n openOrders: { apiId: 'ka10075', path: PATHS.acnt, korean: '미체결요청', listKey: 'oso' },\n executions: { apiId: 'ka10076', path: PATHS.acnt, korean: '체결요청', listKey: 'cntr' },\n realizedPlByDate: { apiId: 'ka10072', path: PATHS.acnt, korean: '일자별종목별실현손익요청_일자', listKey: 'dt_stk_div_rlzt_pl' },\n realizedPlByPeriod: { apiId: 'ka10073', path: PATHS.acnt, korean: '일자별종목별실현손익요청_기간', listKey: 'dt_stk_rlzt_pl' },\n tradeJournal: { apiId: 'ka10170', path: PATHS.acnt, korean: '당일매매일지요청', listKey: 'tdy_trde_diary' },\n dailyReturn: { apiId: 'kt00016', path: PATHS.acnt, korean: '일별계좌수익률상세현황요청' },\n\n // ── Order (주문) — WRITE, real money ──────────────────────────────────────\n buy: { apiId: 'kt10000', path: PATHS.ordr, korean: '주식 매수주문', isWrite: true },\n sell: { apiId: 'kt10001', path: PATHS.ordr, korean: '주식 매도주문', isWrite: true },\n modify: { apiId: 'kt10002', path: PATHS.ordr, korean: '주식 정정주문', isWrite: true },\n cancel: { apiId: 'kt10003', path: PATHS.ordr, korean: '주식 취소주문', isWrite: true },\n creditBuy: { apiId: 'kt10006', path: PATHS.crdordr, korean: '신용 매수주문', isWrite: true },\n creditSell: { apiId: 'kt10007', path: PATHS.crdordr, korean: '신용 매도주문', isWrite: true },\n creditModify: { apiId: 'kt10008', path: PATHS.crdordr, korean: '신용 정정주문', isWrite: true },\n creditCancel: { apiId: 'kt10009', path: PATHS.crdordr, korean: '신용 취소주문', isWrite: true },\n\n // ── Ranking (순위정보) ─────────────────────────────────────────────────────\n rankFluctuation: { apiId: 'ka10027', path: PATHS.rkinfo, korean: '전일대비등락률순위요청', listKey: 'pred_pre_flu_rt_upper' },\n rankVolume: { apiId: 'ka10030', path: PATHS.rkinfo, korean: '당일거래량상위요청', listKey: 'tdy_trde_qty_upper' },\n rankTradeAmount: { apiId: 'ka10032', path: PATHS.rkinfo, korean: '거래대금상위요청', listKey: 'trde_prica_upper' },\n rankVolumeSurge: { apiId: 'ka10023', path: PATHS.rkinfo, korean: '거래량급증요청', listKey: 'trde_qty_sdnin' },\n rankPrevVolume: { apiId: 'ka10031', path: PATHS.rkinfo, korean: '전일거래량상위요청', listKey: 'pred_trde_qty_upper' },\n rankForeignInst: { apiId: 'ka90009', path: PATHS.rkinfo, korean: '외국인기관매매상위요청', listKey: 'frgnr_orgn_trde_upper' },\n\n // ── Sector / industry (업종) ───────────────────────────────────────────────\n sectorPrice: { apiId: 'ka20001', path: PATHS.sect, korean: '업종현재가요청', listKey: 'inds_cur_prc_tm' },\n sectorStocks: { apiId: 'ka20002', path: PATHS.sect, korean: '업종별주가요청', listKey: 'inds_stkpc' },\n sectorAllIndex: { apiId: 'ka20003', path: PATHS.sect, korean: '전업종지수요청', listKey: 'all_inds_idex' },\n sectorDaily: { apiId: 'ka20009', path: PATHS.sect, korean: '업종현재가 일별요청', listKey: 'inds_cur_prc_daly_rept' },\n} satisfies Record<string, EndpointDef>;\n\nexport type EndpointKey = keyof typeof ENDPOINTS;\n","import { unpad, formatStamp } from './format';\n\nexport interface BookLevel {\n level: number;\n price: string;\n qty: string;\n}\n\nexport interface ParsedBook {\n baseTime: string;\n asks: BookLevel[]; // highest ask first (level 10 → 1)\n bids: BookLevel[]; // best bid first (level 1 → 10)\n totalAskQty: string;\n totalBidQty: string;\n}\n\n/**\n * Parse a ka10004 (주식호가요청) payload into ordered bid/ask levels.\n *\n * The field naming is irregular: level-1 quotes use the `*_fpr_*` (최우선)\n * keys, while levels 2–10 use `*_{N}th_pre_*`.\n */\nexport function parseOrderbook(d: Record<string, any>): ParsedBook {\n const asks: BookLevel[] = [];\n for (let n = 10; n >= 2; n--) {\n asks.push({\n level: n,\n price: unpad(d[`sel_${n}th_pre_bid`]),\n qty: unpad(d[`sel_${n}th_pre_req`]),\n });\n }\n asks.push({ level: 1, price: unpad(d.sel_fpr_bid), qty: unpad(d.sel_fpr_req) });\n\n const bids: BookLevel[] = [];\n bids.push({ level: 1, price: unpad(d.buy_fpr_bid), qty: unpad(d.buy_fpr_req) });\n for (let n = 2; n <= 10; n++) {\n bids.push({\n level: n,\n price: unpad(d[`buy_${n}th_pre_bid`]),\n qty: unpad(d[`buy_${n}th_pre_req`]),\n });\n }\n\n return {\n baseTime: formatStamp(d.bid_req_base_tm),\n asks,\n bids,\n totalAskQty: unpad(d.tot_sel_req),\n totalBidQty: unpad(d.tot_buy_req),\n };\n}\n\n/** Render a parsed book as a compact two-sided ladder for the terminal. */\nexport function renderOrderbook(book: ParsedBook, title: string): string {\n const lines: string[] = [];\n lines.push(`\\n Order Book: ${title} (${book.baseTime})\\n`);\n lines.push(' ── Asks ──');\n for (const a of book.asks) {\n lines.push(` ${a.price.padStart(12)} ${a.qty.padStart(12)}`);\n }\n lines.push(' ─────────');\n for (const b of book.bids) {\n lines.push(` ${b.price.padStart(12)} ${b.qty.padStart(12)}`);\n }\n lines.push(' ── Bids ──');\n lines.push(`\\n Total ask qty: ${book.totalAskQty} Total bid qty: ${book.totalBidQty}\\n`);\n return lines.join('\\n');\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat, OutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst } from '../utils/helpers';\nimport { unpad, won, price, formatStamp, formatFields, toNumber } from '../utils/format';\nimport { parseOrderbook, renderOrderbook } from '../utils/orderbook';\n\nexport function registerMarketCommands(program: Command): void {\n const market = program.command('market').description('Market data — prices, quotes, order book, trades');\n\n // market price <code>\n market\n .command('price <code>')\n .description('Current price snapshot (ka10007)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.priceTableInfo, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n const chg =\n Math.abs(toNumber(data.cur_prc)) - Math.abs(toNumber(data.pred_close_pric));\n output(\n {\n name: data.stk_nm,\n code: data.stk_cd,\n price: price(data.cur_prc),\n change: Number.isNaN(chg) ? '' : `${chg > 0 ? '+' : ''}${chg}`,\n changeRate: `${unpad(data.flu_rt)}%`,\n open: price(data.open_pric),\n high: price(data.high_pric),\n low: price(data.low_pric),\n volume: won(data.trde_qty),\n bestAsk: price(data.sel_1bid),\n bestBid: price(data.buy_1bid),\n prevClose: price(data.pred_close_pric),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market orderbook <code>\n market\n .command('orderbook <code>')\n .alias('book')\n .description('10-level bid/ask order book (ka10004)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.orderbook, { stk_cd: stk });\n if (getOutputFormat(options) === 'json') {\n output(data, 'json');\n return;\n }\n console.log(renderOrderbook(parseOrderbook(data), stk));\n } catch (err) {\n handleError(err);\n }\n });\n\n // market after-hours <code>\n market\n .command('after-hours <code>')\n .description('After-hours single-price quotes (ka10087)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.afterHoursOrderbook, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n price: unpad(data.ovt_sigpric_cur_prc),\n change: unpad(data.ovt_sigpric_pred_pre),\n changeRate: `${unpad(data.ovt_sigpric_flu_rt)}%`,\n volume: won(data.ovt_sigpric_acc_trde_qty),\n askTotal: won(data.ovt_sigpric_sel_bid_tot_req),\n bidTotal: won(data.ovt_sigpric_buy_bid_tot_req),\n baseTime: formatStamp(data.bid_req_base_tm),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market daily <code>\n market\n .command('daily <code>')\n .description('Daily price history (ka10086)')\n .option('-d, --date <yyyymmdd>', 'Base date (most recent day)', todayKst())\n .option('-t, --type <0|1>', 'Display type: 0=quantity, 1=amount', '0')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.dailyPrice, {\n stk_cd: stk,\n qry_dt: options.date,\n indc_tp: options.type,\n });\n emitList(data, ENDPOINTS.dailyPrice.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n date: formatStamp,\n open_pric: unpad,\n high_pric: unpad,\n low_pric: unpad,\n close_pric: unpad,\n flu_rt: unpad,\n trde_qty: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market trades <code>\n market\n .command('trades <code>')\n .description('Recent tick-by-tick executions (ka10003)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.stockTrades, { stk_cd: stk });\n emitList(data, ENDPOINTS.stockTrades.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n tm: formatStamp,\n cur_prc: unpad,\n pred_pre: unpad,\n pre_rt: unpad,\n cntr_trde_qty: unpad,\n acc_trde_qty: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market strength <code>\n market\n .command('strength <code>')\n .description('Trade strength (체결강도) time series (ka10046 / ka10047)')\n .option('--daily', 'Daily series instead of intraday')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const ep = options.daily ? ENDPOINTS.strengthByDay : ENDPOINTS.strengthByTime;\n const { data } = await client.callEndpoint(ep, { stk_cd: stk });\n emitList(data, ep.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n cntr_tm: formatStamp,\n dt: formatStamp,\n cur_prc: unpad,\n flu_rt: unpad,\n cntr_str: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // market inst-foreign <code>\n market\n .command('inst-foreign <code>')\n .description('Per-stock institution/foreigner trading trend (ka10045)')\n .option('-s, --start <yyyymmdd>', 'Start date')\n .option('-e, --end <yyyymmdd>', 'End date', todayKst())\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.instForeignTrend, {\n stk_cd: stk,\n strt_dt: options.start ?? options.end,\n end_dt: options.end,\n orgn_prsm_unp_tp: '0',\n for_prsm_unp_tp: '0',\n });\n emitList(data, ENDPOINTS.instForeignTrend.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n dt: formatStamp,\n close_pric: unpad,\n flu_rt: unpad,\n orgn_daly_nettrde_qty: unpad,\n for_daly_nettrde_qty: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n\n/** Shared helper: emit a list payload as JSON (raw) or a formatted table. */\nexport function emitList(\n data: Record<string, any>,\n listKey: string,\n fmt: OutputFormat,\n rowFormatter?: (row: Record<string, unknown>) => Record<string, unknown>,\n): void {\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n const rows: Record<string, unknown>[] = Array.isArray(data[listKey]) ? data[listKey] : [];\n if (rows.length === 0) {\n console.log('No data');\n return;\n }\n output(rowFormatter ? rows.map(rowFormatter) : rows, 'table');\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst, parseIntStrict } from '../utils/helpers';\nimport { unpad, won, price, formatStamp, formatFields } from '../utils/format';\nimport { emitList } from './market';\n\nexport function registerStockCommands(program: Command): void {\n const stock = program.command('stock').description('Stock information — fundamentals, search, members');\n\n // stock info <code>\n stock\n .command('info <code>')\n .description('Stock fundamentals snapshot (ka10001)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.stockInfo, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n name: data.stk_nm,\n code: data.stk_cd,\n price: price(data.cur_prc),\n change: unpad(data.pred_pre),\n changeRate: `${unpad(data.flu_rt)}%`,\n open: price(data.open_pric),\n high: price(data.high_pric),\n low: price(data.low_pric),\n upperLimit: price(data.upl_pric),\n lowerLimit: price(data.lst_pric),\n volume: won(data.trde_qty),\n per: data.per,\n eps: data.eps,\n roe: data.roe,\n pbr: data.pbr,\n bps: data.bps,\n marketCap: won(data.mac),\n foreignRate: `${unpad(data.for_exh_rt)}%`,\n high52w: price(data['250hgst']),\n low52w: price(data['250lwst']),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock search <keyword>\n stock\n .command('search <keyword>')\n .description('Search the stock list by name or code (ka10099)')\n .option('-m, --market <0|10>', 'Market: 0=KOSPI, 10=KOSDAQ', '0')\n .option('-n, --limit <n>', 'Maximum rows to return', '30')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (keyword: string, options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(\n ENDPOINTS.stockList,\n { mrkt_tp: options.market },\n { paginate: true },\n );\n const fmt = getOutputFormat(options);\n const limit = parseIntStrict(options.limit, 'limit');\n const needle = keyword.toLowerCase();\n const list: Record<string, any>[] = Array.isArray(data[ENDPOINTS.stockList.listKey!])\n ? data[ENDPOINTS.stockList.listKey!]\n : [];\n const filtered = list\n .filter(\n (item) =>\n String(item.name ?? '').toLowerCase().includes(needle) ||\n String(item.code ?? '').startsWith(keyword),\n )\n .slice(0, limit);\n if (filtered.length === 0) {\n console.log('No matches');\n return;\n }\n if (fmt === 'json') {\n output(filtered, 'json');\n return;\n }\n const rows = filtered.map((item) => ({\n code: item.code,\n name: item.name,\n market: item.marketName,\n sector: item.upName,\n lastPrice: unpad(item.lastPrice),\n }));\n output(rows, 'table');\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock resolve <code>\n stock\n .command('resolve <code>')\n .description('Resolve a single stock\\'s listing metadata (ka10100)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.stockInfoSingle, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n code: data.code,\n name: data.name,\n market: data.marketName,\n sector: data.upName,\n sizeTier: data.upSizeName,\n listedShares: won(data.listCount),\n lastPrice: unpad(data.lastPrice),\n state: data.state,\n nxtEnable: data.nxtEnable,\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock members <code>\n stock\n .command('members <code>')\n .description('Top 5 buy/sell trading members (ka10002)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.tradingMembers, { stk_cd: stk });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n const rows = [];\n for (let i = 1; i <= 5; i++) {\n rows.push({\n rank: i,\n sellMember: data['sel_trde_ori_nm_' + i],\n sellQty: unpad(data['sel_trde_qty_' + i]),\n buyMember: data['buy_trde_ori_nm_' + i],\n buyQty: unpad(data['buy_trde_qty_' + i]),\n });\n }\n output(rows, 'table');\n } catch (err) {\n handleError(err);\n }\n });\n\n // stock credit-trend <code>\n stock\n .command('credit-trend <code>')\n .description('Credit trading trend (신용매매동향) (ka10013)')\n .option('-d, --date <yyyymmdd>', 'Base date', todayKst())\n .option('-t, --type <1|2>', 'Query type: 1=융자, 2=대주', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const { data } = await client.callEndpoint(ENDPOINTS.creditTrend, {\n stk_cd: stk,\n dt: options.date ?? todayKst(),\n qry_tp: options.type ?? '1',\n });\n emitList(data, ENDPOINTS.creditTrend.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n dt: formatStamp,\n cur_prc: unpad,\n trde_qty: won,\n new: won,\n rpya: won,\n remn: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS, EndpointDef } from '../client/endpoints';\nimport { output, getOutputFormat, OutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst, parseIntStrict } from '../utils/helpers';\nimport { unpad, won, formatStamp, formatFields } from '../utils/format';\nimport { CHART_PER_PAGE_CAP, CHART_MAX_COUNT, ChartType } from '../config/constants';\nimport { ActionableError } from '../output/error';\n\n/** Per-row formatters shared by every chart TR (fields overlap across types). */\nconst CHART_ROW_FORMATTERS: Record<string, (v: string) => string> = {\n cntr_tm: formatStamp,\n dt: formatStamp,\n open_pric: unpad,\n high_pric: unpad,\n low_pric: unpad,\n cur_prc: unpad,\n trde_qty: won,\n acc_trde_qty: won,\n trde_prica: won,\n pred_pre: unpad,\n trde_tern_rt: unpad,\n};\n\n/**\n * Per-request row cap for each chart TR (rows returned by a single API call).\n * Kiwoom returns at most this many candles per page; larger `--count` values are\n * served by paging on the `cont-yn` / `next-key` headers (see runIntraday/runPeriod).\n * Sourced from the shared constants registry.\n */\nexport const PER_PAGE_CAP = CHART_PER_PAGE_CAP;\n\n/**\n * Parse + validate the `--count` flag locally so a bad value fails clearly here\n * instead of leaking a raw server 400. Must be a positive integer; clamps to\n * CHART_MAX_COUNT to bound auto-pagination.\n */\nfunction parseCount(raw: string): number {\n const n = parseIntStrict(raw, 'count');\n if (n < 1) {\n throw new ActionableError(`--count must be a positive integer (got ${n}).`);\n }\n return Math.min(n, CHART_MAX_COUNT);\n}\n\n/**\n * Render a chart payload: raw JSON, or a formatted table of the first `count`\n * candles under the endpoint's listKey. The list is always sliced to `count` so\n * the output never exceeds the requested number, whether one page or many pages\n * (auto-pagination) were fetched.\n */\nfunction emitChart(data: Record<string, any>, ep: EndpointDef, fmt: OutputFormat, count: number): void {\n const all: Record<string, unknown>[] = Array.isArray(data[ep.listKey!]) ? data[ep.listKey!] : [];\n const sliced = all.slice(0, count);\n if (fmt === 'json') {\n output({ ...data, [ep.listKey!]: sliced }, 'json');\n return;\n }\n if (sliced.length === 0) {\n console.log('No data');\n return;\n }\n output(\n sliced.map((row) => formatFields(row, CHART_ROW_FORMATTERS)),\n 'table',\n );\n}\n\nexport function registerChartCommands(program: Command): void {\n const chart = program\n .command('chart')\n .description(\n 'OHLC charts — tick / minute / daily / weekly / monthly / yearly. ' +\n 'Per-request caps: tick/min 900, day 600, week 300, month 240, year 30. ' +\n '--count beyond the cap auto-paginates via cont-yn/next-key.',\n );\n\n /**\n * Decide whether to auto-paginate: explicitly requested via `--paginate`, or\n * implied because `--count` exceeds the per-page cap for this chart type.\n * Returns the max pages needed so we never over-fetch.\n */\n function planFetch(type: ChartType, count: number, paginate: boolean): { paginate: boolean; maxPages: number } {\n const cap = PER_PAGE_CAP[type];\n const active = paginate || count > cap;\n // Pages needed to reach `count` rows, capped only by data availability.\n const maxPages = active ? Math.max(1, Math.ceil(count / cap)) : 1;\n return { paginate: active, maxPages };\n }\n\n /** Intraday family (tick, min): body keyed on tic_scope. */\n async function runIntraday(\n ep: EndpointDef,\n type: ChartType,\n code: string,\n ticScope: string,\n options: any,\n ): Promise<void> {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const count = parseCount(options.count);\n const plan = planFetch(type, count, !!options.paginate);\n const { data } = await client.callEndpoint(\n ep,\n { stk_cd: stk, tic_scope: ticScope, upd_stkpc_tp: options.raw ? '0' : '1' },\n { paginate: plan.paginate, maxPages: plan.maxPages },\n );\n emitChart(data, ep, getOutputFormat(options), count);\n }\n\n /** Period family (day, week, month, year): body keyed on base_dt. */\n async function runPeriod(\n ep: EndpointDef,\n type: ChartType,\n code: string,\n baseDt: string,\n options: any,\n ): Promise<void> {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const count = parseCount(options.count);\n const plan = planFetch(type, count, !!options.paginate);\n const { data } = await client.callEndpoint(\n ep,\n { stk_cd: stk, base_dt: baseDt, upd_stkpc_tp: options.raw ? '0' : '1' },\n { paginate: plan.paginate, maxPages: plan.maxPages },\n );\n emitChart(data, ep, getOutputFormat(options), count);\n }\n\n // chart tick <code>\n chart\n .command('tick <code>')\n .description(`Tick chart (ka10079) — up to ${PER_PAGE_CAP.tick} candles/request, auto-paginates beyond that`)\n .option('-s, --scope <n>', 'Ticks per candle (1/3/5/10/30)', '1')\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 900)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runIntraday(ENDPOINTS.tickChart, 'tick', code, options.scope, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart min <code>\n chart\n .command('min <code>')\n .alias('minute')\n .description(`Minute chart (ka10080) — up to ${PER_PAGE_CAP.minute} candles/request, auto-paginates beyond that`)\n .option('-i, --interval <n>', 'Minutes per candle (1/3/5/10/15/30/45/60)', '1')\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 900)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runIntraday(ENDPOINTS.minuteChart, 'minute', code, options.interval, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart day <code>\n chart\n .command('day <code>')\n .alias('daily')\n .description(`Daily chart (ka10081) — up to ${PER_PAGE_CAP.day} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 600)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.dailyChart, 'day', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart week <code>\n chart\n .command('week <code>')\n .description(`Weekly chart (ka10082) — up to ${PER_PAGE_CAP.week} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 300)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.weeklyChart, 'week', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart month <code>\n chart\n .command('month <code>')\n .description(`Monthly chart (ka10083) — up to ${PER_PAGE_CAP.month} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 240)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.monthlyChart, 'month', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // chart year <code>\n chart\n .command('year <code>')\n .description(`Yearly chart (ka10094) — up to ${PER_PAGE_CAP.year} candles/request, auto-paginates beyond that`)\n .option('-d, --date <yyyymmdd>', 'Base date (most recent candle)', todayKst())\n .option('-n, --count <n>', 'Number of candles (auto-paginates when > 30)', '50')\n .option('-p, --paginate', 'Force fetching multiple pages (cont-yn/next-key)')\n .option('--raw', 'Unadjusted (수정주가 미반영) prices')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n await runPeriod(ENDPOINTS.yearlyChart, 'year', code, options.date, options);\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { normalizeStockCode, todayKst } from '../utils/helpers';\nimport { unpad, won, formatStamp, formatFields } from '../utils/format';\n\n/** Format a value as \"<n>%\" using unpad to strip padding/sign artifacts. */\nconst pct = (v: unknown) => `${unpad(v as string)}%`;\nimport { ACCOUNT_EXCHANGE_TYPES } from '../config/constants';\nimport { emitList } from './market';\n\nexport function registerAccountCommands(program: Command): void {\n const account = program\n .command('account')\n .alias('acct')\n .description('Account — balance, deposit, orders, executions, P/L');\n\n const exchangeHint = `Exchange filter (${ACCOUNT_EXCHANGE_TYPES.join('/')})`;\n\n // account balance\n account\n .command('balance')\n .description('Account evaluation balance with holdings (kt00018)')\n .option('-x, --exchange <KRX|NXT|%>', exchangeHint, 'KRX')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.balance, {\n qry_tp: '1',\n dmst_stex_tp: options.exchange || 'KRX',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n totalPurchase: won(data.tot_pur_amt),\n totalEval: won(data.tot_evlt_amt),\n evalPnl: won(data.tot_evlt_pl),\n profitRate: `${unpad(data.tot_prft_rt)}%`,\n estDepositAsset: won(data.prsm_dpst_aset_amt),\n },\n 'table',\n );\n emitList(data, ENDPOINTS.balance.listKey!, 'table', (row: any) => ({\n code: row.stk_cd,\n name: row.stk_nm,\n qty: won(row.rmnd_qty),\n avgPrice: won(row.pur_pric),\n curPrice: won(row.cur_prc),\n evalAmt: won(row.evlt_amt),\n pnl: won(row.evltv_prft),\n pnlRate: pct(row.prft_rt),\n weight: pct(row.poss_rt),\n }));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account deposit\n account\n .command('deposit')\n .description('Deposit detail — cash, orderable, withdrawable (kt00001)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.deposit, { qry_tp: '3' });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n cash: won(data.entr),\n orderable: won(data.ord_alow_amt),\n withdrawable: won(data.pymn_alow_amt),\n d2Deposit: won(data.d2_entra),\n substitute: won(data.repl_amt),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account eval\n account\n .command('eval')\n .description('Account evaluation status with holdings (kt00004)')\n .option('-x, --exchange <KRX|NXT|%>', exchangeHint, 'KRX')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.evalStatus, {\n qry_tp: '0',\n dmst_stex_tp: options.exchange || 'KRX',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n accountName: data.acnt_nm,\n branch: data.brch_nm,\n deposit: won(data.entr),\n totalEstimate: won(data.tot_est_amt),\n assetEval: won(data.aset_evlt_amt),\n totalPurchase: won(data.tot_pur_amt),\n },\n 'table',\n );\n emitList(data, ENDPOINTS.evalStatus.listKey!, 'table', (row: any) => ({\n code: row.stk_cd,\n name: row.stk_nm,\n qty: won(row.rmnd_qty),\n avgPrice: won(row.avg_prc),\n curPrice: won(row.cur_prc),\n evalAmt: won(row.evlt_amt),\n pnl: won(row.pl_amt),\n pnlRate: pct(row.pl_rt),\n }));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account settled\n account\n .command('settled')\n .description('Settled (executed) balance (kt00005)')\n .option('-x, --exchange <KRX|NXT|%>', exchangeHint, 'KRX')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.settledBalance, {\n dmst_stex_tp: options.exchange || 'KRX',\n });\n emitList(data, 'stk_cntr_remn', getOutputFormat(options), (row: any) => ({\n code: row.stk_cd,\n name: row.stk_nm,\n qty: won(row.cur_qty),\n avgPrice: won(row.buy_uv),\n curPrice: won(row.cur_prc),\n evalAmt: won(row.evlt_amt),\n pnl: won(row.evltv_prft),\n pnlRate: pct(row.pl_rt),\n }));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account open-orders\n account\n .command('open-orders')\n .description('Unfilled (open) orders (ka10075)')\n .option('-c, --code <code>', 'Filter by stock code')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const body = options.code\n ? {\n all_stk_tp: '0',\n trde_tp: '0',\n stk_cd: normalizeStockCode(options.code),\n stex_tp: '0',\n }\n : { all_stk_tp: '1', trde_tp: '0', stk_cd: '', stex_tp: '0' };\n const { data } = await client.callEndpoint(ENDPOINTS.openOrders, body);\n emitList(data, 'oso', getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_nm: (v) => v,\n ord_no: (v) => v,\n ord_qty: won,\n ord_pric: won,\n oso_qty: won,\n cur_prc: unpad,\n tm: formatStamp,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account executions\n account\n .command('executions')\n .description('Filled executions (ka10076)')\n .option('-c, --code <code>', 'Filter by stock code')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.executions, {\n stk_cd: options.code ? normalizeStockCode(options.code) : '',\n qry_tp: options.code ? '1' : '0',\n sell_tp: '0',\n ord_no: '',\n stex_tp: '0',\n });\n emitList(data, 'cntr', getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_nm: (v) => v,\n ord_no: (v) => v,\n cntr_qty: won,\n cntr_uv: won,\n ord_uv: won,\n cnfm_tm: formatStamp,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account order-detail\n account\n .command('order-detail')\n .description('Detailed order/execution history (kt00007)')\n .option('-d, --date <yyyymmdd>', 'Order date', '')\n .option('-c, --code <code>', 'Filter by stock code')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.orderDetail, {\n ord_dt: options.date || '',\n qry_tp: '1',\n stk_bond_tp: '0',\n sell_tp: '0',\n stk_cd: options.code ? normalizeStockCode(options.code) : '',\n fr_ord_no: '',\n dmst_stex_tp: '%',\n });\n emitList(data, 'acnt_ord_cntr_prps_dtl', getOutputFormat(options));\n } catch (err) {\n handleError(err);\n }\n });\n\n // account pnl <code>\n account\n .command('pnl <code>')\n .description('Realized profit/loss by date or period (ka10072 / ka10073)')\n .option('-s, --start <yyyymmdd>', 'Start date')\n .option('-e, --end <yyyymmdd>', 'End date (enables period query, max 3 months)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (code: string, options) => {\n try {\n const client = createClient();\n const stk = normalizeStockCode(code);\n const ep = options.end ? ENDPOINTS.realizedPlByPeriod : ENDPOINTS.realizedPlByDate;\n const body = options.end\n ? { stk_cd: stk, strt_dt: options.start || options.end, end_dt: options.end }\n : { stk_cd: stk, strt_dt: options.start || todayKst() };\n const { data } = await client.callEndpoint(ep, body);\n emitList(data, ep.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n dt: formatStamp,\n stk_nm: (v) => v,\n cntr_qty: won,\n buy_uv: won,\n cntr_pric: won,\n tdy_sel_pl: won,\n pl_rt: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // account journal\n account\n .command('journal')\n .description(\"Today's trading journal with totals (ka10170)\")\n .option('-d, --date <yyyymmdd>', 'Base date', '')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.tradeJournal, {\n base_dt: options.date || '',\n ottks_tp: '1',\n ch_crd_tp: '0',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n totalSell: won(data.tot_sell_amt),\n totalBuy: won(data.tot_buy_amt),\n commissionTax: won(data.tot_cmsn_tax),\n pnl: won(data.tot_pl_amt),\n profitRate: `${unpad(data.tot_prft_rt)}%`,\n },\n 'table',\n );\n emitList(data, 'tdy_trde_diary', 'table');\n } catch (err) {\n handleError(err);\n }\n });\n\n // account returns\n account\n .command('returns')\n .description('Daily account return detail over a period (kt00016)')\n .option('-s, --start <yyyymmdd>', 'Start date (defaults to first of this month)')\n .option('-e, --end <yyyymmdd>', 'End date', todayKst())\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.dailyReturn, {\n fr_dt: options.start || `${todayKst().slice(0, 6)}01`,\n to_dt: options.end || todayKst(),\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n investBase: won(data.invt_bsamt),\n evalProfit: won(data.evltv_prft),\n profitRate: `${unpad(data.prft_rt)}%`,\n turnoverRate: `${unpad(data.tern_rt)}%`,\n totalFrom: won(data.tot_amt_fr),\n totalTo: won(data.tot_amt_to),\n },\n 'table',\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { prompt } from './config';\nimport { ENDPOINTS, EndpointDef } from '../client/endpoints';\nimport {\n ORDER_TYPES,\n MARKET_ORDER_TYPES,\n ORDER_EXCHANGE_TYPES,\n OrderExchangeType,\n} from '../config/constants';\nimport { getEffectiveConfig } from '../config/store';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError, ActionableError } from '../output/error';\nimport { normalizeStockCode, parseIntStrict } from '../utils/helpers';\n\nfunction resolveExchange(value: string | undefined): OrderExchangeType {\n const ex = (value ?? 'KRX').toUpperCase();\n if (!ORDER_EXCHANGE_TYPES.includes(ex as OrderExchangeType)) {\n throw new ActionableError(\n `Invalid exchange \"${value}\". Use one of: ${ORDER_EXCHANGE_TYPES.join(', ')}`,\n );\n }\n return ex as OrderExchangeType;\n}\n\n/**\n * Resolve trde_tp + ord_uv from --type/--price:\n * - explicit --type wins;\n * - else a --price implies limit (0), no price implies market (3).\n * Market types must carry an empty ord_uv; limit types require a price.\n */\nfunction resolveOrderType(\n typeOpt: string | undefined,\n priceOpt: string | undefined,\n): { trde_tp: string; ord_uv: string } {\n let trde_tp = typeOpt ?? (priceOpt ? '0' : '3');\n if (!ORDER_TYPES[trde_tp]) {\n throw new ActionableError(\n `Invalid order type \"${trde_tp}\". Known types: ${Object.entries(ORDER_TYPES)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ')}`,\n );\n }\n const isMarket = MARKET_ORDER_TYPES.has(trde_tp);\n if (isMarket) {\n if (priceOpt) {\n throw new ActionableError('Market orders must not specify a price (--price).');\n }\n return { trde_tp, ord_uv: '' };\n }\n if (!priceOpt) {\n throw new ActionableError(\n `Order type ${trde_tp} (${ORDER_TYPES[trde_tp]}) requires --price.`,\n );\n }\n return { trde_tp, ord_uv: priceOpt };\n}\n\nasync function confirm(summary: string, skip: boolean): Promise<boolean> {\n console.log(summary);\n if (skip) return true;\n const answer = await prompt('Proceed? (y/N): ');\n return /^y(es)?$/i.test(answer.trim());\n}\n\nasync function submit(\n def: EndpointDef,\n body: Record<string, unknown>,\n outputFmt: { output?: string },\n): Promise<void> {\n const client = createClient();\n const { data } = await client.callEndpoint(def, body);\n output(\n {\n orderNo: data.ord_no,\n exchange: data.dmst_stex_tp,\n message: data.return_msg,\n },\n getOutputFormat(outputFmt),\n );\n}\n\nexport function registerOrderCommands(program: Command): void {\n const order = program\n .command('order')\n .description('Place / modify / cancel orders (REAL money on the \"real\" environment)');\n\n // order buy <code> <qty>\n order\n .command('buy <code> <qty>')\n .description('Place a buy order')\n .option('-p, --price <won>', 'Limit price; omit for a market order')\n .option('-t, --type <code>', 'Order type code (trde_tp); default 0=limit / 3=market')\n .option('--cond-price <won>', 'Trigger price for conditional/stop types (e.g. type 28)')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing', 'KRX')\n .option('--credit', 'Use a credit (margin) order')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((code, qty, options) => placeOrder('buy', code, qty, options).catch(handleError));\n\n // order sell <code> <qty>\n order\n .command('sell <code> <qty>')\n .description('Place a sell order')\n .option('-p, --price <won>', 'Limit price; omit for a market order')\n .option('-t, --type <code>', 'Order type code (trde_tp); default 0=limit / 3=market')\n .option('--cond-price <won>', 'Trigger price for conditional/stop types (e.g. type 28)')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing', 'KRX')\n .option('--credit', 'Use a credit (margin) order')\n .option('--credit-deal <code>', 'Credit deal type (신용거래구분): 33=융자, 99=융자합', '33')\n .option('--loan-date <yyyymmdd>', 'Credit loan date (required for some credit sells)')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action((code, qty, options) => placeOrder('sell', code, qty, options).catch(handleError));\n\n // order modify <orderNo> <code> <qty> <price>\n order\n .command('modify <orderNo> <code> <qty> <price>')\n .description('Modify a resting order (new qty + price)')\n .option('--cond-price <won>', 'New trigger price for conditional/stop orders')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing (must match original)', 'KRX')\n .option('--credit', 'Modify a credit order')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (orderNo, code, qty, price, options) => {\n try {\n const stk = normalizeStockCode(code);\n parseIntStrict(qty, 'qty');\n parseIntStrict(price, 'price');\n const exchange = resolveExchange(options.exchange);\n const def = options.credit ? ENDPOINTS.creditModify : ENDPOINTS.modify;\n const body = {\n dmst_stex_tp: exchange,\n orig_ord_no: orderNo,\n stk_cd: stk,\n mdfy_qty: qty,\n mdfy_uv: price,\n mdfy_cond_uv: options.condPrice ?? '',\n };\n const ok = await confirm(\n `\\nMODIFY ${options.credit ? '(credit) ' : ''}order ${orderNo} ${stk} → qty ${qty} @ ${price} [${exchange}] on ${getEffectiveConfig().env.toUpperCase()}`,\n options.yes,\n );\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n await submit(def, body, options);\n } catch (err) {\n handleError(err);\n }\n });\n\n // order cancel <orderNo> <code>\n order\n .command('cancel <orderNo> <code>')\n .description('Cancel a resting order')\n .option('-q, --qty <qty>', 'Quantity to cancel; 0 = all remaining', '0')\n .option('-x, --exchange <KRX|NXT|SOR>', 'Exchange routing (must match original)', 'KRX')\n .option('--credit', 'Cancel a credit order')\n .option('-y, --yes', 'Skip the confirmation prompt')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (orderNo, code, options) => {\n try {\n const stk = normalizeStockCode(code);\n parseIntStrict(options.qty, 'qty'); // '0' = all remaining\n const exchange = resolveExchange(options.exchange);\n const def = options.credit ? ENDPOINTS.creditCancel : ENDPOINTS.cancel;\n const body = {\n dmst_stex_tp: exchange,\n orig_ord_no: orderNo,\n stk_cd: stk,\n cncl_qty: options.qty,\n };\n const qtyLabel = options.qty === '0' ? 'ALL remaining' : options.qty;\n const ok = await confirm(\n `\\nCANCEL ${options.credit ? '(credit) ' : ''}order ${orderNo} ${stk} → ${qtyLabel} [${exchange}] on ${getEffectiveConfig().env.toUpperCase()}`,\n options.yes,\n );\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n await submit(def, body, options);\n } catch (err) {\n handleError(err);\n }\n });\n}\n\nasync function placeOrder(\n side: 'buy' | 'sell',\n code: string,\n qty: string,\n options: Record<string, any>,\n): Promise<void> {\n const stk = normalizeStockCode(code);\n parseIntStrict(qty, 'qty');\n const exchange = resolveExchange(options.exchange);\n const { trde_tp, ord_uv } = resolveOrderType(options.type, options.price);\n\n const credit = Boolean(options.credit);\n const def = credit\n ? side === 'buy'\n ? ENDPOINTS.creditBuy\n : ENDPOINTS.creditSell\n : side === 'buy'\n ? ENDPOINTS.buy\n : ENDPOINTS.sell;\n\n const cond_uv = options.condPrice ?? '';\n // Stop-limit (type 28) requires a trigger price; cond_uv is otherwise optional.\n if (trde_tp === '28' && !cond_uv) {\n throw new ActionableError('Stop-limit orders (type 28) require --cond-price <trigger>.');\n }\n const body: Record<string, unknown> = {\n dmst_stex_tp: exchange,\n stk_cd: stk,\n ord_qty: qty,\n ord_uv,\n trde_tp,\n cond_uv,\n };\n if (credit && side === 'sell') {\n body.crd_deal_tp = options.creditDeal ?? '33';\n if (options.loanDate) body.crd_loan_dt = options.loanDate;\n }\n\n const priceLabel = MARKET_ORDER_TYPES.has(trde_tp) ? 'MARKET' : `@ ${ord_uv}`;\n const env = getEffectiveConfig().env;\n const summary =\n `\\n${side.toUpperCase()} ${credit ? '(credit) ' : ''}${stk} qty ${qty} ${priceLabel}` +\n ` type ${trde_tp}(${ORDER_TYPES[trde_tp]}) [${exchange}] on ${env.toUpperCase()}` +\n (env === 'real' ? ' ⚠ REAL MONEY' : '');\n\n const ok = await confirm(summary, options.yes);\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n await submit(def, body, options);\n}\n\n// Exposed for unit testing the body-construction logic without network calls.\nexport const _internal = { resolveExchange, resolveOrderType };\n","import { unpad, won } from './format';\n\nexport type Investor = 'foreign' | 'institution';\nexport type NetSide = 'buy' | 'sell';\n\n/**\n * ka90009 (외국인기관매매상위) returns ONE list (`frgnr_orgn_trde_upper`) where each\n * row holds four parallel rankings side-by-side. These are the column-name prefixes\n * for each (investor, side) pair; the full fields are `<prefix>_stk_cd/_stk_nm/_amt/_qty`.\n */\nexport const NETTRADE_FIELDS: Record<Investor, Record<NetSide, string>> = {\n foreign: { buy: 'for_netprps', sell: 'for_netslmt' },\n institution: { buy: 'orgn_netprps', sell: 'orgn_netslmt' },\n};\n\n/** Pull the top-N rows for one (investor, side) column group out of the ka90009 list. */\nexport function extractNetTrade(\n rows: Record<string, string>[],\n prefix: string,\n n: number,\n): Record<string, unknown>[] {\n return rows\n .slice(0, n)\n .map((r, i) => ({\n rank: i + 1,\n code: r[`${prefix}_stk_cd`],\n name: r[`${prefix}_stk_nm`],\n 금액: won(unpad(r[`${prefix}_amt`] ?? '')),\n 수량: won(unpad(r[`${prefix}_qty`] ?? '')),\n }))\n .filter((x) => x.code);\n}\n\n/** Build the per-investor net-trade ranking object from a raw ka90009 list. */\nexport function buildNetTradeResult(\n rows: Record<string, string>[],\n investors: Investor[],\n side: NetSide,\n n: number,\n): Record<string, Record<string, unknown>[]> {\n const result: Record<string, Record<string, unknown>[]> = {};\n for (const inv of investors) result[inv] = extractNetTrade(rows, NETTRADE_FIELDS[inv][side], n);\n return result;\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { getOutputFormat, output } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { unpad, won, formatFields } from '../utils/format';\nimport { NETTRADE_FIELDS, extractNetTrade, type Investor } from '../utils/ranking';\nimport { emitList } from './market';\n\n/** Shared row formatter for ranking tables (signed prices/rates unpadded, quantities/amounts comma-grouped). */\nfunction formatRankRow(row: Record<string, unknown>): Record<string, unknown> {\n return formatFields(row, {\n stk_cd: (v) => v,\n stk_nm: (v) => v,\n cur_prc: unpad,\n flu_rt: unpad,\n pred_pre: unpad,\n trde_qty: won,\n now_trde_qty: won,\n trde_prica: won,\n trde_amt: won,\n sdnin_rt: unpad,\n });\n}\n\nexport function registerRankingCommands(program: Command): void {\n const ranking = program\n .command('ranking')\n .alias('rank')\n .description('Ranking lists — gainers, volume, value');\n\n // ranking fluctuation\n ranking\n .command('fluctuation')\n .alias('gainers')\n .description('Price change rate ranking (ka10027)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-s, --sort <1-5>', 'Sort: 1=상승률, 2=상승폭, 3=하락률, 4=하락폭, 5=보합', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankFluctuation, {\n mrkt_tp: options.market,\n sort_tp: options.sort || '1',\n trde_qty_cnd: '0000',\n stk_cnd: '0',\n crd_cnd: '0',\n updown_incls: '1',\n pric_cnd: '0',\n trde_prica_cnd: '0',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankFluctuation.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking volume\n ranking\n .command('volume')\n .description('Today volume ranking (ka10030)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-s, --sort <1-3>', 'Sort: 1=거래량, 2=거래회전율, 3=거래대금', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankVolume, {\n mrkt_tp: options.market,\n sort_tp: options.sort || '1',\n mang_stk_incls: '0',\n crd_tp: '0',\n trde_qty_tp: '0',\n pric_tp: '0',\n trde_prica_tp: '0',\n mrkt_open_tp: '0',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankVolume.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking amount\n ranking\n .command('amount')\n .alias('value')\n .description('Trade value (거래대금) ranking (ka10032)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankTradeAmount, {\n mrkt_tp: options.market,\n mang_stk_incls: '1',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankTradeAmount.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking surge\n ranking\n .command('surge')\n .description('Volume surge (거래량급증) ranking (ka10023)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('-s, --sort <1-4>', 'Sort type', '1')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankVolumeSurge, {\n mrkt_tp: options.market,\n sort_tp: options.sort || '1',\n tm_tp: '2',\n trde_qty_tp: '5',\n tm: '',\n stk_cnd: '0',\n pric_tp: '0',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankVolumeSurge.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking prev-volume\n ranking\n .command('prev-volume')\n .description('Previous-day volume ranking (ka10031)')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '3')\n .option('--query <1|2>', 'Query type', '1')\n .option('--from <n>', 'Rank start', '0')\n .option('--to <n>', 'Rank end', '100')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankPrevVolume, {\n mrkt_tp: options.market,\n qry_tp: options.query || '1',\n rank_strt: options.from || '0',\n rank_end: options.to || '100',\n stex_tp: options.exchange,\n });\n emitList(data, ENDPOINTS.rankPrevVolume.listKey!, getOutputFormat(options), formatRankRow);\n } catch (err) {\n handleError(err);\n }\n });\n\n // ranking net-buy (수급: 외국인/기관 순매수·순매도 상위, ka90009)\n ranking\n .command('net-buy')\n .alias('supply')\n .description('Foreign/institution net-buy 수급 ranking (ka90009)')\n .option('-b, --by <foreign|institution|both>', 'Investor: foreign=외국인, institution=기관, both', 'both')\n .option('--side <buy|sell>', 'buy=순매수, sell=순매도', 'buy')\n .option('-m, --market <000|001|101>', 'Market: 000=all, 001=KOSPI, 101=KOSDAQ', '000')\n .option('-x, --exchange <1|2|3>', 'Exchange: 1=KRX, 2=NXT, 3=unified', '1')\n .option('-n, --count <n>', 'Top N (1-50)', '10')\n .option('-q, --rank-by <1|2>', 'Rank by 1=amount(금액), 2=quantity(수량)', '1')\n .option('-d, --date <YYYYMMDD>', 'Query date (default: latest)')\n .option('-o, --output <format>', 'Output format (table/json)', 'table')\n .action(async (options) => {\n try {\n const side: 'buy' | 'sell' = options.side === 'sell' ? 'sell' : 'buy';\n const by = ['foreign', 'institution', 'both'].includes(options.by) ? options.by : 'both';\n const investors: Investor[] = by === 'both' ? ['foreign', 'institution'] : [by];\n const n = Math.min(Math.max(parseInt(String(options.count), 10) || 10, 1), 50);\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.rankForeignInst, {\n mrkt_tp: options.market,\n amt_qty_tp: options.rankBy === '2' ? '2' : '1',\n qry_dt_tp: options.date ? '1' : '0',\n date: options.date || '',\n stex_tp: options.exchange,\n });\n const rows: Record<string, string>[] = Array.isArray(data?.[ENDPOINTS.rankForeignInst.listKey!])\n ? data[ENDPOINTS.rankForeignInst.listKey!]\n : [];\n const fmt = getOutputFormat(options);\n const sideKo = side === 'buy' ? '순매수' : '순매도';\n const labelKo: Record<string, string> = { foreign: '외국인', institution: '기관' };\n\n if (fmt === 'json') {\n const result: Record<string, unknown> = {\n side,\n rankBy: options.rankBy === '2' ? 'quantity' : 'amount',\n };\n for (const inv of investors) {\n result[inv] = extractNetTrade(rows, NETTRADE_FIELDS[inv][side], n);\n }\n output(result, 'json');\n return;\n }\n\n for (const inv of investors) {\n const list = extractNetTrade(rows, NETTRADE_FIELDS[inv][side], n);\n console.log(`\\n${labelKo[inv]} ${sideKo} TOP${n} (${options.rankBy === '2' ? '수량' : '금액'} 기준)`);\n output(list, 'table');\n }\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from './_helpers';\nimport { ENDPOINTS } from '../client/endpoints';\nimport { output, getOutputFormat } from '../output/formatter';\nimport { handleError } from '../output/error';\nimport { unpad, won, formatStamp, formatFields } from '../utils/format';\nimport { emitList } from './market';\n\nexport function registerSectorCommands(program: Command): void {\n const sector = program\n .command('sector')\n .alias('industry')\n .description('Sector / industry indices');\n\n const withSharedOptions = (cmd: Command): Command =>\n cmd\n .option('-m, --market <0|1|2>', 'Market: 0=KOSPI, 1=KOSDAQ, 2=KOSPI200', '0')\n .option('-c, --code <inds_cd>', 'Industry code (001=종합KOSPI, 101=종합KOSDAQ)', '001')\n .option('-o, --output <format>', 'Output format (table/json)', 'table');\n\n // sector price\n withSharedOptions(sector.command('price').description('Sector index snapshot (ka20001)')).action(\n async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorPrice, {\n mrkt_tp: options.market || '0',\n inds_cd: options.code || '001',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n price: unpad(data.cur_prc),\n change: unpad(data.pred_pre),\n changeRate: `${unpad(data.flu_rt)}%`,\n open: unpad(data.open_pric),\n high: unpad(data.high_pric),\n low: unpad(data.low_pric),\n volume: won(data.trde_qty),\n rising: data.rising,\n falling: data.fall,\n },\n 'table',\n );\n emitList(data, ENDPOINTS.sectorPrice.listKey!, 'table', (row) =>\n formatFields(row, {\n tm_n: formatStamp,\n cur_prc_n: unpad,\n trde_qty_n: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n },\n );\n\n // sector stocks\n withSharedOptions(\n sector.command('stocks').description('Stock prices within a sector (ka20002)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorStocks, {\n mrkt_tp: options.market || '0',\n inds_cd: options.code || '001',\n stex_tp: '1',\n });\n emitList(data, ENDPOINTS.sectorStocks.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_cd: (v) => v,\n stk_nm: (v) => v,\n cur_prc: unpad,\n flu_rt: unpad,\n now_trde_qty: won,\n open_pric: unpad,\n high_pric: unpad,\n low_pric: unpad,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // sector all\n withSharedOptions(\n sector.command('all').description('All sector indices (ka20003)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorAllIndex, {\n inds_cd: options.code || '001',\n });\n emitList(data, ENDPOINTS.sectorAllIndex.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n stk_cd: (v) => v,\n stk_nm: (v) => v,\n cur_prc: unpad,\n flu_rt: unpad,\n trde_qty: won,\n trde_prica: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // sector daily\n withSharedOptions(\n sector.command('daily').description('Sector index daily history (ka20009)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(ENDPOINTS.sectorDaily, {\n mrkt_tp: options.market || '0',\n inds_cd: options.code || '001',\n });\n const fmt = getOutputFormat(options);\n if (fmt === 'json') {\n output(data, 'json');\n return;\n }\n output(\n {\n price: unpad(data.cur_prc),\n changeRate: `${unpad(data.flu_rt)}%`,\n open: unpad(data.open_pric),\n high: unpad(data.high_pric),\n low: unpad(data.low_pric),\n },\n 'table',\n );\n emitList(data, ENDPOINTS.sectorDaily.listKey!, 'table', (row) =>\n formatFields(row, {\n dt_n: formatStamp,\n cur_prc_n: unpad,\n flu_rt_n: unpad,\n acc_trde_qty_n: won,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n\n // sector codes\n withSharedOptions(\n sector.command('codes').description('Valid industry codes per market (ka10101)'),\n ).action(async (options) => {\n try {\n const client = createClient();\n const { data } = await client.callEndpoint(\n ENDPOINTS.sectorCodeList,\n { mrkt_tp: options.market || '0' },\n { paginate: true },\n );\n emitList(data, ENDPOINTS.sectorCodeList.listKey!, getOutputFormat(options), (row) =>\n formatFields(row, {\n marketCode: (v) => v,\n code: (v) => v,\n name: (v) => v,\n group: (v) => v,\n }),\n );\n } catch (err) {\n handleError(err);\n }\n });\n}\n"],"mappings":"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","names":["path","program","program","program","program","program","program","program","price","program","program"]}