- 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
65 lines
2.2 KiB
Python
65 lines
2.2 KiB
Python
import os
|
|
import finestock
|
|
from finestock import APIProvider
|
|
|
|
try:
|
|
# 선택 의존성: 설치돼 있으면 .env 파일을 자동으로 읽어 os.environ에 채워준다.
|
|
# pip install python-dotenv
|
|
from dotenv import load_dotenv
|
|
load_dotenv()
|
|
except ImportError:
|
|
pass
|
|
|
|
finestock.print_version_info()
|
|
|
|
# 실키/토큰은 절대 코드에 하드코딩하지 말 것. 환경변수로 주입한다.
|
|
# 예 (PowerShell): $env:APP_KEY="..."; $env:APP_SECRET="..."
|
|
app_key = os.environ.get("APP_KEY", "YOUR_APP_KEY")
|
|
app_secret = os.environ.get("APP_SECRET", "YOUR_APP_SECRET")
|
|
access_token = os.environ.get("ACCESS_TOKEN", "")
|
|
|
|
# 모의투자로 테스트하려면 APIProvider.NHV를 사용한다. 단, 접근토큰발급(oauth())은
|
|
# NH·NHV 모두 항상 운영 도메인에서만 발급된다(모의투자 계좌로 거래하더라도 토큰은 동일).
|
|
api = finestock.APIFactory.create_api(APIProvider.NH)
|
|
api.set_oauth_info(app_key, app_secret)
|
|
|
|
login = False
|
|
if login:
|
|
api.oauth()
|
|
print(api.access_token)
|
|
else:
|
|
api.headers['authorization'] = f"Bearer {access_token}"
|
|
|
|
# 1) 계좌 목록 조회 — /n2/acctinfo. acct_type이 01/02면 운영(NH) 전용, 03이면 모의투자(NHV) 전용.
|
|
accounts = api.get_account_list()
|
|
print(accounts)
|
|
|
|
# 계좌목록에서 사용할 계좌를 골라 세팅한다. act_no는 11자리 단일 값이라 sub는 비워둔다.
|
|
account_num = os.environ.get("ACCOUNT_NUM", "YOUR_ACCOUNT_NUM")
|
|
#account_num_sub = os.environ.get("ACCOUNT_NUM_SUB", "YOUR_ACCOUNT_NUM")
|
|
api.set_account_info(account_num, "")
|
|
|
|
'''
|
|
# 2) 시세 조회
|
|
price = api.get_price("005930")
|
|
print(price)
|
|
|
|
ohlcvs = api.get_ohlcv("005930", "20260701", "20260821")
|
|
print(len(ohlcvs), ohlcvs[:3] if ohlcvs else ohlcvs)
|
|
|
|
orderbook = api.get_orderbook("005930")
|
|
print(orderbook)
|
|
'''
|
|
# 3) 계좌/잔고 조회
|
|
acc = api.get_balance()
|
|
print(acc)
|
|
if acc:
|
|
print(len(acc.hold), acc.hold[:3] if acc.hold else acc.hold)
|
|
|
|
# 4) 주문 (실제 체결되니 운영 도메인에서는 주의 — 테스트는 APIProvider.NHV 권장)
|
|
# res = api.do_order("005930", finestock.ORDER_FLAG.BUY, 0, 1) # price=0 -> 시장가
|
|
# print(res)
|
|
# if res:
|
|
# cancel = api.do_order_cancel(res.order_num, "005930", 0) # qty<=0 -> 전량취소
|
|
# print(cancel)
|