앞서 포스팅한 xingAPI의 여러 데이터 조회 방법 중 [단일 데이터 조회]에 대해 포스팅 해본다.
보면 알겠지만 C#을 사용해서 자동 매매 프로그램을 만들고 있기 때문에 C#으로 코드를 짤 것이다.
xingAPI COM 개발 가이드에는 엑셀 VBA를 이용한 프로그램의 코드가 소개되어 있다.
개발이 익숙한 사람이라면 COM 형식의 개발은 라이브러리 참조 후 객체의 함수들을 보면 대충 어떤 경우에 어떤 함수를 사용하면 될지 감이 온다.
우선 xingAPI 가이드에 나온 내용부터 보자. 아래는 가이드에서 정리한 [단일 데이터 조회] 순서이다.
단일데이터 조회는 XAQuery 객체를 사용.
- XAQuery 선언
- XAQuery 생성
- RES 등록
- 입력데이터 설정
- 입력데이터를 서버로 전송하기
- 서버로부터 데이터 받기
물론 가이드에는 위의 과정들이 엑셀 VBA로 되어 있어서 엑셀 VBA로 프로그램을 만들 예정이면 가이드를 보고 따라 하면 된다. 나는 C#으로 위의 과정들을 만들어 본다.
우선 단일데이터 조회를 위해 [자산현황 조회] 기능을 사용한다.
해당 버튼을 클릭할 때마다 1회, 단일적으로 데이터를 요청하고 수신하는 방식이다.
xingAPI의 요청-응답은 요청하는 함수, 그리고 서버로부터 데이터를 수신하는 함수의 두 개의 함수가 쌍을 이루는 형태로 구성된다.
즉, xingAPI에서 제공되는 모든 TR 처리는 요청하는 함수와 응답을 수신하는 함수, 두 개의 함수를 구현해야지만 완성이 된다.
먼저 [자산현황 조회]를 위한 TR을 찾기 위해 'DevCenter'에 접속하여 TR을 찾아보자.
'DevCenter' 사용 법은 아래에...
2020/08/14 - [Trading] - [Trading] XingAPI - DevCenter 사용하기
'DevCenter'의 TR 목록 중, 계좌 자산 현황 정보를 볼 수 있을 것 같은 TR은 아래처럼 4가지가 가능해 보인다.
위의 4가지 종류의 TR을 하나하나 눌러가며 'OutBlock'의 항목들을 잘 살펴보고 내가 필요한 정보들을 모두 획득할 수 있는 TR을 선택한다.
내가 필요로 하는 정보들은 아래와 같다.
- 실자산총액
- D+1 예수금
- D+2 예수금
- 총 매입금액
- 평가손익
- 평가금액
- 손익률
나는 저 위의 4가지 TR을 모두 사용해보고 많은 시간을 삽질(?)하며 결국 [CSPAQ12200] TR을 선택했다.
나와 같은 삽질을 하지 않도록...각 TR에 대한 내용을 조금 정리해 본다.
1. CSPAQ12200 현물계좌 예수금/주문가능금액/총평가조회(API)
이름만 보면...내가 필요한 정보들이 다~있을 것만 같은 TR 이름이다. 하지만 '총 매입금액'과 '평가손익'에 대한 정보는 존재하지 않아 존재하는 나머지 정보들을 이용해서 두 개 정보를 얻어냈다. 간단한 수학 공식으로 얻어낼 수 있다.
다시 CSPAQ12200에 대해 얘기해 보자. 나의 경우는 이 TR을 내가 원할 때 1회 조회함으로써 내 자산 정보를 확인할 수 있도록 하는 하는데에 사용하였는데, 의외로 주기적으로 이 정보를 요청하도록 개발하는 사람이 많은지 TR 요청 폭주로 인해서 잦은 장애가 발생한다고 한다. 그래서 이베스트 측에서는 이 TR 대신 CSPAQ22200을 새로 만들어 사용하게 했다고 했다. 하지만....CSPAQ22200은 정말 적은 정보를 제공하여 나에게는 적합하지 않은 TR이었다.
2. CSPAQ12300 현물계좌 잔고내역 조회(API)
이 TR이야말로 내가 원하는 정보들을 다~ 제공해주는 TR이다. 하지만 공교롭게도 이 TR은 모의투자에서만 지원하고 실투자에서는 지원하지 않는다. 이유는 나도 모르겠다. 이것은 이베스트에서 공식적으로 실투자에서는 제공되지 않는다고 한 사항이며, 그걸 알기 전까지 정말 엄청난 시간 소모와 삽질을 했다...실투자용 자동매매 프로그램을 만들 경우 이 TR은 사용하지 않는다.
3. t0424 주식잔고2
이 TR도 CSPAQ12300과 마찬가지로 내가 원하는 정보들은 다~ 제공해 주는 TR이다. t0424 TR 정보를 보면 알겠지만, 이 TR 하나로 자산현황과 해당 계좌에 존재하는 체결된 종목 리스트들을 함께 전달해 준다. 설계한 내 프로그램의 기능상 이 두 가지 기능이 분리되어 사용되어야 하기에 이 TR은 자산현황 조회 시 사용하지 않고 오로지 계좌 잔고 조회에만 사용하였다. 설계한 프로그램이 굳이 이 두 가지 기능을 따로 분리할 필요가 없다면, t0424 TR을 사용하는 것을 추천한다. 이 TR을 사용하는 법은 다음 포스팅에...
이제 구현 후 테스트를 해보자.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using XA_SESSIONLib;
using XA_DATASETLib;
namespace xingAPI_Test
{
public partial class xingAPI_Test : Form
{
// Global 변수
bool gIsConnHTS = false;
string gAccount = string.Empty;
// xingAPI Session 클래스 선언
XASessionClass myXASessionClass;
// xingAPI TR 클래스 선언
XAQueryClass CSPAQ12200; // 자산현황 조회
public xingAPI_Test()
{
InitializeComponent();
// xingAPI Session 객체 생성
myXASessionClass = new XASessionClass();
}
// Form Load될 때 초기화
private void xingAPI_Test_Load(object sender, EventArgs e)
{
Realtime_Log.Items.Add("====== xingAPI Test 프로그램 시작 ======");
// HTS 로그인 핸들러 등록
myXASessionClass._IXASessionEvents_Event_Login += new XA_SESSIONLib._IXASessionEvents_LoginEventHandler(myXASessionClass_Login);
// xingAPI TR 이벤트 등록
CSPAQ12200 = new XAQueryClass();
CSPAQ12200.ResFileName = @"C:\eBEST\xingAPI\Res\CSPAQ12200.res"; // xingAPI 서버로부터 수신한 응답 메시지를 COM 버전의 API에서 사용할 수 있도록 Format을 맞춰주는 파일
CSPAQ12200.ReceiveData += CSPAQ12200ReceiveData; // xingAPI 서버로부터 CSPAQ12200의 응답 메시지를 수신할 함수 등록
}
// HTS 서버 접속
private void Btn_Conn_Server_Click(object sender, EventArgs e)
{
string serverType = "hts.ebestsec.co.kr";
gIsConnHTS = myXASessionClass.ConnectServer(serverType, 20001); // 20001은 HTS 서버 고정 Port 값
if (gIsConnHTS == true)
{
Realtime_Log.Items.Add("이베스트 실투자 서버 접속 완료");
}
else // 연결 실패했을 경우
{
int ErrCode = myXASessionClass.GetLastError();
var ErrMsg = myXASessionClass.GetErrorMessage(ErrCode);
string err_log = String.Format("[서버연결] ERR - {0}({1})", ErrMsg, ErrCode);
}
}
// HTS 서버 로그인
private void Btn_Login_Click(object sender, EventArgs e)
{
if (gIsConnHTS == true) // HTS 서버 로그인은 서버 접속이 완료된 이후에만 가능.
{
bool reqLogin = ((XA_SESSIONLib.IXASession)myXASessionClass).Login(TB_User_ID.Text, TB_User_Passwd.Text,
"", 0, false); // 세번째 인자는 공인인증비번을 입력하는 칸이지만 보안을 위해 입력 받지 않고 보안 프로그램에서 입력하는 것이 좋다.
// reqLogin의 결과 값은 로그인 완료 여부가 아닌, 서버에 로그인 요청을 전송 완료 여부이다. 때문에 Login Handler 함수를
// 별도 추가하여 요청한 로그인 정보가 정상적으로 성공했는지 확인해야한다.
if (reqLogin == true)
{
Realtime_Log.Items.Add("HTS 로그인 요청 완료");
}
else
{
Realtime_Log.Items.Add("HTS 로그인 요청 실패");
int ErrCode = myXASessionClass.GetLastError();
var ErrMsg = myXASessionClass.GetErrorMessage(ErrCode);
string err_log = String.Format("[로그인] ERR - {0}({1})", ErrMsg, ErrCode);
}
}
}
// HTS 서버 로그인 결과
void myXASessionClass_Login(string code, string msg)
{
if (code == "0000") // code 0000은 성공을 의미
{
Realtime_Log.Items.Add("HTS 로그인 완료");
// 보유 계좌 정보 Loading
int AccountCount = myXASessionClass.GetAccountListCount();
for (int i = 0; i < AccountCount; i++)
{
string AccountNo = string.Empty;
string AccountName = string.Empty;
string AccountDetailName = string.Empty;
string AccountNickName = string.Empty;
string AccountFinal = string.Empty;
AccountNo = myXASessionClass.GetAccountList(i);
AccountName = myXASessionClass.GetAccountName(AccountNo);
AccountDetailName = myXASessionClass.GetAcctDetailName(AccountNo);
AccountNickName = myXASessionClass.GetAcctDetailName(AccountNo);
AccountFinal = AccountNo + "(" + AccountName + ")";
Realtime_Log.Items.Add(AccountFinal);
CB_Account_List.Items.Add(AccountNo);
}
Realtime_Log.Items.Add("보유 계좌 정보 Loading 완료");
}
}
// 보유 계좌 선택
private void Btn_Input_Account_Click(object sender, EventArgs e)
{
if (CB_Account_List.Text != "")
{
gAccount = CB_Account_List.Text;
string str_log = String.Format("[보유계좌선택] {0} 선택완료.", gAccount);
Realtime_Log.Items.Add(str_log);
}
}
// 자산현황 조회 [단일데이터]
private void Btn_Get_Balance_Click(object sender, EventArgs e)
{
// CSPAQ12200 TR의 InBlock 데이터 세팅
CSPAQ12200.SetFieldData("CSPAQ12200InBlock1", "RecCnt", 0, "00001");
CSPAQ12200.SetFieldData("CSPAQ12200InBlock1", "MgmtBrnNo", 0, " ");
CSPAQ12200.SetFieldData("CSPAQ12200InBlock1", "AcntNo", 0, gAccount);
CSPAQ12200.SetFieldData("CSPAQ12200InBlock1", "Pwd", 0, "실제비밀번호");
CSPAQ12200.SetFieldData("CSPAQ12200InBlock1", "BalCreTp", 0, "0");
// TR 요청
var result = CSPAQ12200.Request(false);
if (result > 0)
MessageBox.Show("CSPAQ12200 요청 완료");
else
MessageBox.Show("CSPAQ12200 요청 실패");
}
private void CSPAQ12200ReceiveData(string trCode)
{
// 요청한 CSPAQ12200 TR에 대한 응답 메시지 수신
// CSPAQ12200 TR의 OutBlock2에서 필요한 데이터 추출
// 1. 예탁자산 총액
var temp_value = CSPAQ12200.GetFieldData("CSPAQ12200OutBlock2", "DpsastTotamt", 0);
decimal estimated_assets = Convert.ToDecimal(temp_value);
// 2. D+1 예수금
temp_value = CSPAQ12200.GetFieldData("CSPAQ12200OutBlock2", "D1Dps", 0);
decimal d1_deposit = Convert.ToDecimal(temp_value);
// 3. D+2 예수금
temp_value = CSPAQ12200.GetFieldData("CSPAQ12200OutBlock2", "D2Dps", 0);
decimal d2_deposit = Convert.ToDecimal(temp_value);
// 4. 손익률
temp_value = CSPAQ12200.GetFieldData("CSPAQ12200OutBlock2", "PnlRat", 0);
double valuation_rate = Convert.ToDouble(temp_value);
// 5. 잔고평가금액
temp_value = CSPAQ12200.GetFieldData("CSPAQ12200OutBlock2", "BalEvalAmt", 0);
decimal evaluation_amounts = Convert.ToDecimal(temp_value);
string text = String.Format("[예탁자산총액 : {0:#,0}] [D+1 예수금 : {1:#,0}] [D+2 예수금 : {2:#,0}] [손익률 : {3:f2}%] [잔고평가금액 : {4:#,0}]",
estimated_assets, d1_deposit, d2_deposit, valuation_rate, evaluation_amounts);
MessageBox.Show(text);
}
// 계좌잔고 조회 [반복데이터]
private void Btn_Get_Items_Click(object sender, EventArgs e)
{
}
}
}
TR을 사용할 때 어떤 값을 입력해야 하는지, 그리고 응답 메시지에서 어떤 값을 추출해야 하는 지는 'DevCenter'에서 TR 정보를 보면 쉽게 알 수 있다.
TR을 사용하기 전에 반드시 해야하는 작업이 있다.
바로 res 파일들을 다운로드하여 저장해 두고 있어야 하는데 해당 작업은 'DevCenter'에서 제공한다.
필요한 TR만 다운로드할 수 있긴 하지만, 그냥 전부다 다운로드하여두면 편하다.
다운로드하면 아래 경로에 자동적으로 저장이 되고, 개발할 때 해당 경로의 .res 파일을 ResFileName에 넣어 주면 된다.
아래의 이전 포스팅을 참조해서 [서버연결]-[로그인]-[계좌선택]까지 완료해보자.
2020/08/24 - [Trading] - [Trading] xingAPI - 서버연결, 로그인, 보유계좌 불러오기
위 상태에서 [자산현황 조회] 버튼을 누르면 메시지 박스에 결과가 표시될 것이다.
xingAPI의 기본 TR 요청/응답처리를 구현해 봤다. 모든 TR이 이와 같은 원리로 동작하니 이것만 할 수 있다면 다른 TR들에 대한 구현도 어렵지 않을 것이다.
'Trading' 카테고리의 다른 글
[Trading] xingAPI - 데이터 표시하기 (4) | 2021.11.07 |
---|---|
[Trading] xingAPI - 반복 데이터 조회 (2) | 2020.10.10 |
[Trading] xingAPI - 서버연결, 로그인, 보유계좌 불러오기 (0) | 2020.08.24 |
[Trading] xingAPI - TR과 데이터 조회 (0) | 2020.08.23 |
[Trading] MS VS C# xingAPI 사용하기 (0) | 2020.08.21 |