투자자/알고리즘

저장된 재무제표를 읽어오려면 (feat. 문자열 유사성 판단하는 로직)

나그네_즈브즈 2021. 4. 15. 10:30

백테스트 활용에 자유도를 확보하려면 재무데이터는 필수적이다. 이를 위해 내가 활용할 DART는 하루 접근횟수와 자료 조회속도에 제한이 걸려있기 때문에, 이대로는 백테스트가 어렵다. 결국 모든 자료를 저장해두어야 하고, 알맞게 읽어올 수 있어야 한다.

 

각 종목별로 과거의 모든 재무제표들을 저장하는 작업은 지루하지만 쉽다. 반면에 이걸 읽어오는 부분은 흥미롭지만 어렵다. 앞 단계에서 '일단 저장'에만 몰두했던 덕분인지, 폴더에 남은 자료들의 속내를 들여다 보면 참 가관이다. 예를 들어 당기순이익 계정과목은 기업에 따라 당기순이익, 당기순손익, 당기이익, 당 기 순 이 익 등의 다양한(?) 형태를 띠고 있다. 계정과목 이름이 길어지면 다양성은 훨씬 증가할 수 있다. 세부 계정과목들로 보면, 포함시킨 기업도 있고 그렇지 않은 기업들도 있다. 

 

개발자의 가슴을 뛰게 만드는 이 작업의 계획은 대략 다음과 같다.

 

1. 필요한 계정과목 종류를 모두 정리한다.

2. 계정과목이 주어지면 그와 유사하다고 생각되는 문자열을 찾아 모은다.

3. 비슷한 '사촌 문자열'들을 표준적 '대표 문자열'로 모두 바꾼다.

4. 해당 계정과목의 데이터를 읽어온다.

 

여기서도 가장 핵심적인 작업은 2단계의 '사촌 문자열' 찾아 모으기라고 할 수 있다. 내가 입력한 문자열과 비교할 문자열이 '비슷하다'는 걸 어떻게 컴퓨터에게 판단하게 할 것인가. 내 기준은 두 가지다. ▲입력 문자열의 상당수가 비교 문자열에 들어있을 것과 ▲공통 문자열들이 나열된 순서가 똑같아야 한다는 조건이다. 

 

예를 들어보자. 나는 '매출총이익'을 찾고 싶다. 이게 입력 문자열이 된다. 컴퓨터가 반복문을 돌다보면 매출총손익, 매출이익, 매출손익, 매각이익, 총이익매출 등등을 만날 수 있다. 얘네들이 차례차례 비교 문자열이 된다. 총손익매출을 만난 경우를 생각해 보자. 여기서 공통 문자열은 매, 출, 총, 익 네 글자다. 

 

공통 문자열 길이가 입력 문자열 길이의 4/5배, 즉 80%다. 이 정도면 충분하다. 대신 이 기준은 개발자가 정해줘야 한다. 두 번째 조건을 살펴보자. 우리가 원하는 순서는 '매' 뒤에 '출' 그 다음에 '총' 그리고 '익'이 마지막인 모습이다. 이 기준에서 볼 때 총이익매출은 탈락이다.

 

그러면 이번에는, '매출손익'을 비교 문자열로 삼아서 순서를 테스트 해보자. 공통 문자열은 [매, 출, 익] 세 글자다. 첫 번째인 '매'를 가지고 온다. 비교 문자열에서 이 글자를 기준으로 뒷부분을 잘라온다. '출손익'이 남겨질 것이다. 이 안에 공통 문자열의 두 번째인 '출'이 포함되어 있는가? 좋다. 이제는 공통 문자열의 두 번째인 '출'을 기준으로 비교 문자열 '매출손익'을 잘라내 그 뒷부분을 살펴보자. '손익'이 남는다. 여기에 공통 문자열의 다음 글자 '익'이 들어 있을까? 그런 것 같다. 중간 단계 어느 곳에서라도 '아니오'가 나온다면 순서 비교 작업은 False를 내며 종료된다. 

 

두 문자열의 유사성을 판별하는 함수의 로직은 대략 이 정도다. 이렇게 해도 예외적인 경우들은 많다. 귀속, 지배, 처분, 환수, 매각, 계속, 중단, 외, 기타, ... 등이 포함된 것들을 걸러주는 조건문을 추가해주면 간단히 해결된다. 마지막으로 앞서 소개한 1단계에서 내가 원하는 계정과목들을 정리해보며 포스팅을 마칠까 한다.

 

매출액  매출총이익  영업이익  법인세차감전계속사업이익  당기순이익  자산총계  유동자산  재고자산  매출채권  부채총계  유동부채  자본금  영업활동현금흐름  투자활동현금흐름  재무활동현금흐름  최대주주이름  최대주주소유주식  총주식

 

이 정도면 영업이익률, 순이익률, 자본총계, 부채비율, 당좌비율, EPS, BPS, PER, PBR, PSR, PEG, GP/A, ROE, ROA, 시가총액 정도는 계산해내는 게 가능할 것이다. 

반응형