Files
finestock/finestock/path.py
T
shinalokandClaude Sonnet 5 900a7cd97b Add NH(나무) broker integration and fix balance/holds parsing
- finestock/nh/: Nh/NhV 브로커 클래스 추가 (시세/주문/잔고/실시간 WS)
- api_factory.py, path.py: APIProvider.NH/NHV 등록, 도메인/엔드포인트 매핑
- kis.py: get_holds/get_ohlcv_min/get_index_min/get_stock_list 스텁 추가,
  oauth() Content-Type 헤더 수정
- get_balance()의 실전 디버깅으로 드러난 버그 수정:
  - Hold.total(매입금액)이 존재하지 않는 byn_amt 필드를 참조해 항상 0이던 것을
    eal_amt - eal_pls_amt로 계산하도록 수정
  - rsp_cd를 "00000" 단일 값으로만 성공 판정해 정상 응답('00218' 연속조회 중,
    '00166' 마지막 페이지 등)을 실패로 오판하던 것을 Output_0 존재 여부로 판정
  - 응답 헤더의 cts/cts_flag로 연속조회를 재귀 처리해 10건 넘는 보유종목도
    전부 합쳐서 반환하도록 구현
- doc/, tests/, example_*.py, setup.py, requirements.txt, CLAUDE.md 등 추가
- README.md에 .env 환경변수 설정 가이드 추가

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01225Lu4Fc2UpMz6QixEcNT8
2026-08-31 14:35:30 +09:00

110 lines
3.9 KiB
Python

_EBEST_ = {
"DOMAIN": "https://openapi.ebestsec.co.kr:8080",
"DOMAIN_WS": "wss://openapi.ebestsec.co.kr:9443/websocket",
"OAUTH": "oauth2/token",
"REVOKE": "oauth2/revoke",
"CHART": "stock/chart",
"INDEX": "indtp/chart",
"ORDERBOOK": "stock/market-data",
"PRICE": "stock/market-data",
"ACCOUNT": "stock/accno",
"ORDER": "stock/order",
"INDEX_LIST": "indtp/market-data",
"STOCK_LIST": "stock/etc",
"CONDITION_LIST": "stock/item-search",
}
_LS_ = {
"DOMAIN": "https://openapi.ls-sec.co.kr:8080",
"DOMAIN_WS": "wss://openapi.ls-sec.co.kr:9443/websocket",
"OAUTH": "oauth2/token",
"REVOKE": "oauth2/revoke",
"CHART": "stock/chart",
"INDEX": "indtp/chart",
"ORDERBOOK": "stock/market-data",
"PRICE": "stock/market-data",
"ACCOUNT": "stock/accno",
"ORDER": "stock/order",
"INDEX_LIST": "indtp/market-data",
"STOCK_LIST": "stock/etc",
"CONDITION": "stock/item-search",
}
_LS_V_ = {
**_LS_,
"DOMAIN_WS":"wss://openapi.ls-sec.co.kr:29443/websocket"
}
_KIS_ = {
"DOMAIN": "https://openapi.koreainvestment.com:9443",
"DOMAIN_WS": "ws://ops.koreainvestment.com:21000",
"OAUTH": "oauth2/tokenP",
"REVOKE": "oauth2/revokeP",
"CHART": "uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice",
"ACCOUNT": "uapi/domestic-stock/v1/trading/inquire-balance",
"ORDER": "uapi/domestic-stock/v1/trading/order-cash",
"INDEX": "uapi/domestic-stock/v1/quotations/inquire-daily-indexchartprice",
"ORDERBOOK": "uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn",
}
_KIS_V_ = {
**_KIS_,
"DOMAIN":"https://openapivts.koreainvestment.com:29443",
}
_KIWOOM_ = {
"DOMAIN": "https://api.kiwoom.com",
"DOMAIN_WS": "wss://api.kiwoom.com:10000/api/dostk/websocket",
"OAUTH": "oauth2/token",
"REVOKE": "oauth2/revoke",
"STOCK_CHART": "api/dostk/chart",
"INDEX_CHART": "api/dostk/chart", # Using same endpoint based on research
"STOCK_INFO": "api/dostk/stkinfo",
"STOCK_ORDERBOOK": "api/dostk/mrkcond", # TR ka10004
"CHART": "uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice", # Placeholder to keep compatibility if used elsewhere
"ACCOUNT": "uapi/domestic-stock/v1/trading/inquire-balance", # Placeholder
"ORDER": "uapi/domestic-stock/v1/trading/order-cash", # Placeholder
}
_KIWOOM_V_ = {
**_KIWOOM_,
"DOMAIN": "https://api.kiwoom.com", # Default is https://api.kiwoom.com ??? Wait, main DOMAIN is api.kiwoom.com
# User said: mockapi.kiwoom.com in previous example.
# Let's verify standard.
# If main is api.kiwoom.com (Production), then mock is likely openapi.kiwoom.com or mockapi.kiwoom.com.
# User's example said: #host = 'https://mockapi.kiwoom.com' # 모의투자
# So I will use that.
"DOMAIN": "https://mockapi.kiwoom.com",
"DOMAIN_WS": "wss://mockapi.kiwoom.com:10000/api/dostk/websocket",
}
_NH_ = {
"DOMAIN": "https://api.nhplug.com:8443",
"DOMAIN_WS": "wss://api.nhplug.com:7070",
# 접근토큰발급(oauth2/token)은 모의투자 미제공 — 항상 운영 도메인에서만 발급.
# NhV(모의투자)에서도 이 값은 바뀌지 않는다.
"OAUTH_DOMAIN": "https://api.nhplug.com:8443",
"OAUTH": "oauth2/token",
"ACCOUNT_LIST": "n2/acctinfo",
"ORDER_CASH_BUY": "krstock/order/v1/cashBuy",
"ORDER_CASH_SELL": "krstock/order/v1/cashSell",
"ORDER_CANCEL": "krstock/order/v1/cancel",
"ORDER_MODIFY": "krstock/order/v1/modify",
"BALANCE": "krstock/inquiry/v1/balance",
"PRICE": "krstock/quote/v1/currentPrice",
"CHART": "krstock/quote/v1/period",
}
_NH_V_ = {
**_NH_,
"DOMAIN": "https://moapi.nhplug.com:8443",
"DOMAIN_WS": "wss://moapi.nhplug.com:17070",
}
_API_PATH_ = {
"EBest": {**_EBEST_},
"LS": {**_LS_},
"LSV": {**_LS_V_},
"Kis": {**_KIS_},
"KisV": {**_KIS_V_},
"Kiwoom": {**_KIWOOM_},
"KiwoomV": {**_KIWOOM_V_},
"Nh": {**_NH_},
"NhV": {**_NH_V_},
}