Coder Social home page Coder Social logo

kiwoom's Introduction

Kiwoom Open API+

Simple Python Wrapper for Kiwoom Open API+ (Stable)

What is it?

  • 키움증권에서 제공하는 Open API+ 인터페이스 사용을 위한 간단한 Python Wrapper 모듈

  • PyQt5를 이용해 직접 개발하고자 하는 사람을 위한 모듈로 부가적인 기능은 최대한 배제

Main Features

1. Open API+ 함수 호출 간소화

  • 함수명과 변수명을 깔끔하게 Python 방식으로 통일
# Before
OnReceiveTrCondition(BSTR sScrNo, BSTR strCodeList, BSTR strConditionName, int nIndex, int nNext)

# After
on_receive_tr_condition(scr_no, code_list, condition_name, index, next)
  • 반복되는 dynamicCall 제거
# Before
self.dynamicCall("CommRqData(QString, QString, Int, QString)", rq_name, tr_code, prev_next, scr_no)

# After
self.comm_rq_data(rq_name, tr_code, prev_next, scr_no)

2. 간단한 기능 지원

  • 로그인 기능
from kiwoom import *
api = Kiwoom()
api.login()
  • loop / unloop 함수를 통해 간단히 코드 실행 / 대기 제어
from kiwoom import *

# QEventLoop 활용
api = Kiwoom()
api.loop()
api.unloop()
  • 요청 후 처리 결과를 반환하는 함수에 한해 에러 발생 시 메세지 자동 발생
# 구현되어있는 메인 클래스
class Kiwoom(API):
    ...
    # 만일 send_order() 실행 후 정상처리 되지 않았다면 @catch_error 에서 에러 메세지 자동 발생
    # ex) An error occured from send_order,  "-308 : OP_ERR_ORD_OVERFLOW (주문전송과부하)"
    @catch_error
    def send_order(self, rq_name, scr_no, acc_no, ord_type, code, qty, price, hoga_gb, org_order_no):
        return super().send_order(rq_name, scr_no, acc_no, ord_type, code, qty, price, hoga_gb, org_order_no)
    ...
from kiwoom import *

# 지정번호 확인
print(config.MARKETS)  # {'0': 'KOSPI', '3': 'ELW', ... }
print(config.SECTORS)  # {'001': '종합(KOSPI)', '002': '대형주', ... }

# 다운로드
api = Kiwoom()
api.histories(market='0', period='tick', start='20201001', merge=True)  # KOSPI Stocks
api.histories(sector='2', period='tick', start='20201001', merge=True)  # KOSPI200 Index
  • 순수한 API 기능만을 사용해 직접 개발하고 싶은 경우
from kiwoom import API

# API 파이썬 래핑 
class Kiwoom(API):
    # Overriding Here
    def __init__(self):
        super().__init__()

3. 통신을 위한 체계적인 코드 작성 지원

  • 데이터를 요청하는 함수와 데이터를 받는 함수를 분리해서 작성

  • Signal에 해당하는 'Bot' 클래스와 Slot에 해당하는 'Server' 클래스

  • 작성 후 Kiwoom.connect() 함수로 서로 연결시켜 서버에서 응답 시 자동 호출 지원

  • 자세한 내용 및 코드는 튜토리얼5. TR 데이터 항목을 통해 확인 가능

from kiwoom import Bot

# 서버에 데이터를 요청하는 클래스 (사용자 작성)
class MyBot(Bot):
    def __init__(self, server):
        super().__init__(server)

        # 1) Kiwoom.set_connect_hook(event, param)
        # 이벤트 OnReceiveTrData 발생 시 주어진 rq_name 인자값에 따라 slot을 호출하도록 설정
        # 만일 설정하지 않는다면, 하나의 이벤트에는 하나의 slot만 연결가능
        self.api.set_connect_hook('on_receive_tr_data', 'rq_name')

        # 2) Kiwoom.connect(event, signal, slot, key=None)
        # OnReceiveTrData 이벤트에 대하여 1)에 의해 특정 rq_name 값에 따라 signal과 slot을 연결
        # key 값이 주어지지 않을 시, rq_name은 signal과 slot의 함수 이름 'balance'로 자동 설정
        self.api.connect(
            event='on_receive_tr_data',
            signal=self.balance, 
            slot=self.server.balance,
        )

        # 1)과 2) 연결 설정 후에는 다음과 같이 활용할 수 있다.
        # on_receive_tr_data(..., rq_name='balance', ...) 이벤트 수신 시 server.balance 자동 호출됨
        # self.api.signal('on_receive_tr_event', 'balance') 호출 시 bot.balance 함수 핸들 반환
        # self.api.slot('on_receive_tr_event', 'balance') 호출 시 server.balance 함수 핸들 반환 

        # 참고 가이드          
        # 1) print(config.events)  # 이벤트 목록
        # 2) print(Kiwoom.api_arg_spec('on_receive_tr_data'))  # 함수인자 목록
        # 3) help(Kiwoom.connect) and help(Kiwoom.set_connect_hook)  # Doc String
        # 4) Github 튜토리얼 (https://github.com/breadum/kiwoom/tree/main/tutorials)
    
    def balance(self, prev_next='0'):
        ...
        # '계좌평가잔고내역'을 받기 위해 서버로 rq_name='balance'로 요청 전송
        self.api.comm_rq_data(rq_name='balance', tr_code='opw00018', prev_next='0', scr_no='0000')
        self.api.loop()  # 이벤트가 호출 될 때까지 대기
        ...

    def run(self):
        # 버전처리 및 로그인 
        self.login()

        # 계좌평가잔고내역 요청
        self.balance()

        # 전송된 데이터 확인
        print(self.share['balance']['예탁금'])
from kiwoom import Server

# 서버에서 데이터를 받아 처리하는 클래스 (사용자 작성)
class MyServer(Server):
    def __init__(self):
        super().__init__()
        self.downloading = False

    def balance(self, scr_no, rq_name, tr_code, record_name, prev_next):
        ...
        # 만일 데이터가 더 있을 경우 연결했던 Signal 함수 다시 호출
        if prev_next == '2':
            fn = self.api.signal('on_receive_tr_data', rq_name)  # rq_name='balance'
            fn(prev_next)  # Bot.balance(prev_next='2')

        # 데이터를 다 받았다면 unloop을 통해 대기중인 코드 실행
        else:
            ...
            self.downloading = False
            self.api.unloop()
# 구현되어있는 메인 클래스
class Kiwoom(API):
    ...
    # rq_name = 'balance'라면, @map 데코레이터가 매핑된 함수를 자동 호출
    # >> slot.balance(scr_no, rq_name, tr_code, record_name, prev_next, *args)
    @map
    def on_receive_tr_data(self, scr_no, rq_name, tr_code, record_name, prev_next, *args):
        pass
  • 간단한 실행 스크립트 예시 (여러가지 방식 가능)
from PyQt5.QtWidgets import QApplication
from kiwoom import *
import sys

    
if __name__ == '__main__':

    # 통신을 위해 QApplication 활용
    app = QApplication(sys.argv)

    # 인스턴스 생성
    bot = MyBot(MyServer())
   
    # 봇 작동시작
    bot.run() 

    # 데이터 통신을 위해 스크립트 종료 방지
    app.exec()

4. 디버깅을 위한 에러 출력

  • PyQt5 모듈을 사용하는 경우 Pycharm과 같은 IDE 사용 시 에러 메세지가 발생하지 않는 문제 해결

Tutorial

Installation

Prerequisite

1. 키움 Open API+ 사용 신청 (Step1), 모듈 다운로드 (Step2), KOA Studio 다운로드 (Step3)
2. 32-bit Python 3.7 이상 Windows 환경 세팅
# 실제로 잘 작동하지 않는 방식
set CONDA_FORCE_32BIT=1  

# 권장하는 방식 
conda create -n 32bit  # 가상환경 생성
conda activate 32bit  # 가상환경 실행
conda config --env --set subdir win-32  # 현위치에서 32bit 설정
conda install python=3.10  # Python 3.7/3.8/3.9/3.10 설치
conda install 'pandas<2.0'  # 32bit Pandas 별도 설치
  • 아래 코드로 '32Bit'인지 반드시 확인 후 설치
import platform; print(platform.architecture())
3. KOA Studio를 활용해 간단한 데이터 조회로 정상작동 여부 확인 필수
  • 키움에서 Open API+ 모듈을 받아도 처음 실행 시 여러가지 오류 발생

    키움 OpenAPI 등록, 타인계좌 사용불가, AhnLab Safe Transaction 설치 등등

  • 먼저 KOA Studio를 통해 오류 확인 및 해결 후 파이썬 모듈 설치

  • 키움 OpenAPI 등록, 모의투자 신청, 버전처리, 계좌비밀번호 저장(AUTO) 등을 확인

Install from pip

pip install kiwoom

Install from source

# After git clone and cd into the dir
git clone https://github.com/breadum/kiwoom.git && cd kiwoom
python3 setup.py install

License

Finally

  • 본 프로젝트의 개발자는 키움증권과 아무런 관련이 없습니다.

  • 엉망인 키움 Open API를 활용하여 시스템을 직접 개발할 때 도움이 되고자 개발했습니다.

  • 발생한 어떠한 손실에 대하여 어떻게 발생하였든지 개발자는 이에 대해 아무런 책임이 없음을 알립니다.

  • 버그, 기능요청, 문의사항 등은 Github 이슈 게시판을 통해 남겨주세요.

kiwoom's People

Contributors

breadum avatar gamjaa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kiwoom's Issues

실시간 목록 - 주식체결 tutorials에 추가 부탁드립니다.

실시간 목록 - 주식체결 신청하여 실시간 현재가를 받아올려고 하는데요 이게 맞는지 모르겠습니다. ㅠ
고견 부탁드립니다.

class Bot(Bot):
def init(self, server):
super().init(server)

    self.api.set_connect_hook('on_receive_real_data', 'real_type')
    self.api.connect('on_receive_real_data', signal=self.real_price, slot=self.server.real_price)

def real_price():
    self.api.set_real_reg("2000", "005930;005380", "10", "0")   #삼성전자;현대차  10:현재가
    print('주가체결 구독')

class Server(Server):
def init(self):
super().init()
self.downloading = False

def real_price():
    for code in code_list:
        real_dict={code:{}}
        current_price = self.api.get_comm_real_data(code, '10')
        real_dict[code].update({'현재가':current_price})

if name == 'main':
app = QApplication(sys.argv)
bot = Bot(Server())
bot.login()
bot.account()
bot.balance()
bot.real_price()

보유종목이 많을 때 오류

안녕하세요.
코드는 Tutorial 의 5번 "TR Data.py" 에서 나고, 보유종목이 많을 때, 다음 과 같은 에러가 나네요.
오류 내용입니다.

[GetPCIdentity] VER 3.2.0.0 build 2015.8.12

로그인 정상처리

  • 시스템 점검
    • 월 ~ 토 : 05:05 ~ 05:10
    • 일 : 04:00 ~ 04:30

Bot.deposit() 호출

화면번호: 0000, 요청이름: deposit, TR코드: opw00001
[100000] 모의투자 조회완료

    Server.deposit(scr_no, rq_name, tr_code, record_name, prev_next) 호출
    Server.deposit(scr_no, rq_name, tr_code, record_name, prev_next) 종료

Bot.deposit() 종료
Bot.balance(prev_next) 호출

화면번호: 0000, 요청이름: balance, TR코드: opw00018
[100000] 모의투자 조회가 계속됩니다. 계속조회시 다음키를 누르십시오.

    Server.balance(scr_no, rq_name, tr_code, record_name, prev_next) 호출

Bot.balance(prev_next) 호출
Bot.balance(prev_next) 종료

화면번호: 0000, 요청이름: balance, TR코드: opw00018
[100000] 모의투자 조회가 계속됩니다. 계속조회시 다음키를 누르십시오.

    Server.balance(scr_no, rq_name, tr_code, record_name, prev_next) 호출

Bot.balance(prev_next) 호출
Bot.balance(prev_next) 종료

화면번호: 0000, 요청이름: balance, TR코드: opw00018
[100000] 모의투자 조회가 계속됩니다. 계속조회시 다음키를 누르십시오.

    Server.balance(scr_no, rq_name, tr_code, record_name, prev_next) 호출

Bot.balance(prev_next) 호출
Bot.balance(prev_next) 종료

화면번호: 0000, 요청이름: balance, TR코드: opw00018
[100000] 모의투자 조회가 계속됩니다. 계속조회시 다음키를 누르십시오.

    Server.balance(scr_no, rq_name, tr_code, record_name, prev_next) 호출

Bot.balance(prev_next) 호출
Traceback (most recent call last):
File "c:\Users\Administrator\OneDrive - DZS\dev\ktrader-dev\kydwin\kiwoom\core\connector.py", line 386, in wrapper
slot(*args)
File "c:\Users\Administrator\OneDrive - DZS\dev\ktrader-dev\kydwin\5. TR Data.py", line 352, in balance
fn(prev_next) # call signal function again to receive remaining data
File "c:\Users\Administrator\OneDrive - DZS\dev\ktrader-dev\kydwin\5. TR Data.py", line 217, in balance
self.api.comm_rq_data('balance', tr_code, prev_next, '0000')
File "c:\Users\Administrator\OneDrive - DZS\dev\ktrader-dev\kydwin\kiwoom\config\error.py", line 73, in wrapper
print(f'\nAn error occurred from {fn.name}.\n * {msg(out)}')
File "c:\Users\Administrator\OneDrive - DZS\dev\ktrader-dev\kydwin\kiwoom\config\error.py", line 50, in msg
etype, msg = ERR[ecode]
KeyError: -211

vscode 사용시 Server class의 self.api.xxx() 를 인지하지 못하네요.

안녕하세요.
Server Class의 아래있는 methold를 vscode가 인식하지 못하는데, 인식하게 할 수 있는 방법이 있을까요?
(인식이라 함은 Ctrl+마우스 버튼 누를 때 hyperlink처럼 함수를 보여주거나 하는 것을 말합니다)

class MyServer(Server):
    def __init__(self):
        super().__init__()

   def condition_ver(self, lRet, sMsg):
      condition_list = self.api.get_condition_name_list()

이것을 Server.py에서,

class Server:
    def __init__(self):
        self.api = None   --> 이곳을 self.api = Kiwoom() 으로 하면 해결이 되지만, 이렇게 하는 것이 맞는지요?
        self.share = None 

    def init(self, api, share):
        self.api = api
        self.share = share

혹시 API 로 업종별 코드를 얻는 기능이 있을까요?

안녕하세요 kiwoom wrapper 직접 개발하다가
잘 만들어진 프로젝트 발견해서 fork 하려고 합니다

근데 업종별 코드 (농업, 의약 등) 를 얻는 방법을 찾기가 힘든데
혹시 raw kiwoom api 에서 이걸 확인할 방법이 있을까요??

피크 타임에 응답없음

안녕하세요?
실서버에서 구동중에
주로 9시 ~ 9시 15분 사이에
api/ set_real_reg
api/ set_real_remove
(실시간 시세 조회 및 해제)
요청 시 빈번하게 전체 프로세스가 멈추는 현상이 있습니다.
( 3초마다 한번씩 API를 요청하여 빈도를 현저하게 낮추어도 동일하게 문제가 발생하고 있습니다.
장초반 10~20종목 정도 set_real_reg로 등록합니다 )

해당 현상 발생시 catch_error로 오류이벤트가 발생하지 않고
멀티스레딩 중인 스케쥴러(로깅) 또한 함께 멈추는 것으로 보입니다.

디버깅을 어떻게 해야할지
해당 원인이 키움 쪽에서 응답없음이라면,
어떤 식으로 대응해야할지 조언 부탁드립니다.

api.py SendOrderFO 주문 요청과 이벤트 처리 connect 하려고 하는데 방법 ?

api.py SendOrderFO 주문 요청과 이벤트 처리 connect 하려고 하는데 아래와 같이 하면 적절한지요 ?
rq_name 대신 gubun ??

    self.api.set_connect_hook('on_receive_chejan_data', 'gubun')           

    self.api.connect('on_receive_chejan_data', signal=self.orderfo, slot=self.server.orderfo)

   주문후 이벤트 처리하는 예제를 tutorials 에 추가해주시면 감사 감사 ~

로그인 이후 on_event_connect 이벤트 처리

안녕하세요.

로그인 이후 on_event_connect 이벤트 핸들러에서 접속 이후 처리를 하려고 합니다. (계좌비번을 자동으로 넣는 RPA 코드 실행) 그런데 해당 함수가 로그인 이후에 호출이 안됩니다. (break point를 걸었으나 걸리지 않음) 혹시 이유를 알 수 있을까요?

def on_event_connect(self, err_code):
"""
# 개발가이드 > 로그인 버전처리

    [OnEventConnect()이벤트]

    OnEventConnect(
      long nErrCode   // 로그인 상태를 전달하는데 자세한 내용은 아래 상세내용 참고
    )

    로그인 처리 이벤트입니다. 성공이면 인자값 nErrCode가 0이며 에러는 다음과 같은 값이 전달됩니다.

    nErrCode별 상세내용
    -100 사용자 정보교환 실패
    -101 서버접속 실패
    -102 버전처리 실패
    """
    pass

Kiwoom 객체 생성 시 오류

Kiwoom() 으로 객체 만들 때

Canceled future for execute_request message before replies were done

문구와 함께 에러가 발생합니다.

터미널에서 실행 테스트 했을 시에
QWidget: Must construct a QApplication before a QWidget
메시지를 출력하네요.

kiwoom 객체 생성 전에 QT app 먼저 실행해주니까 에러없이 실행됩니다~
app = QApplication(sys.argv)

api.py SendOrderFO parameter 가 한개 부족

api.py SendOrderFO parameter 가 한개 부족

fn = "SendOrderFO(QString, QString, QString, Int, QString, Int, Int, QString, QString)"

=>>  fn = "SendOrderFO(QString, QString, QString, QString, int, QString, QString, int, QString, QString)"  

판다스 32bit 지원 중지

안녕하세요.
kiwoom 모듈을 설치 후 판다스 32bit 버전을 따로 설치하려고 할 때 판다스가 더이상 구버전의 wheel을 지원하지 않게 되어 설치가 불가한 것 같습니다. 그에 따라 kiwoom 모듈의 사용도 불가합니다.
이젠 더이상 kiwoom 모듈을 사용이 불가능한 건가요?

주식분봉차트조회요청 TR에 주식코드를 넘기는 방법 문의

안녕하세요.
기존에는 _OnReceiveTrData_slot의 경우 code가 인자로 넘어오지 않기 때문에, 분봉울 가져올 때 rq_name의 인자로 조건식명-코드 (예: '조건식_417790')로 넘겨서 코드와 조건식을 mapping해서 사용했습니다. 그런데 제공해주신 Library에서 자동으로 hook되어 함수명으로 직접 연결되기 때문에, rq_name이 계속 코드에 따라 수시로 바뀌는 환경에서는 고정적인 함수를 만들 수 없게 됩니다만, 이 경우 hook하지 않고 원래대로 slot 동작으로 rq_name을 받아서 처리하는 방법 있을까요?
class MyServer(Server)에 코드와 조건식을 mapping하는 글로벌 변수를 잡아서 분봉 TR요청을 하고 TR로 들어오면 해당 글로벌 변수에 넣어 사용하면 될텐데, 이렇게 해도 조건식에 의해서 detection된 TR요청한 순서대로 들어온다는 보장이 되는지 잘 모르겠네요.

현재는

class MyBot(Bot):
    def __init__(self, server = None):
        super().__init__(server)
        self.api.OnReceiveTrData.connect(self.server.on_receive_tr_data)

class MyServer(Server):
    def __init__(self):
        super().__init__()
        ...
    def on_receive_tr_data(self, scr_no, rq_name, tr_code, record_name, prev_next):
        condition, code = rq_name.split('_')

이런식으로 했는데, 동작은 하지만 아래 warning이 들어와요~
kiwoom.on_receive_tr_data(4080, 주식분봉차트조회요청_417790, opt10080, , 0) has been called.
But the event handler, 'on_receive_tr_data', is not connected to any slot.
Please try to connect event and slot by using kiwoom.connect() method

조건검색 hook 처리 문의

조건검색은 OnReceiveConditionVer, OnReceiveTrCondition,OnReceiveRealCondition 등의 slot들 처리함에 있어서

    self.api.set_connect_hook('on_receive_tr_condition', param='condition_name')
    self.api.connect('on_receive_tr_condition', slot=self.server.test_condition1)

    self.api.set_connect_hook('on_receive_real_condition', param='condition_name')
    self.api.connect('on_receive_real_condition', slot=self.server.test_condition1)

위같이 하면, self.server 내에서 조건식명이 같기 때문에(test_condition1) 함수명을 어떻게 처리하나요 (중복)?

'실시간 체결 데이터' 수신 slot의 unloop 실행과 관련하여 문의 드립니다.

bot에서 ready_optsise(or SetRealReg 등록) 호출로 server slot이  '실시간 체결 데이터'(on_receive_real_data)를

실시간 수신 받게 되면 계속 unloop가 거의 실시간 반복 실행되는 상황인데 굳이 unloop 지정 해야 하는지 ?

=> 실시간 수신 받으면서 계속 unloop실행됨으로 다른 함수의 unloop 실행을 가로채는 것 아닌지 ? 어찌 풀어야 할지 ?

=> 도움 답변 감사합니다.

3일동안 고민이 해결되지 않아 글을 올립니다.

Historical data를 실행하면 입력한 시작날짜와 종료와 무관하게 3월 데이터만 csv로 추출합니다. 도저히 이해가 되지 않아 글을 올립니다. 제가 잘못하고 있는 것인가요?

도움부탁드립니다.^^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.