목 차
1. 들어가며
2. 사전설명
1) 키움에서 받아오는 데이터는 문자형
2) 문자형 → 실수형 → 정수형 → 절대값으로 작업 필요
3. 코드설명
4. 전체코드
5. 마치며
1. 들어가며
지난 글에서는 패턴의 개념 및 적용하는 방법을 알아보았다.
대단한 개념은 아니다.
필자도 고수들처럼 AI를 통한 머신러닝, 3음봉/3양봉 후 진입을 생각해 보았는데, 머신러닝을 위한 GPU 가격이 부담되고, 3음봉/3양봉을 어렵게 구현하더라도 수익이 난다는 100% 확신이 없는 상황에서 쉽게 다른 방법으로 코드를 구현하는 것은 부담이 되는 게 사실이다.
이번 글부터는 패턴을 본격적으로 만들어가보고자 한다.
패턴은 앞에서도 설명하였듯이, OHLC에 각각 10,000을 곱해서 부동소수점 문제를 회피하고나서 OHLC 간 사칙연산을 통해 패턴을 만들어줄 것이다.
브리티쉬 파운드(6BH23)의 패턴을 만들어보자.
※ (정정) 부동소수점 문제 회피 방법 (추가)
※ (정정) 부동소수점 문제를 회피 방법 (엑셀에서 패턴 만들 때 round 함수 추가)
1. 문제점
ㅇ 부동소수점 문제를 회피하기 위해 10,000을 OHLC에 곱해서 패턴을 만들는 과정에서 문제 발생
- 파운드를 엑셀에서 계산하는 과정에서 부동소수점 문제가 발생했다.
* 파이썬은 시가 0.0002 x 10000 을 하면 2이고, 고가 0.0004 x 10000을 하면 4로서, (고가)-(저가) = 2가 나온다.
문제는 엑셀에서 부동소수점 문제가 발생한다. -_-+
시가 0.0002 x 10000 을 하면 2이고, 고가 0.0004 x 10000을 하면 4인데, (고가)-(저가) = 1.999...
ㅇ < 그림1-1 > P9셀에서 부동소수점이 발생하는 것을 확인할 수 있다.
* 패턴 : 0 -4.999....18 - 3
→ 원래는 0 - 5 - 3으로 나타나야 하는데, 부동소수점 문제가 엑셀에서 발생한 것이다. ㅠㅠ
2. 해소 방법
< 그림1-2 >에서처럼, 사칙연산 이후 엑셀의 반올림하는 round 함수를 넣어준다.
설명은 이 글의 본문에서 하겠다.
2. 사전설명
1) 키움에서 받아오는 데이터는 문자형
키움증권에서 제공하는 데이터는 문자형이다.
예를들어 1.25를 키움에서 받았다면, 1.25의 태형은 실수(float)가 아닌 문자형(str)이다.
2) 문자형 → 실수형 → 정수형 → 절대값으로 작업 필요
①문자형을 실수형으로 바꾸는 방법은 문자형에 실수형(float)를 붙인다.
②실수형을 사칙연산한 경우, 부동소수점 문제가 발생하므로, 10000을 곱하여 정수화 한다.
예를 들어, 1.2345에 10000을 곱하면 12345가 되는데 이는 실수형이다. (실수형 x 10000 = 실수형)
→ 실수형을 정수화하는 방법은 실수형 앞에 정수화(int)를 붙이는 것이다.
③WKOA Studio에서 데이터를 받아보면 알겠지만,
키움증권에서 받는 데이터의 종가가 "마이너스"인 경우를 확인할 수 있다.
1분전의 종가보다 작아지면 "마이너스"로 표현되는 경우가 있다고 한다.
→ 만약의 경우를 위해 절대값을 붙여 "마이너스"가 나오지 않도록 한다.
* 참고자료 : 문자형을 절대값으로 수정 링크
※ (결론) open = abs (int( float(문자형) x 10000 ) ) 의 형태로 표기할 예정이다.
3) 엑셀 round 함수
- 엑셀 정의 : 설정한 소수점에 반올림
- 활용 형태 : round ( 셀, 소수점 자리수)
- 활용 예시 : round ( 1.23, 1) → 소수 첫째자리(1)에서 반올림하므로 1이 된다.
3. 패턴만들기 설명
1) 키움증권에서 제공하는 1분봉 패턴
이 글부터는 pyautogui를 통한 半자동 로그인은 설명하지 않을 예정이다.
어차피... 자동로그인이 되지 않는다면, 굳이 연습할 때 반자동 로그인을 설명할 실익이 적어 보인다.
귀찮더라도, 아이디의 비밀번호 및 계좌비밀번호는 스스로 입력하자.
1줄~5줄 : 로그인 및 QEventLoop 등을 활용하기 위해 필요 모듈을 임포트한다.
9줄 : 키움증권 OpenAPI-W 관련 레지스트리를 self.kiwoom에 담는다.
12줄~13줄 : 20줄(login_Connect)과 28줄(rq_data_opc10002)를 15~16줄 및 36줄의 결과값을 받아오기 위해 연결한다.
14줄 : 접속을 위한 로그인창의 비밀번호 창을 띄운다.
17줄 : 계좌 비밀번호 입력을 위한 창을 띄운다.
코드가 약간 짤렸는데, 이 글의 4번(전체코드)에 모두 있으니, 여기서는 참고만 하자.
28줄 : OHLC를 받아오기 위해, 종목/분봉 종류 입력 및 요청을 위해 함수를 선언한다.
29줄 : SetInputValue 함수를 이용하여 종목단위 및 시간단위가 들어갈 데이터를 키움서버에 입력한다.
30줄 : CommRqData 함수를 이용하여 28~29줄에서 키움서버에 입력한 데이터를 키움서버에 요청한다.
32줄 : 나중에 설명하겠지만, 키움측에서는 CommRqData 함수의 1초 당 5회 이상 조회시, OpenAPI 사용제한을 한다.
37줄 : 28줄~34줄까지 키움서버에 입력/요청한 데이터는 13줄(onreceive)의 연결을 통해 데이터를 받아온다.
38줄 ~ 53줄 : OHLC를 받아와서 패턴을 만드는 코드이다. 마음편히 쭈욱 훑어만 보자
38줄 : for문을 통해 데이터를 뽑아오는데, range(1, 2)는 1분전의 봉을 가져오라는 뜻이다.
* range(0,1)이면 현재 시간(06:59)의 데이터를 가져오라는 것이다.
* 현재는 장이 종료되어 있어서, 06:58분이 데이터를 가져온다.
39~43줄 : 체결시간 및 OHLC를 키움증권이 제공하는 GetCommData 함수를 통해 받아온다.
* 참고할 것은 < 그림3 >에서처럼 7개 데이터(현재가, 거래량 ~ 영업일자)를 받아오는데,
필자는 여기서, 5개 데이터만 사용 예정(체결시간, 현재가, 고가, 저가, 종가)이다.
* 사용자가 활용 예정인 데이터는 39줄~43줄처럼 받아오면 된다.
45줄 : 이 글의 첫번째 핵심이다. 패턴을 만들어준다.
* 여기에서 부동소수점이 발생한다. < 그림2-2 >에서 화면이 짤렸지만, 아래의 4번(전체코드)에서 확인하였듯이, 시가~종가에 10,000을 곱한 것을 확인할 수 있다.
50줄~51줄 : 이 글의 두번째 핵심이다.
우리가 현재 하고자하는 거래는 선물거래이다. 양방향으로 투자할 수 있는 장점이 있는 거래이다.
나중에 설명하겠지만, long / short 으로 동일 패턴을 각각 변수화 시키되,
향후 사용자가 만들 패턴에서 구분만 해주면 된다.
59줄 : 파운드('23.3월물)의 1분봉을 받기 위해 28줄의 함수를 실행하면 결과는 아래와 같다.
4. 전체 코드
※ 40줄~43줄의 시가~종가를 보면, 줄의 끝에 10000에 곱해지는 것을 확인하자.
import sys
from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import time
class btl_system():
def __init__(self):
self.kiwoom = QAxWidget("KFOPENAPI.KFOpenAPICtrl.1")
print("로그인 시작!")
self.kiwoom.OnEventConnect.connect(self.login_Connect)
self.kiwoom.OnReceiveTrData.connect(self.trdata_get)
self.kiwoom.dynamicCall("CommConnect(1)") # CommConnect() : 괄호 안에 자동(1)을 넣는다.
self.login_event_loop = QEventLoop()
self.login_event_loop.exec_()
self.kiwoom.dynamicCall("GetCommonFunc(QString, QString)", "ShowAccountWindow", "") # 계좌번호 입력창을 띄우는 내부함수
########## 로그인 관련 함수 ##########
def login_Connect(self, err_code):
if err_code == 0:
print('로그인 성공했습니다!')
self.login_event_loop.exit()
else:
print('로그인 실패했습니다!')
########## 키움서버에 TR 요청하는 함수 모음 ##########
def rq_data_opc10002(self, stock_code_num, time_unit):
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "종목코드", stock_code_num)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "시간단위", time_unit)
self.kiwoom.dynamicCall("CommRqData(QString, QString, QString, QString)", "opc_10002", "opc10002", "", "1012")
time.sleep(0.5)
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
def trdata_get(self, scrno, rqname, trcode, recordname, prenext):
if rqname == "opc_10002":
for i in range(1, 2):
dealed_time = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "체결시간").strip()
open = abs(int(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "시가").strip()) * 10000))
high = abs(int(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "고가").strip()) * 10000))
low = abs(int(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "저가").strip()) * 10000))
close = abs(int(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "현재가").strip()) * 10000))
pattern = str(high - open) + str(low - open) + str(close - open)
pattern = str(pattern)
print(f" {dealed_time}의 패턴은 {pattern }이다.")
self.check_pattern_jongmok_long = pattern
self.check_pattern_jongmok_short = pattern
self.tr_event_loop.exit()
if __name__ == "__main__":
app = QApplication(sys.argv)
btl = btl_system()
btl.rq_data_opc10002("6BH23", "1") # 1분봉 패턴 받기
app.exec_()
# (expected result)
# 20230114065800의 패턴은 1-3-1이다.
5. 마치며
글이 상당히 길어졌다. 해외선물도 국내주식과 유사한 구조(OHLC)여서, 비교적 수월하게 패턴을 만들 수 있었다.
다만, 소수점 틱단위가 있기 때문에 부동소수점 문제도 발생하고, 조금은 골치 아프다.
10,000을 곱해서 끝낼 수 있을 것 같았는데, 엑셀에서 부동소수점 문제가 발생할 줄이야...
다음 시간에는 엑셀에서 패턴 만드는 방법을 알아보자.
'2. 해외선물 > 2-4. 해외선물 API (사용)' 카테고리의 다른 글
(키움증권 해외선물 OpenAPI-W) 주문가능금액 조회 (opw30009, 예수금및증거금현황조회) (2) | 2023.01.22 |
---|---|
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (8) 참고사항 (5) | 2023.01.21 |
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (7) eval모듈, zip함수, for문으로 패턴 추출하기 (2) | 2023.01.20 |
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (6) 패턴 만들기(엑셀) (0) | 2023.01.19 |
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (4) 패턴 개념 이해하기 (0) | 2023.01.17 |
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (3) 패턴 만들기 필요성 (0) | 2023.01.16 |
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (2) 부동소수점 문제 회피하기 (0) | 2023.01.15 |
(키움증권 해외선물 OpenAPI-W) 패턴 만들기 (1) 해외선물 종목의 시가, 고가, 저가, 종가 받아오기 (0) | 2023.01.14 |