한국투자증권 주식매매프로그램 만들기

파이썬 주식매매프로그램 만들기

미국 주식 프로그램 만들기(eFriend expert)

8. 미국 주식 자동매매 프로그램 만들기 - 데이터프레임 행추가

토폴로지 2022. 4. 7. 23:10

yfinance로 받아오면 하루 지난 값은 받아도 오늘 것을 받지 못한다.

 

따라서 전략은 

과거의 데이터 => yfinance

현재 데이터 => 한국투자증권(실시간체결가 조회)

 

이렇게 하기 위해서는 yfinance 데이터 프레임에 행 하나를 추가할 필요가 있다.

 

우선 나스닥 시간을 맞추기 위해서 우선 미국 시각 설정을 할 필요가 있다

nasdaq_time = datetime.now(timezone('US/Eastern'))

 

또한 yfinance를 좀 더 쉽게 다루기 위해 데이터프레임 형태로 변환한다.

yf.pdr_override()   #yifannce 오버라이드

 

이에 따라 바뀌는 데이터 다운로드 코드

self.df = pdr.get_data_yahoo('TQQQ', start='2022-01-01', end=self.today_date) #yfinance 에서 TQQQ 데이터 다운로드 

 

아래 코드는 리스트 하나 만들어서 오늘날짜로 인덱스 설정하고 값들은 0으로 세팅

추후 실시간 체결가를 여기다 세팅할 예정

1
2
3
4
5
6
self.df_dummy_data = [[000000000]] # 행 하나 추가
self.df_columns = ['Open''High''Low''Close''Adj Close''Volume''SMA''ICMK''RSI']         
self.today_date = [nasdaq_time.strftime("%Y-%m-%d")]
self.df_today = DataFrame(data=self.df_dummy_data, index=pd.to_datetime(self.today_date), columns=self.df_columns)
self.df = pd.concat([self.df, self.df_today])
print(self.df)
cs

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import sys
from PyQt5.QtWidgets import *  #pip install PyQt5
from PyQt5.QtGui import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
 
import yfinance as yf #pip install yfinance
from pandas_datareader import data as pdr #pip install pandas_datareader
yf.pdr_override()   #yifannce 오버라이드
import pandas as pd
from pandas import DataFrame
 
import mplfinance as mpf #pip install mplfinance
from matplotlib.backends.backend_qt5agg import FigureCanvas as FigureCanvas
from matplotlib.ticker import FormatStrFormatter
 
from datetime import datetime
from pytz import timezone  #나스닥 타임존 설정용
 
koreanInvest_id = "@"
koreanInvest_account = ""
koreanInvest_account_code = ""
koreanInvest_account_password = ""
 
koreanInvest_stock_buy_exchange = "NASD"
koreanInvest_stock_buy_code = "TQQQ"
koreanInvest_stock_buy_count = "1"
koreanInvest_stock_buy_price = "6.11"
koreanInvest_stock_buy_type = "00" # 00:지정가, 01:시장가, LOO:32, LOC:34
 
koreanInvest_stock_sell_exchange = "NASD"
koreanInvest_stock_sell_code = "TQQQ"
koreanInvest_stock_sell_count = "1"
koreanInvest_stock_sell_price = "6.11"
koreanInvest_stock_sell_type = "00" # 00:지정가, 01:시장가, LOO:32, LOC:34
 
def ICMK(data, period=26):
    period_high = data['High'].rolling(window=period).max()
    period_low = data['Low'].rolling(window=period).min()
    return (period_high + period_low) / 2
 
def SMA(data, period=20):
    return data.rolling(window=period).mean()
 
def computeRSI (data, time_window):
    diff = data.diff(1).dropna()        # diff in one field(one day)
 
    #this preservers dimensions off diff values
    up_chg = 0 * diff
    down_chg = 0 * diff
    
    # up change is equal to the positive difference, otherwise equal to zero
    up_chg[diff > 0= diff[ diff>0 ]
    
    # down change is equal to negative deifference, otherwise equal to zero
    down_chg[diff < 0= diff[ diff < 0 ]
    
    # check pandas documentation for ewm
    # https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.ewm.html
    # values are related to exponential decay
    # we set com=time_window-1 so we get decay alpha=1/time_window
    up_chg_avg   = up_chg.ewm(com=time_window-1 , min_periods=time_window).mean()
    down_chg_avg = down_chg.ewm(com=time_window-1 , min_periods=time_window).mean()
    
    rs = abs(up_chg_avg/down_chg_avg)
    rsi = 100 - 100/(1+rs)
 
    return rsi
 
class MainWidget(QWidget):
     def __init__(self):
          super().__init__()
          nasdaq_time = datetime.now(timezone('US/Eastern'))   #나스닥 거래소 시간으로 설정
          self.today_date = nasdaq_time.strftime("%Y-%m-%d")
          self.df = pdr.get_data_yahoo('TQQQ', start='2022-01-01', end=self.today_date) #yfinance 에서 TQQQ 데이터 다운로드 
          self.df['SMA'= SMA(self.df['Close'], 20#이평선 20
          self.df['ICMK'= ICMK(self.df, 26# 일목균형표 26일
          self.df['RSI'= computeRSI(self.df['Close'], 14#RSI 14 일
 
          self.df_dummy_data = [[000000000]] # 행 하나 추가
          self.df_columns = ['Open''High''Low''Close''Adj Close''Volume''SMA''ICMK''RSI']         
          self.today_date = [nasdaq_time.strftime("%Y-%m-%d")]
          self.df_today = DataFrame(data=self.df_dummy_data, index=pd.to_datetime(self.today_date), columns=self.df_columns)
          self.df = pd.concat([self.df, self.df_today])
          print(self.df)
 
          fig, axlist = mpf.plot(self.df, datetime_format='%b %d', type='candle', volume=True, mav=(20), style='starsandstripes', returnfig=True)  # 그래프 그리기
          axlist[0].yaxis.set_major_formatter(FormatStrFormatter('$%.0f'))  #숫자 뒤에 $ 붙이기
          canvas = FigureCanvas(fig)
          canvas.draw()
 
          self.text_edit = QTextEdit(self)
          self.text_edit.setGeometry(001200600)
          # self.text_edit.setEnabled(False)
 
          # 매수 버튼
          self.btn_buy = QPushButton("Buy"self)   # 버튼 텍스트
          self.btn_buy.clicked.connect(self.btn_buy_clicked) # 클릭 시 실행할
 
          # 매도 버튼
          self.btn_sell = QPushButton("Sell"self)   # 버튼 텍스트
          self.btn_sell.clicked.connect(self.btn_sell_clicked) # 클릭 시 실행할
 
          # 실시간 라이브 on 버튼
          self.btn_live_on = QPushButton("Live on"self)   # 버튼 텍스트
          self.btn_live_on.clicked.connect(self.btn_live_on_clicked) # 클릭 시 실행할
 
          # 실시간 라이브 off 버튼
          self.btn_live_off = QPushButton("Live off"self)   # 버튼 텍스트
          self.btn_live_off.clicked.connect(self.btn_live_off_clicked) # 클릭 시 실행할
 
          mainLayout = QVBoxLayout()  #레이아웃 추가
          sub1Layout = QHBoxLayout()
          sub2Layout = QHBoxLayout()
          chartLayout = QVBoxLayout()
 
          mainLayout.addLayout(sub1Layout)
          mainLayout.addLayout(sub2Layout)
          mainLayout.addLayout(chartLayout)
 
          sub1Layout.addWidget(self.text_edit)
          sub2Layout.addWidget(self.btn_buy)
          sub2Layout.addWidget(self.btn_sell)
          sub2Layout.addWidget(self.btn_live_on)
          sub2Layout.addWidget(self.btn_live_off)
          chartLayout.addWidget(canvas)
 
          self.setLayout(mainLayout)
          self.setGeometry(001200600)
 
     def btn_buy_clicked(self):
          # 주문 입력 및 전송
          self.tran_os_us_buy = QAxWidget("ITGExpertCtl.ITGExpertCtlCtrl.1")
          self.tran_os_us_buy.SetSingleData(0, koreanInvest_account) #종합계좌번호 ##계좌일련번호[8],) 
          self.tran_os_us_buy.SetSingleData(1, koreanInvest_account_code) #계좌상품코드 ##계좌 상품코드, GetAccount() 함수 이용(뒤 2자리)
          self.tran_os_us_buy.SetSingleData(2self.tran_os_us_buy.GetEncryptPassword(koreanInvest_account_password)) #계좌비밀번호(반드시 암호화 처리 필요)
          self.tran_os_us_buy.SetSingleData(3, koreanInvest_stock_buy_exchange) #해외거래소코드 ##거래소코드 나스닥 NASD 뉴욕 NVSE 아맥스 AMEX
          self.tran_os_us_buy.SetSingleData(4, koreanInvest_stock_buy_code) #상품번호 ##종목코드
          self.tran_os_us_buy.SetSingleData(5, koreanInvest_stock_buy_count) #주문수량
          self.tran_os_us_buy.SetSingleData(6, koreanInvest_stock_buy_price) #해외주문단가 ##주문가격
          self.tran_os_us_buy.SetSingleData(7""#연락전화번호 #전화번호 필수값 아님
          self.tran_os_us_buy.SetSingleData(8""#운용사지정주문번호 입력하지 않음
          self.tran_os_us_buy.SetSingleData(9"0"#주문서버구분코드 고정값 0
          self.tran_os_us_buy.SetSingleData(10, koreanInvest_stock_buy_type) # 주문구분, 00: 지정가, 01: 시장가 LOO:32 LOC:34
 
          #항목 설정
          self.tran_os_us_buy.RequestData("OS_US_BUY")
          self.text_edit.append("미국 매수주문 전송 [" + str(self.tran_os_us_buy.GetSendRqID()) + "] ")
          self.tran_os_us_buy.ReceiveData.connect(self.tran_os_us_buy_receivedata) #이벤트 연결
 
     def tran_os_us_buy_receivedata(self):
          # 주문응답 이벤트
          self.text_edit.append("미국 매수주문 응답 [" + str(self.tran_os_us_buy.GetSendRqID()) + "] ")
 
          #결과 메세지
          self.text_edit.append("[" + str(self.tran_os_us_buy.GetSendRqID()) + "] " + self.tran_os_us_buy.GetReqMsgCode() + " " + self.tran_os_us_buy.GetReqMessage())
          self.text_edit.append("주문번호 : " + self.tran_os_us_buy.GetSingleData(10))
          self.text_edit.append("주문시간 : " + self.tran_os_us_buy.GetSingleData(20))
 
     def btn_sell_clicked(self):
          # 주문 입력 및 전송
          self.tran_os_us_sell = QAxWidget("ITGExpertCtl.ITGExpertCtlCtrl.1")
          self.tran_os_us_sell.SetSingleData(0, koreanInvest_account) #계좌일련번호[8], GetAccount() 함수 이용(앞 8자리)
          self.tran_os_us_sell.SetSingleData(1, koreanInvest_account_code) #계좌 상품코드, GetAccount() 함수 이용(뒤 2자리)
          self.tran_os_us_sell.SetSingleData(2self.tran_os_us_sell.GetEncryptPassword(koreanInvest_account_password)) #계좌비밀번호(반드시 암호화 처리 필요)
          self.tran_os_us_sell.SetSingleData(3, koreanInvest_stock_sell_exchange) #거래소코드
          self.tran_os_us_sell.SetSingleData(4, koreanInvest_stock_sell_code) #종목코드
          self.tran_os_us_sell.SetSingleData(5, koreanInvest_stock_sell_count) #주문수량
          self.tran_os_us_sell.SetSingleData(6, koreanInvest_stock_sell_price) #주문가격
          self.tran_os_us_sell.SetSingleData(7""#전화번호
          self.tran_os_us_sell.SetSingleData(8""#운용사지정주문번호
          self.tran_os_us_sell.SetSingleData(9"0"#주문서버구분코드
          self.tran_os_us_sell.SetSingleData(10, koreanInvest_stock_sell_type) # 주문구분, 지정가:00 MOO:31 MOC:33 LOO:32 LOC:34
 
          #항목 설정
          self.tran_os_us_sell.RequestData("OS_US_SELL")
          self.text_edit.append("미국 매도주문 전송 [" + str(self.tran_os_us_sell.GetSendRqID()) + "] ")
          self.tran_os_us_sell.ReceiveData.connect(self.tran_os_us_sell_receivedata) #이벤트 연결
 
     def tran_os_us_sell_receivedata(self):
          # 주문응답 이벤트
          self.text_edit.append("미국 매도주문 응답 [" + str(self.tran_os_us_sell.GetSendRqID()) + "] ")
 
          #결과 메세지
          self.text_edit.append("[" + str(self.tran_os_us_sell.GetSendRqID()) + "] " + self.tran_os_us_sell.GetReqMsgCode() + " " + self.tran_os_us_sell.GetReqMessage())
          self.text_edit.append("주문번호 : " + self.tran_os_us_sell.GetSingleData(10))
          self.text_edit.append("주문시간 : " + self.tran_os_us_sell.GetSingleData(20))
 
     def btn_live_on_clicked(self):
          self.check_os_stcnto_r = QAxWidget("ITGExpertCtl.ITGExpertCtlCtrl.1")
          self.check_os_stcnto_r.SetSingleData(0"DNASTQQQ"#실시간종목코드
 
          self.check_os_stcnto_r.RequestRealData("OS_STCNT0_R""DNASTQQQ")
          self.text_edit.append("미국 실시간 데이터 체결 조회 on [" + str(self.check_os_stcnto_r.GetSendRqID()) + "] ")
          self.check_os_stcnto_r.ReceiveRealData.connect(self.check_os_stcnto_r_receiverealdata) #이벤트 연결
 
     def check_os_stcnto_r_receiverealdata(self):
          self.text_edit.append(self.check_os_stcnto_r.GetSingleData(10+ " 현재가: " + self.check_os_stcnto_r.GetSingleData(110))
          #print("현재가 : " + self.check_os_stcnto_r.GetSingleData(11, 0))
 
          #self.df_today['Open'] = self.check_os_stcnto_r.GetSingleData(8, 0)
          #self.df_today['High'] = self.check_os_stcnto_r.GetSingleData(9, 0)
          #self.df_today['Low'] = self.check_os_stcnto_r.GetSingleData(10, 0)
          #self.df_today['Close'] = self.check_os_stcnto_r.GetSingleData(11, 0)  #오늘의 실시간 체결가 = 종가
          #self.df_today['SMA'] = SMA(self.df_today['Close'], 20)
          #self.df_today['ICMK'] = ICMK(self.df_today, 26)
          #self.df_today['RSI'] = RSI(self.df_today['Close'], 14)
 
     def btn_live_off_clicked(self):
          self.check_os_stcnto_r.UnRequestRealData("OS_STCNT0_R""DNASTQQQ")
          self.text_edit.append("미국 실시간 데이터 체결 조회 off [" + str(self.check_os_stcnto_r.GetSendRqID()) + "] ")
 
class MyWindow(QMainWindow):
     def __init__(self):
          super().__init__()
          self.initUI()
    
     def initUI(self):
          self.setWindowTitle("한국투자증권-API")
 
          mainWidget = MainWidget()
          self.setCentralWidget(mainWidget)
          self.setGeometry(001200600)     
          self.show()
 
 
if __name__ == "__main__":
     app = QApplication(sys.argv)
     myWindow = MyWindow()
     myWindow.show()
     app.exec_()
cs

반응형