1. 들어가며
이번 시간에는 키움증권 OpenAPI를 활용하여,
주식의 매수/매도하는 방법을 알아보고자 한다.
"매수는 기술이지만, 매도는 예술이다" 라는 주식 명언이 있듯이
주식 자동매매로 수익을 내려면
매수/매도하는 방법을 파이썬에서 구현할 수 있어야 한다.
급하게 코드를 작성해서 매수/매도를 위해
오류없이 코드 작성하는게 생각보다 시간이 많이 걸렸고,
장 종료시간(18:00)은 다가오고...
캡쳐를 제대로 찍지 못한 점에 대해,
미리 양해의 말씀을 드린다.
이 글에서는 매매를 위한 함수인 SendOrder을 통해
주식의 매수/매도의 과정을 설명하고
카카오(035720) 매수와 신일전자(002700) 매수/매도의 과정을 알아볼 것이다.
2. 사전 준비
1) SendOrder 함수 검색 및 실행방법 찾기
KOA StudioSA에서는 아래와 같이 SendOrder 함수를 설명하고 있다.
① KOA StudioSA에 접속하여 "개발가이트" 탭 선택
② 주문과 잔고처리 > 관련함수 > SendOrder 함수를 찾을 수 있다.
③ SendOrder 함수는 9개의 인자를 준비해야 한다. -_-;;;
④ 시장가 주문시 주문가격은 0으로 설명한다.
⑤ 모의계좌에서는 지정가(00), 시장가(03)로만 실행할 수 있다.
2) SendOrder 함수의 9가지 인자(변수) 설명
SendOrder 함수를 실행하기 위해서는 9가지 변수를 넣어준다.
- 사용자 구분명(sRQName) : 사용자가 함수 내 인수를 구분하게 위해 임의로 짓는 변수
- 화면번호(sScreenNo) : 사용자가 임의로 선언해도 되는 변수(4자리)
- 계좌번호 10자리(sAccNo) : 사용자의 모의투자 계좌 10자리
- 주문유형(nOrderType) : 1.신규매수, 2.신규매도, 3.매수취소, 4.매도취소, 5.매수정정
- 종목코드(sCode) : 종목코드(6자리)
- 주문수량(nQty) : 주문수량
- 주문가격(nPrice) : 주문가격
- 거래구분(혹은 호가구분)(sHogaGb) : 00지정가, 03(시장가), 05(조건부지정가) 등
- 원주문번호(sOrgOrderNo) : 원주문 번호이며, 신규주문에는 공백 입력(" "), 정정/취소시 입력
3) SendOrder 함수의 활용
그림1의 9가지 변수 중 3가지가 매수/매도/취소 등의 관건이다.
핵심은 4번째 변수인 "주문유형"이다.
SendOrder 함수를 일단 선언해 두고,
그림1의 "주문유형(nOrderType)" 번호에 따라 필요할 때마다,
신규매수, 신규매도, 매수취소 등으로 활용할 수 있다.
3. 코드 구현
그간 필자가 SendOrder 함수를 너무 어렵게 생각했나보다. -_-;;
코드를 간략하게 작성해도 매수 주문이 잘 들어가서, 카카오 10주를 매수했다.
위 그림1에서 SendOrder 함수는 아래 3가지와 관련있다.
17줄~18줄 : 계좌번호 전역변수 선언한다.
37줄에서 모의계좌 10자리를 넣어주어야 한다.
27줄~30줄 : 키움에서 안내한 대로 9가지 변수가 들어갈 수 있도록,
SendOrder 함수 만들어 준다. (37줄에서 활용하기 위함)
37줄 : 종목코드, 주문물량 등을 입력하여 SendOrder 함수 실행
①~② 사용자 구분명, 화면번호는 임의로 이름을 정했고
③ 계좌번호는 17줄~18줄에서 전역변수로 선언된 str형태인 deposit_num을 넣어준다.
- deposit_num은 17~18줄에서 계좌번호가 쌍 따옴표(" ")로 묶여서
이미 문자형(QString)으로 선언되었다.
- 37줄에서 문자형으로 선언된 deposit_num에 양 따옴표(" ")
④ 주문유형은 신규매수이므로 int형태인 숫자 1을 넣어준다.
⑤ 종목코드는 문자형(QString)으로 카카오의 035720을 양 따옴표(" ")로 묶어준다.
⑥ 주문수량은 키움증권 OpenAPI에서 안내한 인수형(int)인 숫자 10을 넣어준다.
⑦ 그림1에서 설명하였듯이 시장가 주문은 0을 넣어준다.
⑧ 거래구분은 시장가 이므로, 문자형(QString)인 "03" 넣어준다.
⑨ 원주문번호는 신규주문이므로 공백(" ")을 입력한다
※ 9개 변수 중 첫번째(sRQName) ~ 두번째 변수(sScreenNo)는
함수를 만들 때(27줄)는 키움 KOA Studio에서 안내한대로 함수를 작성하되,
함수를 실행할 때(37줄)는, 사용자 마음대로 이름을 지어도 된다.
필자는 첫번째 변수는 "신규매수1", 두번째 변수는 "4949"로 화면번호를 임의로 지었다.
※ 로그인 방법은 아래에서 설명한다.
https://springcoming.tistory.com/17?category=1048804
(주식 자동 매매) 키움증권 OpenAPI 로그인
1. 들어가며 키움증권에서 제공하는 OpenAPI를 통해 키움서버에 접근하기 위해서는, 파이썬을 통해 OpenAPI에 접속하여 로그인할 수 있어야 한다. 당초 로그인 후 예수금 받기까지 진행하려고 했으
springcoming.tistory.com
4. 매수/매도 화면
1) 카카오(035720) 10주 매수 결과
그림3-1에서는 계좌에 카카오 주식이 없다.
그림3-2는 위의 함수를 실행하여 카카오 10주를 매수한 후의 화면이다.
2) 신일전자(002700) 10주 매수/매도하는 화면
그림2의 37줄의 함수에서 종목코드만 바꾸어주면 10주를 매수한다.
그림4-1은 신일전자(002700)을 매수 전 계좌현황이다.
그림2를 신일전자(002700) 10주 매수 명령어로 바꾸어 실행하면,
그림4-2처럼 체결될 때 "체결내역통보"가 된다.
신일전자(002700) 10주가 체결되고 나서의 계좌 잔고이다.
금일 매수 10주가 눈에 띈다.
이제 매수한 신일전자 10주를 매도해 보자.
매수코드에서 4번째 변수인 주문유형(nOrderType)을 "2.신규매도"로 바꾸기 위해,
4번째 인수에 "2"를 넣었다.
※ 첫번째(사용자 구분명, sRQName)과 화면번호(sScreenNo)는, 매수코드와 똑같이 해도 상관없다.
(여기서는 매도코드를 강조하기 위해, 첫번째~두번째 인수를 바꾼 것이다)
매도가 제대로 키움서버에 요청되었다면, 미체결 주문이 올라가 있다.
(현재가로 팔려고 했는데, 다른 주문들이 먼저 처리되어야 해서,
필자의 주문이 대기하고 있는 상태이다.)
신일전자 10주 매도를 걸었는데. 1주가 먼저 체결되고,
미체결 주문이 9개 남았다.
당초 미체결 9주가 다 팔린 모습이다.
미체결 주문내역에는 "미체결 내역"이 없고,
체결내역통보에 10주가 다 팔린 걸 확인할 수 있다.
※ 한가지 의문인건, 분명 현재가(1,710원)에 매도 주문을 넣었는데,
모의계좌라서 그런가?
바로 체결이 안된 부분이 의문이긴 하다.
모의계좌에서 매도한 신일전자(002700) 없는 화면이다.
5. 전체 코드
import sys
from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class btl_system():
def __init__(self):
self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
print("로그인 시작!")
self.kiwoom.OnEventConnect.connect(self.login_Connect)
self.kiwoom.dynamicCall("CommConnect()")
self.login_event_loop = QEventLoop()
self.login_event_loop.exec_()
global deposit_num
deposit_num = "계좌번호 10자리 넣는 곳"
def login_Connect(self, err_code):
if err_code == 0:
print('로그인 성공했습니다!')
else:
print('로그인 실패했습니다!')
self.login_event_loop.exit()
def sendorder_trading(self, rqname, scrno, accno, ordertype, scode, qty, price, hogagb, orgorderno):
print("키움서버에 매매 요청하였습니다.")
self.kiwoom.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
[rqname, scrno, accno, ordertype, scode, qty, price, hogagb, orgorderno])
if __name__ == "__main__":
app = QApplication(sys.argv)
btl = btl_system()
btl.sendorder_trading("신규매수1", "4949", deposit_num, 1, "035720", 10, 0, "03", "") # 카카오
app.exec_()
6. 마치며
매매를 위한 함수인 SendOrder 함수를 통해
카카오(035720) 매수와 신일전자(002700) 매수/매도의 과정을 알아보았다.
물론 if 조건문이나 for반복문을 쓰면 더 복잡해 지겠지만.
SendOrder 함수의 작동 원리가 생각보다 간단하다는 감각만 있으면 될거 같다.
4번째 변수인 주문유형(nOrderType)을 1번(매수), 2번(매도)로 바꾸어주면
제대로 작동한다.
미체결 내역을 취소하는 것까지 생각을 했으나,
장이 종료(18:00)되어, "취소 주문"이 자동으로 삭제되어 버렸다. ㅠㅠ
다음에는 "미체결 내역"에 대해 삭제하는 코드를 알아보고자 한다.
일부 주식만 매수 체결될 경우 매수주문 취소하는 방법과
매수/매도 주문 내역을 전체 취소하는 방법을 검토 중인데,
일부 주식만 매수체결된 경우, 그 경우가 쉽게 올 것 같지 않다.ㅠㅠ
주식이 워낙 순식간에 체결되기 때문에
그 상황이 먼저 발생해야 하고, 오류없이 코드를 작성하고,
일부체결 안되는 내용을 취소하려는데, 쉽지 않은 여건임을 감안하면,
어쩔 수 없이, 매수/매도 주문 내역 전체를 취소하는 방법을 검토할 것이다.
'1. 국내주식 > 1-2. 키움 OpenAPI (사용)' 카테고리의 다른 글
(주식 자동 매매) 키움증권 OpenAPI - 미체결 주문을 SendOrder 함수로 취소하기 (3) 주문번호와 원주문번호 구분 필요 (0) | 2022.10.08 |
---|---|
(주식 자동 매매) 키움증권 OpenAPI - 미체결 주문을 SendOrder 함수로 취소하기 (2) 취소주문 테스트 (5) | 2022.10.07 |
(주식 자동 매매) 키움증권 OpenAPI - 미체결 주문을 SendOrder 함수로 취소하기 (1) 취소 방법 (0) | 2022.10.06 |
(주식 자동 매매) 키움증권 OpenAPI - 1분봉 데이터 실시간 받기(opt10080) (2) | 2022.10.05 |
(주식 자동 매매) 키움증권 OpenAPI 매수한 4종목의 매수가격, 매수량 받아오기(opt10085) (0) | 2022.09.28 |
(주식 자동 매매) 키움증권 OpenAPI 종목의 현재가를 전역변수에 담기(opt10001) (0) | 2022.09.27 |
(주식 자동 매매) 키움증권 OpenAPI 4종목 현재가 조회(opt10001) (0) | 2022.09.26 |
(주식 자동 매매) 키움증권 OpenAPI 현재가 조회(opt10001) (0) | 2022.09.25 |