본문 바로가기
대충 만들면서 배우자/자동 매매 (키움 API)

[C#/WPF 키움 API] 키움 API_로그인/종목/실시간 시세 (3)

by 프갭 2023. 3. 29.

(1) 로그인

khAPI:키움 ocx

khAPI.CommConnect() : 로그인 창 오픈 메서드 (로그인 창 오픈 0이면 성공/1이면 실패 )

khAPI.GetConnectState() : 연결상태 메서트 (1이면 로그인 상태)

 

생성자에 이벤트 등록

        khAPI.OnEventConnect += khAPI_OnEventConnect;

        public bool IsConnected { get { return khAPI.GetConnectState() != 0; } }

        private void khAPI_OnEventConnect(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnEventConnectEvent e)
        {
            if (loginHandler.ExNotNull())
            {
                loginHandler(IsConnected);
            }

            loginHandler = null;
        }

 

        public void Login(Action<bool> onLoginResultHandler = null)
        {
            if (!IsConnected )
            {
                loginHandler = onLoginResultHandler;
                if (khAPI.CommConnect() != 0)
                {
                    if (onLoginResultHandler.ExNotNull())
                    {
                        loginHandler = null;
                        onLoginResultHandler(false);
                    }
                }
            }
            else
            {
                onLoginResultHandler(true);
            }
        }

코드 설명 

onLoginResultHandler :  로그인 완료시 호출하는 델리게이트

로그인 상태 이면 onLoginResultHandler 를 호출하여 성공 여부를 전달

아닐경우 로그인 창 오픈 후 로그인 완료 이벤트 발생하면 onLoginResultHandler  발생 (loginHandler = onLoginResultHandler)

 

 

(2) Auto Login 및 계좌 비밀번호 설정

AUTO 체크 /계좌 비밀번호 등록(정확하게 입력해야한다 경고 메시지 없음)

       

public void ShowAutoLogin()        

{
            khAPI.KOA_Functions("ShowAccountWindow", "");         

}

(3) 계정 정보 가지고오기

khAPI.GetLoginInfo("USER_ID") : 로그인 아이디

khAPI.GetLoginInfo("USER_NAME") : 로그인 이름

khAPI.GetLoginInfo("GetServerGubun") : 모의투자/실거래 여부

khAPI.GetLoginInfo("ACCNO") :  계좌번호

 

public KHUserInfo GetAccountInfo()
        {
            KHUserInfo rtn = new KHUserInfo();
            rtn.UserID = khAPI.GetLoginInfo("USER_ID");
            rtn.UserName = khAPI.GetLoginInfo("USER_NAME");
            rtn.ServerType = khAPI.GetLoginInfo("GetServerGubun");


            rtn.Accounts = new List<AccountInfo>();
            List<string> accs = khAPI.GetLoginInfo("ACCNO").ExSplit(";");
            if (accs.ExNotNull())
            {
                foreach (string str in accs)
                {
                    if (str.ExNotNullOrEmpty())
                    {
                        AccountInfo accInfo = new AccountInfo();
                        accInfo.AccountNumber = str;
                        rtn.Accounts.Add(accInfo);
                    }
                }
            }

            return rtn;
        }

KHUserInfo.cs
0.00MB

 

(KHUserInfo 내용은 수시로 변경 될 수 있다)

(4) 전체 종목 가지고오기

khAPI.GetCodeListByMarket : 종목 리스트 메서드 (0:장내,3:ELW,4:뮤추얼펀드,5:신주인수권,6:리츠,8:ETF,9:하이일드펀드,10:코스닥,30:K-OTC,50:코넥스)

khAPI.GetMasterCodeName : 종목명 가지고오는 메서드

 

public List<KHStock> GetStockList(string type = "0")
        {
            List<KHStock> rtn = new List<KHStock>();
            List<string> strCodes = khAPI.GetCodeListByMarket(type).ExSplit(";");
            foreach (string strCode in strCodes)
            {
                string name = khAPI.GetMasterCodeName(strCode);

                if (name.ExNotNullOrEmpty() && !name.Contains("ETN"))
                {
                    KHStock item = KHStock.GetSingInstance(strCode);
                    item.Name = name;
                    rtn.Add(item);
                }
            }

            return rtn;
        }

코드 설명

KHStock.GetSingInstance  : KHStock 클래스 같은 경우 종콕 코드 기준으로 싱글 인스턴스로 구성 하였습니다.

현재 시세나 속성 값이 변경 될 때 모두 동일하게 변경 되야 하기때문에

 

KHStock.cs
0.00MB

 

 

(KHStock 내용은 수시로 변경 될 수 있다)

(5) 종목 정보 및 실시간 시세

1. 종목 정보

khAPI.SetInputValue("종목코드", code) : 종목 코드 입력후

khAPI.CommRqData("주식기본정보", "OPT10001", 0, sn.No) : CommRqData 호출 하면 khAPI.OnReceiveTrData 이벤트 발생하여 정보를 가지고 온다

 

 

생성자에 이벤트 등록

khAPI.OnReceiveTrData += khAPI_OnReceiveTrData;

private void khAPI_OnReceiveTrData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent e)
        {
            ScreenNumber sn = ScreenNumber.GetSingInstance(e.sScrNo);
            if (sn.ExNotNull() && sn.OnCompleted.ExNotNull())
                sn.OnCompleted(e);
        }

 

public void GetStockInfo(string code, Action<KHStock, string> completedHandler)
        {
            khAPI.SetInputValue("종목코드", code);
            ScreenNumber sn = ScreenNumber.GetNext();

            int result = khAPI.CommRqData("주식기본정보", "OPT10001", 0, sn.No);
            if (KHError.IsError(result))
            {
                string msg = KHError.ErrorMsg(result);

                if (completedHandler.ExNotNull())
                {
                    completedHandler(null, msg);
                }
            }
            else
            {
                sn.OnCompleted = (p) =>
                {
                    if (completedHandler.ExNotNull() && p is AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent)
                    {
                        AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent e = p as AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent;

                        if (code.ExNotNullOrEmpty())
                        {
                            KHStock stock = KHStock.GetSingInstance(code);
                            if (stock.Name.ExIsNullOrEmpty())
                            {
                                stock.Name = khAPI.GetCommData(e.sTrCode, e.sRQName, 0, "종목명").ExStringTrim();
                            }

                            stock.Price = (khAPI.GetCommData(e.sTrCode, "", 0, "현재가").ExStringTrim()).ExInt();
                            stock.FluctuationRate = (khAPI.GetCommData(e.sTrCode, "", 0, "등락율").ExStringTrim()).ExDouble();
                            stock.Volume = (khAPI.GetCommData(e.sTrCode, "", 0, "거래량").ExStringTrim()).ExInt();


                            completedHandler(stock, string.Empty);

                        }
                    }
                };

            }

        }  

코드 설명

SccreenNumber도 HKStock 와 같은 방식으로 넘버 기준으로 싱글 인스턴스로 구성 하였다.

SccreenNumber에는 No와 OnCompleted 델리게이트가 존재 한다.

종목 호출부 와 종목 결과 이벤트부분이 서로 떨어져 있어 호출부에서 결과를 받아 리턴할수 있게 구성하였다.

ScreenNumber.cs
0.00MB
KHErrorCode.cs
0.00MB

 

 

(ScreenNumber,KHErrorCode 내용은 수시로 변경 될 수 있다)

 

*종목 정보를 조회하면 자동으로 실시간 시세가 등록되어 시세변경시 이벤트를 받을수 있다

2. 실시간 시세

 int result = khAPI.SetRealReg(스크린넘버, 종목리스트, 검색 필드, "1"); 0 실시간등록/1실시간 추가등록

생성자에 이벤트 등록

khAPI.OnReceiveRealData += khAPI_OnReceiveRealData;

private void khAPI_OnReceiveRealData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealDataEvent e)
        {
            if (e.sRealType == "주식체결")
            {
                KHStock stock = KHStock.GetSingInstance(e.sRealKey);
                stock.Price = khAPI.GetCommRealData(e.sRealKey, 10).ExStringTrim().ExInt(); // 현재가
            }
        }

 public void SetRealStock(List<string> codes)
        {
            ScreenNumber sn = ScreenNumber.GetSingInstance(ScreenNumber.REALTIMENUMBER);
            string strCodeList = string.Empty;
            foreach (string code in codes)
            {
                if (strCodeList.ExNotNullOrEmpty())
                    strCodeList += ";" + code;
                else
                    strCodeList = code;
            }
            int result = khAPI.SetRealReg(sn.No, strCodeList, "10;12;16;17;18;", "1");
            if (KHError.IsError(result))
            {
                string msg = KHError.ErrorMsg(result);
            }
        }

 

 

반응형

댓글