과거 주식 가격 데이터 확보를 위해 지금까지 삽질해 본 것들

요즘은 집에서 컴퓨터에 설치된 HTS 를 통해 주식을 거래하는 것을 넘어서 스마트폰으로 언제든지 어디서든 주식 가격을 확인하고 거래하는게 가능한 세상이다. 또한 각종 증권사들 뿐만 아니라 다른 다양한 곳에서, 예를 들어 트레이딩뷰 같은 곳에서 제공하는 여러 기본 보조지표들을 포함하는 강력한 차트 툴 처럼, 주식 가격 분석에 활용 가능한 여러 기능들을 탑재한 프로그램들을 제공하고 있어 누구나 쉽게 기본적인 가격 데이터 분석을 시작해 볼 수 있다.

하지만 그렇게 제공되는 기능들로는 만족하지 못하고, 대신 자신이 직접 나름대로의 방법으로 데이터를 분석해보고 싶은 사람들은, 아마도 가장 첫번째 난관으로 주식 가격 데이터를 어떻게 확보해야할지 부터 고민하게 되지 않을까 생각한다. 그리고 이 문서는 그렇게 나와 비슷하게 이러한 데이터 확보의 난관에 봉착한 사람들에게 내 일련의 삽질 경험을 공유함으로써 약간이나마 도움이 되었으면 하는 마음에서 적어보려고 한다.

1. 우리에게 친숙한 포털의 금융 주제 페이지

여기저기 찾다보면 비교적 가장 먼저, 그러고 쉽게 먼저 접할 수 있는 데이터 소스중 하나지 않을까 싶다.

접근성 측면에서는 좋은 데이터 소스이지만 아쉬운 점들이 몇가지 있다.

위의 내용중에 크롤러를 직접 구현해보는건 생각만 해도 머리가 아파서 따로 시도해보지 않았다.

참고로 위에서 언급된 다른 능력자 분들께서 이미 구현해주신 코드는 아래처럼 사용이 가능한 정도로만 확인했다. 또한 해당 라이브러리는 내부적으로 네이버측의 주식 가격정보 API 를 활용하고 있는 것을 확인할 수 있었다.

2. 아니 외국 사이트들은 주가를 다운로드 받을 수 있던데?

주로 해외 자료를 찾다보면 종종 나오는 웹사이트 기반 데이터 소스들로 아래 정도가 있던 걸로 기억한다.

앞선 국내 포털의 금융 주제 웹페이지와 구별되는 특징 중 장점이라고 볼 수 있는게 몇가지 있다.

하지만 역시나 한계점은 있다.

비교적 쉬워보이는 Yahoo Finance 출처에 대한 데이터 다운로더 툴을 간단하게 개발해봤는데 다음과 같았다.

좀 더 찾다보니 역시나 이미 다른 능력자들이 구현해놓은게 있었다. 역시나 머리가 나쁘면 혼자 바퀴를 발명하는 삽질을 하게 된다.

값을 앞선 결과와 비교해보니 기본적으로 수정주가의 형태로 가져오는 것으로 보인다.

3. 일반적인 웹 사이트들은 못써먹겠다. 공식 데이터 관리처에서 데이터를 받아올 수 있을까?

우리나라의 주식 거래 데이터는 당연하게도 한국거래소(KRX) 가 관리하고 있다. 이건 약간 TMI 지만 사실 실제 내부적으로 거래소의 전산관련 업무는 코스콤이라는 회사에서 맡아서 관리하고 있긴 하다. 어찌 되었든 여기서 어떻게 데이터를 받아올수만 있다면 데이터의 신뢰성과 관련해서는 걱정할 필요가 없어 보인다.

KRX 데이터 상품

여기저기 찾다보니 거래소에서 데이터를 상품으로 팔고 있다는걸 먼저 알아냈다. 가격이 그리 부담스럽지 않다면 데이터를 구매하는게 가장 바람직하지 않을까?

아래 페이지에서 데이터 구입에 대한 안내를 하고 있다.

판매 데이터의 가격을 확인해봤다. 위의 페이지에 첨부된 문서에서 가장 일반적인 주식 > 일별매매정보 > 유가/코스닥 > 전체항목 을 먼저 확인해봤다. 가격은 1년치 30만원... 단순하게 2000년 부터 시작하는 것으로 가정하고 20년 정도를 구매한다 하면 600만원이다. 만약에 이 데이터를 구매하면 내가 600만원 이상을 벌 수 있을까? 나는 도저히 본전도 못 채울 것 같아서 바로 포기했다.

혹시나 해서 데이터 구입 안내 메뉴 바로 밑의 페이지에서 좀 더 구체적인 견적도 내어봤는데 결과는 아래와 같다.

만약에 해당 가격이 부담되지 않는 사람이 있다면 (그 사람은 더이상 주식투자를 하지 않아도 되지 않나 싶지만) 도전해보고 알려주길 바란다.

KRX 정보데이터 시스템

좀 더 찾다보니 어느정도 기본적인 통계 정보들은 해당 사이트상에서 확인이 가능하도록 제공중인 것을 알게 되었다.

구체적으로 아래 페이지에서 개별종목의 일별 시세추이를 확인할 수 있다. 무려 다운로드도 가능했다!

관련해서 다른 능력자 분들께서 이미 구현해놓으신 코드를 참고하면서, 추가적으로 약간의 리버스 엔지니어링을 거쳐 아래와 같은 툴을 개발할 수 있었다.

해당 출처의 데이터를 사용하면 아래와 같은 장점이 있다고 생각한다.

다만 아래는 조금은 아쉬운 부분이다.

필자는 혹시나 매번 각 종목에 대한 전체 일자에 대한 데이터를 받아오는 것이 거래소의 서버에 부담이 되지 않을까 우려해, 아래처럼 로컬에 데이터를 저장하고 정말 필요한 경우에만 최신 데이터를 요청해 덧붙여 나가는 식으로 추가적으로 구현해 사용 중이다. 수정주가가 아닌 액면 그대로의 주가 데이터를 다루다 보니 과거의 데이터는 별도 오류로 인한 수정이 필요하지 않는 이상 갱신할 필요가 없어서 가능한 동작이다.

4. 사실 당연하게도 HTS 에서 데이터를 얻을 수 있다.

키움증권의 영웅문 HTS 기준으로 아래처럼 하면 단일 종목의 과거 가격데이터를 엑셀파일로 저장할 수 있다.

  1. 키움증권 영웅문 HTS 실행 및 접속
  2. 키움종합차트 창 생성
  3. 원하는 종목코드를 입력해 차트 불러오기
  4. 필요하다면 우측상단의 톱니버튼을 클릭해 수정주가 적용여부 설정 (기본값은 수정주가 적용)
  5. 우측상단의 연속조회 버튼을 최대한 많이 클릭해 최대한 많은 과거 데이터를 불러오기
  6. 차트화면 우클릭 후 데이타표 저장 기능 클릭
  7. 저장할 항목 설정 창에서 원하는 항목 체크 후 확인 버튼 클릭
  8. 최종적으로 엑셀파일을 원하는 경로에 원하는 이름으로 저장

image.png

증권사를 통해서 데이터를 받게 되면 아래와 같은 이점을 기대할 수 있다.

다만 위와 같은 방식은 아래와 같은 단점이 떠오른다.

여기서 자연스럽게 다음 단계로 고려되는 것이 각 증권사에서 제공하는 OpenAPI 와 같은 기능들을 직접 사용하는 것이 되겠다.

5. 증권사 API 를 활용해서 데이터를 가져와보자.

맨 처음 시도해볼 증권사 API 를 고를 때, 참고할 자료들이 가장 풍부해 보이는 키움증권의 OpenAPI+ 를 먼저 사용해보기로 마음먹고 개발을 시작했다. 이후 이것저것 삽질하면서 개발을 하다 보니 결론적으로는 koapy 를 개발하게 되었다. 개발과정에서의 여러 삽질들은 여기서 설명하자면 너무 길어질듯해 나중에 기회가 되면 이야기를 풀어봤으면 한다.

여기서는 koapy 를 사용해서 과거 일봉 데이터를 가져와 다른 데이터들과 한번 비교해본다.

키움증권의 OpenAPI+ 활용하기

먼저 현재 환경이 32Bit 환경이 맞는지 확인을 하고 진행할 것이다.

로그인 처리와 관련해서는 이미 자동 로그인 설정이 되어있는 것이 좋지만, 그게 아니라면 이후 진행하면서 팝업되는 로그인 창에 수동으로 인증정보를 입력해 로그인을 진행한다.

이제 아래처럼 koapy 를 사용해서 과거 일봉 데이터를 가져올 수 있다.

위의 주가는 수정주가가 적용되지 않은 결과이다. 이것을 앞서 KRX 에서 확인했던 데이터와 비교해보자.

차이가 없는 것이 확인된다. 긍정적인 결과이다.

이번에는 수정주가를 확인해보자.

맨 처음의 FinancialDataReader 가 네이버 금융의 데이터를 가져오고 있고, 해당 데이터는 수정주가가 적용된 데이터이다. 해당 데이터와 값을 비교해보자

꽤나 차이가 발생하는 것을 확인할 수 있으며, 이것은 각 데이터 출처에서 수정주가를 계산하는 방식이 다른 것으로 인한 차이이지 않을까 추측해볼 수 있다.

좀 더 시각적으로 확인해보자면 아래처럼 해볼 수 있다.

대략 2013년과 2014년 사이에 뭔 일이 있었는지 급격한 가격변화가 있었고, 해당 시점에서 부터 두 데이터의 가격 차이가 발생하는 것으로 보인다.

사실 해당 시점은 현재 NAVER 의 전신인 당시의 NHN 이 2013.08.01 을 기점으로 NAVER 와 NHN엔터테인먼트 (현재의 NHN) 으로 기업분할을 한 시점이다. 여기서 유추해볼 수 있는건 네이버와 키움증권이 해당 이벤트를 전후해서 수정주가 처리를 다른 방식으로 하고 있다는 것이다. 어느 방식이 더 적절한지에 대해서는 당장은 알 수 없기 때문에 제삼자의 케이스를 추가로 확인해보는게 좋겠다.

내가 알고 있는 것 처럼 FinancialDataReader 의 데이터가 수정주가가 아닐 수도 있을 것 같아서 원래 키움증권의 데이터와도 비교해봤다.

꽤나 차이가 크다. 이상하게 2007년부터 2009년 정도까지는 가격이 또 겹치는 구간이 있는거 같은데 뭘까.. 내가 보기에는 원래 수정주가가 최근부터 가장 오래된 시점까지 쭉 이어져서 수정되어야 하지만 여기서는 2009년에 한번 뚝 끊고 다시 거기서부터 수정주가를 적용한듯한 느낌도 든다.

대신증권의 Cybos Plus 활용해보기

여기서는 대신증권의 Cybos Plus 를 활용해 수정주가를 가져와 추가적으로 확인해보자.

대신증권 Cybos Plus 의 경우도 마찬가지로 32Bit 환경에서만 사용이 가능하다.

앞의 키움증권 케이스와는 다르게 여기서는 자동 로그인과 같은 설정은 따로 없다. 대신에 Cybos Plus 프로그램을 미리 실행 및 로그인까지 진행해두는 것이 필요하다. 미리 실행시켜두지 않았다면 지금 실행하자.

이제 아래처럼 koapy 를 사용해서 과거 일봉 데이터를 가져올 수 있다.

앞서 시각적으로 확인해 봤던 결과에서 위의 케이스를 추가해보자.

키움증권의 OpenAPI+ 와 대신증권의 CybosPlus 사이에서도 데이터 값의 차이가 발생하는 것을 확인할 수 있었다. 대신에 그 둘의 차이가 나머지 FinancialDataReader 케이스와의 차이보다 확연하게 적은 것을 봤을 때 FinancialDataReader 의 데이터가 약간은 표준에서 동떨어진 데이터가 아닐지 의심해볼 수 있겠다.

번외1. 만약에 앞에서 확인했던 Yahoo Financial 의 데이터까지 그려보면 어떻게 될까?

무엇이 가장 올바른 수정주가일지는 아직 잘 모르겠지만, 개인적으로는 야후의 데이터도 신뢰가 간다. 야후의 데이터가 키움증권과 대신증권의 데이터의 중간즘에 있어서 더욱 그렇게 보이는 걸지도 모르겠다. 위아래의 둘도 사실은 별다른 이슈 없이 실전에 충분히 활용 가능하지 않을까 하는 생각은 든다.

번외2. 만약에 KRX 데이터를 임의로 수정주가 처리해 같이 그려보면 어떻게 될까?

KRX 로 부터 받은 데이터를 어떻게 활용해볼 수 없을까 고민하다가 아래처럼 생각을 해보고 관련 아이디어를 적용해봤다.

다만 해당 방식을 나이브하게 여러 종목에 적용해보다가 아래와 같은 문제가 있어서 약간은 무식하게 대응한게 있는데, 구체적으로 아래와 같다.

이외에 또 다른 문제가 있을지는 아직까지는 잘 모르겠다.

놀랍게도 수정한 KRX 데이터가 앞서 대신증권 Cybos Plus 를 활용해 받은 수정주가 데이터를 거의 가려버리는 형국으로 보인다. 아마도 대신증권에서는 수정주가 계산시 내가 위에서 생각해낸 아이디어와 거의 비슷한 방향으로 접근하고 있는건 아닐지 조심스레 추측해본다.

6. 그래서 과거 주식 가격 데이터를 지속적으로 업데이트 하는데에 있어서 가장 좋은 방법은 뭘까?

일단 당장 자신있게 내릴 수 있는 결론 하나는 다음과 같다.

아래의 조건에 만족하는 경우 KRX 의 데이터를 활용한다.

  • 수정주가는 필요없다.
  • 일봉보다 작은 타임프레임의 가격 데이터는 필요없다.

그 다음으로 아래도 생각해볼 수 있겠다.

아래의 조건에 만족하는 경우 Yahoo Finance 의 데이터를 활용한다.

  • 일봉보다 작은 타임프레임의 가격 데이터는 필요없지만 수정주가는 필요하다.
  • 증권사 API 를 사용하는건 너무 번거로운 것 같다.

당장 Yahoo Finance 를 사용하지 말아야 할 이유는 떠오르지 않지만, 만약에 Yahoo Finance 는 싫은데 일봉 단위 수정주가가 필요한 경우, 차선책으로 KRX 데이터로부터 직접 수정주가를 생성하는 방식도 어느정도 유효하지 않을까 싶은 생각이다. 이 경우 자신이 직접 수정주가를 처리하는 것에 대한 리스크는 어느정도 감수해야 한다. (개인적으로 그리 크게 리스크가 있을 것 같지는 않다는 생각이다.)

아래의 조건에 만족하는 경우 KRX 의 데이터에 기반해 직접 수정주가 처리를 해서 활용한다.

  • 일봉보다 작은 타임프레임의 가격 데이터는 필요없지만 수정주가는 필요하다.
  • 증권사 API 를 사용하는건 너무 번거로운 것 같다.
  • 수정주가 처리방식을 내가 직접 관리하고 싶다.
  • 왠지 Yahoo Finance 는 쓰기 싫다.

이외에 일봉보다 작은 타임프레임의 영역으로 들어가게 되면 결국 증권사 API 의 사용은 필수가 된다. 수정주가의 경우는 제공 안하는 증권사를 찾는게 더 어렵지 않을까 싶다.

여기서 고려했던 두 증권사 API 말고도 다른 다양한 API 가 있겠지만, 먼저 고려했던 둘 중에 하나를 고르자면, 적어도 주식 가격데이터 확보의 관점에서는, 개인적으로 대신증권의 Cybos Plus 를 권하고 싶다. 구체적인 이유는 다음과 같다.

  1. Cybos Plus 가 속도 측면에서 압도적으로 빠르다.
    • 모든 증권사 API 는 과도한 요청을 제한하기 위해 시간당 API 요청 횟수의 제한을 두는데 상대적으로 Cybos Plus 가 훨씬 느슨하게 제한을 하고 있다.
    • 키움증권의 OpenAPI+ 의 경우 표면적으로 1초당 5회라고 이야기하고 있지만 내부적으로는 길게 봤을때 1시간당 1000회로, 거의 4초당 1회 꼴로 제한을 두고 있다.
      • 그러면서 1회 호출마다 확보 가능한 레코드 수는 600건 정도에 불과하다.
        • 일봉 데이터 기준 단순 속도를 계산해보면 150일/초 정도가 된다.
    • 반면에 대신증권의 Cybos Plus 는 단순하게 15초에 60회, 나눠보면 1초에 4회 정도까지 호출이 가능하다.
      • Cybos Plus 는 요청시에 필요한 컬럼들만 가져오도록 설정이 가능하다.
      • Cybos Plus 는 1회 요청에서 결과 테이블 내 전체 셀 개수의 총량을 제한하는 식으로 트래픽을 조절하고 있다.
      • 위의 두가지 성격으로 인해 1회 호출시에 확보 가능한 레코드 수는 요청하는 컬럼수에 반비례하게 된다.
      • 따라서 정말 필요한 컬럼들로만 제한해 호출하는 경우 속도는 더욱 빨라질 수 있다.
      • 일반적인 컬럼들로 설정했다고 가정했을때 1회 호출마다 대략 2000건의 레코드를 받을 수 있다.
        • 일봉 데이터 기준 단순 속도를 계산해보면 8000일/초 정도가 된다. 대략 키움증권 OpenAPI+ 의 50배가 되는 속도이다.
  2. Cybos Plus 가 지원하는 확인 가능한 과거 데이터의 기간도 더 길다.
    • 더 과거의 데이터를 확인할 수 있다는 의미다.
    • 만약에 최대한 많은 데이터를 확보하려는 입장이라면 유의미한 차이로 볼 수 있다.
  3. 요청시에 필요한 컬럼들만 가져오도록 설정 가능한 부분이 유용하게 사용될 수 있다. 예를 들어 아래와 같은 구성이 가능하다.
    1. 일별 타임프레임하에 수정주가비율 관련 정보만 요청해 주기적으로 업데이트 한다.
      • 수정주가가 하루 단위보다 더 잘게 나뉘어서 적용되지는 않기 때문에 일별 타임프레임으로 저장하면 된다.
      • 해당 정보는 매번 전체 업데이트를 거쳐도 된다. 필요한 컬럼만 요청하기 때문에 비교적 빠르게 값을 갱신하는 것이 가능하다.
      • 주기적으로 업데이트 처리를 하는게 가능하다면 효율성 측면에서 아래처럼 처리할 수도 있어 보인다.
        1. 업데이트시 현재 로컬에 가지고 있는 데이터 기준으로 가장 최근의 영업일과 중복되는/겹쳐지는 결과가 되도록 기간을 설정해 API 를 통해 수정주가비율을 요청한다.
          • 매일 업데이트 하는 경우 기간을 최근 2영업일로 설정해 요청하면 된다.
        2. 겹치게 되는 영업일의 수정주가비율에서 차이가 발생하게 되면 전체 기간에 대한 업데이트를 진행한다.
          • 만약에 차이가 없으면 겹치는 날짜를 제외한 나머지 신규 데이터만 추가한다.
          • 차이가 발생하는 경우의 기존 과거기간 전체에 대한 업데이트는 아래와 같은 방식으로도 가능하다.
            1. 겹치는 영업일에서 기존/신규 수정주가비율 사이의 값의 차이를 비율 형태로 확인한다.
            2. 기존에 가지고 있던 과거 수정주가비율 전체를 해당 비율만큼 동일하게 조정해준다.
              • * 겹치게 되는 영업일에서 기존 로컬의 수정주가비율이 요청을 통해 받은 신규 수정주가비율 만큼 되도록 조정해주는 것으로 보면 된다.
    2. 다른 필요한 주식 가격 데이터들은 모두 수정주가를 적용하지 않은 버전으로 가져와 로컬에 저장한다.
      • 이 경우 매번 전체 데이터를 업데이트 할 필요 없이 누락된 최신 데이터만 추가로 요청해 덧붙이는 식으로 업데이트가 가능하다.
    3. 이후 수정주가가 필요할때마다 아래와 같이 처리해 사용한다.
      1. 원본주가 데이터를 먼저 로드한다.
      2. 일별 주가수정비율 데이터도 같이 로드한다.
      3. 날짜 기준으로 위의 두 데이터를 조인 후 주가수정비율에 맞게 각 가격의 값을 조정한다.

증권사 API 선택방식과 관련해서 정리하자면 아래처럼 될 수 있겠다.

아래의 조건에 만족하는 경우 대신증권 Cybos Plus 의 데이터를 활용한다.

  • 분봉 이하를 포함한 다양한 타임프레임의 가격 데이터가 필요하다.
  • 데이터 업데이트를 효율적으로 하고 싶다.
  • 더 많은 기간의 데이터를 확보하는 것이 중요하다.

아래의 조건에 만족하는 경우 키움증권 OpenAPI+ 의 데이터를 활용한다.

  • 분봉 이하를 포함한 다양한 타임프레임의 가격 데이터가 필요하다.
  • 업데이트 속도나 효율성은 크게 중요하지 않다.
  • 확보 가능한 과거 데이터의 기간도 크게 중요하지 않다.
  • 여러 증권사 API 를 사용하는게 번거로울 것 같다. 나는 원래 쓰던 키움증권만 쓰련다.

각 증권사마다 수정주가 계산을 다르게 처리하는 것과 관련해서는, 필요하다면 각기 증권사에 문의해본 뒤에 자신에게 맞는 방식을 골라서 사용하면 되지 않을지 하는 생각이다.

Cybos Plus 를 활용한 수정주가 별도 관리 방식의 구체적인 예시

위의 Cybos Plus 의 장점을 설명하는 내용중 마지막 3번에서 설명했던 방식을 좀 더 구체적인 예시를 들어보자면 아래와 같다.

데이터 소스별 지원 기간 비교

위에서 검토해본 데이터 소스들에서 제공 가능한 가장 오래된 데이터의 범위가 어디까지인지 비교해본다.

대신증권의 Cybos Plus 가 가장 많은 데이터를 제공하는 것을 확인할 수 있다.