Content
<h1 align="center">DB Securities Open API Sample Code (Python)</h1>
<p align="center">
<img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+">
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT">
<img src="https://img.shields.io/badge/DB%20Securities-Open%20API-orange.svg" alt="DB Securities Open API">
</p>
<p align="center">
A Python library and example collection for calling DB Securities Open API endpoints with a single client.<br>
Supports domestic stocks, overseas stocks, domestic futures options, overseas futures options, exchange-traded bonds, and real-time WebSocket.
</p>
<p align="center">
<a href="https://openapi.dbsec.co.kr" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/badge/DB%20Securities_Open_API_Portal-00A862?style=flat-square&logoColor=white" alt="DB Securities Open API Portal">
</a>
</p>
---
## Purpose and Target Users
### Purpose of Sample Code
This repository is a Python sample code repository for DB Securities Open API, designed to be intuitively learnable and applicable in both **generative AI-based coding environments** (ChatGPT, Claude, Gemini) and **traditional Python development environments**.
- **`dbsec_sdk/`** authentication, HTTP client, WebSocket client
- **`examples/`** — API examples, one file per API endpoint (`<method>.py`) — all standalone and executable
- **`mcp_server/`** — MCP server for LLM coding tools (Claude Code, Cursor, etc.) to query API groups, specifications, and sample code
- **MCP and LLM-friendly naming** — method names prefixed with market domain identifiers (`kr_stock_*`, `ov_stock_*`, `kr_futopt_*`, `ov_futopt_*`, `bond_*`)
### Target Users
- Python developers new to DB Securities Open API
- Individual investors who want to backtest or automate their investment ideas using code
- Developers with experience in other securities company Open APIs or considering multi-broker configurations
- Users who want to build stock exploration, market analysis, and automated trading using LLM code agents (including MCP tools)
---
**[Important Notes on Using OpenAPI Sample Code]**
- This sample code provides examples of how to integrate with DB Securities Open API. It is provided as a reference to help you get started with your development.
- The sample code may be continuously improved and updated, and changes may be made without separate notice.
- The sample code is provided as a reference example, so please ensure that you thoroughly review and test it before applying it to your actual service.
- We are not responsible for any direct or indirect damages caused by malfunctions, trading losses, data errors, etc. that occur during the development, operation, or use of programs developed or operated using this sample code.
- Actual trading orders may be executed, so be sure to test in a **simulated investment environment** first.
- The access token is valid for **24 hours**, and if issued within the valid period, the **same token** will be issued. If you want to reissue a token within the valid period, please discard the existing token and issue a new one.
- For details on TR code InBlock/OutBlock, refer to the [DB Securities API Guide](https://openapi.dbsec.co.kr/apiservice).
- When receiving real-time market data for overseas stocks, you need to apply for real-time market data (free) through MTS/HTS.
- When receiving real-time market data for overseas futures options, you need to apply for real-time market data (paid) through GMTS/GTS.
---
## Table of Contents
- [Key Features](#key-features)
- [Prerequisites](#prerequisites)
- [Quick Start (5 minutes)](#quick-start-5-minutes)
- [Using the examples Folder](#using-the-examples-folder)
- [MCP Server](#mcp-server)
- [Folder Structure](#folder-structure)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Authentication (Automatic Token)](#1-authentication-automatic-token)
- [Unified API Call Pattern — `client.apis`](#2-unified-api-call-pattern--clientapis)
- [Domestic Stocks — Orders/Inquiries](#3-domestic-stocks--ordersinquiries)
- [Other Products — Overseas Stocks, Futures Options, Bonds, Charts, WebSocket](#4-other-products--overseas-stocks-futures-options-bonds-charts-websocket)
- [DataFrame Conversion](#5-dataframe-conversion)
- [All Groups & APIs](#all-groups--apis)
- [Method Naming Conventions (Domain Prefix)](#method-naming-conventions-domain-prefix)
- [Production vs. Simulated Investment](#production-vs-simulated-investment)
- [Error Codes & Rate Limiting](#error-codes--rate-limiting)
- [Appendix — API Simulated Investment Support Status](#appendix--api-simulated-investment-support-status)
---
## Key Features
| Feature | Description |
|------|------|
| **API Coverage** | DB Securities Open API **full endpoint coverage** |
| **Asynchronous Client** | `DBSecClient` is **asynchronous** — `await client.apis.group.method(...)`. Can be called concurrently using `asyncio.gather`. |
| **Single Entry Point** | Client creation with one line of code, handling authentication, token caching, and continuous inquiries automatically. |
| **Domain-Prefixed Methods** | Method names prefixed with market identifiers (e.g., `kr_stock_order`, `ov_stock_inquire_balance_margin`) for easy identification. |
| **Automatic Rate Limiting** | 2-tier automatic pacing to prevent `IGW00201` (excessive calls). |
| **Automatic Token Issuance/Reissuance** | `auto_token=True` (default): automatic token issuance and reissuance when the token is invalid or expires. |
| **Flexible Response** | `APIResponse` dict wrapper, with optional conversion to DataFrame using `resp.to_dataframe(key="Out1")`. |
| **WebSocket Automation** | Built-in connection, reconnection, subscription restoration, and termination lifecycle management. |
| **Individual Executable Examples** | `examples/<group>/<method>.py` — copy, modify values, and execute. |
| **LLM and AI Agent Friendly** | [`llms.txt`](llms.txt) (repository structure, specifications, and example guidance) + MCP server for easy API exploration. |
---
## Prerequisites
1. **Open a DB Securities account** — [non-face-to-face account opening](https://www.dbsec.co.kr/custcenter/account/cu_NonfaceBranch_viw.do)
2. **Apply for Open API usage** — apply through the DB Securities website -> OpenAPI service application menu (https://www.dbsec.co.kr/online/accservice/on_OpenApi_wrk00.do)
3. **Obtain APP_KEY and APP_SECRET** — issued after application completion
4. **Apply for simulated investment** — required before applying for OpenAPI apps for simulated investment — DB Securities website -> simulated investment -> regular simulated investment application menu (https://www.dbsec.co.kr/custcenter/vts/vts_Index_viw02.do)
5. **Install Python 3.10 or higher**
---
## Quick Start (5 minutes)
> If you're new to programming or need step-by-step guidance, refer to **[HOWTOUSE.md](HOWTOUSE.md)** (beginner's guide).
```bash
git clone https://github.com/DBsecurities/dbsec-open-api.git
cd dbsec-open-api
pip install -e . # install dbsec_sdk and dependencies (requests, pyyaml, websockets, pandas)
cp config.yaml.example config.yaml # input APP_KEY/SECRET and mode: demo (macOS/Linux/Git Bash)
# Windows CMD: copy config.yaml.example config.yaml
# Windows PowerShell: Copy-Item config.yaml.example config.yaml
python dbsec_sdk/client_examples/quickstart.py # SDK demo (read-only inquiries)
# or run a standalone example (using examples/dbsec_helper.py): python examples/kr_stock_quote/kr_stock_inquire_price.py
```
`DBSecClient` is an **asynchronous** client (use `await` for all calls, and `asyncio.run` for entry).
```python
import asyncio
from dbsec_sdk import DBSecClient
async def main():
# create client — with rate limiting and token options (all default values, so can be omitted: DBSecClient("config.yaml"))
async with DBSecClient(
"config.yaml",
rate_limit=True, # rate limiting: prevents IGW00201 (excessive calls) by adjusting app TPS and API TPS intervals
rate_limit_safety=0.9, # safety factor (0 < s ≤ 1): actual rate = app TPS × s. 0.9 = 90% (10% margin, recommended)
auto_token=True, # automatic token issuance and reissuance
rate_limit_backoff=True, # exponential backoff: retry after 1, 2, 4, 8 seconds if IGW00201 occurs
) as client:
# domestic stock current price inquiry — Samsung Electronics (read-only)
resp = await client.apis.kr_stock_quote.kr_stock_inquire_price(
InputCondMrktDivCode="J", # J: KRX stock
InputIscd1="005930") # Samsung Electronics
# check response success (rsp_cd == "00000") before using values
if resp.rsp_cd == "00000":
out = resp.body["Out"]
print(f"Samsung Electronics current price: {int(out['Prpr']):,} KRW\n")
# print all response fields (or convert to DataFrame using resp.to_dataframe())
for field, value in out.items():
print(f" {field}: {value}")
else:
print(f"[{resp.rsp_cd}] inquiry failed: {resp.rsp_msg}")
asyncio.run(main())
```
---
## Using the examples Folder
`examples/` contains **standalone scripts** that can be executed without the SDK. Each API has one file (`<method>.py`), and they work with `examples/dbsec_helper.py` (standard library + `requests` and `pyyaml`).
### Execution
```bash
cp config.yaml.example config.yaml # input APP_KEY and mode: demo (once, macOS/Linux/Git Bash)
# Windows CMD: copy config.yaml.example config.yaml
# Windows PowerShell: Copy-Item config.yaml.example config.yaml
# from repository root:
python examples/kr_stock_quote/kr_stock_inquire_price.py
# or from within examples/:
cd examples && python kr_stock_quote/kr_stock_inquire_price.py
```
- The token cache `.dbsec_token.json` is used first (shared with SDK), and if no valid cache is found, the user is prompted to issue a token on the first run — `[1]` issue and continue / `[2]` cancel (default). In non-interactive environments (pipes/CI), the prompt is safely skipped.
### REST Inquiry/Order Example Pattern
```python
import sys, pathlib
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1])) # add dbsec_helper path
from dbsec_helper import call_rest, print_response
resp, data = call_rest( # call_rest makes the request and returns (resp, data)
url="/api/v1/quote/kr-stock/inquiry/price",
body={"In": {"InputCondMrktDivCode": "J", "InputIscd1": "005930"}},
label="current price inquiry",
)
print_response(resp, data) # print entire response (optional)
print("current price:", data["Out"]["Prpr"]) # extract and use values
# for paginated inquiries, use pages = call_rest_paged(...)
```
### Real-time (WebSocket) Example Pattern
```python
from dbsec_helper import ws_subscribe, run_ws
run_ws(ws_subscribe(
tr_cd="S00", # trade TR
tr_key="", # stock code (or account for account-based TR)
group_slug="kr_stock_realtime",
tr_type="1", # subscription type (directly specified): 1 = subscribe, 2 = unsubscribe, 3 = account registration
)) # exit with Ctrl+C (tr_type="1" subscription will be unsubscribed before exiting)
```
> `tr_type` is directly specified by the caller (not automatically determined). For regular market TR, use `tr_type="1"`, and for account-based TR (`IS0/IS1/IS2/IF0/O/P` — order receipt, execution, balance), use `tr_type="3"`.
> **examples vs. SDK** — `examples/` is for quick learning and one-off testing using `call_rest("/api/...", body={...})` (free dict input, synchronous), while `dbsec_sdk/` is for embedding in apps/bots using `await client.apis.group.method(field=value)` (type signature, asynchronous, rate limiting, automatic token issuance). Refer to [docs/sdk_usage.md](docs/sdk_usage.md) for detailed SDK usage.
## MCP Server for Code Assistant
`mcp_server/` is an MCP (stdio) server that allows LLM coding tools (such as Claude Desktop, Claude Code, and Cursor) to directly query the **list of groups and endpoints**, **request (In) and response (Out) parameter specifications**, and **executable sample code** for the DB Securities Open API.
| Tool | Description |
|---|---|
| `list_api_groups()` | List of groups + number of APIs per group + number of simulation supports |
| `search_apis(query, group?)` | Search APIs by keyword, TR code, slug, or path (supports Korean) |
| `get_api_spec(identifier)` | Endpoint, TPS, **In/Out parameters**, and request/response examples |
| `get_sample_code(identifier)` | Original Python sample code for the API |
| `get_setup_guide()` | Installation, setup, token issuance, and execution start guide |
```bash
pip install -r mcp_server/requirements.txt
python mcp_server/run_server.py # From the repository root (local)
python /absolute/path/to/dbsec-open-api/mcp_server/run_server.py # Regardless of cwd (same for Claude Desktop)
```
- The server synchronizes with the remote repository by performing a **`git fetch` + `git reset --hard`** when it starts — **it does not commit or push**. Untracked files (such as `config.yaml` and `.dbsec_token.json`) are preserved.
- In environments that do not guarantee `cwd`, such as Claude Desktop, specify the **absolute path to `run_server.py`** in `args` (no `cwd` required).
- Environment variables `DBSEC_MCP_GIT_REPO` (clone target URL), `DBSEC_MCP_GIT_BRANCH`, `DBSEC_MCP_GIT_DIR`, and `DBSEC_MCP_GIT_SKIP_SYNC` (offline) control the behavior.
- Refer to **[mcp_server/README.md](mcp_server/README.md)** for client registration methods (`mcpServers` JSON) and verification.
> Each example docstring's `응답 파라미터 (Out)` section is based on the portal specification.
> If the API changes, directly modify the **docstring of the example file**, and it will be reflected in the MCP server.
## Folder Structure
```
dbsec-open-api/
├── pyproject.toml # Package settings (pip + uv)
├── requirements.txt # Dependencies
├── config.yaml.example # Configuration template
│
├── dbsec_sdk/ # Client library
│ ├── client.py # DBSecClient (asynchronous single entry point) + internal synchronous core
│ ├── config.py # Configuration (YAML + env)
│ ├── auth.py # OAuth2 token lifecycle (get_token/force_refresh/revoke) + auto_token automatic issuance
│ ├── rate_limiter.py # Rate limiting (app 20TPS + endpoint-specific TPS, 2-tier)
│ ├── exceptions.py # APIError + error code reference
│ ├── response.py # APIResponse + to_dataframe()
│ │
│ ├── apis/ # ★ Group-specific API methods
│ │ ├── registry.py # APIRegistry — client.apis entry point
│ │ ├── auth/ # OAuth authentication
│ │ ├── common/ # Interested stocks
│ │ ├── kr_stock_order/ # Domestic stock orders
│ │ ├── kr_stock_quote/ # Domestic stock quotes
│ │ ├── kr_stock_realtime/ # Domestic stock real-time
│ │ ├── kr_futopt_order/ # Domestic futures and options orders
│ │ ├── kr_futopt_quote/ # Domestic futures and options quotes
│ │ ├── kr_futopt_realtime/ # Domestic futures and options real-time
│ │ ├── kr_chart/ # Domestic stock and futures charts
│ │ ├── ov_stock_order/ # Overseas stock orders
│ │ ├── ov_stock_quote/ # Overseas stock quotes
│ │ ├── ov_stock_realtime/ # Overseas stock real-time
│ │ ├── ov_futopt_order/ # Overseas futures and options orders
│ │ ├── ov_futopt_quote/ # Overseas futures and options quotes
│ │ ├── ov_futopt_realtime/ # Overseas futures and options real-time
│ │ ├── bond_order/ # Bond orders
│ │ ├── bond_quote/ # Bond quotes
│ │ ├── bond_realtime/ # Bond real-time
│ │ └── ws_common/ # WebSocket common
│ │
│ ├── websocket/ # Real-time WebSocket (stream.py)
│ └── client_examples/ # SDK (client.apis.*) usage examples
│ ├── quickstart.py # Read-only query demo (async)
│ ├── kr-stock-trading-basic.ipynb # Domestic stock trading basics (notebook)
│ └── ov-stock-trading-basic.ipynb # Overseas stock trading basics (notebook)
│
├── examples/ # Group-specific standalone examples (call_rest style)
│ ├── dbsec_helper.py # Common helper (config loading, token, REST/WS calls)
│ └── <group_slug>/
│ ├── README.md # Method list within the group + call patterns
│ └── <method>.py # One file per API — independent execution (docstring with In/Out specifications)
│
├── mcp_server/ # Code assistant MCP server (stdio)
│ ├── run_server.py # Entry point (cwd-independent): sync→indexing→server startup
│ ├── sync.py # GitHub forced synchronization fetch+reset (no commit/push)
│ ├── catalog.py # examples + api_support_matrix.md parsing index
│ └── server.py # FastMCP tools (list/search/spec/sample/guide)
│
├── HOWTOUSE.md # Step-by-step usage guide for beginners
└── docs/ # Guide documents
├── sdk_usage.md # dbsec_sdk SDK usage (client.apis.*)
├── api_support_matrix.md # API inventory + simulation support ⭕/❌ + endpoint-specific TPS
└── errors_and_rate_limits.md # Error codes and rate limits
```
## Installation
### pip
```bash
pip install -e .
```
### uv (recommended)
```bash
uv pip install -e .
```
### Dependencies
| Package | Purpose | Required |
|--------|------|:----:|
| `requests` | REST API calls | ✓ |
| `websockets` | Real-time WebSocket communication | ✓ |
| `python-dotenv` | Environment variable management | ✓ |
| `pyyaml` | YAML configuration file loading | ✓ |
| `pandas` | `resp.to_dataframe()` · examples (quickstart·notebooks) | ✓ |
## Configuration
### 1. Create a configuration file
```bash
cp config.yaml.example config.yaml # macOS / Linux / Git Bash
# Windows CMD: copy config.yaml.example config.yaml
# Windows PowerShell: Copy-Item config.yaml.example config.yaml
```
### 2. Modify `config.yaml`
```yaml
auth:
# Production
prd_app_key: "app key"
prd_app_secret: "app key secret"
# Simulation
vtl_app_key: "simulation app key"
vtl_app_secret: "simulation app key secret"
environment:
base_url: "https://openapi.dbsec.co.kr:8443"
# WebSocket — general (most groups)
ws_production: "wss://openapi.dbsec.co.kr:7070/websocket"
ws_demo: "wss://openapi.dbsec.co.kr:17070/websocket"
# WebSocket — overseas futures and options (ov_futopt) dedicated port — operational only (no simulation support)
ws_production_ov_futopt: "wss://openapi.dbsec.co.kr:7071/websocket"
mode: "demo" # "production" → prd_* / "demo" → vtl_*
```
> ⚠️ **Overseas futures and options (`ov_futopt_*`) do not support simulation**. Only available in **operational** (`mode: "production"`) environments. `dbsec_helper` and `dbsec_sdk.Config.ws_url_for()` explicitly block simulation mode calls.
## Usage
### 1. Authentication (automatic token)
`DBSecClient` is an **asynchronous** client — all calls require `await`, and entry points use `asyncio.run()`.
```python
import asyncio
from dbsec_sdk import DBSecClient
async def main():
async with DBSecClient("config.yaml") as client:
# auto_token=True (default): automatic token issuance on the first API call (if absent or expired/invalid)
...
asyncio.run(main())
```
> **Token policy**: 24-hour validity. Requests for reissuance within 24 hours return the existing token. If a new token is needed, use `await client.force_refresh()` (revoke→reissue). Tokens are valid until expiration *time* and do not renew before expiration.
> **`auto_token` (default True)**: If the token is absent or invalid/expired (IGW00121/00123), the SDK automatically issues or reissues it (no stdin prompt → safe for headless/bot/CI environments). Reissue of token rejection responses is limited to `token_retry_limit` times (default 5).
> **`auto_token=False`**: Do not automatically issue tokens → if no token exists, an `AuthError` occurs; if invalid/expired, an `APIError` occurs. Manage tokens directly using `await client.get_token()` / `force_refresh()` / `revoke()`.
To handle tokens explicitly:
```python
token = await client.get_token() # Secure current token (if not in cache, issue)
await client.force_refresh() # Forced renewal (discard and reissue)
await client.revoke() # Discard (server invalidation + local cache deletion)
```
### 2. Integrated API call pattern — `client.apis`
All APIs are called in the form `await client.apis.<group_slug>.<method_name>(...)`.
(These snippets assume execution within an **async function**, like the above `main()`.)
```python
resp = await client.apis.<group_slug>.<method_name>(
field1=value,
field2=value,
...
cont_yn="N", # Continuous transaction flag (default N; fetch_all automatically receives all)
cont_key="", # Continuous key (automatically pass if direct paging is not required)
)
```
- `<group_slug>` : `kr_stock_order`, `ov_stock_quote`, `kr_futopt_realtime`, `bond_order`, etc.
- `<method_name>` : Domain prefix + action/target. Examples: `kr_stock_order`, `ov_stock_inquire_balance_margin`
- Return value: `APIResponse` (`.body`, `.rsp_cd`, `.message`, `.to_dataframe()`, `.has_more`, `.cont_key`)
#### Continuous inquiry (automatic paging) — `fetch_all=True`
For queries with multiple pages of results (rankings, stock inquiries, time-based transactions, tick charts, etc.),
**simply call as usual with `fetch_all=True`** to receive **all results merged into one `APIResponse`** until the server indicates the end (`cont_yn='N'`).
```python
# Same call as usual + fetch_all=True (list block Out1/Out2 accumulates across pages)
resp = await client.apis.kr_stock_quote.kr_stock_inquire_condition_rise_fall(
InputDateClsCode="0",
InputRankSortClsCode1="12", # Today / rising rate
InputMrktClsCode="K",
InputBstpIscd="1001", # KOSPI
fetch_all=True)
df = resp.to_dataframe() # Accumulated results from all pages
n_pages = len(resp.pages) # Number of pages received (original pages accessible via resp.pages)
# For very large queries (e.g., tick charts), set a limit on the number of pages (default None = until the end)
ticks = await client.apis.kr_chart.kr_chart_chart_tick(
**tick_args,
fetch_all=True,
max_pages=10)
# Low-level (direct raw path call): post_paged / get_paged → list[APIResponse]
pages = await client.post_paged("/api/v1/quote/kr-chart/tick", {"In": {...}})
- Continuous key parameters (`cont_yn`/`cont_key`) are automatically processed, so you don't need to worry about them.
- Each page call has **automatic pacing for traffic control** (no separate sleep needed).
- The old version `client.fetch_all(method, …)` also works for backward compatibility, but the above `fetch_all=True` form is recommended.
### 3. Domestic Stock — Order/Inquiry
#### 3-1. Comprehensive Order (CSPAT00600)
```python
# Market price buy
resp = await client.apis.kr_stock_order.kr_stock_order(
IsuNo="A005930", # A + 6 digits (Samsung Electronics)
OrdQty=1,
OrdPrc=0, # 0 for market price
BnsTpCode="2", # 1: sell, 2: buy
OrdprcPtnCode="03", # 00: specified price, 03: market price, 05: conditional specified, 06: best bid, 07: best ask
MgntrnCode="000", # 000: normal (general order), credit redemption 101/103/105/107/180
LoanDt="00000000", # General: 00000000, credit sale: settlement date (YYYYMMDD)
OrdCndiTpCode="0", # 0: none, 1: IOC, 2: FOK
TrchNo=1, # 1: KRX fixed
)
print(resp.body["Out"]["OrdNo"])
```
#### 3-2. Correction/Cancellation
```python
# Correction order (CSPAT00700)
await client.apis.kr_stock_order.kr_stock_order_modify(
OrgOrdNo=14404,
IsuNo="A005930",
OrdQty=5,
OrdprcPtnCode="00",
OrdCndiTpCode="0",
OrdPrc=80000)
# Cancellation order (CSPAT00800)
await client.apis.kr_stock_order.kr_stock_order_cancel(
OrgOrdNo=14414,
IsuNo="A005930",
OrdQty=10)
```
#### 3-3. Balance / Execution / Deposit
```python
# Multiple inquiries can be done simultaneously using asyncio.gather (traffic control automatically complies with TPS)
balance, deposit = await asyncio.gather(
client.apis.kr_stock_order.kr_stock_inquire_balance(QryTpCode0="0"),
client.apis.kr_stock_order.kr_stock_inquire_deposit(),
)
executions = await client.apis.kr_stock_order.kr_stock_inquire_executions(
SorTpYn="2",
ExecYn="0",
TrdMktCode="0",
BnsTpCode="0",
IsuTpCode="0",
QryTp="0")
psbl_qty = await client.apis.kr_stock_order.kr_stock_inquire_psbl_quantity(
BnsTpCode="2",
IsuNo="A005930",
OrdPrc=77000)
```
#### 3-4. Market Data
```python
price = await client.apis.kr_stock_quote.kr_stock_inquire_price(
InputCondMrktDivCode="J",
InputIscd1="005930")
orderbook = await client.apis.kr_stock_quote.kr_stock_inquire_orderbook(
InputCondMrktDivCode="J",
InputIscd1="005930")
ranks = await client.apis.kr_stock_quote.kr_stock_inquire_condition_rise_fall(...)
```
### 4. Other Products — Overseas Stock · Futures Options · Bonds · Charts · WebSocket
Same pattern as domestic stock: `client.apis.<group>.<method>(...)`. For each group's methods, parameters, and examples, refer to the group's README.
| Product | Main Methods | Group Guide |
|-------|----------------|--------------|
| Overseas Stock Order/Inquiry | `ov_stock_order`, `ov_stock_inquire_balance_margin` | [examples/ov_stock_order](examples/ov_stock_order/README.md) · [quote](examples/ov_stock_quote/README.md) · [realtime](examples/ov_stock_realtime/README.md) |
| Domestic Futures Options | `kr_futopt_order`, `kr_futopt_order_night`, `kr_futopt_inquire_balance` | [order](examples/kr_futopt_order/README.md) · [quote](examples/kr_futopt_quote/README.md) · [realtime](examples/kr_futopt_realtime/README.md) |
| Overseas Futures Options ⚠️ (operational only) | `ov_futopt_order`, `ov_futopt_inquire_open_interest` | [order](examples/ov_futopt_order/README.md) · [quote](examples/ov_futopt_quote/README.md) · [realtime](examples/ov_futopt_realtime/README.md) |
| Exchange-Traded Bonds | `bond_order`, `bond_inquire_balance`, `bond_inquire_price` | [order](examples/bond_order/README.md) · [quote](examples/bond_quote/README.md) · [realtime](examples/bond_realtime/README.md) |
| Charts (domestic stock and futures) | `kr_chart_tick`, `kr_chart_day` | [kr_chart](examples/kr_chart/README.md) |
| WebSocket Real-time | `client.create_websocket()` → `add_realtime(tr_cd, tr_key, tr_type)` (1=market data subscription, 3=account registration) | [kr_stock_realtime](examples/kr_stock_realtime/README.md) · [ws_common](examples/ws_common/README.md) |
### 5. DataFrame Conversion
```python
resp = await client.apis.kr_stock_order.kr_stock_inquire_balance(QryTpCode0="0")
print(resp.body["Out"]["TotEvalAmt"]) # dict as is (no pandas needed)
df = resp.to_dataframe() # automatic exploration (list[dict] priority)
df = resp.to_dataframe(key="Out1") # specify a block
```
## All Groups & APIs
| Group | slug | Note |
|------|------|------|
| OAuth Authentication | `auth` | token issuance/disposal |
| Common | `common` | favorites |
| **Domestic Stock Order** | `kr_stock_order` | includes NXT, balance, execution, deposit, credit |
| Domestic Stock Quote | `kr_stock_quote` | stock/current price/quote/execution/investor/sector |
| Domestic Stock Real-time | `kr_stock_realtime` | order execution/quote/ELW/industry index |
| **Domestic Futures Options Order** | `kr_futopt_order` | daytime/nighttime separated |
| Domestic Futures Options Quote | `kr_futopt_quote` | stock/current price/quote/execution/board |
| Domestic Futures Options Real-time | `kr_futopt_realtime` | index/stock/commodity futures/options, mini, weekly, KOSDAQ150, nighttime |
| Domestic Stock/Futures Chart | `kr_chart` | tick/minute/day/week/month |
| **Overseas Stock Order** | `ov_stock_order` | US stock, balance/margin/average purchase price |
| Overseas Stock Quote | `ov_stock_quote` | current price/quote/execution + 5 chart types |
| Overseas Stock Real-time | `ov_stock_realtime` | execution price/quote + delayed version |
| **Overseas Futures Options Order** | `ov_futopt_order` | order/execution/unsettled/margin |
| Overseas Futures Options Quote | `ov_futopt_quote` | quote & current price + chart (futures/options separated) |
| Overseas Futures Options Real-time | `ov_futopt_realtime` | order execution/balance/market data/quote |
| Exchange-Traded Bond Order | `bond_order` | buy/sell/modify/cancel/balance |
| Exchange-Traded Bond Quote | `bond_quote` | detailed search/current price/quote |
| Exchange-Traded Bond Real-time | `bond_realtime` | general/small bond execution/quote |
| WebSocket Common | `ws_common` | session initialization |
> For detailed method names, refer to `docs/api_support_matrix.md` or each group's `examples/<slug>/README.md`.
## Method Naming Conventions (domain prefix)
MCP tool exposure or LLM agent usage **method name identifies market domain** consistently.
| Domain | Prefix | Example |
|--------|--------|------|
| Domestic Stock | `kr_stock_` | `kr_stock_order`, `kr_stock_inquire_balance`, `kr_stock_realtime_execution_price` |
| Overseas Stock | `ov_stock_` | `ov_stock_order`, `ov_stock_inquire_balance_margin`, `ov_stock_realtime_orderbook` |
| Domestic Futures Options | `kr_futopt_` | `kr_futopt_order`, `kr_futopt_inquire_balance`, `kr_futopt_realtime_index_future_orderbook` |
| Overseas Futures Options | `ov_futopt_` | `ov_futopt_order`, `ov_futopt_inquire_open_interest`, `ov_futopt_realtime_future_quote` |
| Exchange-Traded Bonds | `bond_` | `bond_order`, `bond_inquire_balance`, `bond_realtime_normal_execution` |
| Chart (domestic stock and futures) | `kr_chart_` | `kr_chart_tick`, `kr_chart_day`, `kr_chart_month` |
| Authentication / Common / WebSocket | (none) | `token_issue`, `inquire_group_list`, `ws_session_disconnect` |
**Verb/Subject Pattern**
| Verb | Meaning |
|------|------|
| `order`, `order_modify`, `order_cancel`, `order_buy`, `order_sell` | order |
| `inquire_*` | inquiry (balance/execution/deposit/realized profit/loss, etc.) |
| `realtime_*` | WebSocket real-time |
| `chart_*` | time-series chart |
| `search_*` | stock/code master search |
| `token_*`, `ws_*` | authentication/session control |
→ All methods **globally unique** (within and between groups, 0 duplicates)
## Production vs. Simulation
| Item | Production | Simulation |
|------|------|----------|
| **REST API URL** | `https://openapi.dbsec.co.kr:8443` | **Same** (app attribute for internal branching) |
| **WebSocket URL (general)** | `wss://openapi.dbsec.co.kr:7070/websocket` | `wss://openapi.dbsec.co.kr:17070/websocket` |
| **WebSocket URL (ov_futopt)** | `wss://openapi.dbsec.co.kr:7071/websocket` | — (not supported) |
| **APP_KEY / APP_SECRET** | issued for production | issued for simulation |
> REST API has the same URL for production and simulation. The server branches based on the app key's attributes. **Only WebSocket ports differ** (production: 7070, simulation: 17070).
>
> ⚠️ **Overseas Futures Options (`ov_futopt_*`) have no simulation environment** — only production (7071). Library immediately blocks if called in demo mode.
Changing `mode` in `config.yaml` switches the WebSocket URL:
```yaml
environment:
mode: "demo" # simulation (17070)
# mode: "production" # production (7070)
```
> ⚠️ **Not all APIs work in simulation**. Refer to [Appendix — API Simulation Support Status](#appendix--api-simulation-support-status).
## Error Codes & Rate Limiting
Summary of key points. For the complete error code table, rate limiting policy, and usage examples, refer to **[docs/errors_and_rate_limits.md](docs/errors_and_rate_limits.md)**.
**Common Errors**
| Code | Description |
|------|------|
| IGW00121 / IGW00123 | token invalid/expired — `auto_token=True` automatically reissues, `False` raises APIError |
| IGW00201 | call transaction count exceeded — adjust call frequency |
| 2611 | before market open or after market close |
| 2714 / 2752 | insufficient tradable quantity/margin |
**Rate Limiting (SDK automatically paces)**
The SDK applies **2-tier rate limiting** (app 20TPS + endpoint-specific TPS) to prevent server `IGW00201` (call transaction count exceeded). To disable, use `DBSecClient(..., rate_limit=False)`.
Endpoint-specific TPS source is in [docs/api_support_matrix.md](docs/api_support_matrix.md) `TPS` column.
| Category | Limit | Note |
|------|------|------|
| REST app (account) | 20 TPS | endpoint-specific (order 10, balance 2, etc.) in matrix `TPS` column |
| Token issuance/disposal | 1 TPM | file cache (24h reuse) effectively avoids |
| WebSocket session/stock | 2 sessions, 50 stocks per session | `RateLimitError` if exceeded |
```python
from dbsec_sdk.exceptions import lookup_error
print(lookup_error("IGW00123")) # "token has expired."
```
## Appendix — API Simulation Support Status
If there's a **`※ Available for simulation account`** note in the DB Securities Open API guide page description, it's available in simulation. Otherwise, it's only for live trading.
- **⭕ Supported for both simulation and live trading** — market data, real-time, and chart groups are all available
- **❌ Live trading only** — most orders and some inquiry APIs (especially overseas futures options have no simulation environment)
**Complete matrix with ⭕/❌ marking for each API** → **[docs/api_support_matrix.md](docs/api_support_matrix.md)**
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available