목 차
1. 들어가며
2. 사전설명
3. 코드설명
4. 전체코드
5. 마치며
1. 들어가며
지난 글에서는 해외선물 거래를 위해 필요한 보조지표를 얻는 방법을 알아보았다. 보조지표는 어디까지나 매매를 위한 보조수단일뿐 지나치게 맹신하지 않아야 한다. 이유는? 시장은 항상 변하기 때문이다.
이번 글에서는 해외선물 자동매매를 위해 필요한 "시간 관리"에 대해 알아볼 것이다. 시간 관리가 필요한 이유는 무엇일까?
서머타임(3월중순 ~ 11월초) 기준으로 아침7시~익일 6시까지 23시간 시장이 열려있다. 이 중 거래량이 폭발적으로 증가하는 미국장이 개장하는 22:30~05:00까지의 알고리즘과 05:00~22:30분까지의 적용할 알고리즘이 동일할 수는 없을 것이다. 왜냐하면, 거래량과 선물가격의 변화량에서 압도적인 차이가 발생하기 때문이다.
시간 관리의 첫번째 설명으로 현재시간 출력하기에 대해 알아보자. 예전에 비트코인을 공부할 때 시간에 대해 설명(링크 : https://springcoming.tistory.com/57)하였다. 위 링크의 설명을 간략하게 정리할 것이다.
2. 사전설명
시간을 출력하는 방법은 여러가지가 있겠지만, 필자는 파이썬의 datetime 라이브러리를 활용한다. 자세한 설명은 인터넷 검색을 통해 알아보면 좋을 것이고, 여기서는 "현재시간"을 출력하는 방법 위주로 설명한다.
화면에 출력하는 현재시간은 2023-10-21(토), 11:30분이다.
현재시간을 출력하는 코드는 아래와 같다.
from datetime import datetime
def time_update():
date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(date_time)
time_update()
### (expected result)
### 2023-10-21 23:30:44
1줄 : datetime 패키지에서 datetime 라이브러리 관련 내용은 가져온다.
3줄 : 현재시간을 출력해주기 위해 time_update() 함수를 선언한다.
4줄 : datetime 라이브러리 내 now() 함수를 이용하여 시간을 출력한다. strftime의 출력형태는 "연도-월-일" + "시간-분-초"의 형태이다. 예를 들어 2023-10-21 23:30:44초의 형태이다.
5줄 : 현재시간을 출력한다.
7줄 : 3줄의 함수를 실행한다.
3. 코드설명
위에서 설명한 코드를 해외선물 자동매매에서 어떻게 활용할 것인가? 현재시간을 출력하는 내용은 인터넷 검색에 많이 나올 것이다. 우리에게 필요한 것은 "연월일 시간-분-초" 중 "시간과 분"이다. 연월일은 서머타임이 적용/미적용 기간에 따라 장 시작시간만 바꾸어서 코드를 설정해주면 될 것 같다. 초(second)까지 고려하면서 거래를 하고 싶지는 않다.
import sys
from PyQt5.QtWidgets import *
from datetime import datetime
class btl_system():
########## 시간 현행화 ###########
def time_update(self):
self.date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.traded_date = self.date_time[0:10]
self.traded_time = self.date_time[11:19]
print(self.date_time)
print(self.traded_date)
print(self.traded_time)
if __name__ == "__main__":
app = QApplication(sys.argv)
btl = btl_system()
btl.time_update()
app.exec_()
### (expected result)
### 2023-10-21 23:38:20
### 2023-10-21
### 23:38:20
1줄~3줄 : 사용할 라이브러리이며, 설명을 생략한다.
5줄 : 자동매매에서 활용할 클래스를 선언한다.
8줄 : 현재시간을 일정 시간단위로 업데이트 해줄 것(반복적 수행)이기 때문에 함수를 선언한다.
9줄 : datetime 라이브러리의 now()함수를 활용하여 "연-월-일 시간-분-초" 형태로 현재시간을 받아온다.
10줄 : "연월일 시간분초"의 형태에서 0자리~19자리까지 내용을 self.traed_date에 담는다.(연월일)
11줄 : "연월일 시간분초"의 형태에서 11자리~19자리까지 내용을 self.traded_time에 담는다.(시간분초)
13줄~15줄 : 현재시간을 출력하고, 연월일 및 시간-분-초를 각각 출력한다.
4. 전체코드
전체코드는 아래 < 접은글 >과 같다. 6줄과 664줄~668줄이 추가되었다.
※ 아래 < 접은글 >의 코드를 실행하려면 키움증권에 시세조회 이용료($185)를 지불하여야 한다.
import sys
from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import numpy
from datetime import datetime
class btl_system():
def __init__(self):
self.kiwoom = QAxWidget("KFOPENAPI.KFOpenAPICtrl.1")
print("로그인 시작!")
self.kiwoom.dynamicCall("CommConnect(1)") # CommConnect() : 괄호 안에 자동(1)을 넣는다.
self.kiwoom.OnEventConnect.connect(self.login_Connect)
self.kiwoom.OnReceiveTrData.connect(self.trdata_get)
self.login_event_loop = QEventLoop()
self.login_event_loop.exec_()
self.kiwoom.dynamicCall("GetCommonFunc(QString, QString)", "ShowAccountWindow", "") # 계좌번호 입력창을 띄우는 내부함수
##### rsi의 현재 1분 데이터의 au/ad 구하기 #####
self.price_rsi_total = [] # 158~163줄 : 1분봉들의 종가데이터를 담는 리스트 모음
self.close_price_rsi_change = [] # 164~167줄 : 기준값(au/ad)를 세팅하기 위해, 최근 15개 값을 담는 리스트
self.close_price_third = [] # 168~179줄 : 기준값 15개의 각 종가들의 차이 모음 리스트
self.early_au1 = [] # 175~179줄 : 음수를 0으로 표시
self.early_ad1 = [] # 175~179줄 : 양수를 0으로 표시
self.rsi_total_list = [] # 214~235줄 : 각각의 rsi를 담는 리스트 모음
def login_Connect(self, err_code):
if err_code == 0:
print('로그인 성공했습니다!')
else:
print('로그인 실패했습니다!')
self.login_event_loop.exit()
########## 키움서버에 TR 요청하는 함수 모음 ##########
def rq_data_opc10002(self, stock_code_num, time_unit): # 1분봉 받기
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", "", "1002")
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
def rq_data_opw30009(self, deposit_num1, password_2, password_enter3): # 주문가능금액, 실현손익, 미실현손익
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "계좌번호", deposit_num1)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "비밀번호", password_2)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "비밀번호입력매체", password_enter3)
self.kiwoom.dynamicCall("CommRqData(QString, QString, QString, QString)", "opw_30009", "opw30009", "", "3009")
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
def rq_data_opw30011(self, deposit_num1, password_2, password_enter3, futures_code4, sell_buy_gubunm5, order_type6, order_price7): # 주문가능수량
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "계좌번호", deposit_num1)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "비밀번호", password_2)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "비밀번호입력매체", password_enter3)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "종목코드", futures_code4)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "매도수구분", sell_buy_gubunm5)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "해외주문유형", order_type6)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "주문표시가격", order_price7) # "시장가"로 주문할 경우, 함수 실행시 빈칸("")으로 요청
self.kiwoom.dynamicCall("CommRqData(QString, QString, QString,QString)", "opw_30011", "opw30011", "", "3011")
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
def rq_data_opw30012(self, deposit_num1, password_2, password_enter3): # 계좌 현재가, 매도수구분, 보유수량, 매입단가, 계좌현재가, 평가손익
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "계좌번호", deposit_num1)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "비밀번호", password_2)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "비밀번호입력매체", password_enter3)
self.kiwoom.dynamicCall("CommRqData(QString, QString, QString, QString)", "opw_30012", "opw30012", "", "3012")
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
########## OnReceiveTrData을 통해 수신받은 데이터 함수 ##########
def trdata_get(self, scrno, rqname, trcode, recordname, prenext):
if rqname == "opc_10002":
getrepeatcnt = self.kiwoom.dynamicCall("GetRepeatCnt(QString,QString)", trcode, recordname)
self.getrepeatcnt = getrepeatcnt
self.tr_event_loop.exit()
btl.rsi_searching()
btl.bollinger_searching()
btl.macd_searching()
elif rqname == "opw_30009": # 주문가능금액, 실현손익, 미실현손익
orderable_money = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30009", "opw30009", 0, "주문가능금액").strip())
withdrawal_money = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30009", "opw30009", 0, "인출가능금액").strip())
realized_pl = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30009", "opw30009", 0, "선물청산손익").strip())
unrealized_pl = int(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30009", "opw30009", 0, "선물평가손익").strip())
self.orderable_money = orderable_money / 100
self.withdrawal_money = withdrawal_money / 100
self.realized_pl = realized_pl / 100
self.unrealized_pl = unrealized_pl / 100
print(self.orderable_money)
self.tr_event_loop.exit()
elif rqname == "opw_30011": # 주문가능수량
orderable_qty = int(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30011", "opw30011", 0, "주문가능수량").strip())
liquidable_qty = int(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30011", "opw30011", 0, "청산가능수량").strip())
orderable_money_30011 = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30011", "opw30011", 0, "주문가능금액").strip())
currency_code = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30011", "opw30011", 0, "통화코드").strip()
self.orderable_qty = orderable_qty
self.liquidable_qty = liquidable_qty
self.orderable_money_30011 = orderable_money_30011 / 100
self.currency_code = currency_code
self.tr_event_loop.exit()
elif rqname == "opw_30012": # 계좌 현재가, 매도수구분, 보유수량, 매입단가, 계좌현재가, 평가손익
stock_code_d = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30012", "opw30012", 0, "종목코드").strip()
sell_buy_gubun_d = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30012", "opw30012", 0, "매도수구분").strip()
my_qty_d = int(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30012", "opw30012", 0, "수량").strip())
my_price_d = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30012", "opw30012", 0, "매입가격").strip())
current_price_d = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30012", "opw30012", 0, "현재가격").strip()))
estimate_pl_d = int(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opw_30012", "opw30012", 0, "평가손익").strip())
self.stock_code_d = stock_code_d
self.sell_buy_gubun_d = sell_buy_gubun_d
self.my_qty_d = my_qty_d
self.my_price_d_30012 = my_price_d
self.current_price_d_30012 = current_price_d
self.estimate_pl_d_30012 = estimate_pl_d / 100
self.tr_event_loop.exit()
########## 주문요청하는 함수 (키움 OPENApi-w에서 제공) ##########
def sendorder_func(self, rqname, scr, acc, ordertype, futures_code, qty, futures_price, s_stop, hogagb, orgno):
self.kiwoom.dynamicCall("SendOrder(Qstring, Qstring, Qstring, int, Qstring, int, Qstring, Qstring, Qstring, Qstring)",
[rqname, scr, acc, ordertype, futures_code, qty, futures_price, s_stop, hogagb, orgno])
"""
1) BSTR sRQName,
2) BSTR sScreenNo,
3) BSTR sAccNo,
4) LONG nOrderType, *주문유형(1: 신규매도, 2: 신규매수, 3: 매도취소, 4: 매수취소, 5: 매도정정, 6: 매수정정)
5) BSTR sCode,
6) LONG nQty,
7) BSTR sPrice,
8) BSTR sStop, * stop 단가
9) BSTR sHogaGb, * 거래구분(1: 시장가, 2: 지정가, 3: STOP, 4: STOP LIMIT)
10) BSTR sOrgOrderNo)
*(예시) ## openApi.SendOrder("RQ_1", "1000", "5077000072", 1, "6AZ20", / 1, "0.7900", "0", "2", ""); // 지정가 매도
openApi.SendOrder("RQ_1", "1000", "5077000072", 1, "6AZ20", / 1, "0", "0", "1", ""); // 시장가 매도
## openApi.SendOrder("RQ_1", "1000", "5077000072", 1, "6AZ20", / 1, "0", "0.7900", "3", ""); // STOP 매도
## openApi.SendOrder("RQ_1", "1000", "5077000072", 1, "6AZ20", / 1, "0.7850", "0.8000", "4", ""); // STOP LIMIT 매도
## openApi.SendOrder("RQ_1", "1000", "5077000072", 5, "6AZ20", / 1, "0.7850", "0", "2", "500060"); // 정정 매도
## openApi.SendOrder("RQ_1", "1000", "5077000072", 3, "6AZ20", / 1, "0", "0", "2", "500060"); // 취소 매도
"""
def rsi_searching(self):
for i in range(self.getrepeatcnt): # 현재가 → 오래된 값으로 출력된다.
self.current_price_rsi = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "현재가").strip())
self.price_rsi_total.append(self.current_price_rsi)
self.price_rsi_total_final = self.price_rsi_total[::-1]
self.price_rsi_total = []
for i in range(0, 15):
current_price_recent = self.price_rsi_total_final[i]
self.close_price_rsi_change.append(current_price_recent)
for j in range(len(self.close_price_rsi_change) - 1):
self.close_price_second = self.close_price_rsi_change[j + 1] - self.close_price_rsi_change[j]
self.close_price_third.append(self.close_price_second)
self.close_price_rsi_change = []
print("68줄")
for i in self.close_price_third: # 음수를 0으로 표시
if i <= 0:
i = 0
self.early_au1.append(i)
else:
self.early_au1.append(i)
for j in self.close_price_third: # 양수를 0으로 표시
if j >= 0:
j = 0
self.early_ad1.append(j)
else:
self.early_ad1.append(j)
self.au7 = sum(self.early_au1) / len(self.early_au1)
self.ad7 = sum(self.early_ad1) / len(self.early_ad1)
self.ad7 = abs(self.ad7)
self.early_au1 = [] # 초기화
self.early_ad1 = [] # 초기화
del self.close_price_third[:] # 향후 사용하지 않을 분봉 리스트는 초기화(삭제)하여 메모리 효율화 추진
for k in range(1, self.getrepeatcnt-1):
curren_price_rsi_1 = self.price_rsi_total_final[k]
curren_price_rsi_2 = self.price_rsi_total_final[k+1]
current_price_rsi_3 = curren_price_rsi_2 - curren_price_rsi_1
if current_price_rsi_3 >= 0:
positive_price = current_price_rsi_3
negative_price = 0
else:
positive_price = 0
negative_price = abs(current_price_rsi_3)
self.au8 = (self.au7 * 13 + positive_price) / 14
self.ad8 = (self.ad7 * 13 + negative_price) / 14
rs2 = self.au8 / self.ad8
self.rsi_second = rs2 / (1 + rs2) * 100
self.current_rsi = round(self.rsi_second, 2)
self.rsi_total_list.append(self.current_rsi)
self.au7 = self.au8
self.ad7 = self.ad8
self.price_rsi_total_final = []
self.rsi_total_list = self.rsi_total_list[::-1]
self.current_rsi_0 = self.rsi_total_list[0] # 현재시간
self.current_rsi_1 = self.rsi_total_list[1] # 1분전
print(self.current_rsi_0)
print(self.current_rsi_1)
self.rsi_total_list_2_35_minute = [] # 2분전 ~ 35분전
for i in range(2, 36):
self.rsi_total_list_2_35_minute.append(self.rsi_total_list[i])
self.rsi_max_2_35_minute_point = max(self.rsi_total_list_2_35_minute)
self.rsi_max_2_35_minute_position = self.rsi_total_list_2_35_minute.index(self.rsi_max_2_35_minute_point) + 2 # 2를 더한 이유 : 순서가 0부터 시작한다. (2분전~35분까지를 알고 싶음, 2분전에 해당하는 숫자는 for(2, 36)에서 "2"는 0이므로, 0+2를 통해 "2분"을 나타냄)
self.rsi_min_2_35_minute_point = min(self.rsi_total_list_2_35_minute)
self.rsi_min_2_35_minute_position = self.rsi_total_list_2_35_minute.index(self.rsi_min_2_35_minute_point) + 2
def bollinger_searching(self):
self.close_price2 = []
for i in range(0, 20):
close_price1 = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "현재가").strip()))
self.close_price2.append(close_price1)
self.close_price3 = numpy.mean(self.close_price2) + numpy.std(self.close_price2) * 2
self.close_price4 = numpy.mean(self.close_price2) - numpy.std(self.close_price2) * 2
self.bollinger_upper_line = float(round(self.close_price3, 2))
self.bollinger_lower_line = float(round(self.close_price4, 2))
self.close_price2 = [] # 2번째 종목 조회할 때,1종목의 데이터가 들어있어서 누적되는 현상 발생 (초기화 시켜줌)
def macd_searching(self):
##### macd의 현재 1분 데이터의 au/ad 구하기 #####
self.macd_minute_bong_couning = 100 # macd를 구하기 위해 받아올 일봉 갯수
self.price_macd_total = [] # 56~86줄 : 1분봉들의 종가데이터를 담는 리스트 모음
self.macd_12_26_total = [] # macd 시그널을 구하기 위한 리스트 선언
self.ema_var_12 = 2 / (12 + 1)
self.ema_var_26 = 2 / (26 + 1)
self.signal_var_9 = 2 / (9 + 1)
for i in range(self.macd_minute_bong_couning): # 현재가 → 오래된 값으로 출력된다.
self.current_price_macd = float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "현재가").strip())
self.price_macd_total.append(self.current_price_macd)
self.price_macd_total_final = self.price_macd_total[::-1]
### ema_12, ema_26 지수이동평균 구하기 ###
for i in range(self.macd_minute_bong_couning):
if i == 0:
pass
elif i == 1:
self.ema_12_first = (self.price_macd_total_final[1] * self.ema_var_12) + (self.price_macd_total_final[0] * (1 - self.ema_var_12))
self.ema_12_second = self.ema_12_first
self.ema_26_first = (self.price_macd_total_final[1] * self.ema_var_26) + (self.price_macd_total_final[0] * (1 - self.ema_var_26))
self.ema_26_second = self.ema_26_first
elif i >= 2:
self.ema_12_third = self.ema_12_second
self.ema_12_forth = self.price_macd_total_final[i]
self.ema_12_final = (self.ema_12_forth * self.ema_var_12) + (self.ema_12_third * (1 - self.ema_var_12))
self.ema_12_second = self.ema_12_final
self.ema_26_third = self.ema_26_second
self.ema_26_forth = self.price_macd_total_final[i]
self.ema_26_final = (self.ema_26_forth * self.ema_var_26) + (self.ema_26_third * (1 - self.ema_var_26))
self.ema_26_second = self.ema_26_final
# self.macd_12_26 = round(self.ema_12_final - self.ema_26_final, 2) # 소수 셋째 자리에서 반올림 (소수 둘째 자리까지 출력)
self.macd_12_26 = self.ema_12_final - self.ema_26_final # 반올림없이 값 출력
self.macd_12_26_total.append(self.macd_12_26)
if i == self.macd_minute_bong_couning - 7:
self.macd_12_26_6_mintue_ago = self.macd_12_26
elif i == self.macd_minute_bong_couning - 6:
self.macd_12_26_5_mintue_ago = self.macd_12_26
elif i == self.macd_minute_bong_couning - 5:
self.macd_12_26_4_mintue_ago = self.macd_12_26
elif i == self.macd_minute_bong_couning - 4:
self.macd_12_26_3_mintue_ago = self.macd_12_26
elif i == self.macd_minute_bong_couning - 3:
self.macd_12_26_2_mintue_ago = self.macd_12_26
elif i == self.macd_minute_bong_couning - 2:
self.macd_12_26_1_mintue_ago = self.macd_12_26
elif i == self.macd_minute_bong_couning - 1:
self.macd_12_26_current = self.macd_12_26
### macd_signal 구하기 ###
self.macd_12_26_counting = len(self.macd_12_26_total)
print(self.macd_12_26_counting)
for i in range(self.macd_12_26_counting):
if i == 0:
pass
if i == 1:
self.macd_signal_first = (self.macd_12_26_total[1] * self.signal_var_9) + (self.macd_12_26_total[0] * (1 - self.signal_var_9))
self.macd_signal_second = self.macd_signal_first
elif i >= 2:
self.macd_signal_third = self.macd_signal_second
self.macd_signal_forth = self.macd_12_26_total[i]
self.macd_signal_final = (self.macd_signal_forth * self.signal_var_9) + (self.macd_signal_third * (1 - self.signal_var_9))
# self.macd_signal_final = round(self.macd_signal_final, 2) # 소수 셋째 자리에서 반올림 (소수 둘째 자리까지 출력)
self.macd_signal_second = self.macd_signal_final
if i == self.macd_12_26_counting - 7:
self.macd_signal_final_6_mintue_ago = self.macd_signal_final
elif i == self.macd_12_26_counting - 6:
self.macd_signal_final_5_mintue_ago = self.macd_signal_final
elif i == self.macd_12_26_counting - 5:
self.macd_signal_final_4_mintue_ago = self.macd_signal_final
elif i == self.macd_12_26_counting - 4:
self.macd_signal_final_3_mintue_ago = self.macd_signal_final
elif i == self.macd_12_26_counting - 3:
self.macd_signal_final_2_mintue_ago = self.macd_signal_final
elif i == self.macd_12_26_counting - 2:
self.macd_signal_final_1_mintue_ago = self.macd_signal_final
elif i == self.macd_12_26_counting - 1:
self.macd_signal_final_current = self.macd_signal_final
self.price_macd_total = []
self.price_macd_total_final = []
self.macd_12_26_total = []
### macd_oscillators 구하기 ###
self.macd_Oscillator_6_mintue_ago = self.macd_12_26_6_mintue_ago - self.macd_signal_final_6_mintue_ago
self.macd_Oscillator_5_mintue_ago = self.macd_12_26_5_mintue_ago - self.macd_signal_final_5_mintue_ago
self.macd_Oscillator_4_mintue_ago = self.macd_12_26_4_mintue_ago - self.macd_signal_final_4_mintue_ago
self.macd_Oscillator_3_mintue_ago = self.macd_12_26_3_mintue_ago - self.macd_signal_final_3_mintue_ago
self.macd_Oscillator_2_mintue_ago = self.macd_12_26_2_mintue_ago - self.macd_signal_final_2_mintue_ago
self.macd_Oscillator_1_mintue_ago = self.macd_12_26_1_mintue_ago - self.macd_signal_final_1_mintue_ago
self.macd_Oscillator_final_current = self.macd_12_26_current - self.macd_signal_final
self.macd_Oscillator_2_mintue_ago = round(self.macd_12_26_2_mintue_ago - self.macd_signal_final_2_mintue_ago, 2)
self.macd_Oscillator_1_mintue_ago = round(self.macd_12_26_1_mintue_ago - self.macd_signal_final_1_mintue_ago, 2)
self.macd_Oscillator_final_current = round(self.macd_12_26_current - self.macd_signal_final, 2)
print(self.macd_12_26_2_mintue_ago)
print(self.macd_signal_final_2_mintue_ago)
print(self.macd_Oscillator_2_mintue_ago)
print("\n")
print(self.macd_12_26_1_mintue_ago)
print(self.macd_signal_final_1_mintue_ago)
print(self.macd_Oscillator_1_mintue_ago)
print("\n")
print(self.macd_12_26_current)
print(self.macd_signal_final_current)
print(self.macd_Oscillator_final_current)
def stochastic_searching(self):
### 스토캐스틱 지표 #####
self.nq_max_price_list = []
self.nq_min_price_list = []
self.stc_fast_d_list = []
self.stc_slow_k_list_close_min = []
self.stc_slow_k_list_max_min = []
self.stc_slow_d_list_row = []
self.stc_slow_d_list = []
self.stc_slow_k_forth_list = []
self.stc_fast_k_weighting = 2 / (3 + 1)
self.stc_slow_d_weighting = 2 / (5 + 1)
self.stc_oscillator_d_weighting = 2 / (26+1)
self.stc_oscillator_d_9_weighting = 2 / (9+1)
self.stc_slow_oscillator_k_26_close_min_list = []
self.stc_slow_oscillator_k_26_max_min_list = []
self.stc_slow_oscillator_final = []
######################################################
########## 스토캐스틱 패스트 %K, %D ##########
for i in range(0, 50): # 현재 분의 STC_패스트 K, D 구하기
for j in range(i, i + 5):
self.close_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "현재가").strip()))
max_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", j, "고가").strip()))
min_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", j, "저가").strip()))
self.nq_max_price_list.append(max_price_row_data)
self.nq_min_price_list.append(min_price_row_data)
self.close_price_first = self.close_price_row_data
self.max_price_first = max(self.nq_max_price_list)
self.min_price_first = min(self.nq_min_price_list)
self.nq_max_price_list = []
self.nq_min_price_list = []
self.stc_fast_k_first = (self.close_price_first - self.min_price_first) / (self.max_price_first - self.min_price_first) * 100
self.stc_fast_k_first = round(self.stc_fast_k_first, 2) # 소수 셋째자리에서 반올림
self.stc_fast_d_list.append(self.stc_fast_k_first)
self.stc_fast_d_list_final = self.stc_fast_d_list[::-1]
self.stc_fast_k = self.stc_fast_d_list_final[29]
self.stc_fast_d_list = []
for i in range(len(self.stc_fast_d_list_final)):
if i == 0:
self.stc_fast_d_first = self.stc_fast_d_list_final[i]
elif i >= 1:
self.stc_fast_d_second = (self.stc_fast_d_list_final[i] * self.stc_fast_k_weighting) + (self.stc_fast_d_first * (1 - self.stc_fast_k_weighting))
self.stc_fast_d_first = self.stc_fast_d_second
if i == 49:
self.stc_fast_d_0_ago = round(self.stc_fast_d_first, 2) # 현재시간
elif i == 48:
self.stc_fast_d_1_ago = round(self.stc_fast_d_first, 2) # 1분전
elif i == 47:
self.stc_fast_d_2_ago = round(self.stc_fast_d_first, 2) # 2분전
elif i == 46:
self.stc_fast_d_3_ago = round(self.stc_fast_d_first, 2) # 3분전
elif i == 45:
self.stc_fast_d_4_ago = round(self.stc_fast_d_first, 2) # 4분전
elif i == 44:
self.stc_fast_d_5_ago = round(self.stc_fast_d_first, 2) # 5분전
self.stc_fast_d_list_final = []
self.stc_fast_k = round(self.stc_fast_k, 2)
self.stc_fast_d = round(self.stc_fast_d_second, 2)
# print(self.stc_fast_k)
# print(self.stc_fast_d)
########## 스토캐스틱 슬로우 %K, %D ##########
for i in range(0, 50):
for j in range(i, i+5): # 현재 분의 STC_슬로우 K, D 구하기 /// stc_slow_k = ∑(현재가 - 최대값) / ∑(최대값 - 최소값)
for k in range(j, j + 12):
self.close_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", j, "현재가").strip()))
max_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", k, "고가").strip()))
min_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", k, "저가").strip()))
self.nq_max_price_list.append(max_price_row_data)
self.nq_min_price_list.append(min_price_row_data)
self.close_price_first = self.close_price_row_data
self.max_price_first = max(self.nq_max_price_list)
self.min_price_first = min(self.nq_min_price_list)
self.nq_max_price_list = []
self.nq_min_price_list = []
self.price_first_close_min = self.close_price_first - self.min_price_first
self.price_first_max_min = self.max_price_first - self.min_price_first
self.stc_slow_k_list_close_min.append(self.price_first_close_min)
self.stc_slow_k_list_max_min.append(self.price_first_max_min)
self.stc_slow_k_first = sum(self.stc_slow_k_list_close_min)
self.stc_slow_k_second = sum(self.stc_slow_k_list_max_min)
self.stc_slow_k_list_close_min = []
self.stc_slow_k_list_max_min = []
self.stc_slow_k_third = self.stc_slow_k_first / self.stc_slow_k_second * 100
self.stc_slow_k_third = round(self.stc_slow_k_third, 2)
self.stc_slow_k_forth_list.append(self.stc_slow_k_third)
if i == 0:
self.stc_slow_k = self.stc_slow_k_forth_list[0]
elif i == 1:
self.stc_slow_k_1_ago = self.stc_slow_k_forth_list[1]
self.stc_slow_d_list = self.stc_slow_k_forth_list[::-1]
self.stc_slow_k_forth_list = []
for i in range(0, 50):
if i == 0:
self.stc_slow_d_first = self.stc_slow_d_list[i]
elif i >= 1:
self.stc_slow_d_second = (self.stc_slow_d_list[i] * self.stc_slow_d_weighting) + (self.stc_slow_d_first * (1 - self.stc_slow_d_weighting))
self.stc_slow_d_first = self.stc_slow_d_second
if i == 49:
self.stc_slow_d_0_ago = round(self.stc_slow_d_first, 2) # 현재시간
elif i == 48:
self.stc_slow_d_1_ago = round(self.stc_slow_d_first, 2) # 1분전
elif i == 47:
self.stc_slow_d_2_ago = round(self.stc_slow_d_first, 2) # 2분전
elif i == 46:
self.stc_slow_d_3_ago = round(self.stc_slow_d_first, 2) # 3분전
elif i == 45:
self.stc_slow_d_4_ago = round(self.stc_slow_d_first, 2) # 4분전
elif i == 44:
self.stc_slow_d_5_ago = round(self.stc_slow_d_first, 2) # 5분전
self.stc_slow_d = round(self.stc_slow_d_first, 2)
self.stc_slow_d_list = []
# print(self.stc_slow_k)
# print(self.stc_slow_d)
########## 스토캐스틱 오실레이터 ##########
### 오실레이터_fast_%D 구하기 ###
for i in range(0, 150): # 현재 분의 STC_오실레이터 구하기
for j in range(i, i + 12):
self.close_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", i, "현재가").strip()))
max_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", j, "고가").strip()))
min_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", j, "저가").strip()))
self.nq_max_price_list.append(max_price_row_data)
self.nq_min_price_list.append(min_price_row_data)
self.close_price_first = self.close_price_row_data
self.max_price_first = max(self.nq_max_price_list)
self.min_price_first = min(self.nq_min_price_list)
self.nq_max_price_list = []
self.nq_min_price_list = []
self.stc_fast_k_first = (self.close_price_first - self.min_price_first) / (self.max_price_first - self.min_price_first) * 100
self.stc_fast_k_first = round(self.stc_fast_k_first, 2) # 소수 셋째자리에서 반올림
self.stc_fast_d_list.append(self.stc_fast_k_first)
self.stc_fast_d_list_final = self.stc_fast_d_list[::-1]
self.stc_fast_d_list = []
for i in range(len(self.stc_fast_d_list_final)):
if i == 0:
self.stc_oscillator_d_first = self.stc_fast_d_list_final[i]
elif i >= 1:
self.stc_oscillator_d_second = (self.stc_fast_d_list_final[i] * self.stc_oscillator_d_weighting) + (self.stc_oscillator_d_first * (1 - self.stc_oscillator_d_weighting))
self.stc_oscillator_d_first = self.stc_oscillator_d_second
if i == 149:
self.stc_oscillator_fast_d_0_ago = round(self.stc_oscillator_d_first, 2)
elif i == 148:
self.stc_oscillator_fast_d_1_ago = round(self.stc_oscillator_d_first, 2)
elif i == 147:
self.stc_oscillator_fast_d_2_ago = round(self.stc_oscillator_d_first, 2)
elif i == 146:
self.stc_oscillator_fast_d_3_ago = round(self.stc_oscillator_d_first, 2)
elif i == 145:
self.stc_oscillator_fast_d_4_ago = round(self.stc_oscillator_d_first, 2)
elif i == 144:
self.stc_oscillator_fast_d_5_ago = round(self.stc_oscillator_d_first, 2)
self.stc_fast_d_list_final = []
self.stc_oscillator_fast_d = round(self.stc_oscillator_d_first, 2) # 현재시간의 오실레이터_fast_d
# print(self.stc_oscillator_fast_d)
### 오실레이터_slow_%D 구하기 ###
for i in range(0, 150):
for j in range(i, i+26): # 현재 분의 STC_슬로우 K, D 구하기 /// stc_slow_k = ∑(현재가 - 최대값) / ∑(최대값 - 최소값)
for k in range(j, j + 12):
self.close_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", j, "현재가").strip()))
max_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", k, "고가").strip()))
min_price_row_data = abs(float(self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", k, "저가").strip()))
self.nq_max_price_list.append(max_price_row_data)
self.nq_min_price_list.append(min_price_row_data)
self.close_price_first = self.close_price_row_data
self.max_price_first = max(self.nq_max_price_list)
self.min_price_first = min(self.nq_min_price_list)
self.nq_max_price_list = []
self.nq_min_price_list = []
self.price_first_close_min = self.close_price_first - self.min_price_first
self.price_first_max_min = self.max_price_first - self.min_price_first
self.stc_slow_k_list_close_min.append(self.price_first_close_min)
self.stc_slow_k_list_max_min.append(self.price_first_max_min)
self.stc_slow_k_first = sum(self.stc_slow_k_list_close_min)
self.stc_slow_k_second = sum(self.stc_slow_k_list_max_min)
self.stc_slow_k_list_close_min = []
self.stc_slow_k_list_max_min = []
self.stc_slow_oscillator_k_26_close_min_list.append(self.stc_slow_k_first)
self.stc_slow_oscillator_k_26_max_min_list.append(self.stc_slow_k_second)
self.stc_slow_oscillator_k_26_close_min_list = self.stc_slow_oscillator_k_26_close_min_list[::-1]
self.stc_slow_oscillator_k_26_max_min_list = self.stc_slow_oscillator_k_26_max_min_list[::-1]
self.stc_slow_oscillator_k_26_close_min = sum(self.stc_slow_oscillator_k_26_close_min_list)
self.stc_slow_oscillator_k_26_max_min = sum(self.stc_slow_oscillator_k_26_max_min_list)
self.stc_slow_oscillator_k_26_close_min_list = []
self.stc_slow_oscillator_k_26_max_min_list = []
self.stc_slow_oscillator_k_26 = self.stc_slow_oscillator_k_26_close_min / self.stc_slow_oscillator_k_26_max_min * 100
self.stc_slow_oscillator_k_26 = round(self.stc_slow_oscillator_k_26, 2)
self.stc_slow_oscillator_final.append(self.stc_slow_oscillator_k_26)
self.stc_slow_oscillator_final = self.stc_slow_oscillator_final[::-1]
for i in range(0, 150):
if i == 0:
self.stc_oscillator_d_first = self.stc_slow_oscillator_final[i]
elif i >= 1:
self.stc_oscillator_d_second = (self.stc_slow_oscillator_final[i] * self.stc_oscillator_d_9_weighting) + (self.stc_oscillator_d_first * (1 - self.stc_oscillator_d_9_weighting))
self.stc_oscillator_d_first = self.stc_oscillator_d_second
if i == 149:
self.stc_oscillator_slow_d_0_ago = round(self.stc_oscillator_d_first, 2)
elif i == 148:
self.stc_oscillator_slow_d_1_ago = round(self.stc_oscillator_d_first, 2)
elif i == 147:
self.stc_oscillator_slow_d_2_ago = round(self.stc_oscillator_d_first, 2)
elif i == 146:
self.stc_oscillator_slow_d_3_ago = round(self.stc_oscillator_d_first, 2)
elif i == 145:
self.stc_oscillator_slow_d_4_ago = round(self.stc_oscillator_d_first, 2)
elif i == 144:
self.stc_oscillator_slow_d_5_ago = round(self.stc_oscillator_d_first, 2)
self.stc_slow_oscillator_k = self.stc_slow_oscillator_final[99] # 현재시간의 오실레이터_slow_k
self.stc_slow_oscillator_final = []
self.stc_oscillator_slow_d = round(self.stc_oscillator_d_first, 2)
# print(self.stc_oscillator_slow_d)
self.stc_oscillator_current = self.stc_oscillator_fast_d - self.stc_oscillator_slow_d # 200줄, 262줄
self.stc_oscillator_current = round(self.stc_oscillator_current, 2) # 현재시간의 오실레이터_slow_d /// # 부동소수점 문제로 소수 셋째자리에서 반올림
# print(self.stc_oscillator_current)
self.stc_oscillator_0_ago = round(self.stc_oscillator_fast_d_0_ago - self.stc_oscillator_slow_d_0_ago, 2)
self.stc_oscillator_1_ago = round(self.stc_oscillator_fast_d_1_ago - self.stc_oscillator_slow_d_1_ago, 2)
self.stc_oscillator_2_ago = round(self.stc_oscillator_fast_d_2_ago - self.stc_oscillator_slow_d_2_ago, 2)
self.stc_oscillator_3_ago = round(self.stc_oscillator_fast_d_3_ago - self.stc_oscillator_slow_d_3_ago, 2)
self.stc_oscillator_4_ago = round(self.stc_oscillator_fast_d_4_ago - self.stc_oscillator_slow_d_4_ago, 2)
self.stc_oscillator_5_ago = round(self.stc_oscillator_fast_d_5_ago - self.stc_oscillator_slow_d_5_ago, 2)
########## 시간 현행화 ###########
def time_update(self):
self.date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.traded_date = self.date_time[0:10]
self.traded_time = self.date_time[11:19]
if __name__ == "__main__":
app = QApplication(sys.argv)
btl = btl_system()
btl.rq_data_opc10002("NQZ23", "1")
app.exec_()
5. 마치며
현재시간을 출력하는 방법을 알아보았다. 다음 글에서는 위 글을 기반으로 거래량 차이가 많이 발생하는 미국장 개장(22:30~05:00)과 그외 시간(05:00~22:30)을 구분하는 방법을 알아보자.
'2. 해외선물 > 2-1. 해외선물 자동매매 연구' 카테고리의 다른 글
(키움증권 해외선물 자동매매 파이썬) 20. 오버나잇(overnight) 피하는 방법 (매매 종료시간 설정) (5) | 2023.10.27 |
---|---|
(키움증권 해외선물 자동매매 파이썬) 19. 매매시간 및 대기시간 설정 (0) | 2023.10.26 |
(키움증권 해외선물 자동매매 파이썬) 18. 진입/청산 시도횟수 체크하기 (2) | 2023.10.25 |
(키움증권 해외선물 자동매매 파이썬) 17. 시간별 다른 코드 적용하기 (3) | 2023.10.24 |
(키움증권 해외선물 자동매매 파이썬) 15. 보조지표 구하기 (볼린저밴드, MACD, 스토캐스틱) (0) | 2023.10.22 |
(키움증권 해외선물 자동매매 파이썬) 14. rsi 구하기 (4) | 2023.10.21 |
(키움증권 해외선물 자동매매 파이썬) 13. 주문하기(SendOrder) (13) | 2023.10.06 |
(키움증권 해외선물 자동매매 파이썬) 12. 주문가능수량 조회 (opw30011) (4) | 2023.10.05 |