한국거래소의 수정주가 계산 공식을 알아보자

작성자: [관리자] 하얀설표

2025.05.08 14:29 (KST) 작성됨

2025.05.10 13:38 (KST) 수정됨






(05.10) 수정됨.

주가 차트를 그리려면 주식 시세 정보가 필요하다.

주식 시세 데이터를 제공해주는 api는 찾아보면 많은데... 이 글에서 사용하는 api는 금융위원회_주식시세정보다.

 

데이터 보정없이 사용할 때의 문제

막상 데이터를 받아서 사용해보면 증권사 HTS를 사용한 것과는 사뭇 다른 차트가 그려진다.

어떤 종목은 아무 문제 없는데, 어떤 종목은 과거 시세 정보가 전혀 다른 수치를 나타낼 것이다.

 

이런 현상이 발생하는 이유는 "수정주가" 적용 유무에 있다.

 

수정주가란?

네이버 지식백과에서는 수정주가에 대해 다음과 같이 설명한다.

주가는 유무상증자, 배당, 액면분할등이 생길 때 연속성을 잃고 단층을 보이게 된다.
이경우 이전주가와 현재의 주가를 비교하는데 애로가 따르게 된다.
따라서 주가에 연속성을 부여하기 위해 일정한 수정을 할수있는데, 이것을 수정주가라 한다.

예컨대 권리락이 발생했다면, 권리락 전일의 주가를 기준가격으로 하여 이론상 권리락가격을 구하거나 당일 주가를 권리부가격으로 환원하여 수정주가를 산출하게 된다.
전체 주식시장의 주요지표로 사용되는 평균주가의 경우도 채용종목의 일부가 변화되었거나 권리락등이 일어났을 때, 상장주식 주가합계를 나누나 제수에 위와같은 방법으로 수정을 가하여 수정주가평균을 구할수 있다.
이같은 방법은 일정시점의 시장 주가수준을 나타내는데에는 적합치 않지만 여러시점의 비교를 위하여 자주 활용되고 있다.

출처 네이버 지식백과

 

주식시장에 상장된 종목의 시세는 여러 가지 요소에 의해 변동된다.

대표적으로는 주식 감자, 유상증자 또는 무상증자 전에 시행되는 권리락, 배당을 지급하기 전에 이루어지는 배당락, 주식을 일정 비율로 쪼개는 액면분할 등이 있다.

 

확인해보자

이번 작업을 위해 주가가 여러 번 변동된 종목을 찾아야 했는데, 에이루트가 적절해보였다.

 

데이터 요청하기

api를 통해 데이터를 요청하면 다음과 같은 식으로 조회할 수 있다.

 

다음과 같은 코드를 작성해 날짜와 종가, 전일대비 데이터만 따로 저장했다.

import json
import requests

api_key = {api 키}
code = '096690'
r = requests.get(
    f'http://apis.data.go.kr/1160100/service/GetStockSecuritiesInfoService/getStockPriceInfo\
?serviceKey={api_key}&numOfRows=9999&resultType=json&beginBasDt=19900101&likeSrtnCd={code}'
)
j = r.json()
d = []
for i in j['response']['body']['items']['item']:
    print(i['clpr'])
    d.append((i['basDt'], i['clpr'], i['vs']))
d = sorted(d, key=lambda x: x[0])
with open(f'{code}.txt', 'w', encoding='utf-8') as txt:
    json.dump(d, txt, indent='  ', ensure_ascii=False)

 

그러면 다음과 같은 json 파일을 생성할 수 있다.

[
  ["20200102", "1540", "10"], ["20200103", "1530", "-10"], ["20200106", "1485", "-45"], 
  ...,
  ["20250429", "1643", "38"], ["20250430", "1552", "-91"], ["20250502", "1561", "9"], ["20250507", "1570", "9"]
]

 

주가가 변동된 날짜 찾기

미래에서 과거 순으로 루프하고, 미래 데이터에서 계산한 전일 종가와 현재 종가를 비교해 가격에 괴리가 발생한 날짜를 찾아낼 수 있다.

코드로 표현하면 다음과 같다.

import json

with open('096690.txt', 'r', encoding='utf-8') as txt:
    d = json.load(txt)

dates = []
pre_close = None
d = sorted(d, key=lambda x: x[0], reverse=True)
for n, i in enumerate(d):
    close = int(i[1])
    close_pre = close - int(i[2])
    if pre_close and close != pre_close:
        print()
        print(i)
        print(d[n-1])
        print(close, pre_close)
        ratio = pre_close / close
        print(f'{ratio=}')
    pre_close = close_pre

>> 
['20240502', '392', '0']
['20240503', '1950', '-10']
392 1960
ratio=5.0

['20210716', '7250', '-120']
['20210719', '1570', '360']
7250 1210
ratio=0.16689655172413792

['20200528', '1120', '0']
['20200529', '5770', '-360']
1120 6130
ratio=5.473214285714286

 

정수로 떨어지지 않는 비율

2024년 5월 2일과 3일을 보면 가격 비율이 5로 딱 맞아떨어진다.

그러나 2021년 7월 16일과 19일, 2020년 5월 28일과 29은 비율이 정수가 아니게 된다.

 

주가를 보정해보자

수정주가는 현재 주가를 기준으로 과거 주가를 보정한 값이다.

공식으로 나타내면 다음과 같은데,

(수정주가) = (당일 종가) * (익일 데이터에서 구한 당일 종가) / (당일 종가)

 

가령 현재 날짜가 2021년 7월 19일이라면, 2021년 7월 16일의 주가는 7,250 * (1,210 / 7,250) = 1210원이 된다.

이를 통해 20201년 7월 10일부터 19일까지의 주가를 다음과 같이 보정해볼 수 있다.

import json

with open('096690.txt', 'r', encoding='utf-8') as txt:
    d = json.load(txt)

dates = []
pre_close = None
d = sorted(d, key=lambda x: x[0], reverse=True)
data = []
ratio = 1
for n, i in enumerate(d):
    close = int(i[1])
    close_pre = close - int(i[2])
    if '20210710' <= i[0] and i[0] <= '20210719':
        if pre_close and close != pre_close:
            ratio = pre_close / close
        data.append((i[0], close * ratio))
    pre_close = close_pre

for i in data: print(i)

>> ('20210719', 1570)
('20210716', 1210.0)
('20210715', 1230.0275862068966)
('20210714', 1251.7241379310344)
('20210713', 1251.7241379310344)
('20210712', 1240.0413793103448)
('20210709', 1368.551724137931)
('20210708', 1492.0551724137931)
('20210707', 1618.896551724138)
('20210706', 1637.255172413793)
('20210705', 1455.3379310344826)
('20210702', 1416.951724137931)
('20210701', 1280.096551724138)

 

이게 맞는지 확인하기 위해 한국거래소 정보데이터스템에서 해당 기간의 주가를 확인해봤다.

 

코드를 사용한 결과와 한국거래소에서 제공한 정보를 비교해보면 수정주가 적용시 소수점 이하는 반올림을 해 정수로 처리하고 있다고 추측하 수 있다.

 

수정주가를 여러 번 적용해야 하는 경우

주가 보정이 필요한 경우가 딱 1번이라면 위 코드만으로 충분하다.

그러나, 예시로 가져온 에이루트의 주가는 2020년부터 2025년까지 3번의 주가 보정을 필요로 한다.

 

이번에는 주가에 변동이 있을 때마다 수정주가 비율을 중첩하도록 코드를 수정하고, 작동해봤다.

import json

with open('096690.txt', 'r', encoding='utf-8') as txt:
    d = json.load(txt)

dates = []
pre_close = None
d = sorted(d, key=lambda x: x[0], reverse=True)
data = []
ratio = 1
for n, i in enumerate(d):
    close = int(i[1])
    close_pre = close - int(i[2])
    if pre_close and close != pre_close:
        ratio *= round(pre_close / close, 4)
    data.append((i[0], round(close * ratio)))
    pre_close = close_pre

dates = {'20240502', '20240503', '20210716', '20210719', '20200528', '20200529'}
for i in data:
    if i[0] in dates: print(i)

>> ('20240503', 1950)
('20240502', 1960)

('20210719', 7850)
('20210716', 6050)

('20200529', 4815)
('20200528', 5115)

 

한국거래소 사이트에서는 최대 2년의 데이터만 조회할 수 있기 때문에 이번에는 HTS나 증권 정보를 볼 수 있는 곳에서 데이터를 조회해야 했다.

 

서로 다른 보정결과

네이버 증권에서 제공하는 차트에서 2020년 5월 28일과 2020년 5월 29일 종가는 각각 (4,810원, 5,110원)이고, KB증권에서 제공하는 종가는 (4,815원, 5,115원)이다. 또한 한국투자증권에서는 (4,814원, 5,115원)이었다.

코드를 작동한 결과는 4,815원이었는데, 차트를 제공하는 곳마다 수정주가 적용 방식이 다른 것 같다.

다른 증권사 HTS도 확인해보니 증권사마다 제공되는 수정주가 데이터가 달랐다.

 

이번에는 소수점 버림..?

수정주가 비율을 중첩하는 것에서 각각 저장한 다음 개별 적용하도록 변경하고, 계산시 반올림이 아닌 소수점 이하 버림을 적용해보았다.

이렇게 하니 네이버에서 제공하는 차트와 동일한 결과값이 나온다.

import json

with open('096690.txt', 'r', encoding='utf-8') as txt:
    d = json.load(txt)

dates = []
pre_close = None
d = sorted(d, key=lambda x: x[0], reverse=True)
# d = [i for i in d if i[0] <= '20210719']
data = []
ratio_list = []
for n, i in enumerate(d):
    close = int(i[1])
    close_pre = close - int(i[2])
    if pre_close and close != pre_close:
        ratio_list.append(round(pre_close / close, 6))
    for ratio in reversed(ratio_list):
        close = int(close * ratio)
    data.append((i[0], close))
    pre_close = close_pre
dates = {'20240502', '20240503', '20210716', '20210719', '20200528', '20200529'}
for i in data:
    if i[0] in dates: print(i)

>> ('20240503', 1950)
('20240502', 1960)

('20210719', 7850)
('20210716', 6050)

('20200529', 4810)
('20200528', 5110)

 

소수점 이하는 절사냐, 반올림이냐??

아무래도 과거의 데이터다 보니까 어느게 정답이라고 할 수는 없을 것 같다.

다만, 주식 거래를 관장하는 한국거래소에서 반올림을 적용하고 있으니 이게 맞지 않을까....?

 

 






추천 (0)


글 목록

댓글을 달 수 없는 게시물입니다.


"분류없음" 카테고리의 #Python, #주식 관련 게시물

썸네일
분류없음
상장폐지된 스팩의 청산시 1주당 반환금액 확인용
수정 08.29 | [관리자] 하얀설표
👍 0
#주식
🗨️ 0
분류없음
예제)특정 조합이 리스트 요소에 반드시 포함되어야 한다는 사실만 알 때의 조건식
수정 08.20 | [관리자] 하얀설표
👍 0
#Python, #예제
🗨️ 0
썸네일
분류없음
주식시장 개장일과 휴장일 정보를 간단하게 가져오는 방법(엑셀, 파이썬)
수정 07.20 | [관리자] 하얀설표
👍 0
#Python, #주식
🗨️ 0
분류없음
해결) 장고 bulk_update의 메모리 누수 문제(django orm bluk_update method memory leak)
수정 07.12 | [관리자] 하얀설표
👍 0
#Python, #Django
🗨️ 0
썸네일
분류없음
관심종목) 2025.06.29
작성 06.29 | [관리자] 하얀설표
👍 0
#주식, #Jesse Livermore
🗨️ 0
썸네일
분류없음
관심종목) 2025.06.22
작성 06.22 | [관리자] 하얀설표
👍 0
#주식, #Jesse Livermore
🗨️ 0
분류없음
해결) django.db.utils.OperationalError: database is locked
수정 06.18 | [관리자] 하얀설표
👍 0
#Python, #에러해결, #Django
🗨️ 0
썸네일
분류없음
관심종목) 2025.06.14
수정 06.14 | [관리자] 하얀설표
👍 0
#주식, #Jesse Livermore
🗨️ 0
썸네일
분류없음
지지선과 저항선 그리기, 기준은 고가, 저가, 종가 중 무엇으로 해야 할까?
수정 06.10 | [관리자] 하얀설표
👍 0
#주식
🗨️ 0
썸네일
분류없음
차트에 지지선과 저항선 긋기
수정 06.05 | [관리자] 하얀설표
👍 0
#주식
🗨️ 0