본문 바로가기
문송충의 코딩하기/파이썬 데이터 분석

공공데이터 Open API를 통해 삼성전자 주주 구성 분석하기 With Python

by 동장군님 2020. 7. 15.
728x90
반응형

주린이로서 오늘도 역시 주식과 관련된 데이타를 분석해보고자 한다. 삼성전자 주식을 갖고 있는 주주들에 대해 간단하게 분석하고 자 하는데 주된 내용은 다음과 같다.

 

1. 주식 수 기준 주주 수 분포도

2 성별 별 주주 분포

3. 연령 별 주주 분포

 

위에 있는 내용을 각각 Open API로 추출해서 시각화까지해서 마무리하고자 한다.

별 의미 없는 내용일 수 있지만 나한테는 어느정도 궁금했던 내용이었다.

그럼 바로 시작하겠다.

 


1. 공공데이터 Open API key 값 받기

 

오늘 사용할 데이터는 바로 공공데이터이다. 정부에서 운영하는 사이트만큼 다양한 데이터를 제공하고 있다. 추후 분석 프로젝트에서도 해당 사이트를 많이 이용할 예정이다. 오늘 분석에 활용될 데이터는 아래 링크로 확인 바란다.

 

https://data.go.kr/data/15001145/openapi.do

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

data.go.kr

 

여기서 활용신청 버튼을 누르면 인증 Key 값이 주어질 것이다.

그리고 코딩에 앞서 먼저 API 요청 값과 출력값에 대해 숙지하길 바란다. 나한테는 굉장히 어려웠다.

 


 

2. 기업 종목 코드 가져오기

 

주주 관련 내용을 분석하기 위해서는 먼저 분석하고자 하는 기업의 코드를 받아야 되는데, 이것 역시 해당 API에서 제공해준다.

from urllib.request import urlopen
from urllib.parse import urlencode, unquote, quote_plus
import urllib
import requests
import pandas as pd
import xmltodict
import json

key='인증키 입력'
url = f'http://api.seibro.or.kr/openapi/service/CorpSvc/getIssucoCustnoByNm?serviceKey={key}&'
queryParams = urlencode({ quote_plus('issucoNm') : '삼성전자', quote_plus('numOfRows') : '100', quote_plus('pageNo') : '1' })

url2 = url + queryParams
response = urlopen(url2) 
results = response.read().decode("utf-8")

results_to_json = xmltodict.parse(results)
data = json.loads(json.dumps(results_to_json))

 

위 코드를 돌릴 경우 문제가 뭐냐면 수백개의 삼성전자 키워드가 포함된 종목이 다 나타나게 된다는 점이다.

그래서 나는 삼성전자가 위치한 index 번호를 추출하기 위해서 아래 한번 더 돌려야 된다.

#상성전자 위치한 인덱스 번호를 출력한다
for index, value in enumerate(data['response']['body']['items']['item']):
    if value['issucoNm']=='삼성전자':
        print(index)
        break;
    
code=data['response']['body']['items']['item'][44]['issucoCustno']

 

 

3. 주식 보유 수 기준 주주 분포 구하기

 

주식 수 기준으로 주주 수를 분류해보고자 한다. 삼성전자 20주 밖에 안들고 있는 주린이지만 이런게 은근히 궁금하더라

 

#다시 API를 통해 주식분포현황 조회하자
distribute=f'http://api.seibro.or.kr/openapi/service/CorpSvc/getStkDistributionOwnQtyStatus?serviceKey={key}&'
queryParams = urlencode({ quote_plus('issucoCustno') : code, quote_plus('rgtStdDt') : '20200331'})
distribute2=distribute+queryParams
response = urlopen(distribute2) 
shares = response.read().decode("utf-8")

results_to_json = xmltodict.parse(shares)
data_shares = json.loads(json.dumps(results_to_json))

data_shares_dict=data_shares['response']['body']['items']['item'][2:]

shares_df=pd.DataFrame(data_shares_dict)

shares_df.columns=['투자자 수','투자자 비중','주식 수 범위','주식 수']

shares_df=shares_df[:-1]
shares_df['주식 수 범위']=shares_df['주식 수 범위'].replace('KSD','1주 보유')


shares_df.set_index('주식 수 범위', inplace=True)

shares_df['투자자 수']=shares_df['투자자 수'].astype(int)
shares_df['투자자 비중']=shares_df['투자자 비중'].astype(float)

코드가 문제 없이 돌아간다면 아래와 같이 결과가 출력될 것이다.

나는 1십주~5십주를 보유한 33%에 포함된다.

 

 

 

분포 시각화는 바 그래프와 라인 그래프의 콤보 그래프로 시도해보았다.

확실히 10주~50주 사이의 주린이들이 많이 삼성전자를 보유하는 것으로 나타났다.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import font_manager, rc
from matplotlib import style
plt.rcParams["figure.figsize"] = (12,8)
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
style.use('ggplot')

shares_df['투자자 수'].plot(kind='bar')
shares_df['투자자 비중'].plot(secondary_y=True)

4. 성별 주주 분포 가져오기

 

계속 거의 똑같은 식으로 돌리는 것 뿐이다. API 요청하는 URL만 다르고 다른건 거의 똑같다.

 

sex_url=f'http://api.seibro.or.kr/openapi/service/CorpSvc/getStkDistributionGenderStatus?serviceKey={key}&'
queryParams = urlencode({ quote_plus('issucoCustno') : code, quote_plus('rgtStdDt') : '20200331'})
sex_url2=sex_url+queryParams
response = urlopen(sex_url2) 
sexs = response.read().decode("utf-8")

results_to_json = xmltodict.parse(sexs)
sexs_shares = json.loads(json.dumps(results_to_json))

sex_df=pd.DataFrame(sexs_shares['response']['body']['items']['item'][1:])

sex_df.columns=['투자자 수','투자자 비중','성별','주식 수']
sex_df.set_index('성별',inplace=True)

sex_df['투자자 수']=sex_df['투자자 수'].astype(int)
sex_df['투자자 비중']=sex_df['투자자 비중'].astype(float)
sex_df['주식 수']=sex_df['주식 수'].astype(float)
sex_df=sex_df[:-1]

결과는:

 

이번 시각화는 파이 차트로 그려보겠다.

역시 국민 주식으로 삼성 주주는 남녀 1대1로 나누어졌음을 확인할 수 있다.

 

파이차트 시각화 코드:

plt.rcParams["figure.figsize"] = (16,16)
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
style.use('ggplot')
plt.pie(sex_df['투자자 비중'], labels=sex_df.index, autopct='%1.1f%%', shadow=True, startangle=90)

 

5. 연령별 주주 분포 가져오기

 

똑같은거 몇번 씩 하니까 귀찮지만 마지막으로 연령별 분포를 진행하겠다.

 

age_url=f'http://api.seibro.or.kr/openapi/service/CorpSvc/getStkDistributionAgeStatus?serviceKey={key}&'
queryParams = urlencode({ quote_plus('issucoCustno') : code, quote_plus('rgtStdDt') : '20200331'})
age_url2=age_url+queryParams
response = urlopen(age_url2) 
ages = response.read().decode("utf-8")

results_to_json = xmltodict.parse(ages)
ages_shares = json.loads(json.dumps(results_to_json))

age_df=pd.DataFrame(owners_shares['response']['body']['items']['item'][1:-1])
age_df.columns=['투자자 수','투자자 비중','연령대','주식 수']

age_df.set_index('연령대',inplace=True)
age_df['투자자 수']=age_df['투자자 수'].astype(int)
age_df['투자자 비중']=age_df['투자자 비중'].astype(float)
age_df['주식 수']=age_df['주식 수'].astype(float)

출력결과:

 

분포 시각화

파이 차트가 제일 무난할 것 같다.

역시 국민 주식이다. 20~50대까지 전반적으로 골고루 분포되어 있다.

삼성전자는 국민에게 사랑 받는 기업

 

plt.rcParams["figure.figsize"] = (16,16)
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
style.use('ggplot')
plt.pie(age_df['투자자 비중'], labels=age_df.index, autopct='%1.1f%%', shadow=True, startangle=90)

삼성전자 연령별 주주 수 비중

 

이번 코딩은 정말 OpenApi를 사용하다 보니 번거로운게 한 두가지가 아니였다. 귀찮다.

성의없는 코딩 끝

728x90
반응형

댓글