2. 해외선물/2-1. 해외선물 자동매매 연구

(키움증권 해외선물 자동매매 파이썬) 6. self의 활용 (self.kiwoom)

봄이오네 2023. 9. 8. 08:06
반응형
목 차
1. 들어가며
2. 사전설명
3. 클래스 내 전역변수로 활용되는 self
   1) 전역변수로서의 self
   2) 클래스 내 함수 실행을 위한 self
4. 자동매매에서 활용 사례
5. 마치며

 

1. 들어가며

지난 글에서는 파이썬을 통해 키움증권의 해외선물 자동매매를 위해 로그인하는 방법을 알아보았다. 아이디/비밀번호, 계좌/비밀번호 등을 일일히 입력해주어야 하는 불편함이 있지만, 그래도 자동매매를 위해서라면 그 정도 불편함을 얼마든지 감수할 수 있을 것 같다.
 
이번 글에서는 파이썬 코딩에서 상당히 많이 작성되는 self의 활용에 대해 알아보도록 하자.


2. 사전설명

인터넷에서 self 의미 및 활용에 대해 상당히 어렵게 설명해 놓은 것을 확인할 수 있다. 필자의 경우 그 어려운 내용을 읽을 때마다 "이렇게 깊숙히 알아야 하나?"라는 생각이 든다. 이 글에서는 self 의미에 대해서는 사실 관심이 없다. 파이썬 코드에서 self가 어떻게 활용되는지 알아볼 것이다. 우리의 목표는 결국 자동매매를 구현하는데 있다는 사실을 잊지 말자!
 
필자가 설명하는 자동매매를 구현할 때 파이썬의 self는 ①클래스 내 함수에 self를 넣어주어야 하는 것과 ②클래스 내에서 전역변수로 활용되는 2가지를 미리 설명한다.
 
사실, 클래스 내 함수(메소드)에 왜 self를 넣어주어야 하는지 정확한 이유는 잘 모르겠다. 다만, 클래스를 만들고 함수를 정의할 때 파이참(pycharm)에서 괄호 안에 자동으로 self가 들어갔다. 추측해 보건대, 함수도 나중에 활용하려고 self를 넣는건 아닐까 생각되지만, 정확하지는 않다.
 
클래스 내에서 전역변수로 활용되는 self에 대해 아래에서 살펴볼 것이다.


3. 클래스 내 전역변수로 활용되는 self

1) 전역변수로서의 self

변수는 크게 전역변수와 지역변수 2가지로 나누어진다. 전역변수는 코드 전체에서 활용되는 변수를 말하며, 지역변수는 함수 내에서 한정적으로 쓰이는 변수를 말한다. 코드를 구현하는 환경에 따라 전역변수/지역변수를 유연하게 사용할 필요가 있다.
 
함수(메소드)를 모아놓은 클래스 내에서 전역변수가 필요할 시점은 언제일까? 다른 함수에서 정의한 변수를 또다른 함수에서 활용하고자 할 때 쓰인다.
예를 들어보자. 현재봉의 몸통길이를 구하려면, 1분봉 데이터의 시가 및 종가 등 2가지가 필요하다. 코드를 구현하는 순서는 ①1분봉 데이터 요청/수신, ②양봉의 몸통길이를 계산하려면 아래와 같이 코드가 이루어진다.
 

class btl_system():
    def __init__(self):			# 함수1
        self.open_price = 15000
        self.close_price = 15004

    def bong_check(self):		# 함수2
        self.bong_body_length = self.close_price-self.open_price
        print(self.bong_body_length)

if __name__ == "__main__":
    btl = btl_system()

    btl.bong_check()
    
    
    ### (expected result)
    ### 4

 
1줄 : 임의의 클래스를 선언한다.
2줄 : 코드가 실행되면 제일 먼저 실행된다. 1줄의 클래스 내 존재하는 함수이므로 괄호 안에 self가 들어간다.
3줄~4줄 : 시가와 종가를 각각 15,000, 15,004로 정의하였다.
6줄 : 임의의 함수를 선언한다.
7줄~8줄 : 봉 길이를 구하기 위해 종가-시가를 작성하고 출력한다.
10줄 : 10줄 그 아래를 실행하라.
11줄 : 1줄의 btl_system() 클래스를 btl 변수에 담는다. (인스턴스)
12줄 : 1줄의 클래스는 11줄에 담겨진 btl 변수화된 점을 기억하자. 6줄의 함수를 실행하라는 뜻이다.
 
위의 코드에서 주의깊게 볼 부분은 2줄 함수(__init__)와 6줄 함수(bong_check)이다. 2줄 함수에서 정의된 시가/종가를 6줄에서 다시 활용하여야 하는 상황이라면, 시가/종가에 self를 붙여 전역변수로 만들면 된다. 즉, self를 통해 2줄에서 정의된 시가/종가를 다른 함수인 6줄~8줄의 함수에서 활용할 수 있는 것이다.
 
 

2) 클래스 내 함수 실행을 위한 self

앞에서 살펴본 바와 같이 self는 클래스 내 함수에서 전역변수로 활용하고자 할 때 쓰인다는 내용을 알아보았다. 향후 파이썬 관련 주식/해선 프로그램에서 self가 보이면 "전역변수"로 활용하고자 미리 선언했다고 생각하면 된다.
 ※ 물론 self 가 다른 형태로 활용될 수는 있겠지만, 이 글에서는 "전역변수"로서의 활용만 설명할 것이다.
 
위의 사례를 약간 변경한 케이스이다. 당초 12줄에 있었던 실행 명령어를 5줄(self.bong_check())를 이동시켰다. 이 사례 또한 결과값은 4로 출력된다. 8줄의 함수를 5줄에서 self를 붙여서 실행하는 내용이다.

class btl_system():
    def __init__(self):          # 함수1
        self.open_price = 15000
        self.close_price = 15004

        self.bong_check()

    def bong_check(self):     # 함수2
        self.bong_body_length = self.close_price-self.open_price
        print(self.bong_body_length)

if __name__ == "__main__":
    btl = btl_system()
    
    
### (expected result)
### 4

4. 자동매매에서 활용 사례

파이썬을 통한 해외선물 자동매매에서 self가 쓰이는 사례는 많다. 앞 글에서도 설명하였던 ①키움API를 레지스터리에 저장하여 데이터를 요청/수신받는 경우, ②다른 함수에서 정의된 변수를 또다른 함수에서 활용하는 사례 등이다.
 
① 키움API 레지스터리를 통한 키움서버 접속

self.kiwoom = QAxWidget("KFOPENAPI.KFOpenAPICtrl.1")

QAxWidget 모듈을 통해 "KFOPENAPI.KFOpenapicTRL.1"의 레지스터리를 읽어오는 것은 self.kiwoom 변수에 저장한다.
 

open_price = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", 1, "현재가")

self.kiwoom은 dynamicCall을 통해 1분봉의 1분전 종가(현재가)를 open_price 변수에 담는다.
 
②다른 함수에서 정의된 변수를 또다른 함수에서 활용

class btl_system():
	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", "", "1002")
		self.tr_event_loop = QEventLoop()
		self.tr_event_loop.exec_()

	def trdata_get(self, scrno, rqname, trcode, recordname, prenext):
		if rqname == "opc_10002":
			self.open_price = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", 1, "시가")
			self.close_price = self.kiwoom.dynamicCall("GetCommData(QString,QString,int,QString)", "opc_10002", "opc10002", 1, "시가")
            
	def bong_check(self):
		self.bong_body_length = self.close_price - self.open_price

위 코드는 1분봉 데이터를 활용한 사례이다. 1분봉의 1분전 종가/시가를 구한 후 bong_check함수에서 봉 몸통길이를 구하는 코드이다.


5. 마치며

self에 대한 설명은 인터넷 검색을 통해 얼마든지 알 수 있다. 다만, 검색을 통해 얻은 정보가 자동매매를 위해 필요한 내용일까? 사람마다 생각의 차이는 있겠지만, 위에서 설명한 대로 전역변수 형태로 활용된다는 사실 하나만 알아도 자동매매를 구현하는 과정에서 문제될 것은 없어 보인다.
 
대개 전역변수는 변수 앞에 global을 붙여서 사용하지만, 파이썬을 통해 자동매매를 한다면, self를 활용하는게 더 편하다는 느낌을 받았다. global을 사용하면 모든 변수에 global을 붙여주어야 해서, 불편함이 많았기 때문이다.
 
다음 글에서는 < 개요 >의 마지막 부분인 클래스의 인스턴스(변수화)에 대해 알아보도록 하자
 

반응형