krx-openapi 0.1.0__tar.gz

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.
Files changed (36) hide show
  1. krx_openapi-0.1.0/.agents/plugins/marketplace.json +20 -0
  2. krx_openapi-0.1.0/.claude-plugin/marketplace.json +27 -0
  3. krx_openapi-0.1.0/.github/workflows/check.yml +22 -0
  4. krx_openapi-0.1.0/.github/workflows/publish.yml +61 -0
  5. krx_openapi-0.1.0/.github/workflows/reusable-check.yml +83 -0
  6. krx_openapi-0.1.0/.gitignore +33 -0
  7. krx_openapi-0.1.0/LICENSE +21 -0
  8. krx_openapi-0.1.0/PKG-INFO +236 -0
  9. krx_openapi-0.1.0/README.en.md +211 -0
  10. krx_openapi-0.1.0/README.md +208 -0
  11. krx_openapi-0.1.0/plugins/krx/.claude-plugin/plugin.json +19 -0
  12. krx_openapi-0.1.0/plugins/krx/.codex-plugin/plugin.json +33 -0
  13. krx_openapi-0.1.0/plugins/krx/skills/fetch/SKILL.md +83 -0
  14. krx_openapi-0.1.0/plugins/krx/skills/fields/SKILL.md +52 -0
  15. krx_openapi-0.1.0/plugins/krx/skills/list/SKILL.md +57 -0
  16. krx_openapi-0.1.0/pyproject.toml +83 -0
  17. krx_openapi-0.1.0/src/krx_openapi/__init__.py +55 -0
  18. krx_openapi-0.1.0/src/krx_openapi/__main__.py +8 -0
  19. krx_openapi-0.1.0/src/krx_openapi/_config.py +74 -0
  20. krx_openapi-0.1.0/src/krx_openapi/_endpoint.py +98 -0
  21. krx_openapi-0.1.0/src/krx_openapi/catalog.py +198 -0
  22. krx_openapi-0.1.0/src/krx_openapi/cli.py +170 -0
  23. krx_openapi-0.1.0/src/krx_openapi/client.py +238 -0
  24. krx_openapi-0.1.0/src/krx_openapi/errors.py +86 -0
  25. krx_openapi-0.1.0/src/krx_openapi/py.typed +0 -0
  26. krx_openapi-0.1.0/src/krx_openapi/session.py +160 -0
  27. krx_openapi-0.1.0/src/krx_openapi/types.py +28 -0
  28. krx_openapi-0.1.0/tests/__init__.py +0 -0
  29. krx_openapi-0.1.0/tests/test_catalog.py +142 -0
  30. krx_openapi-0.1.0/tests/test_cli.py +148 -0
  31. krx_openapi-0.1.0/tests/test_client.py +76 -0
  32. krx_openapi-0.1.0/tests/test_config.py +101 -0
  33. krx_openapi-0.1.0/tests/test_endpoints.py +44 -0
  34. krx_openapi-0.1.0/tests/test_errors.py +31 -0
  35. krx_openapi-0.1.0/tests/test_live.py +28 -0
  36. krx_openapi-0.1.0/tests/test_session.py +257 -0
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "krx-openapi",
3
+ "interface": {
4
+ "displayName": "krx"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "krx",
9
+ "source": {
10
+ "source": "local",
11
+ "path": "./plugins/krx"
12
+ },
13
+ "policy": {
14
+ "installation": "AVAILABLE",
15
+ "authentication": "ON_INSTALL"
16
+ },
17
+ "category": "Productivity"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "krx-openapi",
3
+ "owner": {
4
+ "name": "seokhoonj"
5
+ },
6
+ "description": "Read the Korea Exchange (KRX) Open API",
7
+ "plugins": [
8
+ {
9
+ "name": "krx",
10
+ "displayName": "krx",
11
+ "source": "./plugins/krx",
12
+ "description": "Read the Korea Exchange (KRX) Open API",
13
+ "author": {
14
+ "name": "seokhoonj"
15
+ },
16
+ "homepage": "https://github.com/seokhoonj/krx-openapi",
17
+ "category": "Productivity",
18
+ "keywords": [
19
+ "krx",
20
+ "korea exchange",
21
+ "korea",
22
+ "market data",
23
+ "stock"
24
+ ]
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,22 @@
1
+ name: check
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+
9
+ # A newer push to the same branch or PR makes the older run's result obsolete,
10
+ # so cancel it rather than let both run to completion.
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ # The check only reads the code to lint, type, and test it -- it never writes to the
16
+ # repo -- so it runs with the least privilege that still allows a checkout.
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ check:
22
+ uses: ./.github/workflows/reusable-check.yml
@@ -0,0 +1,61 @@
1
+ name: publish
2
+
3
+ # Publish to PyPI on a GitHub Release, via PyPI Trusted Publishing (OIDC): no API
4
+ # token or password is stored anywhere -- GitHub mints a short-lived identity token
5
+ # that PyPI verifies against the publisher registered for this repo (owner seokhoonj
6
+ # / repo krx-openapi / this workflow / environment "pypi").
7
+ #
8
+ # Three jobs. `gate` runs the same reusable check that check.yml runs, on the
9
+ # release commit, so a red build (a lint/type error, a broken test, a lost py.typed
10
+ # or console script) cannot reach an upload. `build` builds the sdist and wheel and
11
+ # hands them to `publish` as an artifact. `publish` -- the only job holding the OIDC
12
+ # token -- downloads that artifact and uploads it, and checks out no source, so the
13
+ # privileged step runs the least code.
14
+
15
+ on:
16
+ release:
17
+ types: [published]
18
+
19
+ # Workflow-level floor: any job without its own `permissions:` block still gets a
20
+ # read-only token, so a job added later cannot silently inherit a write-capable
21
+ # default. The build and publish jobs narrow it further below.
22
+ permissions:
23
+ contents: read
24
+
25
+ jobs:
26
+ gate:
27
+ uses: ./.github/workflows/reusable-check.yml
28
+
29
+ build:
30
+ needs: gate
31
+ runs-on: ubuntu-latest
32
+ timeout-minutes: 15
33
+ permissions:
34
+ contents: read
35
+ steps:
36
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
37
+ with:
38
+ persist-credentials: false
39
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
40
+ - name: Build sdist and wheel, then check the metadata
41
+ run: |
42
+ uv build
43
+ uvx twine check dist/*
44
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
45
+ with:
46
+ name: dist
47
+ path: dist/
48
+
49
+ publish:
50
+ needs: build
51
+ runs-on: ubuntu-latest
52
+ timeout-minutes: 15
53
+ environment: pypi
54
+ permissions:
55
+ id-token: write # OIDC; this is what replaces a stored token
56
+ steps:
57
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
58
+ with:
59
+ name: dist
60
+ path: dist/
61
+ - uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
@@ -0,0 +1,83 @@
1
+ name: reusable check
2
+
3
+ # The full check -- tests, lint, types, and the zero-dependency assertion -- factored
4
+ # into one reusable job so both `check.yml` (on push / PR) and any release gate run
5
+ # the *identical* thing.
6
+
7
+ on:
8
+ workflow_call:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ check:
15
+ runs-on: ubuntu-latest
16
+ timeout-minutes: 15
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ # The floor and the current release. requires-python is >=3.11, so 3.11 is
21
+ # the version that claim has to hold on; the upper end tracks current CPython.
22
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
23
+
24
+ steps:
25
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
26
+ with:
27
+ persist-credentials: false
28
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
29
+
30
+ - name: Install
31
+ run: |
32
+ uv venv --python ${{ matrix.python-version }}
33
+ uv pip install -e ".[dev]"
34
+ .venv/bin/python -c "import sys; print('testing on', sys.version)"
35
+
36
+ - name: Test
37
+ run: .venv/bin/pytest -q
38
+
39
+ - name: Lint
40
+ run: .venv/bin/ruff check src tests
41
+
42
+ - name: Types
43
+ run: .venv/bin/mypy
44
+
45
+ - name: Confirm the package still has no runtime dependencies
46
+ # The zero-dependency claim is in the README and pyproject; a claim nothing
47
+ # checks quietly stops being true. Installed into a bare environment, the
48
+ # package must import with nothing else present.
49
+ run: |
50
+ uv venv /tmp/bare --python ${{ matrix.python-version }}
51
+ uv pip install --python /tmp/bare/bin/python .
52
+ /tmp/bare/bin/python -c "
53
+ import importlib.metadata as md
54
+ requires = md.requires('krx-openapi') or []
55
+ runtime = [r for r in requires if 'extra ==' not in r]
56
+ assert not runtime, f'runtime dependencies appeared: {runtime}'
57
+ import krx_openapi
58
+ print('krx_openapi', krx_openapi.__version__, 'imports with no third-party packages')
59
+ "
60
+ # The console script runs, and its top-level --version prints (not shoved
61
+ # into a required subcommand).
62
+ /tmp/bare/bin/krx --version
63
+
64
+ - name: Confirm a user's type checker can see the hints
65
+ # Every hint in this package is invisible to a user unless py.typed ships
66
+ # alongside it (PEP 561), and the source cannot answer whether it did:
67
+ # src/krx_openapi/py.typed can sit in git while the built wheel omits it. So
68
+ # ask it the way a user does -- install the built package into a clean
69
+ # environment and run their checker over their code.
70
+ run: |
71
+ uv venv /tmp/typed --python ${{ matrix.python-version }}
72
+ uv pip install --python /tmp/typed/bin/python . mypy
73
+ cat > /tmp/user_code.py <<'PY'
74
+ from krx_openapi import KRX
75
+
76
+ # market is Literal["KOSPI","KOSDAQ","KONEX"]; an int is none of them, so a
77
+ # checker that can see the shipped hints must reject it. If py.typed is
78
+ # missing from the wheel, mypy skips krx_openapi and emits no such error.
79
+ KRX(api_key="k").stock.daily("20200414", market=123)
80
+ PY
81
+ /tmp/typed/bin/mypy /tmp/user_code.py > /tmp/mypy_out 2>&1 || true
82
+ cat /tmp/mypy_out
83
+ grep -q 'incompatible type' /tmp/mypy_out
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+ .env
11
+
12
+ # uv
13
+ uv.lock
14
+
15
+ # Tooling caches
16
+ .pytest_cache/
17
+ .ruff_cache/
18
+ .mypy_cache/
19
+ .coverage
20
+ htmlcov/
21
+
22
+ # Local scratch (never tracked)
23
+ dev/
24
+ refs/
25
+
26
+ # AI coding agents
27
+ CLAUDE.md
28
+ .claude/
29
+ AGENTS.md
30
+ AGENT.md
31
+ .codex/
32
+ GEMINI.md
33
+ .gemini/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Seokhoon Joo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.4
2
+ Name: krx-openapi
3
+ Version: 0.1.0
4
+ Summary: Read the Korea Exchange (KRX) Open API: indices, stocks, ETP, bonds, derivatives, commodities, ESG.
5
+ Project-URL: Homepage, https://github.com/seokhoonj/krx-openapi
6
+ Project-URL: Repository, https://github.com/seokhoonj/krx-openapi
7
+ Project-URL: Issues, https://github.com/seokhoonj/krx-openapi/issues
8
+ Author-email: Seokhoon Joo <seokhoonj@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: finance,korea,korea exchange,krx,market data,한국거래소
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Financial and Insurance Industry
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Office/Business :: Financial
22
+ Requires-Python: >=3.11
23
+ Provides-Extra: dev
24
+ Requires-Dist: mypy>=1.11; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.6; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # krx-openapi
30
+
31
+ [![check](https://github.com/seokhoonj/krx-openapi/actions/workflows/check.yml/badge.svg)](https://github.com/seokhoonj/krx-openapi/actions/workflows/check.yml)
32
+ [![PyPI](https://img.shields.io/pypi/v/krx-openapi)](https://pypi.org/project/krx-openapi/)
33
+ [![Python](https://img.shields.io/pypi/pyversions/krx-openapi)](https://pypi.org/project/krx-openapi/)
34
+ [![License](https://img.shields.io/pypi/l/krx-openapi)](https://github.com/seokhoonj/krx-openapi/blob/main/LICENSE)
35
+
36
+ [English](https://github.com/seokhoonj/krx-openapi/blob/main/README.en.md) | **한국어**
37
+
38
+ 한국거래소 **KRX Open API**의 일별 시장 데이터를 읽어옵니다.
39
+
40
+ 지수(KRX·KOSPI·KOSDAQ·채권·파생), 주식 일별매매정보와 종목기본정보, ETF·ETN·ELW,
41
+ 채권(국채·일반·소액), 선물·옵션, 석유·금·배출권, 그리고 ESG까지 — **공식 API가
42
+ 제공하는 7개 서비스, 31개 항목**을 다룹니다.
43
+
44
+ ## 1. 설치
45
+
46
+ ```bash
47
+ pip install krx-openapi
48
+ ```
49
+
50
+ 무료 인증키는 <https://openapi.krx.co.kr> 에서 발급받습니다. **인증키만으로는 호출이
51
+ 안 되고**, '서비스 이용' 메뉴에서 사용할 개별 API를 신청하고 승인을 받아야 합니다.
52
+
53
+ **config 파일 (모든 OS 공통, 권장)** — `~/.config/krx-openapi/credentials.json`
54
+ (`~`는 홈 폴더 — Linux `/home/이름`, macOS `/Users/이름`, Windows `C:\Users\이름`):
55
+
56
+ ```json
57
+ { "KRX_API_KEY": "발급받은-키" }
58
+ ```
59
+
60
+ **환경변수** — macOS·Linux: `export KRX_API_KEY=...` / Windows PowerShell:
61
+ `setx KRX_API_KEY "..."`.
62
+
63
+ ## 2. 빠른 시작
64
+
65
+ ```python
66
+ from krx_openapi import KRX
67
+
68
+ krx = KRX(api_key="your-key") # 또는 KRX() — 저장해둔 키(env/config)를 자동으로 찾음
69
+
70
+ rows = krx.index.kospi("20200414") # KOSPI 시리즈 지수, 하루치
71
+
72
+ krx.stock.daily("20200414", market="KOSPI") # KOSPI 전종목 일별매매정보
73
+ krx.etp.etf("20200414") # ETF 일별매매정보
74
+ ```
75
+
76
+ 날짜(`date`)는 `YYYYMMDD` 거래일입니다. 반환은 `dict`의 목록(`list`)이라, 표(DataFrame)로
77
+ 한 줄에 바뀝니다 (pandas는 필수가 아닙니다).
78
+
79
+ ```python
80
+ # pandas
81
+ import pandas as pd
82
+ pd.DataFrame(rows)
83
+
84
+ # polars
85
+ import polars as pl
86
+ pl.DataFrame(rows)
87
+ ```
88
+
89
+ ## 3. API
90
+
91
+ | 접근자 | 서비스 |
92
+ |---|---|
93
+ | `krx.index` | KRX·KOSPI·KOSDAQ 시리즈, 채권지수, 파생상품지수 일별시세 |
94
+ | `krx.stock` | KOSPI/KOSDAQ/KONEX 일별매매·종목기본정보, 신주인수권증권·증서 |
95
+ | `krx.etp` | ETF·ETN·ELW 일별매매정보 |
96
+ | `krx.bond` | 국채전문·일반·소액채권 일별매매정보 |
97
+ | `krx.derivatives` | 선물·옵션·주식선물·주식옵션 일별매매정보 |
98
+ | `krx.commodity` | 석유·금·배출권 일별매매정보 |
99
+ | `krx.esg` | 사회책임투자채권·ESG 지수·ESG 증권상품 |
100
+
101
+ 전체 메서드 (모든 인자 `date` = `YYYYMMDD` 거래일):
102
+
103
+ ```text
104
+ KRX()
105
+ ├─ index # 지수
106
+ │ ├─ .krx(date) KRX 시리즈 일별시세
107
+ │ ├─ .kospi(date) KOSPI 시리즈 일별시세
108
+ │ ├─ .kosdaq(date) KOSDAQ 시리즈 일별시세
109
+ │ ├─ .bond(date) 채권지수 시세
110
+ │ └─ .derivatives(date) 파생상품지수 시세
111
+ ├─ stock # 주식
112
+ │ ├─ .info(date, market="KOSPI") 종목기본정보 (KOSPI/KOSDAQ/KONEX)
113
+ │ ├─ .daily(date, market="KOSPI") 일별매매정보 (KOSPI/KOSDAQ/KONEX)
114
+ │ ├─ .warrant(date) 신주인수권증권
115
+ │ └─ .right(date) 신주인수권증서
116
+ ├─ etp # 증권상품
117
+ │ ├─ .etf(date) ETF
118
+ │ ├─ .etn(date) ETN
119
+ │ └─ .elw(date) ELW
120
+ ├─ bond # 채권
121
+ │ ├─ .treasury(date) 국채전문유통시장
122
+ │ ├─ .general(date) 일반채권시장
123
+ │ └─ .small_lot(date) 소액채권시장
124
+ ├─ derivatives # 파생상품
125
+ │ ├─ .futures(date) 선물 (주식선물外)
126
+ │ ├─ .options(date) 옵션 (주식옵션外)
127
+ │ ├─ .stock_futures(date, market="KOSPI") 주식선물 (KOSPI/KOSDAQ)
128
+ │ └─ .stock_options(date, market="KOSPI") 주식옵션 (KOSPI/KOSDAQ)
129
+ ├─ commodity # 일반상품
130
+ │ ├─ .oil(date) 석유시장
131
+ │ ├─ .gold(date) 금시장
132
+ │ └─ .emissions(date) 배출권시장
133
+ └─ esg # ESG
134
+ ├─ .sri_bond(date) 사회책임투자채권
135
+ ├─ .index(date) ESG 지수
136
+ └─ .etp(date) ESG 증권상품
137
+ ```
138
+
139
+ 어떤 서비스에 어떤 필드가 오는지는 네트워크 없이 오프라인으로 확인할 수 있습니다.
140
+
141
+ ```python
142
+ from krx_openapi import catalog
143
+
144
+ catalog.groups() # ['index', 'stock', ...]
145
+ catalog.methods("bond") # ['treasury', 'general', 'small_lot']
146
+ catalog.fields("index", "kospi") # 이 서비스가 돌려주는 필드명 (컬럼)
147
+ ```
148
+
149
+ ## 4. 커맨드라인
150
+
151
+ 명령줄은 세 명령 `list` · `fields` · `fetch`를 씁니다. `list`·`fields`는 오프라인(키
152
+ 불필요)으로 뭐가 있고 어떤 컬럼이 오는지 훑고, `fetch`는 하루치 데이터를 가져옵니다 —
153
+ `krx fetch <그룹> <메서드> <날짜>` (예: `krx fetch index kospi 20200414` =
154
+ `krx.index.kospi("20200414")`). 명령은 `krx` 또는 `python -m krx_openapi`로 실행하고,
155
+ 어디에 `--json`을 붙이면 JSON으로 나옵니다.
156
+
157
+ ```bash
158
+ # 무슨 서비스가 있나 / 어떤 컬럼이 오나 (오프라인, 키 불필요)
159
+ krx list # 전체 그룹·메서드
160
+ krx list stock # 한 그룹만
161
+ krx fields index kospi # 이 서비스가 돌려주는 컬럼
162
+
163
+ # 데이터 조회 (KRX_API_KEY 필요)
164
+ krx fetch index kospi 20200414
165
+ krx fetch stock daily 20200414 --market KOSDAQ
166
+ krx fetch bond treasury 20200414
167
+ ```
168
+
169
+ ## 5. AI 코딩 에이전트에서 사용
170
+
171
+ - 이 저장소는 Claude Code·Codex용 플러그인 마켓플레이스도 겸합니다.
172
+ - `list`·`fields`·`fetch` 스킬을 제공하며, 각각 같은 이름의 `krx` 명령을 호출합니다
173
+ (`krx list`, `krx fields <그룹> <이름>`, `krx fetch <그룹> <이름> <날짜>`).
174
+ - 먼저 위에서 패키지를 설치하세요 (`list`·`fields`는 키 없이, `fetch`는 API 키가 필요합니다).
175
+
176
+ ### 5.1 Claude Code
177
+
178
+ ```
179
+ /plugin marketplace add seokhoonj/krx-openapi
180
+ /plugin install krx@krx-openapi
181
+ ```
182
+
183
+ 설치 후 평범하게 물어보거나("코스피 전종목 시세 가져와", "무슨 KRX 서비스 있어"), 스킬을
184
+ 직접 부르세요 — `/krx:list`, `/krx:fields index kospi`, `/krx:fetch index kospi 20200414`.
185
+
186
+ ### 5.2 Codex
187
+
188
+ ```
189
+ codex plugin marketplace add seokhoonj/krx-openapi
190
+ codex plugin add krx@krx-openapi
191
+ ```
192
+
193
+ ### 5.3 플러그인 없이 (symlink)
194
+
195
+ 플러그인으로 설치하지 않고 쓰려면, 스킬을 각 에이전트의 스킬 디렉터리에 symlink합니다.
196
+
197
+ ```sh
198
+ for s in list fields fetch; do
199
+ ln -s "$PWD/plugins/krx/skills/$s" ~/.claude/skills/$s # Claude Code → /$s
200
+ ln -s "$PWD/plugins/krx/skills/$s" ~/.codex/skills/$s # Codex → $krx:$s
201
+ done
202
+ ```
203
+
204
+ Claude Code는 바로 인식하고, Codex는 재시작해야 로딩됩니다.
205
+
206
+ ## 6. 주의사항
207
+
208
+ - **일별 데이터만.** 당일·실시간·장중 데이터는 없습니다. 전일 데이터가 **다음 영업일
209
+ 오전 8시**에 갱신됩니다. 주말·공휴일, 갱신 전 조회는 빈 결과입니다.
210
+ - **호출 한도**: 인증키당 **하루 10,000회**(IP 아님, 자정 리셋). 초과 시
211
+ `KRXRateLimitError`(HTTP 429). 과도한 호출은 IP 차단 사유가 됩니다.
212
+ - **단순주가(원주가)만** 제공합니다. 수정주가는 없습니다.
213
+ - **API 미제공 데이터**: 투자자별 거래실적, 외국인 보유량, 공매도, PER/PBR,
214
+ ETF 구성종목(PDF), 지정내역(투자경고·거래정지·관리종목) 등은 제공되지 않습니다.
215
+ - **이용약관**: 비상업적 목적(개인 연구·투자)만 허용됩니다. 가공하여 표출할 때는 **출처
216
+ "한국거래소 통계정보"**를 표기하고, 원천 데이터를 제3자에게 재배포할 수 없습니다.
217
+ 자세한 내용은 KRX Open API 이용약관을 확인하세요.
218
+
219
+ ## 7. 에러
220
+
221
+ 모든 에러는 `KRXError`를 상속합니다.
222
+
223
+ | 예외 | 언제 |
224
+ |---|---|
225
+ | `KRXConfigError` | 인증키를 찾을 수 없음 (요청 전) |
226
+ | `KRXAuthError` | 키 거부 또는 **미신청 서비스** (respCode 401) |
227
+ | `KRXRateLimitError` | 일일 호출 한도 초과 (HTTP 429) |
228
+ | `KRXResponseError` | 그 밖의 벤더 에러 (respCode) |
229
+ | `KRXNetworkError` | 전송 실패·비-JSON 응답·기타 HTTP 에러 |
230
+
231
+ 잘못된 `market` 코드는 `ValueError`, 모르는 서비스 이름은 `KeyError`입니다.
232
+
233
+ ## 8. 라이선스
234
+
235
+ MIT. 이 패키지의 코드에 대한 라이선스이며, KRX 데이터 자체의 이용 조건은 위 KRX
236
+ 이용약관을 따릅니다.