ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ECOS API] 한국은행 경제통계 API 이용 (2) json
    Python/텔레그램봇:채권모니터링 2020. 12. 14. 14:34

    원래는 API 기본 값인 xml로 데이터를 처리하다가,

    뒤늦게 json타입도 지원되는 걸 발견하고 환승하면서 코드를 class로 정리해서 모아두기로 했다.

     

    주요 목적은 인증키와 STAT_CODE와 ITEM_CODE1, count 정보를 담은 객체를 만들어두고,

    필요할 때마다 최근 데이터를 불러오는 함수 작성하기. 아래와 같은 모양이다.

    setting = {
                'key': 'asdf'
                'dataType': 'json',
                'language': 'kr',
    }  # 이쪽에 기본 정보를 정리해두고
    
    corpBondAAm = Ecos(setting, STAT_CODE='060Y001', ITEM_CODE1='010300000', count=19)
    print(corpBondAAm.getLatest()) # {'20201211': 2.215} 
    
    corpBondBBBm = Ecos(setting, STAT_CODE='060Y001', ITEM_CODE1='01032000', count=20)
    print(corpBondBBBm.getLatest()) # {'20201211': 8.626}

     

    작성해야할 url 구문은 아래와 같다. 이중 채워야할 부분은 일자타입, 시작/종료일자.

    http://ecos.bok.or.kr/api/StatisticSearch/인증키/json/kr/1/1/STAT_CODE/일자타입/시작일자/종료일자/ITEM_CODE1/

    데이터는 1건씩만 받을 것이라 STAT_CODE 앞의 부분은 /1/1/로 채웠다.

    시작/종료일자는 가장 최근 데이터가 언제인지를 알아야 채울 수 있다.

     

    이 정보는 통계 세부항목 목록(StatisticItemList) 쪽에 url을 보내면 알 수 있다.

    시장금리(일별)(060Y001) 데이터에 세부항목이 23건이 있고, 내가 찾고 싶은 회사채(3년,AA-)(010300000) 데이터는 그중 19번이다.

    count 입력을 생략하도록 할까 하다가, 어차피 서비스 가능한 통계코드를 찾다보면 찾아야해서 그냥 입력하기로 했다.

    http://ecos.bok.or.kr/api/StatisticItemList/인증키/json/kr/19/19/060Y001/

     

    위 쿼리를 보내면 이런 데이터를 얻을 수 있다.

    {
      "StatisticItemList": {
        "list_total_count": 23,
        "row": [
          {
            "END_TIME": "20201211",
            "DATA_CNT": 6633,
            "GRP_NAME": "항목선택",
            "CYCLE": "DD",
            "STAT_NAME": "4.1.1 시장금리(일별)",
            "ITEM_NAME": "회사채(3년,AA-)",
            "GRP_CODE": "Group1",
            "STAT_CODE": "060Y001",
            "ITEM_CODE": "010300000",
            "START_TIME": "19950103",
            "P_ITEM_CODE": ""
          }
        ]
      }
    }

    이제 여기서jsondata['StatisticItemList']['row'][0]['END_TIME']값 20201211을

    위의 시작/종료일자에 채워서 다시 보내면 된다.

     

    그러면 아래와 같은 데이터를 얻을 수 있고, 값은 jsondata['StatisticSearch']['row'][0]['DATA_VALUE']로 접근하면 된다.

    {
      "StatisticSearch": {
        "list_total_count": 1,
        "row": [
          {
            "UNIT_NAME": "연%",
            "STAT_NAME": "4.1.1 시장금리(일별)",
            "ITEM_CODE1": "010300000",
            "STAT_CODE": "060Y001",
            "ITEM_CODE2": " ",
            "ITEM_CODE3": " ",
            "ITEM_NAME1": "회사채(3년,AA-)",
            "ITEM_NAME2": " ",
            "DATA_VALUE": "2.215",
            "ITEM_NAME3": " ",
            "TIME": "20201211"
          }
        ]
      }
    }

    함수를 작성하면 이렇다.

     

    import requests
    
    class Ecos:
        def __init__(self, Key, STAT_CODE, ITEM_CODE1, count):
            # count: StatisticItemList에서 ITEM_CODE1이 STAT_CODE의 몇 번째 항목인지
            self.Key = Key
            self.STAT_CODE = STAT_CODE
            self.ITEM_CODE1 = ITEM_CODE1
            self.base = 'http://ecos.bok.or.kr/api/'
            self.count = count
    
        def getJSON(self, url):
            return requests.get(url).json()
    
        def getDate(self):  # 최근 일자 구하기
            url = self.base + 'StatisticItemList/' + self.Key \
                  + '/json/kr/' + str(self.count) + '/' + str(self.count) \
                  + '/' + self.STAT_CODE
            data = self.getJSON(url)
            return (data['StatisticItemList']['row'][0]['END_TIME'],
                    data['StatisticItemList']['row'][0]['CYCLE'])
    
        def getLatest(self):  # 목표인 금리 데이터 구하기
            date, cycle = self.getDate()
            url = self.base + 'StatisticSearch/' + self.Key \
                  + '/json/kr/1/1/' + self.STAT_CODE + '/' + cycle + '/' \
                  + date + '/' + date + '/' + self.ITEM_CODE1
            data = self.getJSON(url)
            returnDict = {
                'date': date,
                'value': float(data['StatisticSearch']['row'][0]['DATA_VALUE'])
            }
            return returnDict
    
    Key = ''
    
    corpBondAAm = Ecos(Key, STAT_CODE='060Y001', ITEM_CODE1='010300000', count=19)
    print(corpBondAAm.getLatest()) # {'date': '20201211', 'value': 2.215}
    corpBondBBBm = Ecos(Key, STAT_CODE='060Y001', ITEM_CODE1='010320000', count=20)
    print(corpBondBBBm.getLatest()) # {'date': '20201211', 'value': 8.626}

     

     

     


    getLatest() 메소드 보충

     

    20년 12월 15일 오후 4시 30분 경에 코드를 돌리다가 에러가 나는 것을 확인했다.

    StatisticItemList 쪽 END_TIME은 '20201215'로 업데이트 되었는데,

    StatisticSearch 쪽에는 아직 데이터가 추가되지 않아서 에러가 났다. 이 경우 값은 이렇게 반환된다.

    {"RESULT":{"MESSAGE":"해당하는 데이터가 없습니다.","CODE":"INFO-200"}}

    데이터는 4시 40분 경 업데이트 되었으니 정규 마켓타임이 아니라서 실제 불편함은 없을 것 같아서 간단히만 수정했다.

    확인이 완료된 최근 일자를 validDate에 저장해두고 불러쓰는 형식으로 변경:

        def getLatest(self):  # 목표인 금리 데이터 구하기
            date, cycle = self.getDate()
            url = self.base + 'StatisticSearch/' + self.Key \
                  + '/json/kr/1/1/' + self.STAT_CODE + '/' + cycle + '/' \
                  + date + '/' + date + '/' + self.ITEM_CODE1
            data = self.getJSON(url)
            if "RESULT" in data:
                url = url.replace(date, self.validDate, 2)
                data = self.getJSON(url)
            returnDict = {
                'date': date,
                'value': float(data['StatisticSearch']['row'][0]['DATA_VALUE'])
            }
            self.validDate = date
            return returnDict
    

    댓글

Designed by Tistory.