python wrapper for korea broker's REST API services
Project description
๐ Korea Investment Stock
ํ๊ตญํฌ์์ฆ๊ถ OpenAPI๋ฅผ ์ํ ํ์ด์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. Rate Limiting, ์๋ ์ฌ์๋, ๋ฐฐ์น ์ฒ๋ฆฌ ๋ฑ ํ๋ก๋์ ํ๊ฒฝ์ ํ์ํ ๊ธฐ๋ฅ๋ค์ ํฌํจํ๊ณ ์์ต๋๋ค.
๐ ์ฃผ์ ํน์ง
โจ ํต์ฌ ๊ธฐ๋ฅ
- ํ๊ตญํฌ์์ฆ๊ถ API ์์ธ ์กฐํ: ๊ตญ๋ด/ํด์ธ ์ฃผ์ ์์ธ ๋ฐ ์ข ๋ชฉ ์ ๋ณด ์กฐํ
- ๊ณต๋ชจ์ฃผ ์ฒญ์ฝ ์ผ์ ์กฐํ: ๊ณต๋ชจ์ฃผ ์ ๋ณด, ์ฒญ์ฝ ์ผ์ , ์ํ ํ์ธ
- ์๋ Rate Limiting: API ํธ์ถ ์ ํ(์ด๋น 20ํ)์ ์๋์ผ๋ก ๊ด๋ฆฌ
- ์ค๋งํธ ์ฌ์๋: Exponential Backoff์ Circuit Breaker ํจํด ๊ตฌํ
- ๋ฐฐ์น ์ฒ๋ฆฌ: ๋๋ ๋ฐ์ดํฐ ์กฐํ๋ฅผ ์ํ ์ต์ ํ๋ ๋ฐฐ์น ์ฒ๋ฆฌ
- ์ค์๊ฐ ๋ชจ๋ํฐ๋ง: ์์ธํ ํต๊ณ ๋ฐ ์ฑ๋ฅ ์ถ์
- TTL ์บ์ฑ: ์๋ ๋ง๋ฃ๋๋ ์บ์๋ก API ํธ์ถ ์ต์ํ
๐ก๏ธ ์์ ์ฑ
- ์๋ฌ์จ 0%: ํ๋ก๋์ ํ๊ฒฝ์์ ๊ฒ์ฆ๋ ์์ ์ฑ
- ์๋ ์๋ฌ ๋ณต๊ตฌ: ์ผ์์ ์ค๋ฅ ์๋ ์ฒ๋ฆฌ
- Thread-Safe: ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ ์ง์
๐ฆ ์ค์น
pip install korea-investment-stock
์๊ตฌ์ฌํญ
- Python 3.9 ์ด์
- ํ๊ตญํฌ์์ฆ๊ถ API ๊ณ์
๐ ๋น ๋ฅธ ์์
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
from korea_investment_stock import KoreaInvestment
# API ์ธ์ฆ ์ ๋ณด
api_key = "YOUR_API_KEY"
api_secret = "YOUR_API_SECRET"
account_no = "12345678-01"
# ํด๋ผ์ด์ธํธ ์์ฑ
broker = KoreaInvestment(
api_key=api_key,
api_secret=api_secret,
acc_no=account_no,
mock=False # ์ค๊ฑฐ๋: False, ๋ชจ์ํฌ์: True
)
# ํ์ฌ๊ฐ ์กฐํ
price_info = broker.fetch_price("005930") # ์ผ์ฑ์ ์
print(f"ํ์ฌ๊ฐ: {price_info['output']['stck_prpr']}์")
# ์ข
๋ชฉ ์ ๋ณด ์กฐํ
stock_info = broker.fetch_stock_info_list([("005930", "KR")])
print(stock_info)
Context Manager ์ฌ์ฉ (๊ถ์ฅ)
from korea_investment_stock import KoreaInvestment
with KoreaInvestment(api_key, api_secret, account_no) as broker:
# ์๋์ผ๋ก ๋ฆฌ์์ค ์ ๋ฆฌ
price = broker.fetch_price("005930")
# ... ์์
์ํ
# ์๋์ผ๋ก broker.shutdown() ํธ์ถ๋จ
๐ ์ฃผ์ ๊ธฐ๋ฅ
1. ์ฃผ์ ์ ๋ณด ์กฐํ
# ๊ตญ๋ด ์ฃผ์ ํ์ฌ๊ฐ
price = broker.fetch_domestic_price("J", "005930")
# ETF ํ์ฌ๊ฐ
etf_price = broker.fetch_etf_domestic_price("J", "069500") # KODEX 200
# ์ข
๋ชฉ ์ ๋ณด ์กฐํ
stock_info = broker.fetch_stock_info_list([("005930", "KR")])
# ์ฌ๋ฌ ์ข
๋ชฉ ๋์ ์กฐํ
stock_list = [("005930", "KR"), ("000660", "KR"), ("035720", "KR")]
prices = broker.fetch_price_list(stock_list)
# ์ฝ์คํผ/์ฝ์ค๋ฅ ์ ์ฒด ์ข
๋ชฉ ์กฐํ
kospi_symbols = broker.fetch_kospi_symbols()
kosdaq_symbols = broker.fetch_kosdaq_symbols()
2. ๊ณต๋ชจ์ฃผ ์ฒญ์ฝ ์ผ์ ์กฐํ
# ์ ์ฒด ๊ณต๋ชจ์ฃผ ์ผ์ ์กฐํ (์ค๋๋ถํฐ 30์ผ)
ipo_schedule = broker.fetch_ipo_schedule()
if ipo_schedule['rt_cd'] == '0':
for ipo in ipo_schedule['output1']:
print(f"{ipo['isin_name']} - ์ฒญ์ฝ๊ธฐ๊ฐ: {ipo['subscr_dt']}")
print(f"๊ณต๋ชจ๊ฐ: {broker.format_number(ipo['fix_subscr_pri'])}์")
print(f"์ฃผ๊ฐ์ฌ: {ipo['lead_mgr']}")
# ํน์ ๊ธฐ๊ฐ ๊ณต๋ชจ์ฃผ ์กฐํ
ipos = broker.fetch_ipo_schedule(
from_date="20240101",
to_date="20240131"
)
# ํน์ ์ข
๋ชฉ ๊ณต๋ชจ์ฃผ ์ ๋ณด ์กฐํ
ipo_info = broker.fetch_ipo_schedule(symbol="123456")
# ๊ณต๋ชจ์ฃผ ์ํ ํ์ธ (์์ /์งํ์ค/๋ง๊ฐ)
for ipo in ipo_schedule['output1']:
status = broker.get_ipo_status(ipo['subscr_dt'])
d_day = broker.calculate_ipo_d_day(ipo['subscr_dt'])
print(f"{ipo['isin_name']}: {status}, D-{d_day}")
# ์ฃผ์: ๋ชจ์ํฌ์๋ ์ง์ํ์ง ์์ต๋๋ค
# ์ํ์ ์ ๊ณต ์ ๋ณด์ด๋ฏ๋ก ์ฐธ๊ณ ์ฉ์ผ๋ก๋ง ์ฌ์ฉํ์ธ์
3. ๋ฐฐ์น ์ฒ๋ฆฌ (๋๋ ๋ฐ์ดํฐ)
# 100๊ฐ ์ข
๋ชฉ ์กฐํ
large_stock_list = [(f"{i:06d}", "KR") for i in range(1, 101)]
# ๊ณ ์ ํฌ๊ธฐ ๋ฐฐ์น ์ฒ๋ฆฌ
results = broker.fetch_price_list_with_batch(
large_stock_list,
batch_size=20, # 20๊ฐ์ฉ ์ฒ๋ฆฌ
batch_delay=1.0, # ๋ฐฐ์น ๊ฐ 1์ด ๋๊ธฐ
progress_interval=10 # ์งํ์ํฉ ์ถ๋ ฅ
)
# ๋์ ๋ฐฐ์น ์ฒ๋ฆฌ (์๋ฌ์จ์ ๋ฐ๋ผ ์๋ ์กฐ์ )
results = broker.fetch_price_list_with_dynamic_batch(large_stock_list)
4. Rate Limiting ๊ด๋ฆฌ
# Rate Limiter ํต๊ณ ํ์ธ
broker.rate_limiter.print_stats()
# ํต๊ณ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
stats = broker.rate_limiter.get_stats()
print(f"์ด ํธ์ถ: {stats['total_calls']}")
print(f"์๋ฌ์จ: {stats['error_rate']:.1%}")
print(f"ํ๊ท ๋๊ธฐ์๊ฐ: {stats['avg_wait_time']:.3f}์ด")
# ํต๊ณ ์ ์ฅ
broker.rate_limiter.save_stats()
5. ์บ์ ๊ด๋ฆฌ
# ์บ์ ์ํ ํ์ธ
cache_stats = broker.get_cache_stats()
print(f"์บ์ ์ ์ค๋ฅ : {cache_stats['hit_rate']:.1%}")
print(f"๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋: {cache_stats['memory_usage']:.1f}MB")
# ์บ์ ๋น์ฐ๊ธฐ
broker.clear_cache() # ์ ์ฒด ์บ์ ์ญ์
broker.clear_cache("fetch_domestic_price:J:005930") # ํน์ ํญ๋ชฉ๋ง ์ญ์
# ์์ฃผ ์ฌ์ฉํ๋ ์ข
๋ชฉ ๋ฏธ๋ฆฌ ์บ์ฑ
popular_stocks = ["005930", "000660", "035720", "051910", "005380"]
broker.preload_cache(popular_stocks, market="KR")
6. ๊ณ ๊ธ ๊ธฐ๋ฅ
# Circuit Breaker ์ํ ํ์ธ
from korea_investment_stock.rate_limiting import get_backoff_strategy
backoff = get_backoff_strategy()
state = backoff.get_stats()['state'] # CLOSED, OPEN, HALF_OPEN
# ์๋ฌ ๋ณต๊ตฌ ์์คํ
from korea_investment_stock.error_handling import get_error_recovery_system
recovery = get_error_recovery_system()
summary = recovery.get_error_summary(hours=1)
print(f"์ต๊ทผ 1์๊ฐ ์๋ฌ: {summary['total_errors']}๊ฑด")
# ํต๊ณ ๋งค๋์
from korea_investment_stock.monitoring import get_stats_manager
stats_mgr = get_stats_manager()
stats_mgr.save_all_stats() # ๋ชจ๋ ํต๊ณ ์ ์ฅ
7. ๋ชจ๋ํฐ๋ง ๋ฐ ์๊ฐํ
# ์ค์๊ฐ ๋ชจ๋ํฐ๋ง ๋์๋ณด๋ ์์ฑ
dashboard = broker.create_monitoring_dashboard()
broker.save_monitoring_dashboard("monitoring.html")
# ์์คํ
ํฌ์ค ์ฒดํฌ
health_chart = broker.get_system_health_chart()
# API ์ฌ์ฉ๋ ์ฐจํธ
usage_chart = broker.get_api_usage_chart(hours=24)
# ํต๊ณ ๋ฆฌํฌํธ ์์ฑ
report_files = broker.create_stats_report("weekly_report")
๐ง ๊ฐ๋ฐ ์ค์ธ ๊ธฐ๋ฅ
๋ค์ ๊ธฐ๋ฅ๋ค์ ํฅํ ๋ฒ์ ์์ ์ถ๊ฐ๋ ์์ ์ ๋๋ค:
- ์ฃผ๋ฌธ ๊ธฐ๋ฅ: ์์ฅ๊ฐ/์ง์ ๊ฐ ์ฃผ๋ฌธ, ์ฃผ๋ฌธ ์ทจ์
- ์๊ณ ์กฐํ: ๋ณด์ ์ข ๋ชฉ ๋ฐ ์์๊ธ ์กฐํ
- ์ฐจํธ ๋ฐ์ดํฐ: ์ผ๋ด, ๋ถ๋ด ๋ฑ OHLCV ๋ฐ์ดํฐ
- ํด์ธ ์ฃผ์: ๋ฏธ๊ตญ ์ฃผ์ ์์ธ ์กฐํ ๊ธฐ๋ฅ ํ๋
๐ ํ๋ก์ ํธ ๊ตฌ์กฐ
korea_investment_stock/
โโโ __init__.py
โโโ korea_investment_stock.py # ๋ฉ์ธ ํด๋์ค
โโโ rate_limiting/ # Rate Limiting ๋ชจ๋
โ โโโ enhanced_rate_limiter.py
โ โโโ enhanced_backoff_strategy.py
โ โโโ enhanced_retry_decorator.py
โโโ error_handling/ # ์๋ฌ ์ฒ๋ฆฌ ๋ชจ๋
โ โโโ error_recovery_system.py
โโโ batch_processing/ # ๋ฐฐ์น ์ฒ๋ฆฌ ๋ชจ๋
โ โโโ dynamic_batch_controller.py
โโโ caching/ # ์บ์ฑ ๋ชจ๋
โ โโโ ttl_cache.py
โ โโโ market_hours.py
โโโ monitoring/ # ๋ชจ๋ํฐ๋ง ๋ฐ ํต๊ณ
โ โโโ stats_manager.py
โโโ visualization/ # ์๊ฐํ ๋ชจ๋
โ โโโ charts.py
โ โโโ dashboard.py
โ โโโ plotly_visualizer.py
โโโ utils/ # ์ ํธ๋ฆฌํฐ ํจ์
๐ง ํ๊ฒฝ ์ค์
ํ๊ฒฝ ๋ณ์
# Rate Limiting ์ค์
export RATE_LIMIT_MAX_CALLS=15 # ์ต๋ ํธ์ถ ์ (๊ธฐ๋ณธ: 15)
export RATE_LIMIT_SAFETY_MARGIN=0.8 # ์์ ๋ง์ง (๊ธฐ๋ณธ: 0.8)
# Backoff ์ ๋ต ์ค์
export BACKOFF_BASE_DELAY=1.0 # ๊ธฐ๋ณธ ๋๊ธฐ ์๊ฐ
export BACKOFF_MAX_DELAY=60.0 # ์ต๋ ๋๊ธฐ ์๊ฐ
export CIRCUIT_FAILURE_THRESHOLD=5 # Circuit Breaker ์๊ณ๊ฐ
# ์บ์ ์ค์
export CACHE_DEFAULT_TTL=300 # ๊ธฐ๋ณธ ์บ์ TTL (์ด)
export CACHE_MAX_SIZE=10000 # ์ต๋ ์บ์ ํฌ๊ธฐ
๐ ์ฑ๋ฅ ์งํ
- ์ฒ๋ฆฌ๋: 10-12 TPS (์์ ์ )
- ์๋ฌ์จ: < 0.1%
- 100์ข ๋ชฉ ์กฐํ: ~8.5์ด
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ: < 100MB
- CPU ์ฌ์ฉ๋ฅ : < 5%
- ์บ์ ์ ์ค๋ฅ : > 80% (์ผ๋ฐ์ ์ธ ์ฌ์ฉ ํจํด)
๐ค ๊ธฐ์ฌํ๊ธฐ
ํ๋ก์ ํธ์ ๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
๊ฐ๋ฐ ํ๊ฒฝ ์ค์
# ์ ์ฅ์ ํด๋ก
git clone https://github.com/softyoungha/korea-investment-stock.git
cd korea-investment-stock
# ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# ๊ฐ๋ฐ ์์กด์ฑ ์ค์น
pip install -e ".[dev]"
# ํ
์คํธ ์คํ
pytest
๐ ๋ฌธ์
โ ๏ธ ์ฃผ์์ฌํญ
- ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ๊ตญํฌ์์ฆ๊ถ OpenAPI์ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋๋๋ค
- ์ค๊ฑฐ๋ ์ฌ์ฉ ์ ์ถฉ๋ถํ ํ ์คํธ๋ฅผ ๊ฑฐ์ณ ์ฌ์ฉํ์ธ์
- API ํธ์ถ ์ ํ์ ์ค์ํ์ฌ ์ฌ์ฉํ์ธ์
- ํ์ฌ๋ ์์ธ ์กฐํ ๊ธฐ๋ฅ๋ง ์ง์ํฉ๋๋ค
๐ ๋ผ์ด์ ์ค
์ด ํ๋ก์ ํธ๋ MIT ๋ผ์ด์ ์ค ํ์ ๋ฐฐํฌ๋ฉ๋๋ค. ์์ธํ ๋ด์ฉ์ LICENSE ํ์ผ์ ์ฐธ์กฐํ์ธ์.
๐ ๊ฐ์ฌ์ ๊ธ
- ํ๊ตญํฌ์์ฆ๊ถ OpenAPI ํ
- ๋ชจ๋ ๊ธฐ์ฌ์๋ค
- ์ด์ ๋ฆฌํฌํธ์ ํผ๋๋ฐฑ์ ์ฃผ์ ์ฌ์ฉ์๋ถ๋ค
๐ ์ง์
- ์ด์ ํธ๋์ปค: GitHub Issues
- ํ ๋ก : GitHub Discussions
Made with โค๏ธ by the Korea Investment Stock community
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.4.1.tar.gz.
File metadata
- Download URL: korea_investment_stock-0.4.1.tar.gz
- Upload date:
- Size: 98.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9bd18fde401363ba281c28d1fce395b77dcc154b5e4cc459f6627b1bdaa895f4
|
|
| MD5 |
e07d1c83e43013d3db19a4315def9496
|
|
| BLAKE2b-256 |
4e410af2fec3e94d6f3932b553fb294afb88119955ef670aeb88c77600c68a4a
|
File details
Details for the file korea_investment_stock-0.4.1-py3-none-any.whl.
File metadata
- Download URL: korea_investment_stock-0.4.1-py3-none-any.whl
- Upload date:
- Size: 120.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9dfa6359a14193aa73899e1f86e7042f03ad27241c154edb857851aeb5a8675b
|
|
| MD5 |
be4b5796fa3d0c5b0777f94297ff24fd
|
|
| BLAKE2b-256 |
5c18ea9430bcf65dfcc16771be1c10f7cff0eff38d86d972c401431c4e672325
|