매도 조건에 부합하는 경우 check_sell_signal 함수가 True를 반환하며, 종료되고 이후 매도 주문 접수가 됩니다. 반대로 조건에 맞지 않는 경우에는 False를 반환하여 매도 주문이 되지 않도록 합니다. 여기까지 설명한 check_sell_signal 함수를 다시 한 번 정리해 보겠습니다(이해를 돕고자 추가했던 print 함수들은 제거했습니다).
RSIStrategy.py
(...)
def check_sell_signal(self, code): ------ 매도 대상인지 확인하는 함수
universe_item = self.universe[code]
if code not in self.kiwoom.universe_realtime_transaction_info.keys(): ------ 현재 체결 정보가 있는지 확인
print("매도대상 확인 과정에서 아직 체결정보가 없습니다.") ------ 체결 정보가 없으면 더 이상 진행하지 않고 함수 종료
return
open = self.kiwoom.universe_realtime_transaction_info[code]['시가'] high = self.kiwoom.universe_realtime_transaction_info[code]['고가'] low = self.kiwoom.universe_realtime_transaction_info[code]['저가'] close = self.kiwoom.universe_realtime_transaction_info[code]['현재가'] volume = self.kiwoom.universe_realtime_transaction_info[code]['누적거래량']
----- 실시간 체결 정보가 존재하면 현시점의 시가 / 고가 / 저가 / 현재가 / 누적 거래량 저장
today_price_data = [open, high, low, close, volume] ------ 오늘 가격 데이터를 과거 가격 데이터(DataFrame)의 행으로 추가하고자 리스트로 만듦
df = universe_item['price_df'].copy()
df.loc[datetime.now().strftime('%Y%m%d')] = today_price_data ------ 과거 가격 데이터에 금일 날짜로 데이터 추가
period = 2 ------ 기준일 N 설정
date_index = df.index.astype('str')
U = np.where(df['close'].diff(1) > 0, df['close'].diff(1), 0) ------ df.diff로 ‘기준일 종가 - 기준일 전일 종가’를 계산하여 0보다 크면 증가분을 넣고, 감소했으면 0을 넣음
D = np.where(df['close'].diff(1) < 0, df['close'].diff(1) * (-1), 0)------ df.diff로 ‘기준일 종가 - 기준일 전일 종가’를 계산하여 0보다 작으면 감소분을 넣고, 증가했으면 0을 넣음
AU = pd.DataFrame(U, index=date_index).rolling(window=period).mean() ------ AU, period = 2일 동안 U의 평균
AD = pd.DataFrame(D, index=date_index).rolling(window=period).mean() ------ AD, period = 2일 동안 D의 평균
RSI = AU / (AD + AU) * 100 ------ RSI(N) 계산, 0부터 1로 표현되는 RSI에 100을 곱함
df['RSI(2)'] = RSI
purchase_price = self.kiwoom.balance[code]['매입가'] ------ 보유 종목의 매입 가격 조회
rsi = df[-1:]['RSI(2)'].values[0] ------ 금일의 RSI(2) 구하기
if rsi > 80 and close > purchase_price: ------ 매도 조건 두 가지를 모두 만족하면 True
return True
else:
return False