반응형

 

키움 Open API+의 이벤트 중 OnReceiveMsg에 대해 알아보겠습니다.

 

OnReceiveMsg

OnReceiveChejanData는 주문전송 또는 데이터 조회 요청 후 서버 메시지가 수신됩니다. 서버에 주문 전송이나 데이터 조회가 정상적으로 요청되었는지 확인할 수 있습니다. 함수의 원형은 다음과 같습니다.

void OnReceiveMsg(LPCTSTR sScrNo, LPCTSTR sRQName, LPCTSTR sTrCode, LPCTSTR sMsg)
1
2
3
4
5
private void axKHOpenAPI_OnReceiveMsg(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveMsgEvent e)
{
    Logger(Log.조회, "===================================================");
    Logger(Log.조회, "화면번호:{0} | RQName:{1} | TRCode:{2} | 메세지:{3}", e.sScrNo, e.sRQName, e.sTrCode, e.sMsg);
}
cs

※ 메시지에 포함된 6자리 코드번호는 변경될 수 있으니, 여기에 수신된 코드번호를 특정 용도로 사용하지 마시기 바랍니다.

반응형

 

OnReceiveMsg 모의투자 코드 번호

모의투자 서버와 실제 서버의 메시지 코드는 다르기 때문에 구분이 필요하며, 코드번호도 변경되는 경우도 있기 때문에 사용할 때 주의가 필요합니다.

예전 모의투자에서는 [00Z211], [00Z224] 등의 코드 번호가 사용되었으나, 현재 모의 투자 서버에서는 [RC4007], [RC4042] 등의 코드 번호가 사용되고 있습니다.

  • 현재 모의투자 코드 번호 내용
    코드 번호 내용
    100000 모의투자 매수주문완료 or 모의투자 매도주문완료
    RC4007 모의투자 매매금지 종목
    RC4033 모의투자 정정/취소할 수량이 없습니다
    RC4042 모의투자 정정수량이 정정가능수량을 초과합니다
    RC4085 모의투자 체결중인 수량이 있습니다. 
    주문수량을 확인하세요
  • 이전 모의투자 코드 번호 내용
    코드 번호 내용
    00Z211 모의투자 종목코드 오류
    00Z219 모의투자 매매금지 종목
    00Z224 모의투자 주문처리가 안되었습니다
    00Z225 모의투자 주문처리가 안되었습니다
    00Z230 모의투자 원주문번호가 존재하지 않습니다
    00Z353 모의투자 주문가능 수량 확인
    00Z231 모의투자 정정/취소할 수량이 없습니다
반응형

 

OnReceiveMsg 실제투자 코드 번호

코드 번호 내용
100000 매수주문완료 or 매도주문완료
505566 정정가능수량이 없습니다
506550 취소가능수량이 없습니다.
505564 정정수량이 정정가능수량을 초과합니다
855056 매수증거금이 부족합니다. n주 매수가능
반응형

 

OnReceiveMsg TrCode

데이터 조회의 경우에는 입력한 TrCode와 같고, 주문의 경우 주문 종류에 따라서 TrCode가 다르게 들어옵니다.

TrCode 내용
KOA_NORMAL_BUY_KP_ORD 코스피 종목 매수 주문
KOA_NORMAL_SELL_KP_ORD 코스피 종목 매도 주문
KOA_NORMAL_KP_CANCEL 코스피 종목 주문 취소 주문
KOA_NORMAL_KP_MODIFY 코스피 종목 주문 변경 주문
KOA_NORMAL_BUY_KQ_ORD 코스닥 종목 매수 주문
KOA_NORMAL_SELL_KQ_ORD 코스닥 종목 매도 주문
KOA_NORMAL_KQ_CANCEL 코스닥 종목 주문 취소 주문
KOA_NORMAL_KQ_MODIFY 코스닥 종목 주문 변경 주문

TrCode에 주문 종류가 영어 그대로 코드에 들어가며, 코스피(KOSPI) 종목은 KP가 코스닥(KOSDAQ) 종목은 KQ이 TrCode에 들어가 있기 때문에 쉽게 구분 가능합니다.

 

반응형
반응형

 

키움 Open API+의 이벤트 중 OnReceiveChejanData에 대해 알아보겠습니다.

 

OnReceiveChejanData

OnReceiveChejanData는 주문전송 후 주문 접수, 체결 통보, 잔고 통보를 수신할 때마다 발생되며 체결 데이터를 받은 시점을 알 수 있습니다. GetChejanData() 함수를 이용해서 FID항목별 값을 얻을 수 있습니다.

함수의 원형은 다음과 같습니다.

void OnReceiveChejanData(LPCTSTR sGubun, LONG nItemCnt, LPCTSTR sFidList)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void axKHOpenAPI_OnReceiveChejanData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveChejanDataEvent e)
{
    if (e.sGubun == "0")
    {
        Logger(Log.실시간, "구분 : 주문체결통보");
        Logger(Log.실시간, "주문/체결시간 : " + axKHOpenAPI.GetChejanData(908));
        Logger(Log.실시간, "종목명 : " + axKHOpenAPI.GetChejanData(302));
        Logger(Log.실시간, "주문수량 : " + axKHOpenAPI.GetChejanData(900));
        Logger(Log.실시간, "주문가격 : " + axKHOpenAPI.GetChejanData(901));
        Logger(Log.실시간, "체결수량 : " + axKHOpenAPI.GetChejanData(911));
        Logger(Log.실시간, "체결가격 : " + axKHOpenAPI.GetChejanData(910));
        Logger(Log.실시간, "=======================================");
    }
    else if (e.sGubun == "1")
    {
        Logger(Log.실시간, "구분 : 잔고통보");
    }
    else if (e.sGubun == "3")
    {
        Logger(Log.실시간, "구분 : 특이신호");
    }
}
cs
반응형

 

주문 체결 FID 정보

FID 설명 FID 설명
9001 종목코드, 업종코드 9201 계좌번호
9203 주문번호 9205 관리자사번
900 주문수량 901 주문가격
902 미체결수량 903 체결누계금액
904 원주문번호 905 주문구분
(+매수, -매도, 매수취소, 매도취소, +매수정정, -매도정정)
906 매매구분(보통,시장가…) 907 매도수구분 (1:매도,2:매수)
908 주문/체결시간(HHMMSSMS) 909 체결번호
910 체결가 911 체결량
912 주문업무분류
(JJ:주식주문, FJ:선물옵션, JG:주식잔고, FG:선물옵션잔고)
913 주문상태
(접수, 확인, 체결)
914 단위체결가 915 단위체결량
938 당일매매 수수료 939 당일매매세금
10 현재가, 체결가, 실시간종가 27 (최우선)매도호가
28 (최우선)매수호가 302 종목명

 

반응형
반응형

키움 Open API+의 이벤트 중 OnReceiveTrCondition, OnReceiveRealCondition에 대해 알아보겠습니다.

 

OnReceiveTrCondition

OnReceiveTrCondition은 조건 검색 요청에 대한 서버 응답 수신 시 발생하는 이벤트입니다. 함수의 원형은 다음과 같습니다.

void OnReceiveTrCondition(LPCTSTR sScrNo, LPCTSTR strCodeList, LPCTSTR strConditionName, int nIndex, int nNext)
1
2
3
4
5
6
7
8
private void axKHOpenAPI_OnReceiveTrCondition(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrConditionEvent e)
{
    Logger(Log.조회, "[화면번호] : " + e.sScrNo);
    Logger(Log.조회, "[종목리스트] : " + e.strCodeList);
    Logger(Log.조회, "[조건명] : " + e.strConditionName);
    Logger(Log.조회, "[조건명 인덱스 ] : " + e.nIndex.ToString());
    Logger(Log.조회, "[연속조회] : " + e.nNext.ToString());
}
cs

종목코드 리스트는 각 종목코드가 ';'로 구분돼서 전달되기 때문에 ';'를 기준으로 분리가 필요합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[조건검색 결과 수신예시]
OnReceiveTrCondition(LPCTSTR sScrNo,LPCTSTR strCodeList, LPCTSTR strConditionName, int nIndex, int nNext)
{
    if(strCodeList == ""
        return;
    
    CString strCode, strCodeName;
    
    int nIdx = 0;
    
    while(AfxExtractSubString(strCode, strCodeList, nIdx++, _T(';')))// 하나씩 종목코드를 분리
    {
        if(strCode == _T("")) 
            continue;
            
        strCodeName = OpenAPI.GetMasterCodeName(strCode); // 종목명을 가져온다.
    }
}
cs
반응형

 

OnReceiveRealCondition

OnReceiveRealCondition은 실시간 조건 검색 요청으로 신규종목이 편입되거나 기존 종목이 이탈될 때마다 발생되는 이벤트입니다. 편입되었다가 순간적으로 다시 이탈되는 종목에 대한 신호는 조건 검색 서버마다 차이가 발생할 수 있습니다. 함수의 원형은 다음과 같습니다.

void OnReceiveCondition(LPCTSTR strCode, LPCTSTR strType, LPCTSTR strConditionName, LPCTSTR strConditionIndex)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private void axKHOpenAPI_OnReceiveRealCondition(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealConditionEvent e)
{
    Logger(Log.실시간, "========= 조건조회 실시간 편입/이탈 ==========");
    Logger(Log.실시간, "[종목코드] : " + e.sTrCode);
    Logger(Log.실시간, "[실시간타입] : " + e.strType);
    Logger(Log.실시간, "[조건명] : " + e.strConditionName);
    Logger(Log.실시간, "[조건명 인덱스] : " + e.strConditionIndex);
 
    // 자동주문 로직
    if (_bRealTrade && e.strType == "I")
    {
        // 해당 종목 1주 시장가 주문
        // =================================================
 
        // 계좌번호 입력 여부 확인
        if (cbo계좌.Text.Length != 10)
        {
            Logger(Log.에러, "계좌번호 10자리를 입력해 주세요");
 
            return;
        }
 
        // =================================================
        // 주식주문
        int lRet;
 
        lRet = axKHOpenAPI.SendOrder("주식주문"
                                    GetScrNum(), 
                                    cbo계좌.Text.Trim(),
                                    1,      // 매매구분
                                    e.sTrCode.Trim(),   // 종목코드
                                    1,      // 주문수량
                                    1,      // 주문가격 
                                    "03",    // 거래구분 (시장가)
                                    "0");    // 원주문 번호
 
        if (lRet == 0)
        {
            Logger(Log.일반, "주문이 전송 되었습니다");
        }
        else
        {
            Logger(Log.에러, "주문이 전송 실패 하였습니다. [에러] : " + lRet);
        }
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[실시간 조건검색 수신예시]
OnReceiveRealCondition(LPCTSTR sCode, LPCTSTR sType, LPCTSTR strConditionName, LPCTSTR strConditionIndex)
{
    CString strCode(sCode), strCodeName;
    int nIdx = 0;
    CString strType(sType);
    
    if(strType == _T("I"))// 종목편입
    {
        strCodeName = OpenAPI.GetMasterCodeName(strCode); // 종목명을 가져온다.
        long lRet = OpenAPI.SetRealReg(strSavedScreenNo, strCode, _T("9001;302;10;11;25;12;13"), "1");// 실시간 시세등록
    }
    else if(strType == _T("D")) // 종목이탈
    {
        OpenAPI.SetRealRemove(strSavedScreenNo, strCode);// 실시간 시세해지
    }
}
cs

 

 

 

반응형
반응형

키움 Open API+ 컨트롤 이벤트와 OnReceiveTrData, OnReceiveRealData에 대해서 알아보겠습니다.

 

Open API+ 컨트롤 이벤트

C#에서는 컨트롤 이벤트 앞에 axKHOpenAPI가 붙어 있으며 이벤트 목록은 다음과 같습니다.

예) axKHOpenAPI_OnReceiveTrData, axKHOpenAPI_OnReceiveRealData

이름 설명
OnReceiveTrData Tran 수신시 이벤트
OnReceiveRealData 실시간 시세 이벤트
OnReceiveMsg 수신 메시지 이벤트
OnReceiveChejanData 주문 접수/확인 수신시 이벤트
OnEventConnect 통신 연결 상태 변경시 이벤트
OnReceiveCondition 조건검색 실시간 편입, 이탈 종목 이벤트
OnReceiveTrCondition 조건검색 조회 응답 이벤트
OnReceiveConditionVer 로컬에 사용자조건식 저장 성공여부 응답 이벤트
반응형

OnReceiveTrData

OnReceiveTrData는 서버 통신 후 요청한 TR((Transaction) 데이터를 받은 시점을 확인하고, 수신한 TR 데이터 정보를 확인할 수 있습니다. 함수의 원형은 다음과 같습니다.

void axKHOpenAPI_OnReceiveTrData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent e)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
private void axKHOpenAPI_OnReceiveTrData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent e)
{
 
    if (e.sRQName == "주식주문")
    {
        string s원주문번호 = axKHOpenAPI.GetCommData(e.sTrCode, ""0"").Trim();
 
        long n원주문번호 = 0;
        bool canConvert = long.TryParse(s원주문번호, out n원주문번호);
 
        if (canConvert == true)
            txt원주문번호.Text = s원주문번호;
        else
            Logger(Log.에러, "잘못된 원주문번호 입니다");
 
    }
    // OPT1001 : 주식기본정보
    else if (e.sRQName == "주식기본정보")
    {
        int nCnt = axKHOpenAPI.GetRepeatCnt(e.sTrCode, e.sRQName);
 
        for (int i = 0; i < nCnt; i++)
        {
            Logger(Log.조회, "{0} | 현재가:{1:N0} | 등락율:{2} | 거래량:{3:N0} ",
                axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "종목명").Trim(),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "현재가").Trim()),
                axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "등락율").Trim(),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "거래량").Trim()));
        }
    }
    // OPT10081 : 주식일봉차트조회
    else if (e.sRQName == "주식일봉차트조회")
    {
        int nCnt = axKHOpenAPI.GetRepeatCnt(e.sTrCode, e.sRQName);
 
        for (int i = 0; i < nCnt; i++)
        {
            Logger(Log.조회, "{0} | 현재가:{1:N0} | 거래량:{2:N0} | 시가:{3:N0} | 고가:{4:N0} | 저가:{5:N0} ",
                axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "일자").Trim(),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "현재가").Trim()),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "거래량").Trim()),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "시가").Trim()),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "고가").Trim()),
                Int32.Parse(axKHOpenAPI.CommGetData(e.sTrCode, "", e.sRQName, i, "저가").Trim()));
        }
    }
 
}
cs

TR 요청은 주식 주문, 주식기본정보, 주식일봉차트조회 등 다양한 TR이 있으며, 요청 가능한 TR 목록은 KOA StudioSA에서 확인 가능합니다.(KOA StudioSA는 키움증권 사이트에서 최신 버전을 받을 수 있습니다.)

TR 요청은 추후에 더 자세히 살펴보도록 하겠습니다.

반응형

OnReceiveRealData

OnReceiveRealData는 실시간 데이터를 받은 시점을 확인하고, 실시간 데이터 정보를 확인할 수 있습니다. 함수의 원형은 다음과 같습니다.

void axKHOpenAPI_OnReceiveRealData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealDataEvent e)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void axKHOpenAPI_OnReceiveRealData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealDataEvent e)
{
    Logger(Log.실시간, "종목코드 : {0} | RealType : {1} | RealData : {2}",
        e.sRealKey, e.sRealType, e.sRealData);
 
    if( e.sRealType == "주식시세" )
    {
        Logger(Log.실시간, "종목코드 : {0} | 현재가 : {1:C} | 등락율 : {2} | 누적거래량 : {3:N0} ",
                e.sRealKey,
                Int32.Parse(axKHOpenAPI.GetCommRealData(e.sRealType, 10).Trim()),
                axKHOpenAPI.GetCommRealData(e.sRealType, 12).Trim(),
                Int32.Parse(axKHOpenAPI.GetCommRealData(e.sRealType, 13).Trim()));
    }
    
}
cs

실시간 데이터는 주시시세, 주식체결, 주식호가잔량, 잔고 등 다양한 실시간 정보를 확인할 수 있으며, 확인 가능한 실시간 목록은 KOA StudioSA에서 확인 가능합니다.(KOA StudioSA는 키움증권 사이트에서 최신 버전을 받을 수 있습니다.)

실시간 처리도 추후에 더 자세히 살펴보도록 하겠습니다.

 

반응형
반응형

 

시스템 트레이딩이란

시스템 트레이딩이란 현재 주가나 거래량 등의 이용하여 만든 매매 규칙에 따라 컴퓨터를 이용하여 지속적으로 거래하는 매매 방법입니다.

보통 기술적 지표들을 많이 사용하여 시스템을 사용하며, Ai나 개발자의 매매 아이디어나 전략을 체계화하여 매매에 이용합니다.

 

시스템 트레이딩의 장점

시스템 트레이딩을 이용한 매매는 손절매 원칙을 최우선으로 하기 때문에 안정적인 수익을 유지할 가능성이 높고, 매매를 시스템이 보조하기 때문에 손절을 못하는 공포에서 벗어날 수 있어 심리적 안정감을 유지할 수 있습니다. 

또한 시스템 트레이딩을 하면 전략적으로 검증이 가능하며 매수한 이유와 매도한 이유가 분명하기 때문에 뇌동 매매를 줄일 수 있습니다.

직장인의 경우 회의가 있거나, 업무, 식사, 화장실 등 확인이 불가능한 상태여도 시스템 트레이딩으로 자동 매매를 구현할 경우 프로그램이 모든 매매를 대신하기 때문에 시간적 자유를 얻을 수 있습니다.

람은 동시에 여러 개의 매매를 확인하며 매매하기 어려우나 시스템 트레이딩을 이용하면 동시에 여러 개의 매매를 쉽게 할 수 있습니다.

완성된 시스템 트레이딩 전략은 주식이나 옵션, 선물, 코인 등에 추가로 다양한 곳에 적용 가능합니다.

 

 

키움 Open API+란?

키움 Open API+는 키움증권에서 제공하는 Open API 서비스 명으로, 직접 프로그래밍한 투자 전략을 키움증권에서 제공하는 모듈에 연결하여, 시세조회, 잔고 조회, 주문 등을 할 수 있도록 제공하는 서비스입니다.

기존 키움 Open API에서 실시간 조건 검색 제공, 실시간 등록/해지, DATA 수신 속도 개선 등 추가 기능을 제공하여 새롭게 오픈하면서 Open API+로 이름이 변경되었습니다.

 

키움 Open API+의 장점

키움 Open API+는 주식, Kospi 200 선물, kospi200 옵션 상품을 거래할 수 있으며, 영웅문 4(HTS)와 동일한 수수료율이 적용되어 저렴하게 이용이 가능합니다.(해외 파생 상품은 해외 파생 Open API를 이용하여 거래 가능)

개인 투자자가 많이 이용하는 조건 검색식을 키움증권에서 다양한 기능을 제공하는데, 이것을 키움 Open API+와 연동하면 매매 가능한 종목을 빠르게 찾아서 시스템 트레이딩에 활용할 수 있습니다.

 

키움 Open API+ 개발 환경 및 사용 방법

Open API+는 Windows에서 동작이 가능하며, 개발은 C/C++, C#, Visual Basic, Excel, Delphi, Python 등 다양한 언어로 개발이 가능합니다.

Open API+를 사용하기 위해서는 키움증권 계좌를 보유하고 HTS ID를 연결한 고객 모두 이용이 가능하며, 키움증권에서 Open API+ 서비스를 사용 신청 후 Open API+ 모듈을 다운로드하여 설치하면 사용이 가능합니다.

개발과 관련된 내용은 키움증권 홈페이지에서 개발 가이드와 샘플을 제공하고 있으며, 게시판을 이용하여 더 많은 정보를 확인 가능합니다.

시스템 트레이딩을 개발할 때는 실제로 매매를 하기 전에 모의투자를 이용하여 테스트 가능합니다.

 

키움 Open API+ 개발 참고 사항

과도한 데이터 조회로 인한 서버 부하를 예방하기 위하여 Open API 모의투자 서버 내 중복 로그인은 제한됩니다. 

비정상적인 데이터 조회에 의한 서버 부하 발생 시 임의로 접속이 차단될 수 있습니다. (모의투자 서버 및 운영 서버 동일 적용)

모의 투자는 매매 제한 종목은 Open API+를 통해 매매가 불가능합니다.

  • 현재가 1,000원 미만인 종목(ELW 종목 제외)
  • 총 발행 주식수 100,000주 미만 종목
  • K-OTC 종목
  • 관리종목, 정리매매, 투자유의 종목
  • ETN종목

 

반응형

+ Recent posts