Skip to main content

package for XingApi(DLL,COM)

Project description

LS증권 XingAPI wrapper

This is a simple package for XingApi (DLL and COM mode).

Installation

pip install xingAsync

대체거래서 출범관련 TR변경으로 xingAsync 0.3.0 이상 사용. (2025.03.02 업데이트)

Usage

DLL, COM 모드 지원. (DLL 권장)
DLL Wrapper class: XingApi
COM Wrapper class: XingCOM
COM base classes: XASession, XAQuery, XAReal

통합샘플파일

DLL모드 XingApi 이용, DLL를 이용하기 쉽게 Wrapper

로그인/요청/실시간 조회

import asyncio
from xingAsync import XingApi, run_loop
from app_key import user_id, user_pwd, cert_pwd # app_key.py 파일에 사용자 ID, 비번, 공증 비번을 저장해두고 import

#######################################################
# DLL 이용한 XingApi 클래스 테스트
# * 가장빠름
# * 실시간 데이터 수신시 on_realtime 이벤트 처리 필요
#######################################################

async def sample(api:XingApi):
    # 로그인
    if not await api.login(user_id, user_pwd, cert_pwd):
        print(f"로그인 실패: {api.last_message}")
        return

    print(f"로그인 성공: {"모의투자" if api.is_simulation else "실투자"}")

    # 보유계좌 표시
    for x in api.accounts:
        print(x)

    # 요청 t1102: 주식 현재가(시세) 조회
    response = await api.request("t1102", {"shcode": "005930"}) # 005930: 삼성전자
    if not response:
        print(f"t1102 request failed: {api.last_message}")
        return

    # 요청 성공시, 조회된 데이터 확인
    print(f"t1102 request succeeded: {api.last_message}")
    price = response["t1102OutBlock"]["price"]
    print(f"삼성전자 현재가: {price}")

    # 추가작업
    ...

    # 실시간 시세 요청/이벤트 처리
    codes = ["005930", "000660"] # 삼성전자, SK하이닉스 실시간 체결 수신
    # codes = ["HSIG25", "HCEIG25"] # 항셍, 미니항셍 실시간 체결 수신, tr_cd: "OVC"
    if not api.realtime("S3_", codes, True):
        return print(f"실시간 요청 실패: {api.last_message}")

    print("실시간 요청 성공, 60초동안 실시간 수신...")
    await asyncio.sleep(60)

    # 실시간 해지
    api.realtime("", "", False) # 실시간 해지

def on_realtime(code: str, key: str, datas: dict):
    print(f"{code}, {key}, {datas}")


if __name__ == "__main__":
    api = XingApi()
    api.on_realtime.connect(on_realtime)
    run_loop(sample(api))

# Output:
'''
로그인 성공: 실투자
XXXXXXXXXXX 홍길동 홍길동 선물옵션
XXXXXXXXXXX 홍길동 홍길동 해외선옵
XXXXXXXXXXX 홍길동 홍길동 종합매매
t1102 request succeeded: [00000] 정상적으로 조회가 완료되었습니다.
삼성전자 현재가: 53100
실시간 요청 성공, 60초동안 실시간 수신...
S3_, 005930, {'chetime': '125618', 'sign': '2', 'change': '2000', 'drate': '3.92', 'price': '53000', 'opentime': '090010', 'open': '51600', 'hightime': '101356', 'high': '53600', 'lowtime': '090010', 'low': '51500', 'cgubun': '-', 'cvolume': '14', 'volume': '18796692', 'value': '994091', 'mdvolume': '7592337', 'mdchecnt': '46517', 'msvolume': '10388368', 'mschecnt': '59566', 'cpower': '136.83', 'w_avrg': '52886', 'offerho': '53100', 'bidho': '53000', 'status': '00', 'jnilvolume': '19530765', 'shcode': '005930'}
S3_, 000660, {'chetime': '125618', 'sign': '2', 'change': '1200', 'drate': '0.63', 'price': '192100', 'opentime': '090022', 'open': '192900', 'hightime': '101559', 'high': '194300', 'lowtime': '091001', 'low': '190100', 'cgubun': '-', 'cvolume': '1', 'volume': '4108984', 'value': '791376', 'mdvolume': '2096548', 'mdchecnt': '27010', 'msvolume': '1694527', 'mschecnt': '37787', 'cpower': '80.82', 'w_avrg': '192596', 'offerho': '192200', 'bidho': '192100', 'status': '00', 'jnilvolume': '5394963', 'shcode': '000660'}
S3_, 000660, {'chetime': '125618', 'sign': '2', 'change': '1300', 'drate': '0.68', 'price': '192200', 'opentime': '090022', 'open': '192900', 'hightime': '101559', 'high': '194300', 'lowtime': '091001', 'low': '190100', 'cgubun': '+', 'cvolume': '1', 'volume': '4108985', 'value': '791376', 'mdvolume': '2096548', 'mdchecnt': '27010', 'msvolume': '1694528', 'mschecnt': '37788', 'cpower': '80.82', 'w_avrg': '192596', 'offerho': '192200', 'bidho': '192100', 'status': '00', 'jnilvolume': '5394963', 'shcode': '000660'}
S3_, 005930, {'chetime': '125618', 'sign': '2', 'change': '2100', 'drate': '4.12', 'price': '53100', 'opentime': '090010', 'open': '51600', 'hightime': '101356', 'high': '53600', 'lowtime': '090010', 'low': '51500', 'cgubun': '+', 'cvolume': '3', 'volume': '18796695', 'value': '994091', 'mdvolume': '7592337', 'mdchecnt': '46517', 'msvolume': '10388371', 'mschecnt': '59567', 'cpower': '136.83', 'w_avrg': '52886', 'offerho': '53100', 'bidho': '53000', 'status': '00', 'jnilvolume': '19530765', 'shcode': '005930'}
S3_, 005930, {'chetime': '125618', 'sign': '2', 'change': '2100', 'drate': '4.12', 'price': '53100', 'opentime': '090010', 'open': '51600', 'hightime': '101356', 'high': '53600', 'lowtime': '090010', 'low': '51500', 'cgubun': '+', 'cvolume': '1', 'volume': '18796696', 'value': '994091', 'mdvolume': '7592337', 'mdchecnt': '46517', 'msvolume': '10388372', 'mschecnt': '59568', 'cpower': '136.83', 'w_avrg': '52886', 'offerho': '53100', 'bidho': '53000', 'status': '00', 'jnilvolume': '19530765', 'shcode': '005930'}
'''

프로퍼티/메소드/이벤트 (DLL 모드)

프로퍼티 (읽기전용)

    loaded:         # xingApi.dll 로딩 여부 (True/False), xingApi가 설치되지 않은 경우 False
    logined:        # 로그인 여부 (True/False)
    is_simulation:  # 모의투자인 경우 True, 실계좌인 경우 False
    accounts:       # 계좌목록 (list)
    last_message:   # 마지막 수신 메시지, 요청 실패시 실패사유가 저장됨

메소드

    login: # 로그인 (비동기)
        await api.login("user_id", "ser_pwd", "cert_pwd") # 모의투자인 경우 cert_pwd는 ''로 설정
        return: True/False, 로그인 성공여부, 실패시 last_message에 실패사유가 저장됨

    close: # 로그아웃
        api.close()

    request: TR 요청 (비동기)

        # t1102: 주식현재가 요청, 삼성전자 
        response = await api.request("t1102", "005930")
        # 또는 필드명을 지정하여 요청
        response = await api.request("t1102", {'shcode': '005930'})
        
        # 성공시 ResponseData 리턴, 실패시 None 리턴 (실패사유는 last_message에 저장됨)
        # 블록타입이 배열이 아닌 경우 dict 로 반환됨, 배열(occurs)인 경우 list[dict] 로 반환됨)

        # 입력은 dict, 문자열, 리스트 형태로 입력 가능
        # ex) t8407: 주식멀티현재가조회 (입력필드 2개: nrec, shcode)
        inputs = {"nrec": 2, "shcode": "005930000660"}"}    # ex1) dict로 입력
        inputs = "2,005930000660" 						    # ex2) 문자열로 입력 (',' 로 구분하여 필드 순서로 입력)
        inputs = ["2", "005930000660"] 					    # ex3) 리스트로 입력 (필드 순서로 입력)

        # 입력블록이 2개이상인 경우, 블록명을 지정하여 입력
        inputs = {
            "t1104InBlock": {
                "code": "005930",    # 종목코드
                "nrec": "4",         # 건수
                "exchgubun": "K",    # K:KRX, N:NXT, U:통합, 그외 입력값은 KRX로 처리
            },
            "t1104InBlock1": [
                {"indx": "0", "gubn": "1", "dat1": "2", "dat2": "1"}, 
                {"indx": "1", "gubn": "1", "dat1": "3", "dat2": "1"}, 
                {"indx": "2", "gubn": "4", "dat1": "1", "dat2": "5"}, 
                {"indx": "3", "gubn": "4", "dat1": "1", "dat2": "20"}, 
            ],
        }

        # t8410: 주식차트요청 (일주월분), 삼성전자
        inputs = {
            'shcode': '005930',     # 삼성전자
            'gubun': '2',           # 주기구분(2:일3:주4:월5:년)
            'qrycnt': 100,          # 요청건수(최대-압축:2000비압축:500)
            'sdate': '',            # 시작일자
            'edate': '99999999',    # 종료일자
            'cts_date': '',         # 연속일자
            'comp_yn': 'N',         # 압축여부(Y:압축N:비압축)
            'sujung': 'Y',          # 수정주가여부(Y:적용N:비적용)
        }
        response = await api.request("t8410", inputs)
        t8410OutBlock = response['t8410OutBlock']                   # t8410OutBlock 데이터 가져오기
        print(t8410OutBlock['jisiga'], t8410OutBlock['jiclose'])    # 전일시가, 전일종가 출력

        t8410OutBlock1 = response['t8410OutBlock1']                 # t8410OutBlock1 데이터 가져오기 (occurs 경우 list[dict] 로 반환됨)
        for data in t8410OutBlock1:
            print(data['date'], data['close'])                      # 날짜, 종가 출력

        # 연속조회
        if response.cont_yn:
            inputs['cts_date'] = response['cts_date']
            response = await api.request("t8410", inputs, True, response.cont_key)
            t8410OutBlock1 = response['t8410OutBlock1']
            for data in t8410OutBlock1:
                print(data['date'], data['close'])

    realtime: # 실시간 구독/해지
        realtime("S3_", "005930", True)                 # ex1): 단일종목: 삼성전자 구독
        realtime("S3_", "005930,000660", True)          # ex2): 복수종목: 삼성전자, SK하이닉스 구독
        realtime("S3_", ["005930", "000660"], True)     # ex3): 복수종목: 삼성전자, SK하이닉스 구독
        realtime("S3_", "005930", False)                # ex4): 단일종목: 삼성전자 실시간 해지
        realtime("S3_", "005930,000660", False)         # ex5): 복수종목: 삼성전자 실시간 해지
        realtime("S3_", ["005930", "000660"], False)    # ex6): 복수종목: 삼성전자 실시간 해지
        realtime("", "", False)                         # ex7): 모든 실시간 해지

    get_requests_count: TR 초당전송가능횟수, Base시간, 10분당 제한 건수, 10분내 요청 횟수 반환
        print(api.get_requests_count("t1102"))
        # (10, 1, 0, 1)

이벤트

    on_message(msg: str): # 서버 오류 또는 중복로그인 연결 끊김시 수신 (ex. 'DISCONNECT')
        ex: 'DISCONNECT'

    on_realtime(tr_cd: str, key: str, datas: dict): # 실시간 데이터 수신
        ex: 'S3_', '005930', {'chetime': '090000', 'sign': '1', 'change': 100, 'drate': 0.1, 'price': 60000, ...}

    # 이벤트 핸들러 등록
    api.on_message.connect(lambda msg: print(f'오류: {msg}'))
    api.on_realtime.connect(lambda tr_cd, key, datas: print(f'실시간: {tr_cd}, {key}, {datas}'))

COM모드 XingCOM 이용, COM객체를 이용하기 쉽게 Wrapper

로그인/요청/실시간 조회

from xingAsync import XingCOM
from app_key import user_id, user_pwd, cert_pwd # app_key.py 파일에 사용자 ID, 비번, 공증 비번을 저장해두고 import

#########################################################################################
# COM 객체 통합 Wrapper XingCOM 클래스 테스트
# * DLL모드와 인터페이스 동일 (가능한 DLL 모드 XingApi 이용 권장)
# * asyncio를 사용하지 않음, asyncio 이용 어려울 경우 사용
# * 부가서비스(t1857, ChartIndex) 실시간등록은 tr당 1개만 가능, 추가 필요시 XAQuery 이용
#########################################################################################

def sample(api:XingCOM):
    # 로그인
    if not api.login(user_id, user_pwd, cert_pwd):
        print(f"로그인 실패: {api.last_message}")
        return

    print(f"로그인 성공: {"모의투자" if api.is_simulation else "실투자"}")

    # 보유계좌 표시
    for x in api.accounts:
        print(x)

    # 요청 t1102: 주식 현재가(시세) 조회
    response = api.request("t1102", {"shcode": "005930"}) # 005930: 삼성전자
    if not response:
        print(f"t1102 request failed: {api.last_message}")
        return

    # 요청 성공시, 조회된 데이터 확인
    print(f"t1102 request succeeded: {api.last_message}")
    price = response["t1102OutBlock"]["price"]
    print(f"삼성전자 현재가: {price}")

    # 추가작업
    ...

    # 실시간 시세 요청/이벤트 처리
    codes = ["005930", "000660"] # 삼성전자, SK하이닉스 실시간 체결 수신
    # codes = ["HSIG25", "HCEIG25"] # 항셍, 미니항셍 실시간 체결 수신, tr_cd: "OVC"
    if not api.realtime("S3_", codes, True):
        return print(f"실시간 요청 실패: {api.last_message}")

def on_realtime(code: str, key: str, datas: dict):
    print(f"{code}, {key}, {datas}")


if __name__ == "__main__":
    api = XingCOM()
    api.on_realtime.connect(on_realtime)
    sample(api)
    # 실시간 데이터 수신시 메시지 루프 필요
    import pythoncom
    while True:
        pythoncom.PumpWaitingMessages()

# Output:
'''
로그인 성공: 실투자
XXXXXXXXXXX 홍길동 홍길동 선물옵션
XXXXXXXXXXX 홍길동 홍길동 해외선옵
XXXXXXXXXXX 홍길동 홍길동 종합매매
t1102 request succeeded: [00000] 정상적으로 조회가 완료되었습니다.
삼성전자 현재가: 53100
S3_, 005930, {'chetime': '125618', 'sign': '2', 'change': '2000', 'drate': '3.92', 'price': '53000', 'opentime': '090010', 'open': '51600', 'hightime': '101356', 'high': '53600', 'lowtime': '090010', 'low': '51500', 'cgubun': '-', 'cvolume': '14', 'volume': '18796692', 'value': '994091', 'mdvolume': '7592337', 'mdchecnt': '46517', 'msvolume': '10388368', 'mschecnt': '59566', 'cpower': '136.83', 'w_avrg': '52886', 'offerho': '53100', 'bidho': '53000', 'status': '00', 'jnilvolume': '19530765', 'shcode': '005930'}
S3_, 000660, {'chetime': '125618', 'sign': '2', 'change': '1200', 'drate': '0.63', 'price': '192100', 'opentime': '090022', 'open': '192900', 'hightime': '101559', 'high': '194300', 'lowtime': '091001', 'low': '190100', 'cgubun': '-', 'cvolume': '1', 'volume': '4108984', 'value': '791376', 'mdvolume': '2096548', 'mdchecnt': '27010', 'msvolume': '1694527', 'mschecnt': '37787', 'cpower': '80.82', 'w_avrg': '192596', 'offerho': '192200', 'bidho': '192100', 'status': '00', 'jnilvolume': '5394963', 'shcode': '000660'}
S3_, 000660, {'chetime': '125618', 'sign': '2', 'change': '1300', 'drate': '0.68', 'price': '192200', 'opentime': '090022', 'open': '192900', 'hightime': '101559', 'high': '194300', 'lowtime': '091001', 'low': '190100', 'cgubun': '+', 'cvolume': '1', 'volume': '4108985', 'value': '791376', 'mdvolume': '2096548', 'mdchecnt': '27010', 'msvolume': '1694528', 'mschecnt': '37788', 'cpower': '80.82', 'w_avrg': '192596', 'offerho': '192200', 'bidho': '192100', 'status': '00', 'jnilvolume': '5394963', 'shcode': '000660'}
S3_, 005930, {'chetime': '125618', 'sign': '2', 'change': '2100', 'drate': '4.12', 'price': '53100', 'opentime': '090010', 'open': '51600', 'hightime': '101356', 'high': '53600', 'lowtime': '090010', 'low': '51500', 'cgubun': '+', 'cvolume': '3', 'volume': '18796695', 'value': '994091', 'mdvolume': '7592337', 'mdchecnt': '46517', 'msvolume': '10388371', 'mschecnt': '59567', 'cpower': '136.83', 'w_avrg': '52886', 'offerho': '53100', 'bidho': '53000', 'status': '00', 'jnilvolume': '19530765', 'shcode': '005930'}
S3_, 005930, {'chetime': '125618', 'sign': '2', 'change': '2100', 'drate': '4.12', 'price': '53100', 'opentime': '090010', 'open': '51600', 'hightime': '101356', 'high': '53600', 'lowtime': '090010', 'low': '51500', 'cgubun': '+', 'cvolume': '1', 'volume': '18796696', 'value': '994091', 'mdvolume': '7592337', 'mdchecnt': '46517', 'msvolume': '10388372', 'mschecnt': '59568', 'cpower': '136.83', 'w_avrg': '52886', 'offerho': '53100', 'bidho': '53000', 'status': '00', 'jnilvolume': '19530765', 'shcode': '005930'}
...
'''

COM 기본모드 XASession, XAQuery, XAReal 이용

로그인/요청/실시간 조회

from xingAsync import XASession, XAQuery, XAReal
from app_key import user_id, user_pwd, cert_pwd # app_key.py 파일에 사용자 ID, 비번, 공증 비번을 저장해두고 import

##########################################################################################################
# COM 객체 XASession, XAQuery, XAReal 테스트
# * asyncio를 사용하지 않음, asyncio 이용 어려울 경우 사용 (가능한 DLL 모드 XingApi 이용 권장)
# * Res파일 경로 설정 필요없음
# * OnLogin, OnReceiveData 이벤트 처리 필요없음, 실시간 데이터 수신시 OnReceiveRealData 이벤트 처리 필요
##########################################################################################################

def sample():
    # 로그인
    session = XASession()
    session.ConnectServer("api.ls-sec.co.kr", 20001)
    if not session.Login(user_id, user_pwd, cert_pwd, 0, 0):
        print(f"로그인 실패: {session.last_message}")
        return

    print(f"로그인 성공: {session.last_message}")

    # 보유계좌 표시
    acc_count = session.GetAccountListCount()
    print(f"Account List Count: {acc_count}")
    for i in range(acc_count):
        acc_num = session.GetAccountList(i)
        acc_name = session.GetAccountName(acc_num)
        acc_detail = session.GetAcctDetailName(acc_num)
        print(f"{acc_num} {acc_name} {acc_detail}")

    # 요청 t1102: 주식 현재가(시세) 조회
    query = XAQuery("t1102")
    query.SetFieldData("t1102InBlock", "shcode", 0, "005930") # 005930: 삼성전자
    ret = query.Request(False)
    if ret < 0:
        print(f"t1102 request failed: {query.last_message}")
        return

    # 요청 성공시, 조회된 데이터 확인
    print(f"t1102 request succeeded: {query.last_message}")
    price = query.GetFieldData('t1102OutBlock', 'price', 0)
    print(f"삼성전자 현재가: {price}")

    # 추가작업
    ...

    # 실시간 시세 요청/이벤트 처리
    real = XAReal("S3_")
    real.OnReceiveRealData = lambda code: print(f"RealData: {code}")
    real.SetFieldData("InBlock", "shcode", "005930")
    real.AdviseRealData()


if __name__ == "__main__":
    sample()
    # 실시간 데이터 수신시 메시지 루프 필요
    import pythoncom
    while True:
        pythoncom.PumpWaitingMessages()

# Output:
'''
로그인 성공: [0000] 로그인 성공
Account List Count: 3
XXXXXXXXXXX 홍길동 선물옵션
XXXXXXXXXXX 홍길동 해외선옵
XXXXXXXXXXX 홍길동 종합매매
t1102 request succeeded: [00000] 정상적으로 조회가 완료되었습니다.
삼성전자 현재가: 51000
RealData: S3_
RealData: S3_
RealData: S3_
...
'''

XASession, XAQuery, XAReal 클래스 사용법

LS증권 COM 개발가이드 참조: LS증권 COM 개발가이드

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xingasync-0.3.0-py3-none-any.whl (305.9 kB view details)

Uploaded Python 3

File details

Details for the file xingasync-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: xingasync-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 305.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.4

File hashes

Hashes for xingasync-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ecdec1bb5f7f5dda1ce8100dd2562c7a285af543ead0fd559cfbe41506b9a189
MD5 59ba8c9e9032380abec10261d5bbd238
BLAKE2b-256 1b1aef108e82ffa5304d03a713f53703174678e095c0ef87dc20180dcd26663a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page