이베스트 Xing, 대신 Creop Plus(=Cybos Plus), 키움 Open API+, 한투 eFriend Expert

위 네 가지 증권사는 com 또는 ocx 방식의 API 제공해줍니다. 사용방법이 비슷해서 한 가지만 마스터하면 비교적 쉽게 옮길 수는 있지만, 조금씩의 차이가 있어서 헷갈리기로 합니다. 그래서 한번 정리해보고자 합니다. 

증권사 데이터를 조회/수신하는 방법은 크게 세 가지로 구분할 수 있습니다. 
  - 1회성  조회 - 단일 데이타 수신
                    - 멀티 데이터 수신 
  - 실시간 조회 - 단일 데이타 수신 - 시세
                                              - 주문체결

먼저 실현손익 조회를 통해 1회성 싱글 데이터 조회를 하는 방법부터 정리해보겠습니다. 
* 각 증권사마다 실현손익을 조회할 수 있는 TR이 여러 개 있습니다. 아래는 그중 그냥 제가 어쩌다 쓰게 된 TR일 뿐, 특별한 이유가 있는 건 아닙니다. 또한 제가 쓰는 코드를 거의 그대로 복붙 한 거라 깔끔한 예제는 아닙니다. 형식만 참고해주세요.

모든 증권사 공통적으로 비동기 방식이 기본이고, 1. 개체를 생성하고 2. 조건을 입력해서 3. 조회 요청 후 4. 데이터를 수신하는 순으로 진행됩니다. 
* 대신은 동기 방식도 제공해줍니다.

XING

1. 생성 
com 방식으로 1회성 조회 데이터는 모두 XAQuery 라는 객체를 사용합니다. 다만 쿼리 별로 Res 파일을 각각 등록해줘야 하고, 수신 데이터에서 어떤 요청에 대한 회신인지 구분할만한 요소가 TrCode 밖에 없기 때문에 그냥 필요에 따라 개체를 생성해주는 게 편한 듯합니다.  개체별로 이벤트를 각각 등록해줘야 하는 번거로움이 있기는 합니다. 

  1회성 - 단일 1회성 - 멀티 실시간(시세)
2. 조건 입력 SetFiedldData("블럭명", "필드명", 0, "조건값")  좌동 SetFiedldData("블럭명", "필드명", "값") 
3. 조회 요청 Request(false)

좌동
*연속조회일 경우 true
AdviseRealData()
UnadviseRealData()
UnadviseRealDataWithKey("종목코드")
- 리턴값 0     : 성공
음수 : 실패
좌동 없음
4. 데이터 수신
GetFieldData("블럭명", "필드명", 0)
GetFieldData("블럭명", "필드명", index)
* 개수는 GetBlockCount("블럭명") 으로 판단
GetFieldData("블럭명", "필드명")

- "블럭명"과 "필드명"으로 입력하거나 수신할 데이터를 특정해줍니다. 보통 단일 데이터의 경우 "t0424OutBlock" 처럼 숫자가 안 붙고 멀티데이터의 경우 "t0424OutBlock1"처럼 숫자가 붙습니다.
- 데이터 수신시 오류 등을 알려주는 메시지와 데이터가 다른 이벤트로 들어옵니다. 
- 데이터는 깔끔하게 모두 string 형입니다. 숫자데이터가 empty 나 null 값으로 오는 경우도 못 봤습니다. 

Creon

1. 생성
역시 com 방식입니다. Xing과는 다르게 아예 조회 별로 개체가 나누어져 있습니다. 전 오히려 직관적이라 좋더라고요. 어차피 xing과 마찬가지로 요청한 TR과 회신한 데이터를 매치시켜주는 방법이 개체밖에 없기도 하고요.
- 주문 외에는 그럴 경우는 거의 없기는 합니다만, 데이터 수신이 미완료된 개체를 사용하면 에러가 발생합니다. 그래서 GetDibStatus라는 메서드를 사용해서 조회 요청 후 아직 데이터 수신이 안된 개체를 구분해야 합니다. 

  1회성 - 단일 1회성 - 멀티 실시간(시세)
2. 조건 입력 SetInputValue( type, 조건값) 좌동 좌동
3. 조회 요청 Request()
좌동
Subscribe()
Unsubscribe() 
- 리턴값 0     : 성공
양수 : 실패
좌동 없음
4. 데이터 수신
GetHeaderValue( type )
GetDataValue ( type, index )
*개수는 단일데이터에서 제공
GetHeaderValue( type )

- type 으로 입력하거나 수신할 데이터를 특정해줍니다. 그냥 숫자라 코드만 보고는 의미를 알기 힘든 단점이 있습니다. 
- 메세지와 데이터가 동일한 이벤트로 들어와서 이벤트 등록이 좀 덜 번거롭습니다. 
- 회신 데이터가 dynamic 형식이라 캐스팅 없이 형식에 맞게 정의된 변수에 바로 대입 가능합니다. 다만 위 예제처럼 숫자값인데 string 형식으로 회신되는 데이터는 "0" 대신 "" 이 날라올 수 있어 주의해야 합니다. 
- Xing의 GetBlockCount 메서드 대신 싱글데이터에서 멀티데이터의 개수를 알 수 있습니다. 위 예제 td6032처럼 모든 조회에서 다 제공해주지는 않는 것 같습니다. 

KOA+

1. 생성
 ocx 방식으로, 디자인 화면에서 도구상자에서 끌어서 생성합니다. 개체별로 이벤트를 연결시켜줬던 com 방식과는 달리, 키움은 하나의 ocx 개체만 사용하고 회신데이타의 e 에 담겨있는 정보로 처리할 메서드를 구분할 수 있습니다. 
- 요청시 정해줬던 "내맘대로명"과 "화면번호"를 회신시 e.sRQName, e.sScrNo로 확인할 수 있어 서로 매치시켜주면 됩니다. 
* 요 "화면번호" 때문에 신경써줘야 할 부분이 많습니다. 화면번호가 200개를 넘기면 안되고, 같은 화면번호를 연속으로 쓰면 안되고 등등. 또 1회성 조회 요청시 자동으로 실시간 등록이 되기때문에 다시 사용하기 전 DisconnectRealData() 함수로 이전 연결을 끊어줘야 합니다. 저 같은 경우 1회성 TR은 화면번호 2001 ~2010번 안에서 돌려 씁니다. 

  1회성 - 단일 1회성 - 멀티 실시간(시세)
2. 조건 입력 SetInputValue( "아이템명", "조건값") 좌동 X
3. 조회 요청 CommRqData("내맘대로명", "sTrCode", 0, "화면번호")
좌동
TR 요청시 자동으로
DisconnectRealData() 

또는
SetRealReg("화면번호", "종목코드", 아이템번호, "1")
SetRealRemove("화면번호", "종목코드")
- 리턴값 0     : 성공
음수: 실패
좌동 없음
4. 데이터 수신
e
GetCommData(e.sTrCode, e.sRQName, 0, "아이템명")


e
GetCommData(e.sTrCode, e.sRQName, index, "아이템명")
*개수는 GetRepeatCnt (e.sTrCode, e.sRQName);
e
GetCommRealData(e.sRealKey, 아이템번호)


- 무려 한글로 된 "아이템명"으로 입력값과 수신값을 지정해줍니다. 
- 메시지와 데이터가 각각 들어옵니다. 
- 회신 데이터는 모두 string 형식인데 깔끔하지는 않습니다. 앞뒤로 공백문자가 붙어옵니다. 그리고 숫자값인데 "0" 대신 ""이 회신되는 경우도 많아 주의해야 합니다. 
- 멀티데이터의 개수는 GetRepeatCnt 함수로 확인할 수 있습니다만 몇 개 조회의 경우 데이터가 없는데도 1로 값이 넘어오기도 하는 등 100% 신뢰할 수는 없을 듯 합니다.

한투

1. 생성
 ocx 방식으로, 키움과 마찬가지로 디자인 화면에서 도구상자에서 끌어서 생성합니다. 개체별로 이벤트를 연결시켜줬던 com 방식, 하나의 ocx 개체만 사용했던 키움의 하이브리드(?) 정도로 사용합니다. 1회성 조회들은 각각 개체를 만들고, 주문 관련 조회와 실시간 체결은 하나의 개체로 사용할 수 있습니다. 
- 1회성 조회들은 개체로 수신 데이터를 구분하고, 하나의 개체를 사용한 주문은 GetSendRqID()와 GetRecvRqID() 메서드를 사용해 수신 데이터를 구분해줍니다. 키움의 화면번호와 같은 역할입니다. 
* 사실 이렇게 사용하는 게 정답인지는 자신 없습니다. 다만 홈페이지의 예제에서 이런 식으로 사용해서, 저도 그렇게 사용하고 있습니다. 

  1회성 - 단일 1회성 - 멀티 실시간(시세)
2. 조건 입력 SetSingleData(필드index, "조건값") 좌동 사용경헙 없음
3. 조회 요청 RequestData("서비스명")
좌동
 
- 리턴값 없음 없음  
4. 데이터 수신
GetMultiData(블락index, 1 필드index, 0)
GetMultiData(블락index, index, 필드index, 0)
개수는 GetMultiRecordCount(블락index)
 

- 블락index와 필드index로 입력값과 수신값을 지정해줍니다. 
- 메시지와 데이터가 함께 들어오고, 별개로 에러 여부를 알려주는 이벤트가 따로 발생합니다. 
- 수신데이터는 모두 stirng형인데 (string)으로 캐스팅을 해줘야만합니다. 역시 0 대신 "" 이 들어오는 경우가 있습니다. 
- 싱글데이터를 조회하는 GetSingleData 메서드를 제공해주나 작동하지 않는 듯 합니다. 싱글데이터도 GetMultiData 메서드를 사용하고, 싱글데이터를 주는 블럭을 찾아 지정해주어야 합니다. 위 예제에서는 1 이었습니다.
* 멀티데이터 개수를 알려주는 GetMultiRecordCount 메서드도 제공해주나, 데이터가 없는 경우 100으로 조회되는 경우도 있고 100% 믿으면 안될 듯 합니다. 이 부분도 자신은 없습니다. 

+ Recent posts