xingAsync


NamexingAsync JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
Summarypackage for XingApi(DLL,COM)
upload_time2025-02-04 15:07:45
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords xingapi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # LS증권 XingAPI wrapper

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

## Installation

```bash
pip install xingAsync
```

## Usage
DLL, COM 모드 지원. (DLL 권장)<br/>
DLL Wrapper class: XingApi<br/>
COM Wrapper class: XingCOM<br/>
COM base classes: XASession, XAQuery, XAReal<br/>

### 통합샘플파일
- [test/sample_XingApi.py](test/sample_XingApi.py): DLL모드 XingApi 이용 샘플
- [test/sample_XingCOM.py](test/sample_XingCOM.py): COM모드 XingCOM 이용 샘플

## DLL모드 XingApi 이용, DLL를 이용하기 쉽게 Wrapper
### 로그인/요청/실시간 조회
```python
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 모드)

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

### 메소드
```python
    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",         # 건수
            },
            "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)
```

### 이벤트
```python
    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
### 로그인/요청/실시간 조회
```python
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 이용
### 로그인/요청/실시간 조회
```python
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 개발가이드](https://www.ls-sec.co.kr/apiguide/guide.jsp?cno=100)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "xingAsync",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "xingapi",
    "author": null,
    "author_email": "teranum <teranum@gmail.com>",
    "download_url": null,
    "platform": null,
    "description": "# LS\uc99d\uad8c XingAPI wrapper\n\nThis is a simple package for XingApi (DLL and COM mode).\n\n## Installation\n\n```bash\npip install xingAsync\n```\n\n## Usage\nDLL, COM \ubaa8\ub4dc \uc9c0\uc6d0. (DLL \uad8c\uc7a5)<br/>\nDLL Wrapper class: XingApi<br/>\nCOM Wrapper class: XingCOM<br/>\nCOM base classes: XASession, XAQuery, XAReal<br/>\n\n### \ud1b5\ud569\uc0d8\ud50c\ud30c\uc77c\n- [test/sample_XingApi.py](test/sample_XingApi.py): DLL\ubaa8\ub4dc XingApi \uc774\uc6a9 \uc0d8\ud50c\n- [test/sample_XingCOM.py](test/sample_XingCOM.py): COM\ubaa8\ub4dc XingCOM \uc774\uc6a9 \uc0d8\ud50c\n\n## DLL\ubaa8\ub4dc XingApi \uc774\uc6a9, DLL\ub97c \uc774\uc6a9\ud558\uae30 \uc27d\uac8c Wrapper\n### \ub85c\uadf8\uc778/\uc694\uccad/\uc2e4\uc2dc\uac04 \uc870\ud68c\n```python\nimport asyncio\nfrom xingAsync import XingApi, run_loop\nfrom app_key import user_id, user_pwd, cert_pwd # app_key.py \ud30c\uc77c\uc5d0 \uc0ac\uc6a9\uc790 ID, \ube44\ubc88, \uacf5\uc99d \ube44\ubc88\uc744 \uc800\uc7a5\ud574\ub450\uace0 import\n\n#######################################################\n# DLL \uc774\uc6a9\ud55c XingApi \ud074\ub798\uc2a4 \ud14c\uc2a4\ud2b8\n# * \uac00\uc7a5\ube60\ub984\n# * \uc2e4\uc2dc\uac04 \ub370\uc774\ud130 \uc218\uc2e0\uc2dc on_realtime \uc774\ubca4\ud2b8 \ucc98\ub9ac \ud544\uc694\n#######################################################\n\nasync def sample(api:XingApi):\n    # \ub85c\uadf8\uc778\n    if not await api.login(user_id, user_pwd, cert_pwd):\n        print(f\"\ub85c\uadf8\uc778 \uc2e4\ud328: {api.last_message}\")\n        return\n\n    print(f\"\ub85c\uadf8\uc778 \uc131\uacf5: {\"\ubaa8\uc758\ud22c\uc790\" if api.is_simulation else \"\uc2e4\ud22c\uc790\"}\")\n\n    # \ubcf4\uc720\uacc4\uc88c \ud45c\uc2dc\n    for x in api.accounts:\n        print(x)\n\n    # \uc694\uccad t1102: \uc8fc\uc2dd \ud604\uc7ac\uac00(\uc2dc\uc138) \uc870\ud68c\n    response = await api.request(\"t1102\", {\"shcode\": \"005930\"}) # 005930: \uc0bc\uc131\uc804\uc790\n    if not response:\n        print(f\"t1102 request failed: {api.last_message}\")\n        return\n\n    # \uc694\uccad \uc131\uacf5\uc2dc, \uc870\ud68c\ub41c \ub370\uc774\ud130 \ud655\uc778\n    print(f\"t1102 request succeeded: {api.last_message}\")\n    price = response[\"t1102OutBlock\"][\"price\"]\n    print(f\"\uc0bc\uc131\uc804\uc790 \ud604\uc7ac\uac00: {price}\")\n\n    # \ucd94\uac00\uc791\uc5c5\n    ...\n\n    # \uc2e4\uc2dc\uac04 \uc2dc\uc138 \uc694\uccad/\uc774\ubca4\ud2b8 \ucc98\ub9ac\n    codes = [\"005930\", \"000660\"] # \uc0bc\uc131\uc804\uc790, SK\ud558\uc774\ub2c9\uc2a4 \uc2e4\uc2dc\uac04 \uccb4\uacb0 \uc218\uc2e0\n    # codes = [\"HSIG25\", \"HCEIG25\"] # \ud56d\uc14d, \ubbf8\ub2c8\ud56d\uc14d \uc2e4\uc2dc\uac04 \uccb4\uacb0 \uc218\uc2e0, tr_cd: \"OVC\"\n    if not api.realtime(\"S3_\", codes, True):\n        return print(f\"\uc2e4\uc2dc\uac04 \uc694\uccad \uc2e4\ud328: {api.last_message}\")\n\n    print(\"\uc2e4\uc2dc\uac04 \uc694\uccad \uc131\uacf5, 60\ucd08\ub3d9\uc548 \uc2e4\uc2dc\uac04 \uc218\uc2e0...\")\n    await asyncio.sleep(60)\n\n    # \uc2e4\uc2dc\uac04 \ud574\uc9c0\n    api.realtime(\"\", \"\", False) # \uc2e4\uc2dc\uac04 \ud574\uc9c0\n\ndef on_realtime(code: str, key: str, datas: dict):\n    print(f\"{code}, {key}, {datas}\")\n\n\nif __name__ == \"__main__\":\n    api = XingApi()\n    api.on_realtime.connect(on_realtime)\n    run_loop(sample(api))\n\n# Output:\n'''\n\ub85c\uadf8\uc778 \uc131\uacf5: \uc2e4\ud22c\uc790\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud64d\uae38\ub3d9 \uc120\ubb3c\uc635\uc158\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud64d\uae38\ub3d9 \ud574\uc678\uc120\uc635\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud64d\uae38\ub3d9 \uc885\ud569\ub9e4\ub9e4\nt1102 request succeeded: [00000] \uc815\uc0c1\uc801\uc73c\ub85c \uc870\ud68c\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\uc0bc\uc131\uc804\uc790 \ud604\uc7ac\uac00: 53100\n\uc2e4\uc2dc\uac04 \uc694\uccad \uc131\uacf5, 60\ucd08\ub3d9\uc548 \uc2e4\uc2dc\uac04 \uc218\uc2e0...\nS3_, 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'}\nS3_, 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'}\nS3_, 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'}\nS3_, 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'}\nS3_, 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'}\n'''\n```\n\n## \ud504\ub85c\ud37c\ud2f0/\uba54\uc18c\ub4dc/\uc774\ubca4\ud2b8 (DLL \ubaa8\ub4dc)\n\n### \ud504\ub85c\ud37c\ud2f0 (\uc77d\uae30\uc804\uc6a9)\n```python\n    loaded:         # xingApi.dll \ub85c\ub529 \uc5ec\ubd80 (True/False), xingApi\uac00 \uc124\uce58\ub418\uc9c0 \uc54a\uc740 \uacbd\uc6b0 False\n    logined:        # \ub85c\uadf8\uc778 \uc5ec\ubd80 (True/False)\n    is_simulation:  # \ubaa8\uc758\ud22c\uc790\uc778 \uacbd\uc6b0 True, \uc2e4\uacc4\uc88c\uc778 \uacbd\uc6b0 False\n    accounts:       # \uacc4\uc88c\ubaa9\ub85d (list)\n    last_message:   # \ub9c8\uc9c0\ub9c9 \uc218\uc2e0 \uba54\uc2dc\uc9c0, \uc694\uccad \uc2e4\ud328\uc2dc \uc2e4\ud328\uc0ac\uc720\uac00 \uc800\uc7a5\ub428\n```\n\n### \uba54\uc18c\ub4dc\n```python\n    login: # \ub85c\uadf8\uc778 (\ube44\ub3d9\uae30)\n        await api.login(\"user_id\", \"ser_pwd\", \"cert_pwd\") # \ubaa8\uc758\ud22c\uc790\uc778 \uacbd\uc6b0 cert_pwd\ub294 ''\ub85c \uc124\uc815\n        return: True/False, \ub85c\uadf8\uc778 \uc131\uacf5\uc5ec\ubd80, \uc2e4\ud328\uc2dc last_message\uc5d0 \uc2e4\ud328\uc0ac\uc720\uac00 \uc800\uc7a5\ub428\n\n    close: # \ub85c\uadf8\uc544\uc6c3\n        api.close()\n\n    request: TR \uc694\uccad (\ube44\ub3d9\uae30)\n\n        # t1102: \uc8fc\uc2dd\ud604\uc7ac\uac00 \uc694\uccad, \uc0bc\uc131\uc804\uc790 \n        response = await api.request(\"t1102\", \"005930\")\n        # \ub610\ub294 \ud544\ub4dc\uba85\uc744 \uc9c0\uc815\ud558\uc5ec \uc694\uccad\n        response = await api.request(\"t1102\", {'shcode': '005930'})\n        \n        # \uc131\uacf5\uc2dc ResponseData \ub9ac\ud134, \uc2e4\ud328\uc2dc None \ub9ac\ud134 (\uc2e4\ud328\uc0ac\uc720\ub294 last_message\uc5d0 \uc800\uc7a5\ub428)\n        # \ube14\ub85d\ud0c0\uc785\uc774 \ubc30\uc5f4\uc774 \uc544\ub2cc \uacbd\uc6b0 dict \ub85c \ubc18\ud658\ub428, \ubc30\uc5f4(occurs)\uc778 \uacbd\uc6b0 list[dict] \ub85c \ubc18\ud658\ub428)\n\n        # \uc785\ub825\uc740 dict, \ubb38\uc790\uc5f4, \ub9ac\uc2a4\ud2b8 \ud615\ud0dc\ub85c \uc785\ub825 \uac00\ub2a5\n        # ex) t8407: \uc8fc\uc2dd\uba40\ud2f0\ud604\uc7ac\uac00\uc870\ud68c (\uc785\ub825\ud544\ub4dc 2\uac1c: nrec, shcode)\n        inputs = {\"nrec\": 2, \"shcode\": \"005930000660\"}\"}    # ex1) dict\ub85c \uc785\ub825\n        inputs = \"2,005930000660\" \t\t\t\t\t\t    # ex2) \ubb38\uc790\uc5f4\ub85c \uc785\ub825 (',' \ub85c \uad6c\ubd84\ud558\uc5ec \ud544\ub4dc \uc21c\uc11c\ub85c \uc785\ub825)\n        inputs = [\"2\", \"005930000660\"] \t\t\t\t\t    # ex3) \ub9ac\uc2a4\ud2b8\ub85c \uc785\ub825 (\ud544\ub4dc \uc21c\uc11c\ub85c \uc785\ub825)\n\n        # \uc785\ub825\ube14\ub85d\uc774 2\uac1c\uc774\uc0c1\uc778 \uacbd\uc6b0, \ube14\ub85d\uba85\uc744 \uc9c0\uc815\ud558\uc5ec \uc785\ub825\n        inputs = {\n            \"t1104InBlock\": {\n                \"code\": \"005930\",    # \uc885\ubaa9\ucf54\ub4dc\n                \"nrec\": \"4\",         # \uac74\uc218\n            },\n            \"t1104InBlock1\": [\n                {\"indx\": \"0\", \"gubn\": \"1\", \"dat1\": \"2\", \"dat2\": \"1\"}, \n                {\"indx\": \"1\", \"gubn\": \"1\", \"dat1\": \"3\", \"dat2\": \"1\"}, \n                {\"indx\": \"2\", \"gubn\": \"4\", \"dat1\": \"1\", \"dat2\": \"5\"}, \n                {\"indx\": \"3\", \"gubn\": \"4\", \"dat1\": \"1\", \"dat2\": \"20\"}, \n            ],\n        }\n\n        # t8410: \uc8fc\uc2dd\ucc28\ud2b8\uc694\uccad (\uc77c\uc8fc\uc6d4\ubd84), \uc0bc\uc131\uc804\uc790\n        inputs = {\n            'shcode': '005930',     # \uc0bc\uc131\uc804\uc790\n            'gubun': '2',           # \uc8fc\uae30\uad6c\ubd84(2:\uc77c3:\uc8fc4:\uc6d45:\ub144)\n            'qrycnt': 100,          # \uc694\uccad\uac74\uc218(\ucd5c\ub300-\uc555\ucd95:2000\ube44\uc555\ucd95:500)\n            'sdate': '',            # \uc2dc\uc791\uc77c\uc790\n            'edate': '99999999',    # \uc885\ub8cc\uc77c\uc790\n            'cts_date': '',         # \uc5f0\uc18d\uc77c\uc790\n            'comp_yn': 'N',         # \uc555\ucd95\uc5ec\ubd80(Y:\uc555\ucd95N:\ube44\uc555\ucd95)\n            'sujung': 'Y',          # \uc218\uc815\uc8fc\uac00\uc5ec\ubd80(Y:\uc801\uc6a9N:\ube44\uc801\uc6a9)\n        }\n        response = await api.request(\"t8410\", inputs)\n        t8410OutBlock = response['t8410OutBlock']                   # t8410OutBlock \ub370\uc774\ud130 \uac00\uc838\uc624\uae30\n        print(t8410OutBlock['jisiga'], t8410OutBlock['jiclose'])    # \uc804\uc77c\uc2dc\uac00, \uc804\uc77c\uc885\uac00 \ucd9c\ub825\n\n        t8410OutBlock1 = response['t8410OutBlock1']                 # t8410OutBlock1 \ub370\uc774\ud130 \uac00\uc838\uc624\uae30 (occurs \uacbd\uc6b0 list[dict] \ub85c \ubc18\ud658\ub428)\n        for data in t8410OutBlock1:\n            print(data['date'], data['close'])                      # \ub0a0\uc9dc, \uc885\uac00 \ucd9c\ub825\n\n        # \uc5f0\uc18d\uc870\ud68c\n        if response.cont_yn:\n            inputs['cts_date'] = response['cts_date']\n            response = await api.request(\"t8410\", inputs, True, response.cont_key)\n            t8410OutBlock1 = response['t8410OutBlock1']\n            for data in t8410OutBlock1:\n                print(data['date'], data['close'])\n\n    realtime: # \uc2e4\uc2dc\uac04 \uad6c\ub3c5/\ud574\uc9c0\n        realtime(\"S3_\", \"005930\", True)                 # ex1): \ub2e8\uc77c\uc885\ubaa9: \uc0bc\uc131\uc804\uc790 \uad6c\ub3c5\n        realtime(\"S3_\", \"005930,000660\", True)          # ex2): \ubcf5\uc218\uc885\ubaa9: \uc0bc\uc131\uc804\uc790, SK\ud558\uc774\ub2c9\uc2a4 \uad6c\ub3c5\n        realtime(\"S3_\", [\"005930\", \"000660\"], True)     # ex3): \ubcf5\uc218\uc885\ubaa9: \uc0bc\uc131\uc804\uc790, SK\ud558\uc774\ub2c9\uc2a4 \uad6c\ub3c5\n        realtime(\"S3_\", \"005930\", False)                # ex4): \ub2e8\uc77c\uc885\ubaa9: \uc0bc\uc131\uc804\uc790 \uc2e4\uc2dc\uac04 \ud574\uc9c0\n        realtime(\"S3_\", \"005930,000660\", False)         # ex5): \ubcf5\uc218\uc885\ubaa9: \uc0bc\uc131\uc804\uc790 \uc2e4\uc2dc\uac04 \ud574\uc9c0\n        realtime(\"S3_\", [\"005930\", \"000660\"], False)    # ex6): \ubcf5\uc218\uc885\ubaa9: \uc0bc\uc131\uc804\uc790 \uc2e4\uc2dc\uac04 \ud574\uc9c0\n        realtime(\"\", \"\", False)                         # ex7): \ubaa8\ub4e0 \uc2e4\uc2dc\uac04 \ud574\uc9c0\n\n    get_requests_count: TR \ucd08\ub2f9\uc804\uc1a1\uac00\ub2a5\ud69f\uc218, Base\uc2dc\uac04, 10\ubd84\ub2f9 \uc81c\ud55c \uac74\uc218, 10\ubd84\ub0b4 \uc694\uccad \ud69f\uc218 \ubc18\ud658\n        print(api.get_requests_count(\"t1102\"))\n        # (10, 1, 0, 1)\n```\n\n### \uc774\ubca4\ud2b8\n```python\n    on_message(msg: str): # \uc11c\ubc84 \uc624\ub958 \ub610\ub294 \uc911\ubcf5\ub85c\uadf8\uc778 \uc5f0\uacb0 \ub04a\uae40\uc2dc \uc218\uc2e0 (ex. 'DISCONNECT')\n        ex: 'DISCONNECT'\n\n    on_realtime(tr_cd: str, key: str, datas: dict): # \uc2e4\uc2dc\uac04 \ub370\uc774\ud130 \uc218\uc2e0\n        ex: 'S3_', '005930', {'chetime': '090000', 'sign': '1', 'change': 100, 'drate': 0.1, 'price': 60000, ...}\n\n    # \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec \ub4f1\ub85d\n    api.on_message.connect(lambda msg: print(f'\uc624\ub958: {msg}'))\n    api.on_realtime.connect(lambda tr_cd, key, datas: print(f'\uc2e4\uc2dc\uac04: {tr_cd}, {key}, {datas}'))\n```\n\n\n## COM\ubaa8\ub4dc XingCOM \uc774\uc6a9, COM\uac1d\uccb4\ub97c \uc774\uc6a9\ud558\uae30 \uc27d\uac8c Wrapper\n### \ub85c\uadf8\uc778/\uc694\uccad/\uc2e4\uc2dc\uac04 \uc870\ud68c\n```python\nfrom xingAsync import XingCOM\nfrom app_key import user_id, user_pwd, cert_pwd # app_key.py \ud30c\uc77c\uc5d0 \uc0ac\uc6a9\uc790 ID, \ube44\ubc88, \uacf5\uc99d \ube44\ubc88\uc744 \uc800\uc7a5\ud574\ub450\uace0 import\n\n#########################################################################################\n# COM \uac1d\uccb4 \ud1b5\ud569 Wrapper XingCOM \ud074\ub798\uc2a4 \ud14c\uc2a4\ud2b8\n# * DLL\ubaa8\ub4dc\uc640 \uc778\ud130\ud398\uc774\uc2a4 \ub3d9\uc77c (\uac00\ub2a5\ud55c DLL \ubaa8\ub4dc XingApi \uc774\uc6a9 \uad8c\uc7a5)\n# * asyncio\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc74c, asyncio \uc774\uc6a9 \uc5b4\ub824\uc6b8 \uacbd\uc6b0 \uc0ac\uc6a9\n# * \ubd80\uac00\uc11c\ube44\uc2a4(t1857, ChartIndex) \uc2e4\uc2dc\uac04\ub4f1\ub85d\uc740 tr\ub2f9 1\uac1c\ub9cc \uac00\ub2a5, \ucd94\uac00 \ud544\uc694\uc2dc XAQuery \uc774\uc6a9\n#########################################################################################\n\ndef sample(api:XingCOM):\n    # \ub85c\uadf8\uc778\n    if not api.login(user_id, user_pwd, cert_pwd):\n        print(f\"\ub85c\uadf8\uc778 \uc2e4\ud328: {api.last_message}\")\n        return\n\n    print(f\"\ub85c\uadf8\uc778 \uc131\uacf5: {\"\ubaa8\uc758\ud22c\uc790\" if api.is_simulation else \"\uc2e4\ud22c\uc790\"}\")\n\n    # \ubcf4\uc720\uacc4\uc88c \ud45c\uc2dc\n    for x in api.accounts:\n        print(x)\n\n    # \uc694\uccad t1102: \uc8fc\uc2dd \ud604\uc7ac\uac00(\uc2dc\uc138) \uc870\ud68c\n    response = api.request(\"t1102\", {\"shcode\": \"005930\"}) # 005930: \uc0bc\uc131\uc804\uc790\n    if not response:\n        print(f\"t1102 request failed: {api.last_message}\")\n        return\n\n    # \uc694\uccad \uc131\uacf5\uc2dc, \uc870\ud68c\ub41c \ub370\uc774\ud130 \ud655\uc778\n    print(f\"t1102 request succeeded: {api.last_message}\")\n    price = response[\"t1102OutBlock\"][\"price\"]\n    print(f\"\uc0bc\uc131\uc804\uc790 \ud604\uc7ac\uac00: {price}\")\n\n    # \ucd94\uac00\uc791\uc5c5\n    ...\n\n    # \uc2e4\uc2dc\uac04 \uc2dc\uc138 \uc694\uccad/\uc774\ubca4\ud2b8 \ucc98\ub9ac\n    codes = [\"005930\", \"000660\"] # \uc0bc\uc131\uc804\uc790, SK\ud558\uc774\ub2c9\uc2a4 \uc2e4\uc2dc\uac04 \uccb4\uacb0 \uc218\uc2e0\n    # codes = [\"HSIG25\", \"HCEIG25\"] # \ud56d\uc14d, \ubbf8\ub2c8\ud56d\uc14d \uc2e4\uc2dc\uac04 \uccb4\uacb0 \uc218\uc2e0, tr_cd: \"OVC\"\n    if not api.realtime(\"S3_\", codes, True):\n        return print(f\"\uc2e4\uc2dc\uac04 \uc694\uccad \uc2e4\ud328: {api.last_message}\")\n\ndef on_realtime(code: str, key: str, datas: dict):\n    print(f\"{code}, {key}, {datas}\")\n\n\nif __name__ == \"__main__\":\n    api = XingCOM()\n    api.on_realtime.connect(on_realtime)\n    sample(api)\n    # \uc2e4\uc2dc\uac04 \ub370\uc774\ud130 \uc218\uc2e0\uc2dc \uba54\uc2dc\uc9c0 \ub8e8\ud504 \ud544\uc694\n    import pythoncom\n    while True:\n        pythoncom.PumpWaitingMessages()\n\n# Output:\n'''\n\ub85c\uadf8\uc778 \uc131\uacf5: \uc2e4\ud22c\uc790\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud64d\uae38\ub3d9 \uc120\ubb3c\uc635\uc158\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud64d\uae38\ub3d9 \ud574\uc678\uc120\uc635\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud64d\uae38\ub3d9 \uc885\ud569\ub9e4\ub9e4\nt1102 request succeeded: [00000] \uc815\uc0c1\uc801\uc73c\ub85c \uc870\ud68c\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\uc0bc\uc131\uc804\uc790 \ud604\uc7ac\uac00: 53100\nS3_, 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'}\nS3_, 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'}\nS3_, 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'}\nS3_, 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'}\nS3_, 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'}\n...\n'''\n```\n\n\n## COM \uae30\ubcf8\ubaa8\ub4dc XASession, XAQuery, XAReal \uc774\uc6a9\n### \ub85c\uadf8\uc778/\uc694\uccad/\uc2e4\uc2dc\uac04 \uc870\ud68c\n```python\nfrom xingAsync import XASession, XAQuery, XAReal\nfrom app_key import user_id, user_pwd, cert_pwd # app_key.py \ud30c\uc77c\uc5d0 \uc0ac\uc6a9\uc790 ID, \ube44\ubc88, \uacf5\uc99d \ube44\ubc88\uc744 \uc800\uc7a5\ud574\ub450\uace0 import\n\n##########################################################################################################\n# COM \uac1d\uccb4 XASession, XAQuery, XAReal \ud14c\uc2a4\ud2b8\n# * asyncio\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc74c, asyncio \uc774\uc6a9 \uc5b4\ub824\uc6b8 \uacbd\uc6b0 \uc0ac\uc6a9 (\uac00\ub2a5\ud55c DLL \ubaa8\ub4dc XingApi \uc774\uc6a9 \uad8c\uc7a5)\n# * Res\ud30c\uc77c \uacbd\ub85c \uc124\uc815 \ud544\uc694\uc5c6\uc74c\n# * OnLogin, OnReceiveData \uc774\ubca4\ud2b8 \ucc98\ub9ac \ud544\uc694\uc5c6\uc74c, \uc2e4\uc2dc\uac04 \ub370\uc774\ud130 \uc218\uc2e0\uc2dc OnReceiveRealData \uc774\ubca4\ud2b8 \ucc98\ub9ac \ud544\uc694\n##########################################################################################################\n\ndef sample():\n    # \ub85c\uadf8\uc778\n    session = XASession()\n    session.ConnectServer(\"api.ls-sec.co.kr\", 20001)\n    if not session.Login(user_id, user_pwd, cert_pwd, 0, 0):\n        print(f\"\ub85c\uadf8\uc778 \uc2e4\ud328: {session.last_message}\")\n        return\n\n    print(f\"\ub85c\uadf8\uc778 \uc131\uacf5: {session.last_message}\")\n\n    # \ubcf4\uc720\uacc4\uc88c \ud45c\uc2dc\n    acc_count = session.GetAccountListCount()\n    print(f\"Account List Count: {acc_count}\")\n    for i in range(acc_count):\n        acc_num = session.GetAccountList(i)\n        acc_name = session.GetAccountName(acc_num)\n        acc_detail = session.GetAcctDetailName(acc_num)\n        print(f\"{acc_num} {acc_name} {acc_detail}\")\n\n    # \uc694\uccad t1102: \uc8fc\uc2dd \ud604\uc7ac\uac00(\uc2dc\uc138) \uc870\ud68c\n    query = XAQuery(\"t1102\")\n    query.SetFieldData(\"t1102InBlock\", \"shcode\", 0, \"005930\") # 005930: \uc0bc\uc131\uc804\uc790\n    ret = query.Request(False)\n    if ret < 0:\n        print(f\"t1102 request failed: {query.last_message}\")\n        return\n\n    # \uc694\uccad \uc131\uacf5\uc2dc, \uc870\ud68c\ub41c \ub370\uc774\ud130 \ud655\uc778\n    print(f\"t1102 request succeeded: {query.last_message}\")\n    price = query.GetFieldData('t1102OutBlock', 'price', 0)\n    print(f\"\uc0bc\uc131\uc804\uc790 \ud604\uc7ac\uac00: {price}\")\n\n    # \ucd94\uac00\uc791\uc5c5\n    ...\n\n    # \uc2e4\uc2dc\uac04 \uc2dc\uc138 \uc694\uccad/\uc774\ubca4\ud2b8 \ucc98\ub9ac\n    real = XAReal(\"S3_\")\n    real.OnReceiveRealData = lambda code: print(f\"RealData: {code}\")\n    real.SetFieldData(\"InBlock\", \"shcode\", \"005930\")\n    real.AdviseRealData()\n\n\nif __name__ == \"__main__\":\n    sample()\n    # \uc2e4\uc2dc\uac04 \ub370\uc774\ud130 \uc218\uc2e0\uc2dc \uba54\uc2dc\uc9c0 \ub8e8\ud504 \ud544\uc694\n    import pythoncom\n    while True:\n        pythoncom.PumpWaitingMessages()\n\n# Output:\n'''\n\ub85c\uadf8\uc778 \uc131\uacf5: [0000] \ub85c\uadf8\uc778 \uc131\uacf5\nAccount List Count: 3\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \uc120\ubb3c\uc635\uc158\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \ud574\uc678\uc120\uc635\nXXXXXXXXXXX \ud64d\uae38\ub3d9 \uc885\ud569\ub9e4\ub9e4\nt1102 request succeeded: [00000] \uc815\uc0c1\uc801\uc73c\ub85c \uc870\ud68c\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\uc0bc\uc131\uc804\uc790 \ud604\uc7ac\uac00: 51000\nRealData: S3_\nRealData: S3_\nRealData: S3_\n...\n'''\n```\n\n### XASession, XAQuery, XAReal \ud074\ub798\uc2a4 \uc0ac\uc6a9\ubc95\nLS\uc99d\uad8c COM \uac1c\ubc1c\uac00\uc774\ub4dc \ucc38\uc870: [LS\uc99d\uad8c COM \uac1c\ubc1c\uac00\uc774\ub4dc](https://www.ls-sec.co.kr/apiguide/guide.jsp?cno=100)\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "package for XingApi(DLL,COM)",
    "version": "0.2.0",
    "project_urls": {
        "Homepage": "https://github.com/teranum/ls-dev/tree/master/xingAsync"
    },
    "split_keywords": [
        "xingapi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "500aa9508b69934aaabf557197309ea67c58e03a1c038fb678545dc49bce3158",
                "md5": "8b5e8cf773dd149de7d7b0dcca4765c3",
                "sha256": "be34a52af99320ba3d46521c1aeb5878ce52780dc75daec26a38923bb17c6d99"
            },
            "downloads": -1,
            "filename": "xingasync-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8b5e8cf773dd149de7d7b0dcca4765c3",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 304197,
            "upload_time": "2025-02-04T15:07:45",
            "upload_time_iso_8601": "2025-02-04T15:07:45.154589Z",
            "url": "https://files.pythonhosted.org/packages/50/0a/a9508b69934aaabf557197309ea67c58e03a1c038fb678545dc49bce3158/xingasync-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-04 15:07:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "teranum",
    "github_project": "ls-dev",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "xingasync"
}
        
Elapsed time: 1.84083s