Skip to content

Latest commit

 

History

History
2030 lines (1710 loc) · 76.2 KB

README.md

File metadata and controls

2030 lines (1710 loc) · 76.2 KB

Code with OPEN API from LS Securities Co., Ltd.

<Reference>

<List>

TR

Request TR & Save to CSV

OAuth

  • Receive real-time conditional search results by passing the real-time key (sAlertNum) value received from t1860 TR to AFR TR

  • Improve code readability and maintainability by applying @dataclass and typing library

  • Be aware that search conditions are only available in the real environment

  • Future Improvements

    • Make it independent of the request_tr_4 module
    • Apply @dataclass to other TRs as well
  • Code and Results

    Code : t1860_ATR_async.py
    import pprint
    import asyncio
    from dataclasses import dataclass, asdict
    from typing import Optional, Dict, Any
    import json
    import aiohttp
    import oauth_3 as oauth
    from request_tr_4 import request_tr
    import key
    @dataclass
    class APIConfig:
        """LS Open API 설정"""
        is_real: bool
        base_url: str
        websocket_url: str
        stock_item_search_url: str
    
    @dataclass
    class T1860Request:
        """T1860 TR 요청 구조"""
        sSysUserFlag: str
        sFlag: str
        sAlertNum: str
        query_index: str
    
    @dataclass
    class AFRRequest:
        """AFR (실시간) 데이터 요청 구조"""
        tr_type: str
        tr_cd: str
        tr_key: str
    
    @dataclass
    class APIResponse:
        """일반 API 응답 구조"""
        header: Dict[str, Any]
        body: Optional[Dict[str, Any]]
    
    # API 설정
    config = APIConfig(
        is_real=True,
        base_url="https://openapi.ls-sec.co.kr:8080",
        websocket_url="wss://openapi.ls-sec.co.kr:9443/websocket",
        stock_item_search_url="https://openapi.ls-sec.co.kr:8080/stock/item-search"
    )
    class LSOpenAPI:
        """LS Open API 클라이언트: 주식 데이터 요청 및 실시간 데이터 수신 처리"""
    
        def __init__(self):
            """API 클라이언트 초기화: 접근 토큰 및 헤더 설정"""
            self.access_token: str = oauth.oauth(_real=config.is_real)
            self.headers: Dict[str, str] = {
                "content-type": "application/json; charset=utf-8",
                "authorization": self.access_token
            }
    
        async def request_t1860(self, query_index: str) -> Optional[str]:
            """T1860 TR 데이터 요청 및 알림 번호 반환"""
            t1860_request = T1860Request(
                sSysUserFlag="U",
                sFlag="E",
                sAlertNum="",
                query_index=f"{key.USER_ID:8}{query_index}"
            )
    
            t1860_input: Dict[str, Any] = {
                "url": config.stock_item_search_url,
                "tr_name": "t1860",
                "body": {"t1860InBlock": asdict(t1860_request)},
                "out_block_tags": ["t1860OutBlock"],
                "shcode": ""
            }
    
            try:
                data_frames, _, _ = request_tr(t1860_input, _real=config.is_real)
                if data_frames and len(data_frames) > 0:
                    return data_frames[0]['sAlertNum'].iloc[0]
            except Exception as e:
                print(f"request_t1860 오류: {e}")
            return None
    
        async def receive_afr_data(self, alert_num: str) -> None:
            """실시간 AFR 데이터 수신 및 출력"""
            async with aiohttp.ClientSession() as session:
                async with session.ws_connect(config.websocket_url, headers=self.headers) as ws:
                    afr_request = AFRRequest(
                        tr_type="3",
                        tr_cd="AFR",
                        tr_key=alert_num
                    )
                    request_data: Dict[str, Any] = {
                        "header": {
                            "token": self.access_token,
                            "tr_type": afr_request.tr_type
                        },
                        "body": {
                            "tr_cd": afr_request.tr_cd,
                            "tr_key": afr_request.tr_key
                        }
                    }
                    await ws.send_json(request_data)
                    try:
                        while True:
                            msg = await ws.receive()
                            if msg.type == aiohttp.WSMsgType.TEXT:
                                response = APIResponse(**json.loads(msg.data))
                                print("수신된 AFR 데이터:")
                                pprint.pprint(asdict(response))
                            elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
                                print("WebSocket 연결 종료")
                                break
                    except asyncio.CancelledError:
                        print("AFR 데이터 수신 취소됨")
                    finally:
                        await ws.close()
    async def main(_test: bool = False) -> None:
        """API 클라이언트 실행 메인 함수"""
        api = LSOpenAPI()
        alert_num = await api.request_t1860("0000")
        if alert_num:
            print(f"수신된 sAlertNum: {alert_num}")
            receive_task = asyncio.create_task(api.receive_afr_data(alert_num))
            try:
                await asyncio.Event().wait()
            except asyncio.CancelledError:
                print("메인 태스크 취소됨")
            finally:
                receive_task.cancel()
                await asyncio.gather(receive_task, return_exceptions=True)
        else:
            print("sAlertNum 수신 실패")
    
    if __name__ == "__main__":
        try:
            asyncio.run(main())
        except KeyboardInterrupt:
            print("사용자에 의해 프로그램 종료됨")
    Results
    수신된 sAlertNum: 1639410200I
    수신된 AFR 데이터:
    {'body': None,
    'header': {'rsp_cd': '00000',
              'rsp_msg': '정상처리되었습니다',
              'tr_cd': 'AFR',
              'tr_type': '3'}}
  • Improved from 현물주문(CSPAT00601) 外 : 동기식 (2024.09.06) as asynchronous

  • Code : tr_stock_order_async.py

    Import modules and Declare constants
    import asyncio
    import pprint
    import aiohttp
    import oauth_3 as oauth
    # API 요청을 위한 기본 URL 설정
    URL      = "https://openapi.ls-sec.co.kr:9443/stock/websocket"
    MOCK_URL = "https://openapi.ls-sec.co.kr:29443/stock/websocket"
    ORDER_URL = "https://openapi.ls-sec.co.kr:8080/stock/order"
    async def send_api_request()
    async def send_api_request(url, headers, body):
        """
        API 요청을 비동기 방식으로 발송하고 응답을 반환하는 함수
    
        Args:
            url (str): 요청할 API의 URL.
            headers (dict): 요청 헤더.
            body (dict): 요청 본문.
    
        Returns:
            dict: API 응답을 포함한 JSON 객체.
        """
        async with aiohttp.ClientSession() as session:
            async with session.post(url, headers=headers, json=body) as response:
                return await response.json()
    async def send_order_async()
    async def send_order_async(_real=False, _IsuNo=None, _OrdQty=None, _OrdPrc1=None, _OrdprcPtnCode=None):
        """
        비동기 주문 발송 함수
    
        주식 주문을 비동기 방식으로 LS Open API에 요청합니다.
    
        Args:
            _real (bool): 실제 환경 여부. True는 실제 환경, False는 모의 투자.
            _IsuNo (str): 종목 번호 (예: '005930').
            _OrdQty (int): 주문 수량.
            _OrdPrc1 (float): 주문 가격.
            _OrdprcPtnCode (str): 호가유형코드 (예: '00' - 지정가, '03' - 시장가).
    
        Returns:
            dict: 주문 결과를 포함한 JSON 응답. 응답에는 주문 번호 등이 포함됩니다.
        
        주의:
            - 네트워크 요청 실패 시 예외가 발생할 수 있으므로 try-except로 처리하는 것이 좋습니다.
        """
    
        # OAuth 토큰 발급
        _access_token = oauth.oauth(_real=_real)
    
        # 요청 헤더 설정
        _header = {
            "content-type": "application/json; charset=utf-8",  # 요청 데이터 형식
            "authorization": f"Bearer {_access_token}",         # OAuth 토큰
            "tr_cd": "CSPAT00601",                              # TR 코드 (주문)
            "tr_cont": "N",                                     # 연속 조회 여부 (연속조회 미사용)
            "tr_cont_key": "",                                  # 연속 조회 키 (없음)
            "mac_address": ""                                   # MAC 주소 (필요시 사용)
        }
    
        # 요청 본문 설정
        _cspat00601_body = {
            "CSPAT00601InBlock1": {
                "IsuNo": _IsuNo,
                "OrdQty": _OrdQty,
                "OrdPrc": _OrdPrc1,
                "BnsTpCode": "2",                               # 매수/매도 구분 ('2'는 매도)
                "OrdprcPtnCode": _OrdprcPtnCode,                # 호가유형코드
                "MgntrnCode": "000",                            # 신용거래코드 ('000' - 일반)
                "LoanDt": "",                                   # 대출일자 (필요시 사용)
                "OrdCndiTpCode": "0",                           # 주문조건유형코드 ('0' - 기본값)
            }
        }
    
        # API 요청 발송
        return await send_api_request(ORDER_URL, _header, _cspat00601_body)
    async def correct_order_async()
    async def correct_order_async(_real=False, _IsuNo=None, _OrdNo=None, _OrdQty=None, _OrdPrc2=None, _OrdprcPtnCode=None):
        """
        비동기 정정 주문 함수
    
        이미 발송된 주식 주문을 정정하는 요청을 비동기 방식으로 처리합니다.
    
        Args:
            _real (bool): 실제 환경 여부.
            _IsuNo (str): 종목 번호 (예: '005930').
            _OrdNo (str): 주문 번호 (기존 주문 번호).
            _OrdQty (int): 정정할 주문 수량.
            _OrdPrc2 (float): 정정할 주문 가격.
            _OrdprcPtnCode (str): 호가유형코드 (예: '00' - 지정가, '03' - 시장가).
    
        Returns:
            dict: 정정 주문 결과를 포함한 JSON 응답.
        
        주의:
            - 정정 가능한 주문만 대상으로 합니다. 이미 체결된 주문은 정정할 수 없습니다.
        """
    
        # OAuth 토큰 발급
        _access_token = oauth.oauth(_real=_real)
    
        # 요청 헤더 설정
        _header = {
            "content-type": "application/json; charset=utf-8",  # 요청 데이터 형식
            "authorization": f"Bearer {_access_token}",         # OAuth 토큰
            "tr_cd": "CSPAT00701",                              # TR 코드 (정정 주문)
            "tr_cont": "N",                                     # 연속 조회 여부
            "tr_cont_key": "",                                  # 연속 조회 키
            "mac_address": ""                                   # MAC 주소
        }
    
        # 정정 주문 본문 설정
        _cspat00701_body = {
            "CSPAT00701InBlock1": {
                "IsuNo": _IsuNo,
                "OrgOrdNo": _OrdNo,                             # 원래 주문 번호
                "OrdQty": _OrdQty,                              # 정정할 주문 수량
                "OrdPrc": _OrdPrc2,                             # 정정할 가격
                "BnsTpCode": "2",                               # 매도 주문 ('2'는 매도)
                "OrdprcPtnCode": _OrdprcPtnCode,                # 호가유형코드
                "MgntrnCode": "000",                            # 신용거래코드 ('000' - 일반)
                "LoanDt": "",                                   # 대출일자 (필요시 사용)
                "OrdCndiTpCode": "0",                           # 주문조건유형코드 ('0' - 기본값)
            }
        }
    
        # API 요청 발송
        return await send_api_request(ORDER_URL, _header, _cspat00701_body)
    async def cancel_order_async()
    async def cancel_order_async(_real=False, _IsuNo=None, _OrdNo=None, _OrdQty=None):
        """
        비동기 취소 주문 함수
    
        이미 발송된 주식 주문을 취소하는 요청을 비동기 방식으로 처리합니다.
    
        Args:
            _real (bool): 실제 환경 여부.
            _IsuNo (str): 종목 번호 (예: '005930').
            _OrdNo (str): 주문 번호 (취소할 주문 번호).
            _OrdQty (int): 취소할 주문 수량.
    
        Returns:
            dict: 취소 주문 결과를 포함한 JSON 응답.
        
        주의:
            - 취소할 수 있는 상태의 주문만 대상으로 합니다. 체결된 주문은 취소할 수 없습니다.
        """
    
        # OAuth 토큰 발급
        _access_token = oauth.oauth(_real=_real)
    
        # 요청 헤더 설정
        _header = {
            "content-type": "application/json; charset=utf-8",  # 요청 데이터 형식
            "authorization": f"Bearer {_access_token}",         # OAuth 토큰
            "tr_cd": "CSPAT00801",                              # TR 코드 (취소 주문)
            "tr_cont": "N",                                     # 연속 조회 여부
            "tr_cont_key": "",                                  # 연속 조회 키
            "mac_address": ""                                   # MAC 주소
        }
    
        # 취소 주문 본문 설정
        _cspat00801 = {
            "CSPAT00801InBlock1": {
                "IsuNo": _IsuNo,
                "OrgOrdNo": _OrdNo,                             # 취소할 주문 번호
                "OrdQty": _OrdQty,                              # 취소할 수량
            }
        }
    
        # API 요청 발송
        return await send_api_request(ORDER_URL, _header, _cspat00801)
    async def main()
    async def main(_real=False, _IsuNo=None, _OrdQty=None, _OrdPrc1=None, _OrdPrc2=None, _OrdprcPtnCode=None):
        """
        메인 비동기 함수
    
        주식 주문, 정정 주문, 취소 주문을 순차적으로 비동기 방식으로 처리합니다.
        """
    
        # 주문 발송
        _cspat00601_params = await send_order_async(_real, _IsuNo, _OrdQty, _OrdPrc1, _OrdprcPtnCode)
        # 발송된 주문의 주문 번호를 추출하여 저장합니다.
        OrdNo1 = _cspat00601_params['CSPAT00601OutBlock2']['OrdNo']
        # pprint.pprint(_cspat00601_params)                     # 주문 결과 출력
        pprint.pprint(OrdNo1)
    
        # 예시: 1초 후에 정정 주문 발송
        await asyncio.sleep(1)
        _cspat00701_params = await correct_order_async(_real, _IsuNo, OrdNo1, _OrdQty, _OrdPrc2, _OrdprcPtnCode)
        # pprint.pprint(_cspat00701_params)                     # 정정 주문 결과 출력
        # 정정된 주문의 새로운 주문 번호를 추출하여 저장합니다.
        OrdNo2 = _cspat00701_params['CSPAT00701OutBlock2']['OrdNo']
        pprint.pprint(OrdNo2)
    
        # 예시: 2초 후에 취소 주문 발송
        await asyncio.sleep(2)
        _cspat00801_params = await cancel_order_async(_real, _IsuNo, OrdNo2, _OrdQty)
        # pprint.pprint(_cspat00801_params)                     # 취소 주문 결과 출력
    Run
    if __name__ == "__main__":
    
        from datetime import datetime
    
        IS_REAL = True                              # 실제 환경 여부 설정 (False: 모의투자, True: 실제 환경)
        IsuNo = "005930" if IS_REAL else "A005930"  # 주식 종목번호 설정 (삼성전자: 005930, 모의투자는 A005930)
    
        # 현재 시간을 기준으로 호가유형코드 설정
        current_time = datetime.now().time()
        if current_time > datetime.strptime("15:30", "%H:%M").time():
            if current_time < datetime.strptime("16:00", "%H:%M").time():
                OrdprcPtnCode = "81"                # 15:30 ~ 16:00 사이
            else:
                OrdprcPtnCode = "82"                # 16:00 ~ 18:00 사이
        else:
            OrdprcPtnCode = "00"                    # 그 외 시간 (정규 거래 시간)
    
        # 주문 가격과 수량 설정
        OrdPrc1 = 60000.0                           # 최초 주문 가격 (예: 60,000원)
        OrdPrc2 = 60100.0                           # 정정 주문 가격 (예: 60,100원)
        OrdQty = 1                                  # 주문 수량 (1주)
    
        # 비동기 메인 함수 실행
        asyncio.run(main(IS_REAL, IsuNo, OrdQty, OrdPrc1, OrdPrc2, OrdprcPtnCode))
  • Results

    Results : Successful
    "0","주문NO","종목명","매매구분","주문수량","주문가격","현재가","체결수량","체결가격","미체결량","확인수량","상태","원주문","주문유형","주문시간","매체",
    "","23763","삼성전자","매수취소","1","0","61,500","0","0","0","1","취소확인","23762","시간외단일가","16:29:51","OPEN API",
    "","23762","삼성전자","매수정정","1","60,100","61,500","0","0","0","1","정정확인","23761","시간외단일가","16:29:49","OPEN API",
    "","23761","삼성전자","매수","1","60,000","61,500","0","0","0","0","완료","0","시간외단일가","16:29:47","OPEN API",
    
  • LS증권 OPEN API > API가이드 > [주식] 주문 > 현물주문(CSPAT00601), 현물정정주문(CSPAT00701), 현물취소주문(CSPAT00801)

  • Code : tr_stock_order.py

    Import modules and Declare constants
    import sys
    import request_tr_4 as request_tr
    # API 요청을 위한 기본 URL 설정
    URL = "https://openapi.ls-sec.co.kr:8080/stock/order"
    CSPAT00601()
    def CSPAT00601(_body):
        """
        CSPAT00601: 주식 매수 주문 요청을 위한 함수
    
        매수 주문을 위한 TR 요청을 생성하는 함수입니다. 
        해당 함수는 주식 매수 주문에 필요한 정보를 받아 TR 요청을 위해 필요한
        URL, TR 이름, 출력 블록 태그 등의 데이터를 딕셔너리 형태로 반환합니다.
    
        Args:
            _body (dict): 주문 요청에 필요한 데이터가 포함된 딕셔너리
    
        Returns:
            dict: TR 요청에 필요한 정보 (URL, body, TR 이름, 출력 블록 태그 등) 
        """
    
        # TR 요청을 위한 URL 설정
        _url = URL
    
        # 함수 이름으로 TR 이름 설정 (이 함수는 'CSPAT00601')
        _tr_name = sys._getframe().f_code.co_name
    
        # 출력 블록 태그 설정 (결과 데이터를 참조하기 위한 키)
        # _out_block_tags = ["rsp_cd", "rsp_msg"]
        _out_block_tags = []
        for i in range(1, 3):
            _out_block_tags.append(f"{_tr_name}OutBlock{i}")
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,              # 요청 URL
            'body': _body,            # 요청 바디
            'tr_name': _tr_name,      # TR 코드 이름
            'out_block_tags': _out_block_tags,  # 출력 블록 태그
            'shcode': None,           # 종목 코드 (필요시 사용)
        }
    CSPAT00701()
    def CSPAT00701(_body):
        """
        CSPAT00701: 주식 주문 정정 요청을 위한 함수
    
        주식 주문을 정정하기 위한 TR 요청을 생성하는 함수입니다. 
        기존 주문을 정정할 때 필요한 정보를 받아, TR 요청에 사용할 
        URL, TR 이름, 출력 블록 태그 등의 데이터를 딕셔너리 형태로 반환합니다.
    
        Args:
            _body (dict): 주문 정정 요청에 필요한 데이터가 포함된 딕셔너리
    
        Returns:
            dict: TR 요청에 필요한 정보 (URL, body, TR 이름, 출력 블록 태그 등) 
        """
    
        # TR 요청을 위한 URL 설정
        _url = URL
    
        # 함수 이름으로 TR 이름 설정 (이 함수는 'CSPAT00701')
        _tr_name = sys._getframe().f_code.co_name
    
        # 출력 블록 태그 설정 (결과 데이터를 참조하기 위한 키)
        # _out_block_tags = ["rsp_cd", "rsp_msg"]
        _out_block_tags = []
        for i in range(1, 3):
            _out_block_tags.append(f"{_tr_name}OutBlock{i}")
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,              # 요청 URL
            'body': _body,            # 요청 바디
            'tr_name': _tr_name,      # TR 코드 이름
            'out_block_tags': _out_block_tags,  # 출력 블록 태그
            'shcode': None,           # 종목 코드 (필요시 사용)
        }
    CSPAT00801()
    def CSPAT00801(_body):
        """
        CSPAT00801: 주식 주문 취소 요청을 위한 함수
    
        주식 주문을 취소하기 위한 TR 요청을 생성하는 함수입니다. 
        기존 주문을 취소할 때 필요한 정보를 받아, TR 요청에 사용할 
        URL, TR 이름, 출력 블록 태그 등의 데이터를 딕셔너리 형태로 반환합니다.
    
        Args:
            _body (dict): 주문 취소 요청에 필요한 데이터가 포함된 딕셔너리
    
        Returns:
            dict: TR 요청에 필요한 정보 (URL, body, TR 이름, 출력 블록 태그 등) 
        """
    
        # TR 요청을 위한 URL 설정
        _url = URL
    
        # 함수 이름으로 TR 이름 설정 (이 함수는 'CSPAT00801')
        _tr_name = sys._getframe().f_code.co_name
    
        # 출력 블록 태그 설정 (결과 데이터를 참조하기 위한 키)
        # _out_block_tags = ["rsp_cd", "rsp_msg"]
        _out_block_tags = []
        for i in range(1, 3):
            _out_block_tags.append(f"{_tr_name}OutBlock{i}")
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,              # 요청 URL
            'body': _body,            # 요청 바디
            'tr_name': _tr_name,      # TR 코드 이름
            'out_block_tags': _out_block_tags,  # 출력 블록 태그
            'shcode': None,           # 종목 코드 (필요시 사용)
        }
    Run
    if __name__ == "__main__":
        import pprint
    
        # 실제 환경 여부 설정 (False: 모의투자)
        IS_REAL = False
    
        # 주식 종목번호 설정 (삼성전자: A005930)
        IsuNo = "A005930"
    
        # 호가유형코드 및 주문가 설정
        OrdprcPtnCode = "00"  # 지정가
        OrdPrc1 = 60000.0     # 최초 주문가
        OrdPrc2 = 65000.0     # 정정 주문가
        OrdQty = 1            # 주문 수량
    
        # 매수 주문 요청 데이터 설정
        cspat00601_body = {
            "CSPAT00601InBlock1": {
                "IsuNo": IsuNo,                 # 종목번호 (모의투자: A+종목코드)
                "OrdQty": OrdQty,               # 주문수량
                "OrdPrc": OrdPrc1,              # 주문가
                "BnsTpCode": "2",               # 매매구분 (1:매도, 2:매수)
                "OrdprcPtnCode": OrdprcPtnCode, # 호가유형코드 (00:지정가, 03:시장가 등)
                "MgntrnCode": "000",            # 신용거래코드 (000:보통)
                "LoanDt": "",                   # 대출일
                "OrdCndiTpCode": "0",           # 주문조건구분 (0:없음, 1:IOC, 2:FOK)
            }
        }
        # 매수 주문 요청을 위한 TR 요청 데이터 생성
        cspat00601_params = CSPAT00601(cspat00601_body)
        # pprint.pprint(cspat00601_params)
        results1 = request_tr.request_tr(cspat00601_params, _real=IS_REAL, _timeout=3)
        pprint.pprint(results1)
    
        # 첫 번째 주문번호 추출
        OrdNo = int(results1[0][1]["OrdNo"].values[0])
        print(OrdNo)
    
        # 주문 정정 요청 데이터 설정
        cspat00701_body = {
            "CSPAT00701InBlock1": {
                "OrgOrdNo": OrdNo,              # 원주문번호
                "IsuNo": IsuNo,                 # 종목번호 (모의투자: A+종목코드)
                "OrdQty": OrdQty,               # 주문수량
                "OrdprcPtnCode": OrdprcPtnCode, # 호가유형코드 (00:지정가, 03:시장가 등)
                "OrdCndiTpCode": "0",           # 주문조건구분 (0:없음, 1:IOC, 2:FOK)
                "OrdPrc": OrdPrc2,              # 주문가 (정정된 가격)
            }
        }
        # 주문 정정 요청을 위한 TR 요청 데이터 생성
        cspat00701_params = CSPAT00701(cspat00701_body)
        # pprint.pprint(cspat00701_params)
        results2 = request_tr.request_tr(cspat00701_params, _real=IS_REAL, _timeout=3)
        pprint.pprint(results2)
    
        # 두 번째 주문번호 추출
        OrdNo2 = int(results2[0][1]["OrdNo"].values[0])
        print(OrdNo2)
    
        # 주문 취소 요청 데이터 설정
        cspat00801_body = {
            "CSPAT00801InBlock1": {
                "OrgOrdNo": OrdNo2,             # 원주문번호
                "IsuNo": IsuNo,                 # 종목번호 (모의투자: A+종목코드)
                "OrdQty": OrdQty,               # 주문수량
            }
        }
        # 주문 취소 요청을 위한 TR 요청 데이터 생성
        cspat00801_params = CSPAT00801(cspat00801_body)
        # pprint.pprint(cspat00801_params)
        results3 = request_tr.request_tr(cspat00801_params, _real=IS_REAL, _timeout=3)
        pprint.pprint(results3)
    
        # # 결과를 CSV 파일로 저장
        request_tr.save_csv(_data_frames=results1[0], _tr_name=results1[1])
        request_tr.save_csv(_data_frames=results2[0], _tr_name=results2[1])
        request_tr.save_csv(_data_frames=results3[0], _tr_name=results3[1])
  • Results

    CSPAT00601()
    RecCnt,AcntNo,InptPwd,IsuNo,OrdQty,OrdPrc,BnsTpCode,OrdprcPtnCode,PrgmOrdprcPtnCode,StslAbleYn,StslOrdprcTpCode,CommdaCode,MgntrnCode,LoanDt,MbrNo,OrdCndiTpCode,StrtgCode,GrpId,OrdSeqNo,PtflNo,BskNo,TrchNo,ItemNo,OpDrtnNo,LpYn,CvrgTpCode
    1,55503309601,0000,A005930,1,60000.00,2,00,00,0,0,40,000,,000,0,,,0,0,0,0,0,0,0,0
    RecCnt,OrdNo,OrdTime,OrdMktCode,OrdPtnCode,ShtnIsuNo,MgempNo,OrdAmt,SpareOrdNo,CvrgSeqno,RsvOrdNo,SpotOrdQty,RuseOrdQty,MnyOrdAmt,SubstOrdAmt,RuseOrdAmt,AcntNm,IsuNm
    1,22609,145812026,40,00,A005930,,60000,0,0,0,1,0,0,0,0,김프로,삼성전자
    CSPAT00701()
    RecCnt,OrgOrdNo,AcntNo,InptPwd,IsuNo,OrdQty,OrdprcPtnCode,OrdCndiTpCode,OrdPrc,CommdaCode,StrtgCode,GrpId,OrdSeqNo,PtflNo,BskNo,TrchNo,ItemNo
    1,22609,55503309601,0000,A005930,1,00,0,65000.00,40,,,0,0,0,0,0
    RecCnt,OrdNo,PrntOrdNo,OrdTime,OrdMktCode,OrdPtnCode,ShtnIsuNo,PrgmOrdprcPtnCode,StslOrdprcTpCode,StslAbleYn,MgntrnCode,LoanDt,CvrgOrdTp,LpYn,MgempNo,OrdAmt,BnsTpCode,SpareOrdNo,CvrgSeqno,RsvOrdNo,MnyOrdAmt,SubstOrdAmt,RuseOrdAmt,AcntNm,IsuNm
    1,22610,22609,145812530,40,00,A005930,,,,000,,,,,65000,2,0,0,0,0,0,0,김프로,삼성전자
    CSPAT00801()
    RecCnt,OrgOrdNo,AcntNo,InptPwd,IsuNo,OrdQty,CommdaCode,GrpId,StrtgCode,OrdSeqNo,PtflNo,BskNo,TrchNo,ItemNo
    1,22610,55503309601,0000,A005930,1,40,,,0,0,0,0,0
    RecCnt,OrdNo,PrntOrdNo,OrdTime,OrdMktCode,OrdPtnCode,ShtnIsuNo,PrgmOrdprcPtnCode,StslOrdprcTpCode,StslAbleYn,MgntrnCode,LoanDt,CvrgOrdTp,LpYn,MgempNo,BnsTpCode,SpareOrdNo,CvrgSeqno,RsvOrdNo,AcntNm,IsuNm
    1,22611,22609,145813279,40,00,A005930,,,,,,,,,2,0,0,0,김프로,삼성전자
  • LS증권 OPEN API > API가이드 > [주식] 계좌 > 현물계좌 잔고내역(CSPAQ12300), 주식잔고2(t0424)

  • Call the CSPAQ12300 and t0424 TR from LS Open API with request_tr_4 and oauth_3

    • CSPAQ12300 can distinguish between different accounts
    • t0424 in XingAPI includes an accno field, but this field is absent in the Open API, making it impossible to specify an account for trading instead, each account is identified by its own unique keys
  • Code : tr_stock_accno.py

    Import modules and Declare constants
    import sys
    import request_tr_4 as request_tr
    # API 요청을 위한 기본 URL 설정
    URL = "https://openapi.ls-sec.co.kr:8080/stock/accno"
    CSPAQ12300()
    def CSPAQ12300(_BalCreTp="0", _CmsnAppTpCode="0", _D2balBaseQryTp="0", _UprcTpCode="0"):
        """
        CSPAQ12300 TR 요청을 위한 함수.
    
        이 함수는 CSPAQ12300 TR에 필요한 요청 URL, 바디 및 출력 블록 태그를 설정하고 반환합니다.
        주식 계좌와 관련된 잔고 및 수수료 정보 조회에 사용됩니다.
    
        Args:
            _BalCreTp (str, optional): 잔고 구분 타입. 기본값은 '0'.
            _CmsnAppTpCode (str, optional): 수수료 적용 타입 코드. 기본값은 '0'.
            _D2balBaseQryTp (str, optional): D2잔고 기준 조회 타입. 기본값은 '0'.
            _UprcTpCode (str, optional): 단가 타입 코드. 기본값은 '0'.
    
        Returns:
            dict: CSPAQ12300 TR 요청에 필요한 정보가 담긴 딕셔너리.
        """
    
        # TR 요청을 위한 URL 설정
        _url = URL
    
        # 요청 바디 설정
        _body = {
            "t10424InBlock": {
                "BalCreTp": _BalCreTp,
                "CmsnAppTpCode": _CmsnAppTpCode,
                "D2balBaseQryTp": _D2balBaseQryTp,
                "UprcTpCode": _UprcTpCode,
            }
        }
    
        # 함수 이름으로 TR 이름 설정
        _tr_name = sys._getframe().f_code.co_name
    
        # 출력 블록 태그 (결과 데이터를 참조하기 위한 키) 설정
        _out_block_tags = []
        for i in range(1, 4):
            _out_block_tags.append(f"{_tr_name}OutBlock{i}")
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,              # 요청 URL
            'body': _body,            # 요청 바디
            'tr_name': _tr_name,      # TR 코드 이름
            'out_block_tags': _out_block_tags,  # 출력 블록 태그
            'shcode': None,           # 종목 코드 (필요시 사용)
        }
    t0424()
    def t0424(_cts_expcode=""):
        """
        t0424 TR 요청을 위한 함수.
    
        이 함수는 t0424 TR에 필요한 요청 URL, 바디 및 출력 블록 태그를 설정하고 반환합니다.
        주식 계좌와 관련된 정보 조회에 사용됩니다.
        
        Args:
            _cts_expcode (str, optional): 연속 조회를 위한 종목 코드. 기본값은 빈 문자열입니다.
    
        Returns:
            dict: t0424 TR 요청에 필요한 정보가 담긴 딕셔너리.
        """
    
        # TR 요청을 위한 URL 설정
        _url = URL
    
        # 함수 이름으로 TR 이름 설정
        _tr_name = sys._getframe().f_code.co_name
    
        # 요청 바디 설정
        _body = {
            "t10424InBlock": {
                "prcgb": "",  # 가격 구분
                "chegb": "",  # 체결 구분
                "dangb": "",  # 당일/전일 구분
                "charge": "",  # 수수료 구분
                "cts_expcode": _cts_expcode,  # 연속 조회를 위한 종목 코드
            }
        }
    
        # 출력 블록 태그 (결과 데이터를 참조하기 위한 키) 설정
        _out_block_tags = []
        for i in ["", "1"]:
            _out_block_tags.append(f"{_tr_name}OutBlock{i}")
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,              # 요청 URL
            'body': _body,            # 요청 바디
            'tr_name': _tr_name,      # TR 코드 이름
            'out_block_tags': _out_block_tags,  # 출력 블록 태그
            'shcode': None,           # 종목 코드 (필요시 사용)
        }
    Run
    if __name__ == "__main__":
        import pprint
    
        # CSPAQ12300 TR 요청을 위한 파라미터 설정 및 결과 출력
        cspaq12300_params = CSPAQ12300()
        # pprint.pprint(cspaq12300_params)
        results1 = request_tr.request_tr(cspaq12300_params, _real=False, _timeout=3)
        pprint.pprint(results1)
    
        # 결과를 CSV 파일로 저장
        request_tr.save_csv(_data_frames=results1[0], _tr_name=results1[1])
    
        # t0424 TR 요청을 위한 파라미터 설정 및 결과 출력
        t0424_params = t0424(_cts_expcode="")
        results2 = request_tr.request_tr(t0424_params, _real=False, _timeout=3)
    
        # 첫 번째 결과 블록의 첫 번째 데이터와 두 번째 데이터를 출력
        pprint.pprint(results2[0][0])
        pprint.pprint(results2[0][1])
    
        # 결과를 CSV 파일로 저장
        request_tr.save_csv(_data_frames=results2[0], _tr_name=results2[1])
  • Results

    CSPAQ12300
    RecCnt,AcntNo,Pwd,BalCreTp,CmsnAppTpCode,D2balBaseQryTp,UprcTpCode
    1,55503048401,0000,,,,
    RecCnt,BrnNm,AcntNm,MnyOrdAbleAmt,MnyoutAbleAmt,SeOrdAbleAmt,KdqOrdAbleAmt,HtsOrdAbleAmt,MgnRat100pctOrdAbleAmt,BalEvalAmt,PchsAmt,RcvblAmt,PnlRat,InvstOrgAmt,InvstPlAmt,CrdtPldgOrdAmt,Dps,D1Dps,D2Dps,OrdDt,MnyMgn,SubstMgn,SubstAmt,PrdayBuyExecAmt,PrdaySellExecAmt,CrdayBuyExecAmt,CrdaySellExecAmt,EvalPnlSum,DpsastTotamt,Evrprc,RuseAmt,EtclndAmt,PrcAdjstAmt,D1CmsnAmt,D2CmsnAmt,D1EvrTax,D2EvrTax,D1SettPrergAmt,D2SettPrergAmt,PrdayKseMnyMgn,PrdayKseSubstMgn,PrdayKseCrdtMnyMgn,PrdayKseCrdtSubstMgn,CrdayKseMnyMgn,CrdayKseSubstMgn,CrdayKseCrdtMnyMgn,CrdayKseCrdtSubstMgn,PrdayKdqMnyMgn,PrdayKdqSubstMgn,PrdayKdqCrdtMnyMgn,PrdayKdqCrdtSubstMgn,CrdayKdqMnyMgn,CrdayKdqSubstMgn,CrdayKdqCrdtMnyMgn,CrdayKdqCrdtSubstMgn,PrdayFrbrdMnyMgn,PrdayFrbrdSubstMgn,CrdayFrbrdMnyMgn,CrdayFrbrdSubstMgn,PrdayCrbmkMnyMgn,PrdayCrbmkSubstMgn,CrdayCrbmkMnyMgn,CrdayCrbmkSubstMgn,DpspdgQty,BuyAdjstAmtD2,SellAdjstAmtD2,RepayRqrdAmtD1,RepayRqrdAmtD2,LoanAmt
    1,,김프로,100000000,100000000,0,0,0,100000000,0,0,0,0.000000,0,0,0,100000000,100000000,100000000,,0,0,0,0,0,0,0,0,100000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    (No balance in the account)
    t0424
    sunamt,dtsunik,mamt,sunamt1,cts_expcode,tappamt,tdtsunik
    100000000,0,0,100000000,,0,0
    (No balance in the account)
  • LS OPEN API > API가이드 > 주식 > [주식] 종목검색 > 서버저장조건 조건검색 (t1859)

  • Call the t1866 and t1859 TR from LS Open API with request_tr_3 and oauth_3

  • Code : t1859.py

    Import modules and Declare constants
    import key
    import request_tr_3 as request_tr
    # API 요청을 위한 기본 URL 설정
    URL = "https://openapi.ls-sec.co.kr:8080/stock/item-search"
    t1866()
    def t1866(_gb="0", _cont=""):
        """
        종목 검색을 위한 t1866 TR 요청 정보를 생성하는 함수.
    
        Parameters:
            _gb (str): 검색 구분 코드 (기본값은 "0").
            _cont (str): 검색 내용 (기본값은 빈 문자열).
    
        Returns:
            dict: TR 요청에 필요한 URL, 헤더, 바디, 출력 블록 태그 등을 포함한 딕셔너리.
        """
    
        _url = URL
    
        # 요청에 필요한 헤더 설정
        _header = {
            "content-type": "application/json; charset=utf-8",
            "authorization": None,  # 인증 토큰. 이후 추가 필요
            "tr_cd": "t1866",  # TR 코드
            "tr_cont": "N",  # 연속 조회 여부
            "tr_cont_key": "",  # 연속 조회 키 (필요시 사용)
            "mac_address": ""  # MAC 주소 (필요시 사용)
        }
    
        # 요청 바디 설정
        _body = {
            "t1866InBlock": {
                "user_id": key.USER_ID,
                "gb": _gb,
                "group_name": "",
                "cont": _cont,
                "cont_key": "",
            }
        }
    
        # 출력 블록 태그 (결과 데이터를 참조하기 위한 키)
        _out_block_tag = ["OutBlock", "OutBlock1"]
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,
            'header': _header,
            'body': _body,
            'tr_name': t1866.__name__,
            'out_block_tag': _out_block_tag,
            'shcode': None,
        }
    t1859()
    def t1859(_query_index="0000"):
        """
        특정 기준에 따른 종목 리스트 조회를 위한 t1859 TR 요청 정보를 생성하는 함수.
    
        Parameters:
            _query_index (str): 조회할 기준 인덱스 (기본값은 "0000").
    
        Returns:
            dict: TR 요청에 필요한 URL, 헤더, 바디, 출력 블록 태그 등을 포함한 딕셔너리.
        """
    
        _url = URL
    
        # 요청에 필요한 헤더 설정
        _header = {
            "content-type": "application/json; charset=utf-8",
            "authorization": None,  # 인증 토큰. 이후 추가 필요
            "tr_cd": "t1859",  # TR 코드
            "tr_cont": "N",  # 연속 조회 여부
            "tr_cont_key": "",  # 연속 조회 키 (필요시 사용)
            "mac_address": ""  # MAC 주소 (필요시 사용)
        }
    
        # 요청 바디 설정
        _body = {
            "t1859InBlock": {
                "query_index": f"{key.USER_ID:8}{_query_index}",
            }
        }
    
        # 출력 블록 태그 (결과 데이터를 참조하기 위한 키)
        _out_block_tag = ["OutBlock", "OutBlock1"]
    
        # TR 요청에 필요한 정보를 딕셔너리로 반환
        return {
            'url': _url,
            'header': _header,
            'body': _body,
            'tr_name': t1859.__name__,
            'out_block_tag': _out_block_tag,
            'shcode': None,
        }
    Run
    if __name__ == "__main__":
        import pprint
    
        # t1866 TR 요청 테스트
        t1866_params = t1866()
        # pprint.pprint(t1866_params)
    
        # t1866 결과 요청 및 출력
        t1866_results = request_tr.request_tr(t1866_params, _timeout=3)
        # pprint.pprint(t1866_results[0])
        # request_tr.save_csv(_data_frames=t1866_results[0], _tr_name="t1866")
    
        # t1859 TR 요청 테스트
        t1859_results = request_tr.request_tr(t1859("0000"))
        pprint.pprint(t1859_results[0][1])
        request_tr.save_csv(_data_frames=t1859_results[0], _tr_name="t1859")
  • Results

    t1866
    result_count,cont,contkey
    4,,
    query_index,group_name,query_name
    ********0000,나의전략,데일리모멘텀
    ********0001,나의전략,ETF Trading
    ********0002,나의전략,TRIX 주봉
    ********0003,나의전략,TRIX 일봉
    t1859
    result_count,result_time,text
    8,230539,
    shcode,hname,price,sign,change,diff,volume
    295310,에이치브이엠,12700,2,1790,16.41,2256154
    228760,지노믹트리,19080,2,2440,14.66,901801
    007460,에이프로젠,1784,2,184,11.50,29403465
    249420,일동제약,18390,2,1690,10.12,2832893
    461030,아이엠비디엑스,19780,2,1730,9.58,5572316
    462350,이노스페이스,21250,2,1700,8.70,250265
    003060,에이프로젠바이오로직스,1085,2,85,8.50,4552968
    465770,STX그린로지스,12570,2,820,6.98,1046078
  • Advanced from t1716.py in 외인기관종목별동향 (t1716, 2023.07.21)
    • t1716_2.py : Change t1716()'s return type : tupledictionary
    • Import request_tr_2
  • Code and Results
    • t1716_2.py

      Code (Mainly changed part)
      def t1716(shcode = "005930", todt = "", period = 366):
          """
          ……
      
          Returns     :
              dict                    : 함수 호출 시 반환되는 값들을 딕셔너리로 묶어 반환합니다.
          """
      
          ……
      
          return {
              'url'           : _url,
              'header'        : _header,
              'body'          : _body,
              'tr_name'       : t1716.__name__,
              'out_block_tag' : _out_block_tag,
              'shcode'        : shcode
          }
      if __name__ == "__main__":
      
          ……
      
          results = t1716()                                       # 함수 호출 결과를 딕셔너리로 받음
          pprint.pprint(results)
      Results
      {'body': {'t1716InBlock': {'frggubun': '1',
                                'fromdt': '20220725',
                                'gubun': '0',
                                'orggubun': '1',
                                'prapp': 100,
                                'prgubun': '1',
                                'shcode': '005930',
                                'todt': '20230726'}},
      'header': {'authorization': None,
                  'content-type': 'application/json; charset=UTF-8',
                  'mac_address': '',
                  'tr_cd': 't1716',
                  'tr_cont': 'N',
                  'tr_cont_key': ''},
      'out_block_tag': 'OutBlock',
      'shcode': '005930',
      'tr_name': 't1716',
      'url': 'https://openapi.ebestsec.co.kr:8080/stock/frgr-itt'}
    • request_t1716.py

      Code (New)
      """
      eBest Open API / 외인기관종목별동향 (t1716) 실행
      2023.07.25
      
      이 코드는 eBest Open API에서 t1716 TR을 호출하여 주어진 종목 코드와 조회 기간에 따른 외인과 기관의 순매매 정보를 조회하고,
      이를 하나의 DataFrame으로 병합한 뒤 하나의 CSV 파일로 저장하는 작업을 수행합니다.
      
      Parameters  :
          TR_NAME (str)       : TR을 호출하는 함수의 이름으로 사용될 문자열입니다.
          shcodes (list)      : 조회할 종목 코드들이 담긴 리스트입니다.
          todts (list)        : 조회를 종료할 날짜들이 담긴 리스트입니다.
          YEARS (int)         : 조회 기간의 연도 수를 나타내는 정수입니다.
          PERIOD (int)        : 조회 기간을 나타내는 정수로, 최대 366일까지 조회가 가능합니다.
          unique_keys (list)  : 중복된 열을 제거하기 위해 사용될 DataFrame의 열 이름들이 담긴 리스트입니다.
      
      Returns     :
          None
      """
      import time
      import t1716_2 as t1716
      import request_tr_2 as request_tr
      import pandas as pd
      if __name__ == "__main__":
      
          TR_NAME = "t1716"
          shcodes = ["122630", "252670", "233740", "251340"]
          todts   = []
          YEARS   = 10
          for i in range(0, YEARS):
              todts.append(str(2022 - i) + "1231")
          PERIOD  = 366
              # It seems to have a maximum value of 366 (why not 365? considering leap years)
          unique_keys = ["shcode", "date"]                                            # to remove duplicated columns
      
          # print(todts)                                                              # Ok
      
          merged_df = pd.DataFrame()
          for shcode in shcodes:
              merged_df_2 = pd.DataFrame()
              for todt in todts:
                  results = request_tr.request_tr(t1716.t1716(shcode=shcode, todt=todt, period=PERIOD))
                  merged_df_2 = pd.concat([merged_df_2, results[0]])
                  print(f"{TR_NAME} / {shcode} 종목 / {todt} 데이터를 수신하였습니다.")
                  time.sleep(1)
              merged_df_2["shcode"] = shcode
              merged_df = pd.concat([merged_df, merged_df_2])
          merged_df.drop_duplicates(subset=unique_keys, keep='first', inplace=True)
          request_tr.save_csv(data_frame=merged_df, tr_name=TR_NAME)
      Results
      t1716 / 122630 종목 / 20221231 데이터를 수신하였습니다.
      t1716 / 122630 종목 / 20211231 데이터를 수신하였습니다.
      ……
      t1716 / 251340 종목 / 20131231 데이터를 수신하였습니다.
      파일 저장을 완료하였습니다. : Data/T1716_20230726_092217.csv
      date,close,sign,change,diff,volume,krx_0008,krx_0018,krx_0009,pgmvol,fsc_listing,fsc_sjrate,fsc_0009,gm_volume,gm_value,shcode
      20221229,12805,5,-480,-3.61,18306241,3703971,-3248809,-571027,0,56568,0.04,-171027,0,0,122630
      20221228,13285,5,-275,-2.03,16378432,2235121,-1599598,-688470,0,227595,0.16,-1088470,0,0,122630
      20221227,13560,2,185,1.38,17776955,-772417,805734,155566,0,1316065,0.91,155566,0,0,122630
      20221226,13375,3,0,0.00,10881566,-288532,-14282,294974,0,1160499,0.85,294974,0,0,122630
      ……
      20160810,9890,5,-110,-1.10,347391,41873,-41873,0,0,0,0.00,0,0,0,251340
      
  • eBest OPEN API > API 가이드 > 주식 > [주식] 외인/기관 > 외인기관종목별동향 (t1716)

  • Only save parameters, that will be called by request_tr() in Request TR (2023.07.21)

  • Code and Results

    Code : t1716.py
    """
    eBest Open API / 외인기관종목별동향 (t1716)
    2023.07.21
    
    이 코드는 eBest Open API에서 t1716 TR을 호출하기 위한 예시 코드입니다.
    t1716 TR은 주식 시장의 기관 및 외인 순매매 정보를 조회하는 TR입니다.
    """
    from datetime import datetime, timedelta
    import pytz
    def t1716(shcode = "005930", todt = "", period = 365) :
        """
        eBest Open API에서 t1716 TR을 호출하기 위한 URL, 헤더 및 바디 정보를 반환하는 함수입니다.
    
        Parameters:
            shcode (str, optional)  : 종목코드를 지정하는 매개변수입니다. 기본값은 "005930"(삼성전자)로 설정됩니다.
            todt (str, optional)    : 조회를 종료할 날짜를 지정하는 매개변수입니다. 기본값은 오늘 날짜로 설정됩니다.
            period (int, optional)  : 조회 기간을 지정하는 매개변수입니다. 기본값은 365일(1년)입니다.
    
        Returns:
            tuple                   : url, 헤더, 바디 정보, 함수 이름, 반환 데이터 태그, 종목코드를 포함하는 튜플을 반환합니다.
        """
    
        _url_base   = "https://openapi.ebestsec.co.kr:8080"
        _path       = "stock/frgr-itt"
        _url        = f"{_url_base}/{_path}"
    
        _header     = {
            "content-type"  : "application/json; charset=UTF-8",
            "authorization" : None,                             # fill in RunTR()
            "tr_cd"         : "t1716",
            "tr_cont"       : "N",
            "tr_cont_key"   : "",
            "mac_address"   : ""
        }
    
        # 시작일자와 종료일자를 YYYYMMDD 형식으로 생성하기
        _seoul_timezone = pytz.timezone('Asia/Seoul')
        _seoul_dt       = datetime.now(_seoul_timezone)
        _todt           = _seoul_dt.strftime('%Y%m%d') if todt == "" else todt
        _todt_datetime = datetime.strptime(_todt, '%Y%m%d').astimezone(_seoul_timezone)
        _fromdt = (_todt_datetime - timedelta(period)).strftime("%Y%m%d")
    
        _body           = {
            "t1716InBlock" : {
                "shcode"    : shcode,                           # 종목코드
                "gubun"     : "1",                              # 0:일간순매수 1:기간내누적순매수
                "fromdt"    : _fromdt,                          # 시작일자 : YYYYMMDD (default : 종료일자로부터 1년 전)
                "todt"      : _todt,                            # 종료일자 : YYYYMMDD
                "prapp"     : 0,                                # 프로그램매매 감산 적용율 - %단위
                "prgubun"   : "0",                              # PR적용구분(0:적용안함1:적용)
                "orggubun"  : "1",                              # 기관적용(0:미적용 1:적용)
                "frggubun"  : "1"                               # 외인적용(0:미적용 1:적용)
            }
        }
    
        _out_block_tag = "OutBlock"
    
        return _url, _header, _body, t1716.__name__, _out_block_tag, shcode
    if __name__ == "__main__":
    
        import pprint
    
        url, header, body, tr_name, out_block_tag, shcode_ = t1716()
    
        print("URL              :")
        pprint.pprint(url)
        print("\nheader           :")
        pprint.pprint(header)
        print("\nbody             :")
        pprint.pprint(body)
        print("\ntr name          :")
        pprint.pprint(tr_name)
        print("\nOutBlockTag      :")
        pprint.pprint(out_block_tag)
        print("\nshcode           :")
        pprint.pprint(shcode_)
    Results
    URL              :
    'https://openapi.ebestsec.co.kr:8080/stock/frgr-itt'
    
    header           :
    {'authorization': None,
    'content-type': 'application/json; charset=UTF-8',
    'mac_address': '',
    'tr_cd': 't1716',
    'tr_cont': 'N',
    'tr_cont_key': ''}
    
    body             :
    {'t1716InBlock': {'frggubun': '1',
                      'fromdt': '20220722',
                      'gubun': '1',
                      'orggubun': '1',
                      'prapp': 0,
                      'prgubun': '0',
                      'shcode': '005930',
                      'todt': '20230722'}}
    
    tr name          :
    't1716'
    
    OutBlockTag      :
    'OutBlock'
    
    shcode           :
    '005930'
  • eBest OPEN API > API 가이드 > 주식 > [주식] 투자정보 > 재무순위종합

  • Code and Results

    Code : T3341.py
    # import pprint
    import datetime
    import json
    import pandas as pd
    import requests
    
    import OAuth
    URL_BASE    = "https://openapi.ebestsec.co.kr:8080"
    PATH        = "stock/investinfo"
    URL         = f"{URL_BASE}/{PATH}"
    
    header      = {
        "content-type"  : "application/json; charset=UTF-8",
        "authorization" : f"Bearer {OAuth.ACCESS_TOKEN}",
        "tr_cd"         : "t3341",
        "tr_cont"       : "N",
        "tr_cont_key"   : "",
        "mac_address"   : ""
    }
    
    body       = {
        "t3341InBlock"  : {
            "gubun"     : "0",                                  # 0 : 전체
            "gubun1"    : "3",                                  # 3 : 세전계속이익증가율
            "gubun2"    : "1",                                  # 1 : 고정
            "idx"       : 0
        }
    }
    
    res = requests.post(URL, headers=header, data=json.dumps(body), timeout=1)
    # pprint.pprint(res.json())
    
    json_data = res.json()
    df = pd.json_normalize(json_data["t3341OutBlock1"])
    time_stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    df.to_csv(f'Data/T3341_{time_stamp}.csv')
    if __name__ == "__main__":
        print(df)
    Results
        rank     hname  salesgrowth  operatingincomegrowt  ordinaryincomegrowth  liabilitytoequity  enterpriseratio      eps       bps    roe  shcode    per    pbr    peg
    0      1      동양파일         4.39                -35.60               6691.58               5.29          1129.14   245.33   6145.71   4.07  228340  12.66   0.51  38.84
    1      2   감성코퍼레이션       139.90               1300.52               5433.07              64.87            13.62   168.35    568.07  37.70  036620  26.46   7.84   1.31
    2      3  선진뷰티사이언스        31.80                 47.70               3772.86             106.80           955.24  1593.39   5276.18  35.91  086710   5.72   1.73   0.52
    3      4      일신석재        84.19                371.91               3032.30             110.34            43.52    30.31    717.60   4.37  007110  42.10   1.78   0.00
    4      5    모베이스전자        17.80                169.62               2912.85             217.62           376.10    92.64   2380.49   4.08  012860  29.90   1.16   0.00
    ..   ...       ...          ...                   ...                   ...                ...              ...      ...       ...    ...     ...    ...    ...    ...
    95    96     큐에스아이       -22.75                -51.57                179.33               6.22          1685.83   711.54   8929.14   8.34  066310  15.26   1.22   5.74
    96    97   신세계 I&C        11.80                  4.35                178.53              31.66          4596.92  5253.56  23484.59  28.68  035510   2.53   0.57   1.05
    97    98        윈텍        31.57                211.76                176.70              26.46          1128.32    95.72   1228.32   8.08  320000  32.12   2.50  64.16
    98    99    한글과컴퓨터         9.40                 -3.23                176.47              21.47          2506.32  2147.60  13715.19  18.09  030520   5.83   0.91   1.60
    99   100    파크시스템스        41.89                 80.00                173.67              32.17          3336.79  3233.76  17183.96  21.40  140860  58.79  11.06   2.57
    
    [100 rows x 14 columns]
  • Advanced from Request TR 3 (2024.08.22)

    • Set _header directly in request_tr(), no longer receiving it from t****()
  • Code and Results

    request_tr_4.py (mainly changed parts)
    def request_tr(_results, _real=False, _timeout=1):
    
        ……
    
        # 요청에 필요한 정보를 설정
        _url = _results["url"]
        _tr_name = _results["tr_name"]
    
        # 헤더가 딕셔너리에 포함되어 있지 않으면 기본 헤더를 설정
        if not "_header" in _results:
            _header = {
                "content-type": "application/json; charset=utf-8",  # 콘텐츠 타입
                "authorization": None,  # OAuth 토큰 (추후 추가)
                "tr_cd": _tr_name,  # TR 코드
                "tr_cont": "N",  # 연속 조회 여부 (기본값: N)
                "tr_cont_key": "",  # 연속 조회 키 (필요시 사용)
                "mac_address": ""  # MAC 주소 (필요시 사용)
            }
        else:
            _header = _results["header"]
    
        # OAuth 토큰을 설정
        _header["authorization"] = f"Bearer {oauth.oauth(_real=_real)}"
    
        # 바디, 출력 블록 태그, 종목 코드 설정
        _body = _results["body"]
        _out_block_tags = _results["out_block_tags"]
        _shcode = _results["shcode"]
    
        ……
    if __name__ == "__main__":
        ……
        import tr_stock_accno
    
        # CSPAQ12300 TR 요청 및 결과 확인
        tr_outputs = request_tr(tr_stock_accno.CSPAQ12300())
        ……
    
        ……
    Results
    RecCnt,AcntNo,Pwd,BalCreTp,CmsnAppTpCode,D2balBaseQryTp,UprcTpCode
    1,55503048401,0000,,,,
    RecCnt,BrnNm,AcntNm,MnyOrdAbleAmt,MnyoutAbleAmt,SeOrdAbleAmt,KdqOrdAbleAmt,HtsOrdAbleAmt,MgnRat100pctOrdAbleAmt,BalEvalAmt,PchsAmt,RcvblAmt,PnlRat,InvstOrgAmt,InvstPlAmt,CrdtPldgOrdAmt,Dps,D1Dps,D2Dps,OrdDt,MnyMgn,SubstMgn,SubstAmt,PrdayBuyExecAmt,PrdaySellExecAmt,CrdayBuyExecAmt,CrdaySellExecAmt,EvalPnlSum,DpsastTotamt,Evrprc,RuseAmt,EtclndAmt,PrcAdjstAmt,D1CmsnAmt,D2CmsnAmt,D1EvrTax,D2EvrTax,D1SettPrergAmt,D2SettPrergAmt,PrdayKseMnyMgn,PrdayKseSubstMgn,PrdayKseCrdtMnyMgn,PrdayKseCrdtSubstMgn,CrdayKseMnyMgn,CrdayKseSubstMgn,CrdayKseCrdtMnyMgn,CrdayKseCrdtSubstMgn,PrdayKdqMnyMgn,PrdayKdqSubstMgn,PrdayKdqCrdtMnyMgn,PrdayKdqCrdtSubstMgn,CrdayKdqMnyMgn,CrdayKdqSubstMgn,CrdayKdqCrdtMnyMgn,CrdayKdqCrdtSubstMgn,PrdayFrbrdMnyMgn,PrdayFrbrdSubstMgn,CrdayFrbrdMnyMgn,CrdayFrbrdSubstMgn,PrdayCrbmkMnyMgn,PrdayCrbmkSubstMgn,CrdayCrbmkMnyMgn,CrdayCrbmkSubstMgn,DpspdgQty,BuyAdjstAmtD2,SellAdjstAmtD2,RepayRqrdAmtD1,RepayRqrdAmtD2,LoanAmt
    1,,김프로,100000000,100000000,0,0,0,100000000,0,0,0,0.000000,0,0,0,100000000,100000000,100000000,,0,0,0,0,0,0,0,0,100000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    (No balance in the account)
  • Advanced from Request TR 2 (2023.07.25)

    • Passed the real/mock server flag (_real) to oauth.oauth()
    • Added support for multiple t****OutBlock*
    • Added an optional _timeout parameter (int) for requests.post()
  • Code and Results

    request_tr_3.py (mainly changed parts)
    ……
    import oauth_3 as oauth
    def request_tr(_results, _real=False, _timeout=1):
    
        ……
    
        # OAuth 토큰을 헤더에 추가
        _header["authorization"] = f"Bearer {oauth.oauth(_real=_real)}"
    
        # TR 요청을 POST 방식으로 전송
        _res = requests.post(_url, headers=_header, data=json.dumps(_body), timeout=_timeout)
        ……
    
        # 결과 블록 태그가 단일 문자열인 경우 리스트로 변환
        if isinstance(_out_block_tag, str):
            _out_block_tag = [_out_block_tag]
    
        _data_frames = []
    
        # 각 블록 태그에 대해 데이터프레임 생성
        for _out_block in _out_block_tag:
            _data_frame = pd.json_normalize(_json_data[f"{_tr_name}{_out_block}"])
            _data_frames.append(_data_frame)
    
        return _data_frames, _tr_name, _shcode
    def save_csv(_data_frames, _tr_name, _shcode=""):
    
        ……
    
        # 각 데이터프레임을 CSV 파일로 저장
        for i, _data_frame in enumerate(_data_frames):
            if _shcode:
                _path = f'Data/{_tr_name.upper()}_{_shcode}_{_time_stamp}_{i}.csv'
            else:
                _path = f'Data/{_tr_name.upper()}_{_time_stamp}_{i}.csv'
    
            ……
    Results
    date,close,sign,change,diff,volume,krx_0008,krx_0018,krx_0009,pgmvol,fsc_listing,fsc_sjrate,fsc_0009,gm_volume,gm_value
    20240822,78300,3,0,0.00,8138752,152259,-937901,-175582,485762,3358830711,56.26,373805,37485,2927
    20240821,78300,5,-600,-0.76,7799774,-200013,24803,-70499,152840,3357971144,56.25,-88399,11227,878
    20240820,78900,2,600,0.77,10213542,-783354,-1060351,6133,918352,3357906703,56.25,10331,5113,405
    20240819,78300,5,-1900,-2.37,14124565,1735237,134441,-995169,-473472,3356978020,56.23,-1112469,6504,509
    20240816,80200,2,3000,3.89,20895904,-7324889,-993805,4628772,1911883,3358563961,56.26,4626870,63672,5048
    20240814,77200,2,1100,1.45,13176220,-2154441,-928285,1357217,697682,3352025208,56.15,1416317,73153,5651
    20240813,76100,2,600,0.79,10696333,-1579019,-568949,1491290,366354,3349911209,56.11,1716690,13720,1042
    20240812,75500,2,800,1.07,9629370,-539380,-431124,-69985,543883,3347828165,56.08,-216025,14656,1108
    파일 저장을 완료하였습니다. : Data/T1716_005930_20240822_220936_0.csv
  • Advanced from Request TR (2023.07.21)

    • request_tr(): Change the parameters' type : tupledictionary
    • save_csv() : Exclude pandas.DataFrame's index values when saving
  • Code and Results

    request_tr_2.py (mainly changed parts)
    def request_tr(results):
        """
        ……
    
        Parameters :
            results (dict)      : t****() 함수의 리턴값인 딕셔너리입니다.
    
        ……
        """
    
        _url            = results["url"]
        _header         = results["header"]
        _body           = results["body"]
        _tr_name        = results["tr_name"]
        _out_block_tag  = results["out_block_tag"]
        _shcode         = results["shcode"]
    
        ……
    def save_csv(data_frame, tr_name, shcode=""):
        ……
    
        ……
        data_frame.to_csv(_path, index=False)
        ……
    if __name__ == "__main__":
    
        import pprint
        import t1716_2 as t1716
    
        tr_output = request_tr(t1716.t1716(shcode="005930", period=365))             # 삼성전자, 1년치 일일 데이터
        pprint.pprint(tr_output)
        save_csv(*tr_output)
    Results
    (         date  close sign  change   diff    volume  krx_0008  krx_0018  krx_0009   pgmvol  fsc_listing fsc_sjrate  fsc_0009  gm_volume  gm_value
    0    20230726  70000    3       0   0.00         0         0         0         0        0   3165243552      53.02         0          0         0
    1    20230725  70000    5    -400  -0.57  13500986     49193    -23280   1844693  -940037   3165243552      53.02   1895393     249469     17471
    2    20230724  70400    2     100   0.14  13360061  -2249447  -2985631    576591  2421837   3164288196      53.01    582022     187872     13236
    3    20230721  70300    5    -700  -0.99  16528926   3655097   1135251  -3232093  -823435   3161284337      52.95  -2740185     690377     48199
    4    20230720  71000    5    -700  -0.98   9732730    980710  -1071133   -296382   190441   3164847957      53.01   1200568     212026     15104
    ..        ...    ...  ...     ...    ...       ...       ...       ...       ...      ...          ...        ...       ...        ...       ...
    244  20220801  61300    5    -100  -0.16  13154816    530487  -1367169    240197   313794   2974186694      49.82    -66871     186169     11311
    245  20220729  61400    5    -500  -0.81  15093120   1235234   1473091    616021 -1623959   2973939771      49.82     77992     690338     42576
    246  20220728  61900    2     100   0.16  10745302   -208569  -1255580     81602   695515   2975485738      49.84   1398272     155172      9639
    247  20220727  61800    2     100   0.16   7320997     47874     15345    620603  -330594   2973391951      49.81    930383      87069      5349
    248  20220726  61700    2     600   0.98   6597211   -549225   -534799    811790   137251   2972792162      49.80    555180      47626      2933
    
    [249 rows x 15 columns],
    't1716',
    '005930')
    파일 저장을 완료하였습니다. : Data/T1716_005930_20230726_080802.csv
  • Common functions

    • request_tr() : request <t****> tr
    • save_csv() : save data from pandas dataframe to a .csv file
  • Code and Results

    Code : request_tr.py
    """
    eBest Open API / request_tr
    2023.07.21
    
    이 코드는 eBest Open API에서 TR을 호출하여 데이터를 조회하고 CSV 파일로 저장하는 코드입니다.
    """
    import datetime
    import json
    import pytz
    import pandas as pd
    import requests
    
    import oauth2 as oauth
    def request_tr(url, header, body, tr_name, out_block_tag, shcode):
        """
        eBest Open API에서 TR을 호출하여 데이터를 조회하는 함수입니다.
    
        Parameters:
            url (str)           : API 호출을 위한 URL입니다.
            header (dict)       : API 호출에 필요한 헤더 정보가 담긴 딕셔너리입니다.
            body (dict)         : API 호출에 필요한 바디 정보가 담긴 딕셔너리입니다.
            tr_name (str)       : 함수 이름입니다.
            out_block_tag (str) : 반환 데이터의 태그입니다.
            shcode (str)        : 종목코드를 지정하는 매개변수입니다.
    
        Returns:
            pandas.DataFrame    : 조회된 데이터가 담긴 DataFrame 객체를 반환합니다.
            str                 : 함수 이름을 반환합니다.
            str                 : 종목코드를 반환합니다.
        """
    
        header["authorization"] = f"Bearer {oauth.oauth()}"
        _res = requests.post(url, headers=header, data=json.dumps(body), timeout=1)
        _json_data = _res.json()
        # print(json_data)                                                          # Ok
        # print(f"{TR_NAME}{out_block_tag}")                                        # Ok
        _data_frame = pd.json_normalize(_json_data[f"{tr_name}{out_block_tag}"])
    
        return _data_frame, tr_name, shcode
    def save_csv(data_frame, tr_name, shcode=""):
        """
        조회된 데이터를 CSV 파일로 저장하는 함수입니다.
    
        Parameters:
            data_frame (pandas.DataFrame) : 조회된 데이터가 담긴 DataFrame 객체입니다.
            tr_name (str)                 : 저장할 파일의 이름을 지정하는 매개변수입니다.
            shcode (str, optional)        : 종목코드를 지정하는 매개변수입니다. 기본값은 ""(빈 문자열)입니다.
    
        Returns:
            None
        """
    
        _seoul_timezone = pytz.timezone('Asia/Seoul')
        _time_stamp = datetime.datetime.now(_seoul_timezone).strftime("%Y%m%d_%H%M%S")
        if len(shcode) > 0:
            _path = f'Data/{tr_name.upper()}_{shcode}_{_time_stamp}.csv'
        else:
            _path = f'Data/{tr_name.upper()}_{_time_stamp}.csv'
        data_frame.to_csv(_path)
        print("파일 저장을 완료하였습니다. :", _path)
    if __name__ == "__main__":
    
        import t1716
    
        results = request_tr(*t1716.t1716(shcode="005930", period=365))             # 삼성전자, 1년치 일일 데이터
        print(results[0])
        save_csv(*results)
    Results
            date  close sign  change   diff    volume   krx_0008  krx_0018   krx_0009    pgmvol  fsc_listing fsc_sjrate   fsc_0009  gm_volume  gm_value
    0    20230721  70300    5    -700  -0.99  16528926 -135656797 -47587921  187226850  66422136   3161057429      52.95  189453121  111023539   6948297
    1    20230720  71000    5    -700  -0.98   9732730 -139311894 -47899737  191282378  67245571   3164847957      53.01  193243649  110811513   6933193
    2    20230719  71700    5    -300  -0.42  10851948 -140292604 -47019045  191388319  67055130   3163456948      52.99  191852640  110486152   6909844
    3    20230718  72000    5   -1300  -1.77  11282654 -141004884 -45818326  190916335  65954614   3163380264      52.99  191775956  110112691   6882647
    4    20230717  73300    5    -100  -0.14  10060049 -142362894 -45165996  191707382  66590493   3164885311      53.02  193281003  109698081   6852294
    ..        ...    ...  ...     ...    ...       ...        ...       ...        ...       ...          ...        ...        ...        ...       ...
    243  20220728  61900    2     100   0.16  10745302     238401  -2887326    2630540   -829418   2975485738      49.84    3881430     523771     32276
    244  20220727  61800    2     100   0.16   7320997     446970  -2327261    1853423  -1524933   2973391951      49.81    1787643     436702     26927
    245  20220726  61700    2     600   0.98   6597211     399096  -2012012    1563414  -1194339   2972792162      49.80    1187854     389076     23993
    246  20220725  61100    5    -200  -0.33   9193681     948321  -1614464     614373  -1331590   2972099731      49.79     495423     337887     20852
    247  20220722  61300    5    -500  -0.81  10261310    1022114  -1862181     739607   -342577   2972375415      49.79     771107          0         0
    
    [248 rows x 15 columns]
    파일 저장을 완료하였습니다. : Data/T1716_005930_20230722_173359.csv
  • Advanced from Oauth 2 (2023.07.21)

    • oauth_3.py
      • Added a _real parameter to distinguish between real and mock servers
      • Modified the URL string (due to the company name change)
    • key.py : Added KEY and SECRET for the real server and USER_ID for the t1859 TR
  • Code and Results

    Code : key.py (not uploaded)
    KEY = "{your app key}"
    SECRET = "{your secret key}"
    MOCK_KEY = "{your app key}"
    MOCK_SECRET = "{your secret key}"
    
    USER_ID = "{your ID}"
    Code : oauth_3.py (mainly changed parts)
    # OAuth 토큰을 요청할 기본 URL
    URL = "https://openapi.ls-sec.co.kr:8080/oauth2/token"
    def oauth(_test=False, _real=False):
    
        ……
    
        # 실서버 또는 모의서버에 따라 앱 키와 시크릿 키를 설정
        if _real is True:
            _app_key = key.KEY
            _app_secret = key.SECRET
        else:
            _app_key = key.MOCK_KEY
            _app_secret = key.MOCK_SECRET
    
        ……
    if __name__ == "__main__":
        # 테스트 모드로 OAuth 함수 호출하여 액세스 토큰과 요청/응답 데이터를 출력
        url, res, _ = oauth(_test=True)
        ……
    Results
    URL      : https://openapi.ls-sec.co.kr:8080/oauth2/token 
    
    OAuth 응답 내용:
    {'access_token': '********',
    'expires_in': 58023,
    'scope': 'oob',
    'token_type': 'Bearer'}
  • Advanced from Oauth (2023.07.11)

    • A function structure has been introduced into the same actual execution content.
  • Code and Results

    Code : key.py (not uploaded)
    • Add comments
    """
    eBest Open API / key
    2023.07.11
    
    이 파일은 eBest Open API를 사용하기 위해 필요한 애플리케이션 키와 비밀 키를 저장하는 파일입니다.
    애플리케이션 키는 API 호출에 필요한 인증을 위해 사용되며, 반드시 비밀로 유지되어야 합니다.
    따라서 이 파일은 외부에 노출되지 않도록 주의해야 합니다.
    """
    
    MOCK_KEY    = "{your app key}"
    MOCK_SECRET = "{your secret key}"
    Code : oauth2.py
    """
    eBest Open API / 접근토큰 발급 (token)
    2023.07.21
    
    이 코드는 eBest Open API 서버에 OAuth 토큰을 요청하는 함수를 포함한 코드입니다.
    OAuth 토큰은 API를 호출할 때 인증 정보로 사용되며, API 호출을 위해 반드시 필요합니다.
    
    사용 전 준비사항:
    1. eBest Open API 개발자 센터에서 앱 키와 시크릿 키를 발급받아야 합니다.
    2. key.py 파일에 발급받은 앱 키와 시크릿 키를 저장해야 합니다. (예: MOCK_KEY, MOCK_SECRET)
    
    개선사항:
    1. OAuth.py (2023.07.11)의 코드를 oauth()라는 함수로 재작성하였습니다.
    2. test 변수의 값(True/False)에 따라 return값이 달라집니다.
    """
    import pprint
    import requests
    
    import key
    def oauth(test = False):
        """
        eBest Open API 서버에 OAuth 토큰을 요청하는 함수입니다.
    
        Parameters:
            test (bool) : 테스트 모드 여부를 설정하는 매개변수입니다. 기본값은 False입니다.
    
        Returns:
            str         : 성공적으로 OAuth 토큰을 받아온 경우 해당 토큰을 반환합니다.
    
        Raises:
            requests.exceptions.RequestException : OAuth 요청 중 예외가 발생한 경우 예외를 발생시킵니다.
        """
    
        # 개발자가 발급받은 앱 키와 시크릿 키를 사용합니다.
        _app_key = key.MOCK_KEY
        _app_secret = key.MOCK_SECRET
    
        # OAuth 토큰을 요청할 API 경로를 설정합니다.
        _path = "oauth2/token"
        _url_base = "https://openapi.ebestsec.co.kr:8080"
        _url = f"{_url_base}/{_path}"
    
        # OAuth 요청에 필요한 헤더 정보를 설정합니다.
        _header = {
            "content-type": "application/x-www-form-urlencoded"
        }
    
        # OAuth 요청에 필요한 파라미터 정보를 설정합니다.
        _param = {
            "grant_type": "client_credentials",
            "appkey": _app_key,
            "appsecretkey": _app_secret,
            "scope": "oob"
        }
    
        # OAuth 요청을 실행하고 응답을 받아옵니다.
        try:
            _res = requests.post(_url, headers=_header, params=_param, timeout=1)
            _access_token = _res.json()["access_token"]
        except requests.exceptions.RequestException as _e:
            # OAuth 요청 중 예외가 발생한 경우 예외를 발생시킵니다.
            raise _e
    
        if test:
            return _url, _res, _access_token
        else:
            return _access_token
    if __name__ == "__main__":
        # OAuth 함수를 호출하여 액세스 토큰을 받아옵니다.
    
        url, res, _ = oauth(test = True)
        print("URL      :", url, "\n")                          # OAuth 토큰 요청을 보낸 URL 출력
        print("OAuth    :")
        pprint.pprint(res.json())                               # OAuth 응답 내용 출력
    Results
    URL      : https://openapi.ebestsec.co.kr:8080/oauth2/token
    
    OAuth    :
    {'access_token': '******',
    'expires_in': 50352,
    'scope': 'oob',
    'token_type': 'Bearer'}
  • Oauth; Open Authorization

  • References

  • Code and Results

    Code : Key.py (not uploaded)
    MOCK_KEY    = "{your app key}"
    MOCK_SECRET = "{your secret key}"
    Code : Oauth.py
    import pprint
    import requests
    import Key
    APP_KEY     = Key.MOCK_KEY
    APP_SECRET  = Key.MOCK_SECRET
    
    header      = {
        "content-type"  : "application/x-www-form-urlencoded"
    }
    param       = {
        "grant_type"    : "client_credentials",
        "appkey"        : APP_KEY,
        "appsecretkey"  : APP_SECRET,
        "scope"         : "oob"
    }
    
    PATH        = "oauth2/token"
    URL_BASE    = "https://openapi.ebestsec.co.kr:8080"
    URL         = f"{URL_BASE}/{PATH}"
    
    res = requests.post(URL, headers=header, params=param, timeout=1)
    ACCESS_TOKEN = res.json()["access_token"]
    if __name__ == "__main__":
        print("URL          : ", URL, "\n")                     # Ok
        print("OAuth        : ")
        pprint.pprint(res.json())                               # Ok
    Results
    URL          :  https://openapi.ebestsec.co.kr:8080/oauth2/token
    
    OAuth        :
    {'access_token': '******',
     'expires_in': 105831,
     'scope': 'oob',
     'token_type': 'Bearer'}