AAT_Phase 1. Store stock price data

'졸업작품 (AAT)' 시리즈AAT_Phase 1. Store stock price data

mildsalmon

흔치않고, 진귀하다.

Sign in to view email

공부를 통해 새로 알게된 부분

  • sqlite3 - 파이썬 표준 라이브러리 - DB를 쉽게 이용할 수 있다.

    • .version - sqlite3 모듈의 버전
    • .sqlite_version - sqlite 버전
    • 데이터 베이스 생성
      • connect 함수 - Connection 객체 생성
        • 인자값 1. 생성할 데이터베이스 파일의 경로 및 이름.
    • Connection 객체
      • Cursor 객체 - SQL 구문을 호출하려면 필요.
        • 메서드
          • .execute(SQL)
            • 인자값 1. SQL 구문
              • CREATE TABLE (table)(~) - 테이블 만들기
              • INSERT INTO (table) VALUES(~) - 테이블 안으로 VALUES 삽입
              • SELECT * FROM (table) - 테이블의 모든 것을 선택
          • .fetchone() - 선택한 테이블로부터 로우 단위로 데이터를 읽음 / 호출한 로우는 사라짐 / 리스트에 저장해서 인덱싱으로 사용 가능
          • .fetchall() - 한 번에 모든 로우를 읽기 위해 사용
      • 메서드
        • .commit() - 지금까지 작업한 내용을 DB에 반영
        • .close() - DB 연결을 닫는다.
    • 열 (칼럼(column)), 행 (로우(row)), 테이블 (칼럼&로우의 2차원 데이터 구조)
    • SQL 구문 사용.
  • Pandas의 DataFrame 객체로 데이터를 DB에 저장하기

    • 메서드

      • .to_sql() - 명시적으로 SQL 구문을 사용하지 않고도 to_sql 메서드로 데이터 저장 가능 / 테이블에 DataFrame 객체의 내용을 저장.

        • 인자값 1. 테이블, 2. Connection 객체

        • DataFrame.to_sql(name, con, flavor='sqlite', schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None)

          파라미터 설명 name SQL 테이블 이름으로 파이썬 문자열로 형태로 나타낸다. con Cursor 객체 flavor 사용한 DBMS를 지정할 수 있는데 'sqlite' 또는 'mysql'을 사용할 수 있다. 기본값은 'sqlite'이다.schema Schema를 지정할 수 있는데 기본값은 None이다. if_exists 데이터베이스에 테이블이 존재할 때 수행 동작을 지정한다. 'fail', 'replace', 'append' 중 하나를 사용할 수 있는데 기본값은 'fail'이다. 'fail'은 데이터베이스에 테이블이 있다면 아무 동작도 수행하지 않는다. 'replace'는 테이블이 존재하면 기존 테이블을 삭제하고 새로 테이블을 생성한 후 데이터를 삽입한다. 'append'는 테이블이 존재하면 데이터만을 추가한다. index DataFrame의 index를 데이터베이스에 칼럼으로 추가할지에 대한 여부를 지정한다. 기본값은 True이다.index_label 인덱스 칼럼에 대한 라벨을 지정할 수 있다. 기본값은 None이다. chunksize 한 번에 써지는 로우의 크기를 정숫값으로 지정할 수 있다. 기본값은 None으로 DataFrame 내의 모든 로우가 한 번에 써진다. dtype 칼럼에 대한 SQL 타입을 파이썬 딕셔너리로 넘겨줄 수 있다.

        • DataFrame 객체에 많은 로우가 있다. 이를 데이터베이스 한 번에 쓰는 경우 패킷 크기 제약으로 에러가 발생 가능 / chunksize 인자로 한 번에 데이터베이스로 저장될 로우의 개수를 지정.

    • 함수

      • .read_sql() - 데이터베이스의 테이블을 DataFrame 객체로 읽어오기 위해 사용.
        • 인자값 1. SQL 구문, 2. Connection 객체, index_col 인자는 DataFrame 객체에서 인덱스로 사용될 칼럼; 기본값은 None -> 0부터 시작하는 정숫값이 인덱스로 할당
  • Pandas를 이용한 주가 데이터 저장 / DataReader 함수는 DataFrame 객체를 만듬 / DataFrame 객체에서 to_sql 메서드 사용.

  • 키움 OPEN API+

    • 메서드

      • GetCodeListByMarket - 각 시장에 속하는 종목의 종목 코드 리스트를 얻을 수 있다.

        bstr GetCodeListByMarket(LPCTSTR sMarket) 인자-시장 구분- 0:장내, 3:ELW, 4:뮤추얼펀드, 5:신주인수권, 6:리츠, 8:ETF, 9:하이일드펀드, 10:코스닥, 30:K-OTC, 50:코넥스(KONEX) 반환값-종목 코드 리스트,종목간 구분은';'이다.

      • GetMasterCodeName - 종목 코드로 한글 종목명을 얻어온다.

        인자-종목 코드 반환값-종목 한글명

      • SetInputValue - Tran 입력 값을 서버 통신 전에 입력한다.

        void SetInputValue(BSTR sID, BSTR sValue) 인자값= sID -아이템 명, sValue -입력 값 반환값= x

      • CommRqData - Tran을 서버로 송신한다.

        • CommRqData를 통해 키움증권 서버에 TR을 요청하면 데이터가 바로 반환되는 것이 아니다.
        • 키움증권 서버는 TR을 처리한 후, 이벤트를 통해 알려준다. / 이벤트를 줄 때까지 대기해야 한다. → CommRqData를 호출한 후에 이벤트 루프를 만들어주는 코드가 필요하다.

        LONG CommRqData(BSTR sRQName, BSTR sTrCode, long nPrevNext, BSTR sScreenNo) 인자값= sRQName –사용자구분 명 sTrCode - Tran명 입력 nPrevNext - 0:조회, 2:연속 sScreenNo - 4자리의 화면번호 반환값= OP_ERR_SISE_OVERFLOW –과도한 시세조회로 인한 통신불가 OP_ERR_RQ_STRUCT_FAIL –입력 구조체 생성 실패 OP_ERR_RQ_STRING_FAIL –요청전문 작성 실패 OP_ERR_NONE –정상처리

      • GetRepeatCnt - 레코드의 반복횟수를 반환한다.

        LONG GetRepeatCnt(LPCTSTR sTrCode, LPCTSTR sRecordName) 인자값= sTrCode – Tran명sRecordName –레코드 명 반환값=레코드의 반복횟수

      • CommGetData - 키움증권 서버로부터 TR처리에 대한 이벤트가 발생했을 때 데이터를 가져올 때 사용.

        1. CommGetData 원형BSTR CommGetData(…) 설명 이 함수는 지원하지 않을 것이므로 용도에 맞는 전용 함수를 사용할 것(비고참고) 입력값 반환값 비고 조회 정보 요청- openApi.GetCommData(“OPT00001”, RQName, 0, “현재가”); 실시간정보 요청- openApi.GetCommRealData(“000660”, 10); 체결정보 요청- openApi.GetChejanData(9203);
    • 이벤트 (이벤트(시그널) → 메서드(슬롯))

      • OnReceiveTrData - TR 요청의 결과로 발생

        • receive_tr_data 메서드가 호출됐다는 것은 / 키움서버로부터 'OnReceiveTrData' 이벤트가 발생했다는 것을 의미 / 즉, receive_tr_data 메서드 내에서 서버로부터 데이터를 받아오면 된다.

        OnReceiveTrData 원형 void OnReceiveTrData(LPCTSTR sScrNo, LPCTSTR sRQName, LPCTSTR sTrCode, LPCTSTR sRecordName, LPCTSTR sPreNext, LONG nDataLength, LPCTSTR sErrorCode,LPCTSTR sMessage, LPCTSTR sSplmMsg) 설명 서버통신 후 데이터를 받은 시점을 알려준다. 입력값 sScrNo –화면번호 sRQName –사용자구분 명 sTrCode – Tran명 sRecordName – Record명 sPreNext –연속조회 유무 nDataLength – 1.0.0.1버전 이후 사용하지 않음. sErrorCode – 1.0.0.1버전 이후 사용하지 않음. sMessage – 1.0.0.1버전 이후 사용하지 않음. sSplmMsg - 1.0.0.1버전 이후 사용하지 않음. 반환값 없음 비고 sRQName – CommRqData의sRQName과 매핑되는 이름이다. sTrCode – CommRqData의sTrCode과 매핑되는 이름이다.

        _receive_tr_data메서드 구현시3가지 고려사항.

        1.여러 종류의TR을 요청해도 모두_receive_tr_data메서드 내에서 처리해야함. rqname인자를 통해 요청한TR을 구분한 뒤TR에 따라 데이터를 가져오도록 작성. -> rqname값이opt10081_req일때_opt10081메서드를 호출. TR을 요청할 때TR을 구분하기 위한 적당한 문자열을 사용. 데이터를 받을 때는 해당 문자열과 같은지 확인함으로 올바른 데이터를 얻을 수 있다.

        2.연속조회에 대한 처리. 연속조회는 아직 데이터가 존재한다는 것을 의미. TR을 한 번 요청하면900개의 데이터가 반환된다. / 10년치 데이터를 한 번의TR요청으로 받을 수 없다. 이런 경우TR을 또 요청해서 남은 데이터를 받아야 한다. 키움 증권 서버는OnReceiveTrData이벤트가 발생할 때PrevNext인자값을 통해 연속조회가 필요한 경우PrevNext값을2로 리턴. 따라서PrevNext값을 보고2이면 데이터가 더 있다는 사실을 알 수 있고, 이 경우 동일한TR을 한 번 더 요청해서 남은 데이터를 가져와야 한다.

        아래 코드는_receive_tr_data메서드의 인자인next의 값이'2'일 때self.remained_data라는 변수에True를 저장.

        3.이벤트 루프에 대한 처리. CommRqData를 호출할 때 이벤트 루프를 생성했다. 이벤트 루프 덕분에 키움 증권 서버가OnReceiveTrData이벤트를 보낼 때까지 대기할 수 있었다.

          Kiwoom클래스의_receive_tr_data메서드가 호출됐다는 것은
          정상적으로 대기 상태에서 머무르다가 서버로부터 발생한OnReceiveTrData이벤트를 받았음을 의미.
          따라서_receive_tr_data메서드에서 더는 필요하지 않은 이벤트 루프를 종료.

        opt10081_req에 대한 데이터는 opt10081 메서드에서 처리. 이는 각 TR에 대한 데이터를 얻어가는 코드를 _receive_tr_data에 모두 구현하기 보다는 메서드로 따로 빼서 구현한 것.

    • TrCode

      • OpenAPI+가 제공하는 TR을 사용하려면, SetInputValue 메서드를 통해 요청하는 TR에 필요한 데이터를 설정한 후, CommRqData 메서드를 호출해 TR을 키움증권 서버로 전송. / TR 요청받은 서버는 이를 처리한 후 데이터가 준비되면, 이벤트를 발생, 사용자가 데이터를 가져갈 수 있게 알려준다.
      • TR
        • opt10081 - 일봉 데이터 연속 조회
      • 키움은 초당 TR 요청 수를 제한한다. 이 제한을 초과할 경우 일정 시간 이용 정지, 연속될시 더 긴 시간 정지 당한다.
  • 메서드 이름에 _(언더스코어)가 있는 이유. / 주로 자신이 속한 클래스의 메서드에서 호출되기 때문.

  • 키움증권 / 로그인 요청을 받으면 → OnEventConnect 이벤트 발생 → eventconnect 메소드 연결

  • 키움증권 메서드 호출을 위해 dynamicCall 메서드 사용

  • PyQt

    • QEventLoop() - 이벤트 루프 생성.
  • Kiwoom 클래스는 QAxWidget 클래스를 상속받았기 때문에 / Kiwoom 클래스에 대한 인스턴스를 생성하려면 QApplication 클래스의 인스턴스를 생성해야 한다. / 그 다음 Kiwoom 클래스에 대한 인스턴스를 생성할 수 있다.

  • 에러

    • Process finished with exit code -1073741819 (0xC0000005) - 메모리 오류
    • 해결 - 마지막 줄에 app = None 작성.
  • 일봉 데이터를 pandas의 DataFrame 객체로 저장

    • 파이썬 자료구조를 DataFrame 객체로 만드는 방법 → 파이썬 딕셔너리를 사용하는 것
    • 키움 클래스의 인스턴스를 생성한 후, 딕셔너리 추가
    • 딕셔너리 키에 대응되는 파이썬 리스트에 값 추가
    • 딕셔너리를 DataFrame 객체로 변환

좀 더 공부해야하는 부분

  • 키움 OPEN API+
    • 메서드와 이벤트 & TrCode
  • DB → sqlite3도 간편하지만, MongoDB같은 no-sql을 사용할 예정

한줄평

오늘은 Kiwoom OPEN API+ 의 메소드와 이벤트가 많이 나왔다. 정상적으로 작동하지 않으면 어떻하나 싶었지만. 발생한 에러도 쉽게 수정 가능 했고, 우려했던 부분들도 정상적으로 잘 작동했다. 이제 실전 개발 챕터만 남았다. 예상 기일보다 오래 걸린 듯 하다. 주말 알바, 개강 등의 특수성을 고려하지 못하고 계획을 세워서 그런 듯 하다. 어찌됐든 미리 시작한게 이런 부분들에서 이점이 있는 것 같다. 기한이 조금 더 길어서, 타이트한 계획을 세워도 여유롭게 해결이 가능하다는 것. 기한 내에 마무리를 못해도 여유 기간이 있다는 것.

오늘 작성한 코드

Store stock price data · mildsalmon/AAT@28763e8


'졸업작품 (AAT)' 시리즈
실시간 작업 진행 상황을 Notion page를 통해 확인하실 수 있습니다. (https://www.notion.so/mildsalmon/AAT-34c0c21f8f0a474faf2bbc499dd6d0b3)
작성된 댓글이 없습니다!
로그인된 사용자만 댓글을 작성할 수 있습니다.