본문 바로가기
AyoProject/Ayotera-Trade

[AT] 28. 우량주 종목 자동 예측 및 선정 (4-2)

by 청양호박이 2021. 2. 16.

지난 시간에 이어서... 영업이익률 + 현금흐름표에 더해서 추가 Hyper Parameter를 통해서 좀더 정확한 우량주를 판단하는 로직을 구현하겠습니다. 이를 제목으로는 저평가 종목이라고 표현했는데... 지난 글에서는 ROE(Return Of Equity)와 시가종액, 그리고 PBR(Price to Book-value Ratio)을 사용하기로 했습니다.

 

  • 우량주 종목 선정을 위한 기반 데이터 수집 방안 (전자공시시스템 활용) - 1개 종목기준
  • 정리된 데이터 수집 방안에 대해서 코스피, 코스닥 전체 종목에 대한 데이터를 DBMS에 적재
  • 우량주 종목 선정 로직을 적용하여 대상 종목 추출
  • 추출된 우량주 종목에 대해서 저평가 종목 추출
  • 추출된 종목에 대해서 실험실 진행

 

우량주 종목에 대해서 저평가 종목을 추출하는 내용을 완성하기 위해서는 아래의 추가 단계가 필요하고, 앞으로 당분간은 해당 구성을 구현해 보도록 하겠습니다. 

 

앞으로 구성해야할 전체 구성입니다. 현재 완료되어있는 부분과 안되어 있는 부분을 단계별로 확인해 보면....

 

  1. Dart OpenData로 부터 전체 종목의 재무제표정보 추출 (완료)
  2. 영업이익률 / 현금흐름표를 기준으로 우량주 종목을 선정 (완료)
  3. 선정된 우량주 종목을 Database에 저장 (진행)
  4. 키움증권 API로 부터 3번에 저장된 우량주 종목에 대한 지표를 추출
  5. 추출된 종목별 지표를 Database에 저장
  6. 통합 이력기록을 위해서 작업 이력을 이력테이블 생성 및 저장
  7. 저평가 종목을 포함한 최종 종목을 선정 및 화면에 렌더링

 

그래도 많은 부분이 아직 구현이 안되어있네요?? 그렇다면 차근차근 나머지 부분을 진행해 보겠습니다. 이번에는 3번 선정된 우량주 종목을 Database에 저장을 해보겠습니다. 

 

 

1. 고려사항


기존에 Dart OpenData를 통해서, 년도별 / 분기별 재무제표 데이터를 일괄적으로 RestAPI를 통해서 가져오는 부분에 대해서 알아보았습니다. 물론 해당 데이터를 Database에 저장하는 부분도 포함이 되어 있습니다. 하지만 고민을 해야할 부분이 한가지 있습니다. 

 

기업은 모두 정해진 일자에 재무제표 정보를 올리고 공시를 하면 너무나 좋겠지만, 개인적인 생각으로는 어느정도 재무제표가 올라온 시점에서 해당 프로그램을 구동하여 정보를 저장한다고 하더라도... 결국 시점에 대한 차이로 어떤 기업의 정보는 가져오지 않는 상태가 될 수 있습니다. 따라서 주기적으로 돌리는 구조도 구성하겠습니다.

 

추가적으로 우량주 종목으로 선정하는 방식은 타 데이터와 연관성이 없이, 자체적인 데이터로 분석을 하여 선정을 하기 때문에 주기적으로 데이터를 업데이트한다고 해서, 추가 우량주 종목이 생길수는 있어도 기존의 우량주 종목이 비 대상으로 변경되지는 않을 것 입니다. 

 

  • 공시 시점이 다를 수 있어서, 재무제표 데이터를 받아오는 프로그램과 우량주 종목 선정 프로그램을 주기적으로 구동해야 함
  • 단, 우량주 선정하는데 있어서 각 종목별 연관관계가 없기때문에 기존 선정된 종목에 영향이 미치지 않기 때문에 무결성 유지가 가능함

 

그렇다면, 위의 가정으로 선정된 우량주에 대해서 저장을 수행해 보겠습니다. 

 

 

2. Table 구성


결국 분기별로 추천되는 우량주 종목은 1개의 Table에 구분하여 저장합니다. 이를 위해서 아래와 같이 테이블 생성을 하겠습니다. 

 

[quarter_superior_stocks]

CREATE TABLE quarter_superior_stocks(
	stocks_id VARCHAR(10),
	bsns_year VARCHAR(4),
	bsns_quarter VARCHAR(1),
	ins_date DATETIME
);

종목id와 해당년도/분기를 저장하고, 이를 database에 insert한 일자를 추가로 저장해 줍니다. 생성이야 엄청나게 간단하네요~ 현재로써는 해당 테이블로 충분할 것으로 보입니다.

 

 



 

 

3. 기존 프로그램 변경


이제 기존에 우량주 종목을 영업이익률과 현금흐름표를 통해서 추출했던 코드에 수정이 필요합니다. 관련하여 기존에 구현했던 부분은 아래의 글을 참조해주세요.

 

2021/01/15 - [AyoProject/Ayotera-Trade] - [AT] 26. 우량주 종목 자동 예측 및 선정 (3-2)

 

[AT] 26. 우량주 종목 자동 예측 및 선정 (3-2)

바로 전 시간에는 우량주 종목 선정을 위한 기반 데이터를 전자공시시스템에서 제공하는 OPEN DART를 통해서 재무제표 정보를 받아와서 DB Table에 적재하는 로직을 구현하였습니다. 이번시간에는

ayoteralab.tistory.com

기존에는 순전히 우량주 종목의 list를 출력하는 부분만 작성이 되어있기 때문에 나름대로 간단하게... DB에 해당 데이터를 저장하는 로직만 추가하면됩니다.

 

여기서 주의할 점은... 시점차이에 따른 재무제표데이터가 계속 추가될 가능성이 있기때문에, Table에는 insert시 기존데이터를 체크해서 없는 데이터만 저장하도록 아래의 SQL query문을 적용합니다.

 

[SQL query]

sql_dml = '''
    INSERT INTO quarter_superior_stocks(stocks_id, bsns_year, bsns_quarter, ins_date)
    SELECT %s, %s, %s, NOW() FROM DUAL
    WHERE NOT EXISTS (SELECT * FROM quarter_superior_stocks WHERE stocks_id = %s AND bsns_year = %s AND bsns_quarter = %s)
'''

 

[추가 소스코드]

print("선정된 종목 데이터 수 : ", len(superior_stocks))

# 추출된 우량주 종목을 quarter_superior_stocks table에 저장
table_insert_cnt = 0
sql_dml = '''
    INSERT INTO quarter_superior_stocks(stocks_id, bsns_year, bsns_quarter, ins_date)
    SELECT %s, %s, %s, NOW() FROM DUAL
    WHERE NOT EXISTS (SELECT * FROM quarter_superior_stocks WHERE stocks_id = %s AND bsns_year = %s AND bsns_quarter = %s)
'''
for i in superior_stocks:
    sql_data = (i[0], i[3], i[4], i[0], i[3], i[4])
    try:
        mariadb_cur.execute(sql_dml, sql_data)
        table_insert_cnt += 1
    except mariadb.Error as error:
        print(error)

mariadb_conn.commit()

print("DB에 저장된 데이터 수 : ", table_insert_cnt)

이제는 Database에 정상적으로 저장이 되어있는지 확인해 보겠습니다.

 

 

4. 우량주 종목 Database 저장 확인


우선 소스코드에서 판단한 우량주 종목의 개수와 DB에 저장했다고하는 종목의 개수를 확인해 보겠습니다.

 

[결과]

총 데이터 수 :  1637
선정된 종목 데이터 수 :  133
DB에 저장된 데이터 수 :  133

전체 분석대상이 되는 종목은 총 1,637건이고, 그 중에서 우량주 종목으로 판단된 데이터는 총 133건 입니다. 그리고 그 대상을 DB에 저장한 데이터는 133건, 즉 전체 데이터를 저장했다고 합니다. 

 

그럼 DB에서 확인해 볼까요??

정확히 133건이 저장되어 있음을 확인했습니다. 다음에는 해당 종목에 대한 일부 지표를 키움증권에서 제공하는 Open API를 통해서 받아와서 Stock_info에 저장하는 로직을 구현해 보겠습니다. 

 

- Ayotera Lab -

댓글