### Complete Real-Time Market Monitor Example Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RealData.md A comprehensive example demonstrating the setup of a market monitor bot, including registering tick and order book callbacks, subscribing to real-time data, and processing collected data. ```APIDOC ## Complete Example: Real-Time Market Monitor ### Description This example showcases a `MarketBot` class that inherits from `Bot` and utilizes callbacks for real-time tick and order book data. It demonstrates subscribing to multiple real-time data streams and processing the collected information. ### Usage ```python import asyncio import orjson import pandas as pd from kiwoom import Bot, REAL from kiwoom.config.real import RealData class MarketBot(Bot): def __init__(self, host, appkey, secretkey): super().__init__(host, appkey, secretkey) self.ticks = [] self.order_books = {} async def on_tick(self, msg: RealData): data = orjson.loads(msg.values) self.ticks.append({ 'code': msg.item, 'price': int(data['10']), 'volume': int(data['15']), 'time': data['20'], 'type': msg.type, 'name': msg.name }) async def on_hoga(self, msg: RealData): data = orjson.loads(msg.values) self.order_books[msg.item] = { 'ask': int(data['41']), 'ask_vol': int(data['61']), 'bid': int(data['51']), 'bid_vol': int(data['71']), 'spread': int(data['41']) - int(data['51']), 'time': data['21'] } async def run(self): # Register callbacks self.api.add_callback_on_real_data('0B', self.on_tick) self.api.add_callback_on_real_data('0D', self.on_hoga) # Get stock codes codes = await self.stock_list('0') watch_codes = codes[:50] # Watch first 50 stocks # Subscribe to real-time data await self.api.register_tick('1', watch_codes) await self.api.register_hoga('1', watch_codes) # Run for 10 minutes for i in range(600): await asyncio.sleep(1) if i % 60 == 0: print(f"Collected {len(self.ticks)} ticks") print(f"Order books updated: {len(self.order_books)}") # Save ticks to DataFrame df = pd.DataFrame(self.ticks) print(df.describe()) async def main(): async with MarketBot(REAL, 'appkey', 'secretkey') as bot: await bot.connect() await bot.run() asyncio.run(main()) ``` ``` -------------------------------- ### Complete Real-Time Market Monitor Example Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RealData.md A comprehensive example demonstrating a market monitor bot that subscribes to real-time tick and order book data, processes it, and saves it to a Pandas DataFrame. It includes setup, callback registration, data subscription, and data processing. ```python import asyncio import orjson import pandas as pd from kiwoom import Bot, REAL from kiwoom.config.real import RealData class MarketBot(Bot): def __init__(self, host, appkey, secretkey): super().__init__(host, appkey, secretkey) self.ticks = [] self.order_books = {} async def on_tick(self, msg: RealData): data = orjson.loads(msg.values) self.ticks.append({ 'code': msg.item, 'price': int(data['10']), 'volume': int(data['15']), 'time': data['20'], 'type': msg.type, 'name': msg.name }) async def on_hoga(self, msg: RealData): data = orjson.loads(msg.values) self.order_books[msg.item] = { 'ask': int(data['41']), 'ask_vol': int(data['61']), 'bid': int(data['51']), 'bid_vol': int(data['71']), 'spread': int(data['41']) - int(data['51']), 'time': data['21'] } async def run(self): # Register callbacks self.api.add_callback_on_real_data('0B', self.on_tick) self.api.add_callback_on_real_data('0D', self.on_hoga) # Get stock codes codes = await self.stock_list('0') watch_codes = codes[:50] # Watch first 50 stocks # Subscribe to real-time data await self.api.register_tick('1', watch_codes) await self.api.register_hoga('1', watch_codes) # Run for 10 minutes for i in range(600): await asyncio.sleep(1) if i % 60 == 0: print(f"Collected {len(self.ticks)} ticks") print(f"Order books updated: {len(self.order_books)}") # Save ticks to DataFrame df = pd.DataFrame(self.ticks) print(df.describe()) async def main(): async with MarketBot(REAL, 'appkey', 'secretkey') as bot: await bot.connect() await bot.run() asyncio.run(main()) ``` -------------------------------- ### Install kiwoom-restful from PyPI Source: https://github.com/breadum/kiwoom-restful/blob/main/README.md Install the package using pip. It is recommended to use Python 3.11+. ```bash pip install -U kiwoom-restful ``` -------------------------------- ### Install kiwoom-restful from Git Source: https://github.com/breadum/kiwoom-restful/blob/main/README.md Install the package in editable mode from a Git fork or clone. This is useful for development. ```bash pip install -e . ``` -------------------------------- ### Install and Use uvloop for Performance Source: https://github.com/breadum/kiwoom-restful/blob/main/README.md For Linux environments, installing uvloop can improve performance. This snippet shows how to install it and then use it to run an asyncio application. ```python import asyncio, uvloop uvloop.install() asyncio.run(main()) ``` -------------------------------- ### API Class Initialization and Callback Handling Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Utilities.md Illustrates the initialization of the API class, including semaphore for concurrency control and default callback setup. Shows how to add both synchronous and asynchronous callbacks for real-time data. ```python class API(Client): def __init__(self, ...): # Semaphore limits concurrent callback executions self._sem = asyncio.Semaphore(WEBSOCKET_MAX_CONCURRENCY) # Initialize default callbacks self._callbacks = defaultdict(lambda: wrap_sync_callback(self._sem, print)) def add_callback_on_real_data(self, real_type, callback): if iscoroutinefunction(callback): # Wrap async callback self._callbacks[real_type] = wrap_async_callback(self._sem, callback) else: # Wrap sync callback self._callbacks[real_type] = wrap_sync_callback(self._sem, callback) async def close(self): # Cancel receive task safely await cancel(self._recv_task) ``` -------------------------------- ### Load Environment Variables for Configuration Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Demonstrates how to load configuration variables like API keys and host from a .env file using `python-dotenv`. Ensure the `dotenv` library is installed. ```python import os from dotenv import load_dotenv load_dotenv() appkey = os.getenv('KIWOOM_APPKEY') secretkey = os.getenv('KIWOOM_SECRETKEY') host = os.getenv('KIWOOM_HOST', default=REAL) bot = Bot(host=host, appkey=appkey, secretkey=secretkey) ``` -------------------------------- ### Full Request/Response Cycle Example Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Response.md Demonstrates a complete asynchronous request-response cycle using the `Client` class. It includes connecting, making a request, accessing status, headers, and JSON body, and handling pagination information. ```python import asyncio from kiwoom.http.client import Client from kiwoom import REAL async def main(): client = Client(host=REAL, appkey='appkey', secretkey='secretkey') # Connect and get token await client._connect('appkey', 'secretkey') # Make request response = await client.request( endpoint='/api/dostk/stkinfo', api_id='ka10099', data={'mrkt_tp': '0'} ) # Access response data print(f"Status: {response.status}") print(f"Headers: {response.headers}") body = response.json() print(f"Return code: {body['return_code']}") print(f"Data: {body['list'][:5]}") # Check pagination if response.headers.get('cont-yn') == 'Y': print(f"More data available, next key: {response.headers.get('next-key')}") await client.close() asyncio.run(main()) ``` -------------------------------- ### Print Message Example Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RealData.md Demonstrates how to print a message, which in this context, shows the string representation of a RealData object. ```python print(msg) # RealData(values=b'{"10": "75800", ...}', type='0B', # name='주식체결', item='005930') ``` -------------------------------- ### Install uvloop for AsyncIO Performance Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md For enhanced performance on Linux systems, install and use uvloop to replace the default asyncio event loop. This requires importing uvloop and calling `uvloop.install()` before running your asyncio application. ```python import asyncio import uvloop uvloop.install() async def main(): ... asyncio.run(main()) ``` -------------------------------- ### Custom Logging via Callbacks Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Implement custom logging by hooking into callbacks. This example shows how to set up a logger for 'kiwoom' and log received real-time data ticks. ```python import logging logger = logging.getLogger('kiwoom') logger.setLevel(logging.DEBUG) async def on_tick(msg: RealData): logger.info(f"Tick received: {msg.item}") # ... process ... api.add_callback_on_real_data('0B', on_tick) ``` -------------------------------- ### Complete Market Data Pipeline with Kiwoom Bot Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/DataProcessing.md This example shows how to set up a bot, connect to the real-time API, retrieve stock lists, process daily candle data for multiple stocks, and save it to CSV files. It also demonstrates fetching and saving trade history. ```python from kiwoom import Bot, REAL from kiwoom.proc import candle, trade from datetime import datetime, timedelta async def main(): async with Bot(REAL, 'appkey', 'secretkey') as bot: await bot.connect() # Get stock list codes = await bot.stock_list('0') # Process candle data for top 10 stocks for code in codes[:10]: df = await bot.candle(code, 'day', 'stock') await candle.to_csv(file=f'{code}.csv', path='./data/', df=df) # Get trade history start = (datetime.today() - timedelta(days=30)).strftime('%Y%m%d') trades = await bot.trade(start) await trade.to_csv('trade_history.csv', './', trades) asyncio.run(main()) ``` -------------------------------- ### Example: Fetch and Save Candle Data Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/DataProcessing.md Demonstrates fetching daily candle data for a stock code and saving it to a CSV file. This is a common workflow for collecting historical price data. ```python from kiwoom.proc import candle df = await bot.candle('005930', 'day', 'stock') await candle.to_csv(file='samsung.csv', path='./data/', df=df) ``` -------------------------------- ### Example Usage of State Enum Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/types.md Demonstrates how to instantiate and interact with the State enum to monitor API connection status. The initial state is typically CLOSED before connection. ```Python from kiwoom.config.http import State api = API(REAL, 'appkey', 'secretkey') print(api._state) # State.CLOSED initially await api.connect() print(api._state) # State.CONNECTED await api.close() print(api._state) # State.CLOSED ``` -------------------------------- ### Callback with State Management Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RealData.md This example demonstrates how to manage state within a callback by using a class. It appends tick data to a list for later processing. ```python class MyBot: def __init__(self): self.ticks = [] async def on_tick(self, msg: RealData): data = orjson.loads(msg.values) self.ticks.append({ 'item': msg.item, 'price': int(data['10']), 'volume': int(data['15']), 'time': data['20'] }) async def run(self): api.add_callback_on_real_data('0B', self.on_tick) await api.register_tick('1', codes) await asyncio.sleep(60) print(f"Collected {len(self.ticks)} ticks") ``` -------------------------------- ### Rate Limiting Verification Example Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Demonstrates how the API automatically enforces rate limits by making rapid requests and measuring the elapsed time. The output should reflect the configured rate limit (e.g., ~1.0s for 5 requests if the limit is 5/sec). ```python import time from kiwoom import API api = API(REAL, 'appkey', 'secretkey') await api.connect() # Make rapid requests - automatically rate-limited start = time.time() for i in range(5): await api.stock_list('0') elapsed = time.time() - start print(f"5 requests took {elapsed:.2f}s (should be ~1.0s)") ``` -------------------------------- ### Example of Handling Empty DataFrame Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/errors.md Demonstrates how to check the length and columns of a DataFrame returned when candle data is empty or invalid. ```python df = await bot.candle(code='nonexistent', period='day', ctype='stock') print(len(df)) # 0 print(df.columns) # ['일자', '시가', '고가', '저가', '종가', '거래량', '거래대금'] ``` -------------------------------- ### Implement Custom API for Stock Data Source: https://github.com/breadum/kiwoom-restful/blob/main/README.md This example shows how to extend the base API class to create a custom API for fetching specific stock data. It demonstrates making a request that continues until a condition is met and processing the response. ```python from kiwoom import API, Bot from kiwoom.http import Response # API 상세 구현 class MyAPI(API): def __init__(self, host:str, appkey: str, secretkey: str): super().__init__(host, appkey, secretkey) # 증권사별매매상위요청 async def what_stocks_ebest_bought_today(self) -> list[dict]: endpoint = '/api/dostk/rkinfo' api_id = 'ka10039' data = { 'mmcm_cd': '063', # 회원사코드 'trde_qty_tp': '0', # 거래량구분 (전체 '0') 'trde_tp': '1', # 매매구분 (순매수 '1') 'dt': '0', # 기간 (당일 '0') 'stex_tp': '3' # 거래소구분 (통합 '3') } # 다음 데이터가 있으면 무조건 계속 요청 should_continue = lambda res: True # 키움 REST API 서버 응답 데이터 취합 후 반환 res: dict = await self.request_until( should_continue, endpoint, api_id, data=data ) key = 'sec_trde_upper' if key in res: return res[key] return [] # or raise Exception ``` -------------------------------- ### Example: Display Processed Candle DataFrame Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/DataProcessing.md Shows how to display the resulting DataFrame after processing candle data, including its index and the last row. This helps in verifying the data structure and content. ```python df = await bot.candle(code='005930', period='day', ctype='stock') print(df) # 시가 고가 저가 종가 거래량 거래대금 # 일자 # 2025-01-02 75000 76000 74500 75800 2500000 188400000000 # 2025-01-03 76000 77000 75500 76500 2200000 167800000000 print(df.index) # DatetimeIndex(['2025-01-02', '2025-01-03', ...], name='일자', freq=None) print(df.iloc[-1]) # 시가 75500 # 고가 76800 # ... ``` -------------------------------- ### Socket.connect Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Socket.md Establishes a WebSocket connection to the Kiwoom server and starts the message receiving task. Requires an authenticated HTTP session and an access token. ```APIDOC ## Socket.connect ### Description Establishes a WebSocket connection to the Kiwoom server and starts the message receiving task. ### Parameters #### Path Parameters - **session** (aiohttp.ClientSession) - Required - Authenticated HTTP session (from Client._session) - **token** (str) - Required - OAuth2 access token from authentication ### Process 1. Closes any existing WebSocket and task 2. Creates WebSocket connection with autoping and heartbeat 3. Starts background message receiving task 4. Sends LOGIN message with token 5. Sets state to CONNECTED ### Heartbeat 30 seconds (WEBSOCKET_HEARTBEAT) ### Request Example ```python import aiohttp async def main(): session = aiohttp.ClientSession() socket = Socket(url=Socket.REAL + Socket.ENDPOINT, queue=queue) token = '...' # From API authentication await socket.connect(session, token) ``` ``` -------------------------------- ### Implement Custom Trading Strategy Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md An abstract method to be overridden for implementing custom trading logic. The example demonstrates fetching a list of KOSPI stock codes, retrieving daily candle data for the first 10, and printing the closing price of the latest candle. ```python class MyBot(Bot): async def run(self): kospi_codes = await self.stock_list('0') for code in kospi_codes[:10]: df = await self.candle(code, 'day', 'stock') if len(df) > 0: print(f"{code}: {df.iloc[-1]['종가']}") async def main(): async with MyBot(REAL, 'appkey', 'secretkey') as bot: await bot.connect() await bot.run() asyncio.run(main()) ``` -------------------------------- ### Example: Safe Task Cancellation Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Utilities.md Demonstrates the usage of the safe cancel function with an asyncio task. It shows cancelling a running task and also cancelling a None value. ```python import asyncio from kiwoom.http.utils import cancel async def main(): # Start background task task = asyncio.create_task(some_coro()) await asyncio.sleep(1) # Cancel safely (no exception raised) await cancel(task) # Safe to cancel None (no-op) await cancel(None) ``` -------------------------------- ### Automatic Rate Limiting Compliance Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RateLimiter.md This example demonstrates how the RateLimiter automatically enforces per-second limits. The loop sends 6 requests, but the limiter ensures they are processed at a maximum rate of 5 per second. ```python # These 6 requests will automatically be rate-limited for i in range(6): response = await api.request(endpoint, api_id, data) # Limiter automatically waits between requests # Effective throughput: 5 requests per second ``` -------------------------------- ### Fetch Stock Trading Data with Kiwoom API Source: https://github.com/breadum/kiwoom-restful/blob/main/docs/index.md This example demonstrates how to create a custom API class inheriting from `kiwoom.API` to fetch specific trading data, such as which stocks were most traded by brokerage firms today. It uses `request_until` to handle paginated or continuous data responses. ```python from kiwoom import API from kiwoom.http import Response # API 상세 구현 class MyAPI(API): def __init__(self, host:str, appkey: str, secretkey: str): super().__init__(host, appkey, secretkey) # 증권사별매매상위요청 async def what_stocks_ebest_bought_today(self) -> list[dict]: endpoint = '/api/dostk/rkinfo' api_id = 'ka10039' data = { 'mmcm_cd': '063', # 회원사코드 'trde_qty_tp': '0', # 거래량구분 (전체 '0') 'trde_tp': '1', # 매매구분 (순매수 '1') 'dt': '0', # 기간 (당일 '0') 'stex_tp': '3' # 거래소구분 (통합 '3') } # 다음 데이터가 있으면 무조건 계속 요청 should_continue = lambda res: True # 키움 REST API 서버 응답 데이터 취합 후 반환 res: dict = await self.request_until( should_continue, endpoint, api_id, data=data ) key = 'sec_trde_upper' if key in res: return res[key] return [] # or raise Exception ``` -------------------------------- ### Import Main Exports and Extended Modules in Python Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/DOCUMENTATION_INDEX.md This snippet shows the main exports from the kiwoom library and common extended imports for configuration, HTTP clients, real-time data, utilities, and data processing modules. Ensure these modules are installed and accessible. ```python # Main exports from kiwoom import API, Bot, REAL, MOCK # Extended imports from kiwoom.config import ENCODING from kiwoom.http import Client, Response, Socket from kiwoom.config.real import RealData from kiwoom.http.utils import RateLimiter, wrap_async_callback, wrap_sync_callback, cancel from kiwoom.proc import candle, trade, stock_list, sector_list ``` -------------------------------- ### HTTP Timeout Example Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Illustrates how HTTP timeouts are applied to API connection and request calls. The connection attempt has a total timeout of 10 seconds, while individual requests are subject to connection, read, and total timeouts. ```python # Connection timeout (3s) - fails if server doesn't accept in 3s # Read timeout (5s) - fails if no data received in 5s # Total timeout (10s) - fails if entire request takes >10s await api.connect() # Will timeout if takes >10s response = await api.request(endpoint, api_id, data) # Individual request timeout ``` -------------------------------- ### Client Initialization and Usage Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Demonstrates the typical usage pattern for initializing the Client, establishing a connection, making a request, and closing the connection. ```APIDOC ## Client Initialization and Usage ### Description This code snippet shows the standard way to use the `Client` class. It involves creating an `aiohttp.ClientSession`, initializing the `Client` with necessary credentials, connecting to the API, performing a request, and then properly closing the client connection. ### Method ```python async with aiohttp.ClientSession() as session: client = Client(host, appkey, secretkey) await client._connect(appkey, secretkey) # Use client for requests response = await client.request(endpoint, api_id, data=data) await client.close() ``` ### Parameters - **host** (str): API server domain. - **appkey** (str): Application key. - **secretkey** (str): Secret key. - **endpoint** (str): The specific API endpoint to request. - **api_id** (str): The identifier for the API call. - **data** (dict, optional): Data payload for the request. ``` -------------------------------- ### trade(start, end) Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/DOCUMENTATION_INDEX.md Get account execution history within a specified date range. ```APIDOC ## trade(start, end) ### Description Get account execution history within a specified date range. ### Method trade ### Parameters #### Path Parameters - **start** (string) - Required - The start date (YYYYMMDD). - **end** (string) - Required - The end date (YYYYMMDD). ``` -------------------------------- ### candle(code, period, ctype, start, end) Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/DOCUMENTATION_INDEX.md Get candlestick data for a given stock code, period, and date range. ```APIDOC ## candle(code, period, ctype, start, end) ### Description Get candlestick data for a given stock code, period, and date range. ### Method candle ### Parameters #### Path Parameters - **code** (string) - Required - The stock code. - **period** (string) - Required - The candle period (e.g., 'D' for daily). - **ctype** (string) - Required - The candle type. - **start** (string) - Required - The start date (YYYYMMDD). - **end** (string) - Required - The end date (YYYYMMDD). ``` -------------------------------- ### Initialize API with RateLimiter Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RateLimiter.md Demonstrates how to initialize the API client and configure its RateLimiter based on the host environment (real or mock). ```python class API(Client): def __init__(self, host: str, appkey: str, secretkey: str): # ... self._limiter = RateLimiter() # Configure based on server if host == config.REAL: self._limiter.set(REQ_LIMIT_PER_SECOND) # 5 else: self._limiter.set(REQ_LIMIT_PER_SECOND_MOCK) # 1 ``` -------------------------------- ### Apply Rate Limiting in Client Ready Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RateLimiter.md Shows how to integrate the RateLimiter's acquire method into the client's ready process to ensure rate limits are respected before proceeding. ```python async def ready(self): try: await asyncio.wait_for(self._ready_event.wait(), HTTP_TOTAL_TIMEOUT) except asyncio.TimeoutError: raise RuntimeError("Connection timeout") await self._limiter.acquire() # Rate limit every request ``` -------------------------------- ### Retrieve Candlestick Data Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/API.md Get candlestick chart data for a stock or sector. Supports 'tick', 'min', and 'day' periods, and 'stock' or 'sector' chart types. Date ranges can be specified using 'start' and 'end' parameters in YYYYMMDD format. ```python # Retrieve all daily candles for Samsung Electronics df = await api.candle(code='005930', period='day', ctype='stock') # Retrieve minute candles for a specific date range data = await api.candle( code='005930', period='min', ctype='stock', start='20250101', end='20250131' ) ``` -------------------------------- ### Initialize API Instance Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/API.md Instantiate the API class with server host, application key, and secret key. Ensure keys are provided as file paths or raw strings. The host can be set to REAL or MOCK configurations. ```python from kiwoom import API, REAL from kiwoom.config import REAL api = API(host=REAL, appkey='keys/appkey.txt', secretkey='keys/secretkey.txt') ``` -------------------------------- ### Initialize API with File Paths Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Instantiate the API client using file paths for application and secret keys. The client automatically reads keys from these files, stripping whitespace. ```python api = API( host=REAL, appkey='./credentials/appkey.txt', secretkey='./credentials/secretkey.txt' ) ``` -------------------------------- ### sector_list(market) Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/DOCUMENTATION_INDEX.md Get sector codes for a specific market. ```APIDOC ## sector_list(market) ### Description Get sector codes for a specific market. ### Method sector_list ### Parameters #### Path Parameters - **market** (string) - Required - The market for which to retrieve sector codes. ``` -------------------------------- ### stock_list(market) Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/DOCUMENTATION_INDEX.md Get stock codes for a specific market. ```APIDOC ## stock_list(market) ### Description Get stock codes for a specific market. ### Method stock_list ### Parameters #### Path Parameters - **market** (string) - Required - The market for which to retrieve stock codes. ``` -------------------------------- ### Typical Client Usage Pattern Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Demonstrates the standard asynchronous pattern for initializing, connecting, using, and closing the Client. Ensure an aiohttp.ClientSession is active. ```python async with aiohttp.ClientSession() as session: client = Client(host, appkey, secretkey) await client._connect(appkey, secretkey) # Use client for requests response = await client.request(endpoint, api_id, data=data) await client.close() ``` -------------------------------- ### Get API Token Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Retrieves the current API authentication token. Returns an empty string if not connected. ```python await bot.connect() token = bot.token() print(f"Authenticated: {bool(token)}") ``` -------------------------------- ### Bot.__init__ Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Initializes a Bot instance. Optionally accepts a custom API instance for advanced use cases. ```APIDOC ## Bot.__init__ ### Description Initializes a Bot instance. Optionally accepts a custom `API` instance for advanced use cases. ### Parameters #### Path Parameters - **host** (str) - Required - Server: `config.REAL` or `config.MOCK` - **appkey** (str) - Required - Application key: file path or raw key - **secretkey** (str) - Required - Secret key: file path or raw key - **api** (API | None) - Optional - Custom API instance. If None, creates a new `API(host, appkey, secretkey)` ### Request Example ```python from kiwoom import Bot, REAL bot = Bot(host=REAL, appkey='appkey', secretkey='secretkey') # Or with custom API from kiwoom.api import API class MyAPI(API): async def custom_method(self): pass bot = Bot(host=REAL, appkey='appkey', secretkey='secretkey', api=MyAPI(REAL, 'appkey', 'secretkey')) ``` ``` -------------------------------- ### Get Sector List by Market Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Retrieves a list of sector codes for a given market. The returned codes are sorted. ```python sectors = await bot.sector_list('0') print(sectors) # ['001', '002', '003', ...] ``` -------------------------------- ### connect() Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/DOCUMENTATION_INDEX.md Connect to server and authenticate. ```APIDOC ## connect() ### Description Connect to server and authenticate. ### Method connect ### Parameters None specified. ``` -------------------------------- ### Client.__init__ Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Initializes a Client instance for HTTP communication with the Kiwoom REST API. ```APIDOC ## Client.__init__ ### Description Initializes a Client instance for HTTP communication with the Kiwoom REST API. ### Parameters #### Path Parameters - **host** (str) - Required - API server domain: `https://api.kiwoom.com` (real) or `https://mockapi.kiwoom.com` (mock) - **appkey** (str) - Required - Application key: file path or raw key string - **secretkey** (str) - Required - Secret key: file path or raw key string ### Request Example ```python from kiwoom.http import Client from kiwoom import REAL client = Client(host=REAL, appkey='appkey', secretkey='secretkey') ``` ``` -------------------------------- ### Get Candle Data as pandas.DataFrame Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/types.md Retrieves candle data and returns it as a pandas DataFrame. Use this to access historical price data. ```python from pandas import DataFrame df = await bot.candle('005930', 'day', 'stock') print(type(df)) # print(df.columns) print(df.iloc[-1]) # Last row ``` -------------------------------- ### Initialize API with Raw Keys Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Instantiate the API client directly with raw application and secret key strings. This method is used when keys are not stored in separate files. ```python api = API( host=REAL, appkey='your_raw_appkey_here', secretkey='your_raw_secretkey_here' ) ``` -------------------------------- ### Initialize Bot with Custom API Instance Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/configuration.md Create a Bot instance, optionally providing a custom API object. If no custom API is provided, a new API instance is created internally. ```python class MyAPI(API): async def custom_method(self): pass api = MyAPI(REAL, 'appkey', 'secretkey') bot = Bot(REAL, 'appkey', 'secretkey', api=api) ``` -------------------------------- ### Retrieve Trade History Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/API.md Fetches account order execution history for the last 60 days. Specify start and end dates for the desired period. ```python from datetime import datetime, timedelta, date start = (datetime.today() - timedelta(days=30)).strftime('%Y%m%d') end = datetime.today().strftime('%Y%m%d') trades = await api.trade(start, end) ``` -------------------------------- ### Initialize Client Instance Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Initializes a Client instance for HTTP communication with the Kiwoom REST API. Requires host, appkey, and secretkey. ```python from kiwoom.http import Client from kiwoom import REAL client = Client(host=REAL, appkey='appkey', secretkey='secretkey') ``` -------------------------------- ### API Constructor Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/API.md Initializes an API instance that connects to the Kiwoom REST API server. ```APIDOC ## API.__init__ ### Description Initializes an API instance that connects to the Kiwoom REST API server. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | host | str | Yes | — | Server host: `config.REAL` (https://api.kiwoom.com) or `config.MOCK` (https://mockapi.kiwoom.com) | | appkey | str | Yes | — | Application key: file path or raw key string | | secretkey | str | Yes | — | Secret key: file path or raw key string | ### Raises - `ValueError`: Invalid host domain ### Example ```python from kiwoom import API, REAL from kiwoom.config import REAL api = API(host=REAL, appkey='keys/appkey.txt', secretkey='keys/secretkey.txt') ``` ``` -------------------------------- ### Parse Tick Data with orjson Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RealData.md Example of parsing stock execution (Tick) data using orjson. This snippet demonstrates accessing current price, trade volume, and trade time. ```python import orjson async def on_tick(msg: RealData): data = orjson.loads(msg.values) print(f"Code: {msg.item}") print(f" Price: {data['10']}") print(f" Volume: {data['15']}") print(f" Time: {data['20']}") ``` -------------------------------- ### Import and Access Data Processing Functions Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/DataProcessing.md Demonstrates how to import the `proc` module and access its available data processing functions for candle data, trade history, stock lists, and sector lists. ```python from kiwoom import proc # Available exports proc.candle # Candle data processing proc.trade # Trade history processing proc.stock_list() # Extract stock codes proc.sector_list()# Extract sector codes ``` -------------------------------- ### Understanding Concurrency Limits Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Utilities.md Explains the concurrency limit imposed by `WEBSOCKET_MAX_CONCURRENCY` and its impact on callback execution. Provides examples of throughput calculations based on callback speed and message arrival rate. ```python # Remember: only WEBSOCKET_MAX_CONCURRENCY (1000) can run concurrently # If you have 1000 stocks x 2 types = 2000 simultaneous messages, # only 1000 callbacks execute concurrently, others queue # If each callback takes 0.1s and you get 100 messages/sec: # Throughput = 1000 concurrent * 10 callbacks/sec = 10,000 callbacks/sec OK # If callbacks are slow (1s each): # Queue depth = 100 messages/sec - 1000 concurrent / 1s = 100/sec - 1000/sec # Queue will grow if processing can't keep up ``` -------------------------------- ### Response Constructor Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Response.md Initializes a Response instance with the provided URL, status, headers, and pre-parsed JSON body. ```APIDOC ## Response.__init__ ### Description Creates a Response instance by storing response metadata. ### Parameters #### Path Parameters - **url** (str) - Required - Response URL - **status** (int) - Required - HTTP status code (e.g., 200, 400, 500) - **headers** (dict) - Required - Response headers dict - **body** (dict) - Required - Pre-parsed JSON response body ### Request Example ```python from kiwoom.http.response import Response response = Response( url='https://api.kiwoom.com/api/dostk/stkinfo', status=200, headers={'api-id': 'ka10099', 'cont-yn': 'N'}, body={'return_code': 0, 'list': [...]} ) ``` ``` -------------------------------- ### Get Current Access Token Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Returns the current OAuth2 access token without the 'Bearer ' prefix. Returns an empty string if not connected. Raises ValueError for invalid token format. ```python token = client.token() if token: print(f"Connected with token: {token[:20]}...") ``` -------------------------------- ### Rate Limiter Burst Consumption Behavior Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RateLimiter.md Explains that unused rate limit slots within a second do not accumulate, preventing excessive bursting. New slots are granted at the start of each second. ```python # At t=0.0, make 1 request. Rate limit allows 5. # The 4 unused slots are lost. # At t=1.0, you get 5 new slots. # This is intentional - prevents bursting. ``` -------------------------------- ### Initialize Bot Instance Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Initializes a Bot instance. Optionally accepts a custom API instance for advanced use cases. The host parameter can be config.REAL or config.MOCK. Appkey and secretkey can be file paths or raw keys. ```python from kiwoom import Bot, REAL bot = Bot(host=REAL, appkey='appkey', secretkey='secretkey') ``` ```python from kiwoom.api import API class MyAPI(API): async def custom_method(self): pass bot = Bot(host=REAL, appkey='appkey', secretkey='secretkey', api=MyAPI(REAL, 'appkey', 'secretkey')) ``` -------------------------------- ### _connect Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Establishes HTTP session with the Kiwoom server and obtains OAuth2 token. Automatically reads from files if paths are provided. ```APIDOC ## _connect ### Description Establishes HTTP session with the Kiwoom server and obtains OAuth2 token. Automatically reads from files if paths are provided. ### Method `async def _connect(self, appkey: str, secretkey: str, headers: Optional[dict] = None)` ### Parameters #### Path Parameters - **appkey** (str) - Required - Application key or file path - **secretkey** (str) - Required - Secret key or file path - **headers** (dict) - Optional - Custom HTTP headers (User-Agent, etc.) ### OAuth2 Endpoint POST `/oauth2/token` ### Raises - `RuntimeError`: Token not found in response ### Request Example ```python await client._connect('appkey', 'secretkey', headers={'User-Agent': 'MyBot/1.0'}) token = client.token() # Returns the access token ``` ``` -------------------------------- ### Real-Time Data Handling with Callbacks Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Illustrates how to handle real-time tick data by implementing the `on_tick` method and registering a callback for specific real-time events. This is useful for processing live market data. ```python class MyBot(Bot): async def on_tick(self, msg): data = orjson.loads(msg.values) # Process tick data async def run(self): self.api.add_callback_on_real_data('0B', self.on_tick) codes = await self.stock_list('0') await self.api.register_tick(grp_no='1', codes=codes[:100]) # Keep running await asyncio.sleep(3600) ``` -------------------------------- ### Instantiate Response Object Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Response.md Create a Response instance by providing the URL, status code, headers, and a pre-parsed JSON body. ```python from kiwoom.http.response import Response response = Response( url='https://api.kiwoom.com/api/dostk/stkinfo', status=200, headers={'api-id': 'ka10099', 'cont-yn': 'N'}, body={'return_code': 0, 'list': [...]} ) ``` -------------------------------- ### Parse Order Book Data with orjson Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RealData.md Example of parsing stock order book (Hoga) data using orjson. This snippet shows how to access ask and bid prices and volumes for the top two levels. ```python import orjson async def on_hoga(msg: RealData): data = orjson.loads(msg.values) print(f"Code: {msg.item}") print(f" Ask 1: {data['41']} x {data['61']}") # Best ask print(f" Bid 1: {data['51']} x {data['71']}") # Best bid print(f" Ask 2: {data['42']} x {data['62']}") print(f" Bid 2: {data['52']} x {data['72']}") ``` -------------------------------- ### Basic Bot Connection and Stock List Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Demonstrates how to establish a connection to the Kiwoom API using the Bot class and retrieve a list of KOSPI stocks. Ensure you have the necessary API keys. ```python from kiwoom import Bot, REAL import asyncio async def main(): async with Bot(REAL, 'appkey', 'secretkey') as bot: await bot.connect() codes = await bot.stock_list('0') print(f"KOSPI has {len(codes)} stocks") asyncio.run(main()) ``` -------------------------------- ### Get Stock List by Market Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Fetches a list of stock codes for a specified market. By default, includes NXT codes with an '_AL' suffix. For 'NXT' market, it specifically retrieves and returns codes with the '_AL' suffix. ```python kospi_codes = await bot.stock_list('0', ats=True) print(kospi_codes[:5]) # ['000010', '000020_AL', '000030', ...] nxt_codes = await bot.stock_list('NXT') print(nxt_codes) # Only codes with _AL suffix ``` -------------------------------- ### Example Decoding WebSocket Messages with RealType Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/types.md Shows how to use msgspec to decode a raw JSON string into the RealType structure for real-time data. Access nested data fields like type and item from the decoded message. ```Python import msgspec from kiwoom.config.real import RealType decoder = msgspec.json.Decoder(type=RealType) raw_json = '{"trnm":"REAL","data":[{"values":...,"type":"0B","name":"주식체결","item":"005930"}]}' msg = decoder.decode(raw_json) print(msg.trnm) # 'REAL' print(msg.data[0].type) # '0B' print(msg.data[0].item) # '005930' ``` -------------------------------- ### Get Candlestick Data Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Bot.md Retrieves candlestick chart data as a Pandas DataFrame. Supports 'tick', 'min', and 'day' periods for 'stock' or 'sector' chart types. Automatic date range filtering and time adjustments are applied. ```python # Daily chart df = await bot.candle(code='005930', period='day', ctype='stock') print(df.head()) # 시가 고가 저가 종가 거래량 거래대금 # 일자 # 2025-01-02 75000 76000 74500 75800 2500000 188400000 # 2025-01-03 76000 77000 75500 76500 2200000 167800000 # Minute chart with date range df = await bot.candle( code='005930', period='min', ctype='stock', start='20250110', end='20250120' ) # Sector tick data df = await bot.candle(code='001', period='tick', ctype='sector') ``` -------------------------------- ### Burst Handling with RateLimiter Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RateLimiter.md Demonstrates how the RateLimiter allows for brief bursts of requests within the per-second limit. It shows that 5 requests can be initiated quickly, respecting the configured rate. ```python import asyncio import time from kiwoom.http.utils import RateLimiter async def burst_test(): limiter = RateLimiter(rps=5) # 5 per second = 0.2s per request # These can happen "instantly" (within 0.2s allowance) start = time.time() for i in range(5): await limiter.acquire() elapsed = time.time() - start print(f"5 requests took {elapsed:.3f}s") # Output: approximately 0.800s (4 waits of 0.2s each) ``` -------------------------------- ### ready Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/Client.md Waits until the connection is established and a request slot is available under rate limiting. ```APIDOC ## ready ### Description Waits until the connection is established and a request slot is available under rate limiting. ### Method `async def ready(self) -> None` ### Raises - `RuntimeError`: Connection timeout (exceeds HTTP_TOTAL_TIMEOUT) ### Request Example ```python await client.ready() # Blocks until connected and rate limit permits ``` ``` -------------------------------- ### Batching Related API Queries Source: https://github.com/breadum/kiwoom-restful/blob/main/_autodocs/api-reference/RateLimiter.md Demonstrates how to efficiently use the rate limit budget by batching multiple related API queries together using `asyncio.gather`. ```python # Make efficient use of your 5 requests/second budget tasks = [ api.stock_list('0'), # KOSPI api.stock_list('10'), # KOSDAQ api.sector_list('0'), # Sectors # 3 more queries ] results = await asyncio.gather(*tasks) ```