Pure Python wrapper for Korea Investment Securities OpenAPI
Project description
๐ Korea Investment Stock
Pure Python wrapper for Korea Investment Securities OpenAPI
๐ฏ Purpose
A simple, transparent wrapper around the Korea Investment Securities OpenAPI. This library handles API authentication and request formatting, giving you direct access to the API responses without abstraction layers.
Philosophy: Keep It Simple
- Pure wrapper: Direct API access without magic
- Minimal dependencies: Only
requestsandpandas - No abstraction: You get exactly what the API returns
- Implement your way: Add rate limiting, caching, retries as you need them
๐ Features
Core API Support
- โ Stock Price Queries: Domestic (KR) and US stocks
- โ Stock Information: Company details and market data
- โ IPO Schedule: Public offering information and schedules
- โ
Unified Interface: Query KR/US stocks with
fetch_price(symbol, market) - โ Search Functions: Stock search and lookup
Technical Features
- ๐ง Context Manager: Automatic resource cleanup
- ๐ง Thread Pool: Basic concurrent execution support
- ๐ง Environment Variables: API credentials via env vars
๐ฆ Installation
pip install korea-investment-stock
Requirements
- Python 3.11 or higher
- Korea Investment Securities API account
๐ Quick Start
1. Set Up Credentials
# Add to your ~/.zshrc or ~/.bashrc
export KOREA_INVESTMENT_API_KEY="your-api-key"
export KOREA_INVESTMENT_API_SECRET="your-api-secret"
export KOREA_INVESTMENT_ACCOUNT_NO="12345678-01"
2. Basic Usage
from korea_investment_stock import KoreaInvestment
import os
# Create client (using environment variables)
with KoreaInvestment(
api_key=os.getenv('KOREA_INVESTMENT_API_KEY'),
api_secret=os.getenv('KOREA_INVESTMENT_API_SECRET'),
acc_no=os.getenv('KOREA_INVESTMENT_ACCOUNT_NO')
) as broker:
# Query Samsung Electronics
result = broker.fetch_price("005930", "KR")
if result['rt_cd'] == '0':
price = result['output1']['stck_prpr']
print(f"Price: {price}์")
๐ API Methods
Stock Price Queries
# Domestic stock price
result = broker.fetch_price("005930", "KR") # Samsung Electronics
# US stock price (requires real account)
result = broker.fetch_price("AAPL", "US") # Apple
# Direct methods
result = broker.fetch_domestic_price("J", "005930")
result = broker.fetch_etf_domestic_price("J", "069500") # KODEX 200
result = broker.fetch_price_detail_oversea("AAPL", "US")
Stock Information
# Stock info
result = broker.fetch_stock_info("005930", "KR")
# Search stock
result = broker.fetch_search_stock_info("005930", "KR")
IPO Schedule
# All IPOs (today + 30 days)
result = broker.fetch_ipo_schedule()
# Specific period
result = broker.fetch_ipo_schedule(
from_date="20250101",
to_date="20250131"
)
# Specific symbol
result = broker.fetch_ipo_schedule(symbol="123456")
# Helper methods
status = broker.get_ipo_status(ipo['subscr_dt']) # "์์ ", "์งํ์ค", "๋ง๊ฐ"
d_day = broker.calculate_ipo_d_day(ipo['subscr_dt']) # Days until subscription
Symbol Lists
# KOSPI symbols
result = broker.fetch_kospi_symbols()
# KOSDAQ symbols
result = broker.fetch_kosdaq_symbols()
๐ง Advanced Usage
Multiple Stock Queries
# Query multiple stocks
stocks = [
("005930", "KR"), # Samsung
("000660", "KR"), # SK Hynix
("035720", "KR"), # Kakao
]
results = []
for symbol, market in stocks:
result = broker.fetch_price(symbol, market)
results.append(result)
# Add your own rate limiting here if needed
Mixed KR/US Portfolio
portfolio = [
("005930", "KR"), # Samsung Electronics
("AAPL", "US"), # Apple
("035720", "KR"), # Kakao
("MSFT", "US"), # Microsoft
]
for symbol, market in portfolio:
result = broker.fetch_price(symbol, market)
if result['rt_cd'] == '0':
if market == "KR":
output = result['output1']
price = output['stck_prpr']
print(f"{symbol}: โฉ{int(price):,}")
else:
output = result['output']
price = output['last']
print(f"{symbol}: ${price}")
Error Handling
try:
result = broker.fetch_price("INVALID", "US")
if result['rt_cd'] != '0':
# API returned error
print(f"API Error: {result['msg1']}")
except ValueError as e:
# Invalid parameters
print(f"Invalid request: {e}")
except Exception as e:
# Network or other errors
print(f"Error: {e}")
Memory Caching (Optional)
Reduce API calls and improve response times with built-in memory caching:
from korea_investment_stock import KoreaInvestment, CachedKoreaInvestment
# Create base broker
broker = KoreaInvestment(api_key, api_secret, acc_no)
# Wrap with caching (opt-in)
cached_broker = CachedKoreaInvestment(broker, price_ttl=5)
# First call: API request (cache miss)
result1 = cached_broker.fetch_price("005930", "KR") # ~200ms
# Second call: from cache (cache hit)
result2 = cached_broker.fetch_price("005930", "KR") # <1ms
# Cache statistics
stats = cached_broker.get_cache_stats()
print(f"Hit rate: {stats['hit_rate']}") # "50.00%"
TTL Configuration (in seconds):
cached_broker = CachedKoreaInvestment(
broker,
price_ttl=5, # Real-time price: 5 seconds
stock_info_ttl=300, # Stock info: 5 minutes
symbols_ttl=3600, # Symbol lists: 1 hour
ipo_ttl=1800 # IPO schedule: 30 minutes
)
Performance Benefits:
- ๐ API calls reduced by 30-50%
- โก Response time improved by 90%+ (cached queries)
- ๐ Thread-safe with automatic expiration
- ๐พ No external dependencies (memory-only)
See: examples/cached_basic_example.py for comprehensive examples
๐ Response Format
Domestic Stock (KR)
{
'rt_cd': '0', # Return code ('0' = success)
'msg1': '์ ์์ฒ๋ฆฌ๋์์ต๋๋ค', # Message
'output1': {
'stck_prpr': '62600', # Current price
'prdy_vrss': '1600', # Change from previous day
'prdy_ctrt': '2.62', # Change rate (%)
'stck_oprc': '61000', # Opening price
'stck_hgpr': '63000', # High price
'stck_lwpr': '60500', # Low price
'acml_vol': '15234567' # Volume
# ... more fields
}
}
US Stock (US)
{
'rt_cd': '0',
'msg1': '์ ์์ฒ๋ฆฌ๋์์ต๋๋ค',
'output': {
'rsym': 'DNASAAPL', # Exchange + Symbol
'last': '211.16', # Current price
'open': '210.56', # Opening price
'high': '212.13', # High price
'low': '209.86', # Low price
'tvol': '39765812', # Volume
't_xdif': '1.72', # Change
't_xrat': '-0.59', # Change rate (%)
'perx': '32.95', # PER
'pbrx': '47.23', # PBR
'epsx': '6.41', # EPS
'bpsx': '4.47' # BPS
# ... more fields
}
}
โ ๏ธ Important Notes
API Rate Limits
- Korea Investment API: 20 requests/second
- You are responsible for implementing rate limiting
- Exceeding limits will cause API errors
US Stocks
- Auto-detects exchange (NASDAQ โ NYSE โ AMEX)
- Includes financial ratios (PER, PBR, EPS, BPS)
Context Manager
Always use context manager for proper resource cleanup:
# โ
Good: Automatic cleanup
with KoreaInvestment(api_key, api_secret, acc_no) as broker:
result = broker.fetch_price("005930", "KR")
# โ Bad: Manual cleanup required
broker = KoreaInvestment(api_key, api_secret, acc_no)
result = broker.fetch_price("005930", "KR")
broker.shutdown() # Must call manually
๐จ Implementing Your Own Features
Rate Limiting Example
import time
class RateLimiter:
def __init__(self, calls_per_second=15):
self.min_interval = 1.0 / calls_per_second
self.last_call = 0
def wait(self):
elapsed = time.time() - self.last_call
if elapsed < self.min_interval:
time.sleep(self.min_interval - elapsed)
self.last_call = time.time()
# Usage
limiter = RateLimiter(calls_per_second=15)
for symbol, market in stocks:
limiter.wait()
result = broker.fetch_price(symbol, market)
Caching Example
from functools import lru_cache
from datetime import datetime, timedelta
class CachedBroker:
def __init__(self, broker):
self.broker = broker
self.cache = {}
self.ttl = timedelta(minutes=5)
def fetch_price_cached(self, symbol, market):
key = f"{symbol}:{market}"
now = datetime.now()
if key in self.cache:
cached_time, cached_result = self.cache[key]
if now - cached_time < self.ttl:
return cached_result
result = self.broker.fetch_price(symbol, market)
self.cache[key] = (now, result)
return result
Retry Example
import time
def fetch_with_retry(broker, symbol, market, max_retries=3):
for attempt in range(max_retries):
try:
result = broker.fetch_price(symbol, market)
if result['rt_cd'] == '0':
return result
except Exception as e:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt) # Exponential backoff
๐ Examples
See the examples/ directory:
basic_example.py: Simple usage patternsipo_schedule_example.py: IPO queries and helpersus_stock_price_example.py: US stock queries
๐ Migration from v0.5.0
Breaking Changes in v0.6.0
Removed features (~6,000 lines of code):
- Rate limiting system
- TTL caching
- Batch processing methods
- Monitoring and statistics
- Visualization tools
- Automatic retry decorators
API changes:
# v0.5.0 (Old)
results = broker.fetch_price_list([("005930", "KR"), ("AAPL", "US")])
# v0.6.0 (New)
results = []
for symbol, market in [("005930", "KR"), ("AAPL", "US")]:
result = broker.fetch_price(symbol, market)
results.append(result)
See CHANGELOG.md for complete migration guide.
๐ Documentation
๐ค Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Submit a pull request
๐ License
MIT License - see LICENSE file
โก Performance Tips
- Implement rate limiting: Prevent API errors
- Use caching: Reduce redundant API calls
- Batch requests wisely: Don't overwhelm the API
- Handle errors gracefully: Check
rt_cdandmsg1 - Use context manager: Ensure proper cleanup
๐ Credits
- Korea Investment Securities for providing the OpenAPI
- Original contributors: Jonghun Yoo, Brayden Jo, Frank Oh
Remember: This is a pure wrapper. You control rate limiting, caching, error handling, and monitoring according to your needs.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file korea_investment_stock-0.6.0.tar.gz.
File metadata
- Download URL: korea_investment_stock-0.6.0.tar.gz
- Upload date:
- Size: 117.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c46214d0accd5134654fac517e8af4b4257c311a7a131f3f910fe79d71d7d2f
|
|
| MD5 |
38ed298c8af22dfb7c9ffc3bf658be2a
|
|
| BLAKE2b-256 |
c9323a2877d5d7e24943571fbd4a317f0445fbbd45696c24653cfafa77501fc2
|
File details
Details for the file korea_investment_stock-0.6.0-py3-none-any.whl.
File metadata
- Download URL: korea_investment_stock-0.6.0-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e624e46067427429c0beb1b03092ab2c881a87227a3c423d43cc803719b0064
|
|
| MD5 |
9be7a9b305cf231498429332ff3fbc02
|
|
| BLAKE2b-256 |
c8fa1b58acdcabfae56a0a203bfd96fcd9c2580644212b5699d004c7153f2031
|