1. 국내주식/1-1. 국내주식 연구일지

(파이썬) 주식 자동 매매를 위한 알고리즘 패턴 찾기 (3) 파이썬에 적용

봄이오네 2022. 10. 4. 08:06
반응형

1. 들어가며

지난 2번의 글에서 주식 패턴 만들기
만들어진 패턴으로 익절/손절 정하기 등을 알아보았다.

< 그림1. 많이 반복되는 패턴(0-1000)의 수익/손실 빈도율 >


이번 시간에는 input함수와 for 반복문을 통해
패턴 및 익절/손절 타점을 파이썬에 적용하여 보자.

  • input 함수 : 파이썬 내장함수이며, 사용자가 입력한 내용을 변수에 저장할 때 사용한다.
  • for 반복문 : 파이썬 내장함수이며, 사용자가 일정한 패턴을 반복하고자 할 때 사용한다.

※ for 반복문은 아래를 참고 : https://springcoming.tistory.com/12?category=1025768

 

(파이썬) for문 활용 (1) - 기본 설명

1. 들어가며 for문은 반복적인 작업을 간략하고 효율적으로 실행할 수 있는 코드이다. 이 글에서는 키움증권 OpenAPI를 통해 파이썬 코드 작성할 때 사용되는 for문에 대해 알아본다. 2. for문 설명  1

springcoming.tistory.com


키움증권에서 데이터를 받아서 매수/매도를 해야 하나,
장 종료된 점을 고려하여,
매수/매도(SendOrder)는 print 부분으로 대체함을 양해해 주시기 바란다.
* 키움증권에 적용하는 내용은 향후 설명하겠다.


2. 사전 준비

1) input 함수 사용 방법

장 종료로 인해 키움증권에서 데이터를 받아올 수 없으므로,
input 함수에서 종목코드와 패턴값을 임의로 입력한다.
이글에서는 패턴이 어떻게 for문에 적용되어 매수/매도하는지 감각만 익히도록 하자.
* input으로 숫자를 입력하더라도, input함수의 결과값는 숫자가 아닌 문자열이다.

input 함수는 아래와 같이 파이참에서 실행할 수 있다.

< 그림2. input 함수에 패턴 0-1을 입력하는 화면 >

1줄 : pattern 변수에 input을 통해, 입력받은 녹색(패턴 0-1)을 입력한다.
3줄 : input 결과값을 받은 태형은 문자형(str)이다.
5줄 : pattern의 print 값은 0-1이다.

→ 임의로 외부에서 패턴 0-1을 입력해서,
pattern값이 for문으로 순차적으로 들어가는 내용을 생각하고 있다.

2) for 반복문 활용

for문을 통해 패턴 순차적으로 반복하기
패턴과 익절/손절 타점이 매칭되게 for문을 돌릴 예정이다.


3. 코드 설명

장 종료로 키움증권의 데이터를 받지 못한 점을 고려하여,
키움증권의 데이터의 코드번호는 input함수로 임의로 제공할 예정이다.
또한, 엑셀로 통해 도출된 패턴도 input 함수로 입력할 것이다.

※ 코드를 복사하여 실행하는 경우, 4줄의 코드번호 및 5줄의 패턴번호는
각각 1개씩 반드시 입력해 주어야 한다.

삼성전자(005930), SK하이닉스(000660), 아프리카TV(067160) 등 3개의 주식을 예시로 들 예정이다.

< 그림3-1. 패턴 찾는 함수를 코드별로 작성 화면1 >


1줄~10줄은 키움데이터를 대신하여, 임의로 부여하였다.
1줄 : 주식의 현재가
2줄 : 주식의 매수(예정)가격

3줄 : 종목코드 리스트
4줄 : 패턴 리스트 (엑셀로 도출 가능)

7줄 : 수익 리스트
8줄 : 손실 패턴

10줄 : input 함수를 통해 사용자가 직접 입력해야 하는 코드번호 (4줄의 코드번호 중 1개 입력)
11줄 : input 함수를 통해 사용자가 직접 입력해야 하는 패턴 (5줄의 패턴 모음 중 1개 입력)

14줄~18줄 : SendOrder 함수는 매수/매도의 구분은 없다.
매수/매도함수를 임의로 만들되, 15줄/17줄 print 메시지가 나타나도록 함

20줄 : 패턴 체크를 위해 pattern_check 함수를 임의로 만들었다.
21줄 : 입력해준 코드번호가 4줄의 stock_lists의 0번(005930)과 같으면,
22줄 : 5줄의 pattern_lists의 항목 갯수(4개)를 세어서(len), for문을 4번 돌려라.
23줄 : 입력 패턴(11줄)과 패턴 리스트(5줄)의 항목이 같은 내용이 있으면,
24줄 : 매수하라
27줄 : 매수가 + 수익[i] >= 현재가보다 크거나 같으면,
28줄 : 매도하라
30줄 : 수익이 났으면, 결과를 출력해 달라 (print)

31줄 : 매수가 + 수익[i] < 현재가보다 작으면
32줄 : 매도하라
33줄 : 손실이 났으면, 결과를 출력해 달라 (print)

< 그림3-2. 패턴 찾는 함수를 코드별로 작성 화면2 >


37줄 : 입력한 종목코드(4줄)이 10줄의 코드번호[i]와 같다면,
38줄~51줄 : for을 돌려 같은 패턴이 있으면, 익절/손절을 하라.

※ 설명이 반복되므로, 52줄~66줄 생략

68줄 ~ 73줄 : btl_system() 안에 있는 pattern_check 함수를 실행
→ 71줄~73줄을 별도의 함수를 만들어 줄 필요없이,
(당초) 71줄 def start_pattern() (72줄~73줄은 삭제 가능)
(변경) btl.pattern_check()로 바꾸어도 실행된다.

< 그림3-3. 삼성전자의 종목코드와 (임의의) 패턴 입력 결과 >

 

< 그림3-4. SK하이닉스의 종목코드와 (임의의) 패턴 입력 결과 >


4. 전체 코드

current_price = 1000
buy_price = 600

stock_lists = ["005930", "000660", "067160"]    # 005930 삼성전자, 000660 SK하이닉스, 067160 아프리카TV
pattern_lists = ["0-0", "0-1", "0-2", "0-3"]

profit_lists = [800, 700, 400, 300]
loss_lists = [400, 200, 100, 400]

stock_list_input = input("파이참의 실행창에 종목코드를 입력 : ")
pattern_list_input = input("파이참의 실행창에 패턴을 입력 : ")

class btl_system():
    def sendorder_trading_buy(self):
        print("현재가 600원의 매수 주문을 키움서버에 보냈다고 가정함")

    def sendorder_trading_sell(self):
        print("매도 주문을 키움서버에 보냈다고 가정함")

    def pattern_check(self):
        if stock_list_input == stock_lists[0]:
            for i in range(len(pattern_lists)):
                if pattern_list_input == pattern_lists[i]:
                    btl_system.sendorder_trading_buy(self)  # 패턴0에 해당하면 매수하라.
                    print("패턴에 맞게 매수함")
                    if buy_price + profit_lists[i] >= current_price :
                        btl_system.sendorder_trading_sell(self)  # 현재가보다 크면, 매도하라.
                        print("수익이 발생하였으므로 매도""\n")
                        result_pl = buy_price + profit_lists[i] - current_price
                        print("매도결과 수익은 %s원이 발생하였다." % result_pl)
                    else :
                        btl_system.sendorder_trading_sell(self)  # 손절을 치는 코드
                        print("손실이 발생하였으므로 매도""\n")
                        result_pl = buy_price + profit_lists[i] - current_price
                        print("매도결과 손실은 %s원이 발생하였다." % result_pl)

        elif stock_list_input == stock_lists[1]:
            for i in range(len(pattern_lists)):
                if pattern_list_input == pattern_lists[i]:
                    btl_system.sendorder_trading_buy(self)  # 패턴0에 해당하면 매수하라.
                    print("패턴에 맞게 매수함")
                    if buy_price + profit_lists[i] >= current_price :
                        btl_system.sendorder_trading_sell(self)  # 현재가보다 크면, 매도하라.
                        print("수익이 발생하였으므로 매도""\n")
                        result_pl = buy_price + profit_lists[i] - current_price
                        print("매도결과 수익은 %s원이 발생하였다." % result_pl)
                    else :
                        btl_system.sendorder_trading_sell(self)  # 손절을 치는 코드
                        print("손실이 발생하였으므로 매도""\n")
                        result_pl = buy_price + profit_lists[i] - current_price
                        print("매도결과 손실은 %s원이 발생하였다." % result_pl)
        else:
            for i in range(len(pattern_lists)):
                if pattern_list_input == pattern_lists[i]:
                    btl_system.sendorder_trading_buy(self)  # 패턴0에 해당하면 매수하라.
                    print("패턴에 맞게 매수함")
                    if buy_price + profit_lists[i] >= current_price :
                        btl_system.sendorder_trading_sell(self)  # 현재가보다 크면, 매도하라.
                        print("수익이 발생하였으므로 매도""\n")
                        result_pl = buy_price + profit_lists[i] - current_price
                        print("매도결과 수익은 %s원이 발생하였다." % result_pl)
                    else :
                        btl_system.sendorder_trading_sell(self)  # 손절을 치는 코드
                        print("손실이 발생하였으므로 매도""\n")
                        result_pl = buy_price + profit_lists[i] - current_price
                        print("매도결과 손실은 %s원이 발생하였다." % result_pl)

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

    def start_pattern():
    	btl.pattern_check()
    start_pattern()

5. 마치며

여기서 주의할 것은, 많이 나온 패턴이 반드시 수익을 보장해 주지는 않는다.
적게 나온 패턴이라도 수익을 줄 확률이 높다면,
그 패턴을 매매 때 활용하는 것도 좋다.
각 패턴들의 수익/손실 및 진입/청산 타이밍의 정확한 파악이 필요하다.

패턴 만들어서 파이썬 프로그램을 구현하는 것이 생각보다 어려웠다.
키움증권 데이터를 이용하지 않고,
스스로 입력하는 값으로 프로그램을 실행하는 것도 이렇게 시간이 많이 드는데,
키움증권의 데이터를 실시간 수신받아 활용하는 것에는
상당한 시간이 걸릴 거 같다.

그래도, 이번 기회에 많은 시간을 할애하여 패턴 관련 코드를 작성하고 보니,
패턴을 어떻게 적용해야 하는지 대충 감이 오긴 한다.

딥러닝, 머신러닝 등 화려하게 AI를 활용하지 않은 점이 아쉽지만,
그래도 이렇게 하나하나 고민하고 코드를 짜보니,
조금은 기분이 좋아지는건 사실이다.

경제적 자유를 얻을 수 있는 그날까지,
프로그램 공부는 계속해야겠다.

반응형