티스토리 뷰

키움 조회제한


자동 트레이딩 시스템을 만들기 위해 가장먼저 해야 할일은 데이터를 수집하는 일이다. 수집한 데이터를 기반으로 다양한 전략을 백테스팅하고 그중에 쓸만한 몇몇을 추려서 실전에 적용해봐야 한다. 키움증권에서 open api를 통해 다양한 정보를 제공하고 있는데, 주식에서 가장 기본정보인 분봉/일봉/주봉/월봉 데이터를 수집해서 DB에 저장해본다.



KOA Studio 를 이용하면 해당 정보를 가져오는 방법을 알수 있다. KOA Studio 다운로드




이때 주의할 점은 키움증권 open api 서버 과부하 방지를 위해 조회제한이 걸려있다는 점이다. 이를 무시하고 과도하게 request를 하게 되면 아래와 같은 팝업이 뜨고 트레이딩 시스템이 Stop 된다.






조회횟수 제한은 현재(2018년 7월 1일) 기준으로는 다음과 같다.


따라서, 프로그램을 만들때 1초에 5회이상 조회하지 않도록 잘(?) 코드를 작성해야 한다. 근데, 실제로 1분봉 데이터를 DB에 저장하는 프로그램을 돌려보니 1초에 5회이상 요청을 하지 않더라도 특정 시간안에 몇회 이상 조회요청을 하게 되면 동일한 팝업이 등장하는 것을 경험으로 확인했다.. -_-


(경험적으로 알게된) 키움 Open Api 조회제한 발생하는 케이스

  1. 1초에 5회이상
  2. 70초에 100회이상
  3. 600초에 700회이상
  4. 1000회 이상

조회제한 문제를 해결하기 위해 kw 패키지 내부에 tr_controller모듈을 만들어서, 조회제한 상황이 발생하기 전에 적절하게 delay 를 부여하도록 구현했다. 일단, 1번 케이스가 발생하지 않도록 매 요청 시 0.2초의 delay를 줬고, 2, 3번 case에 대해서도 (특정횟수/특정시간)에 적절한 delay 를 부여하여 조회제한에 걸리지 않도록 해결했는데, 문제는 4번이었다. 1분봉 데이터의 경우 kospi의 수많은 종목 데이터를 가져오려면 1000번은 훌쩍넘는 request를 날려야 하는데 요청횟수가 1000번에 도달하는 순간 경고팝업이 뜨면서 프로그램이 정지되어 버렸다. 따라서 이 문제를 해결하기 위해서는 요청횟수가 999번이 되면 재로그인을 수행하고 다시 1000번째 요청을 해야 하는데 이부분은 아직 구현을 못했다. 현재까지 확인한바로는 로그아웃 api는 없는것 같다. 그냥 프로그램을 종료시키고 다시 로그인을 하도록 구현해야 할것 같다.


조회제한 해결책

  1. 1초에 5회이상 -> 2초 delay 부여
  2. 70초에 100회이상 -> 20초 delay 부여
  3. 600초에 700회이상 -> 30초 delay 부여
  4. 1000회 이상 -> 방법없음..


Talib

Talib (Technical Analysis Library) 모듈을 설치하여 Open api에서 기본적으로 제공하는 Data에 추가적으로 다양한 주식관련 지표, 통계데이터를 보충하고자 한다. 봉데이터에서 가져올 수 있는 데이터는 아래 그림을 참고하면 되는데 현재가, 거래량, 체결시간 부터 전일종가까지 데이터를 가져올 수 있다. (하지만 실제로 데이터를 까보면 몇몇 데이터에는 Null 값이 들어가 있다.)



시스템 트레이딩을 위해서는 이러한 기본적인 정보를 기반으로 다양한 파생지표를 함께 분석하는 경우가 많은데, 대표적인 것이 이동평균선(이평선)일듯 싶다. 5일평균, 10일평균 등등 HTS에서 제공하는 다양한 지표(Index)를 open api 를 통해서는 받아볼수가 없는데, talib 에서 다양한 지표를 계산해주는 api를 제공하고 있기때문에 유용하게 사용할 수 있을 것 같다. 데이터 수집단계에서는 지표를 계산하여 DB에 저장할때 사용하면 되고, 실시간 트레이딩에서는 매수시그널을 만드는데 유용하게 활용될듯 싶다.


talib example 코드를 보면 numpy, pandas 에서 다루는 데이터 객체(ndarray, dataframe, series)를 인자로 받는 경우가 많은데 talib 를 제대로(?) 사용하기 위해서는 numpy, pandas를 선행적으로 좀 다룰줄 알아야 할듯 싶다.


Talib 관련 링크

  • http://mrjbq7.github.io/ta-lib/
  • https://www.ta-lib.org/


Talib 설치

$ pip install talib



Jenkins

시스템 트레이딩 개발을 하면서 매번 되풀이되는 반복작업의 경우 자동화 툴의 도움을 받아야 하는데, 자동화의 최고봉은 역시 Jenkins 라고 생각한다. Windows7 에 Jenkins를 설치하였고, 데이터 수집 스크립트를 안정화시키고 나면 Jenkins를 통해 Daily로 데이터를 수집하도록 셋팅해놓을 예정이다. 테스트로 현재 구현된 스크립를 돌려보니 역시 잘 돌아간다. 뿐만 아니라 수행했던 모든 이력(build)이 기록되고, 다양한 Jenkins plugin을 다른 시스템과의 collaboration, (예를 들면 github, slack)도 손쉽게 구현할 수 있다.


Jenkins Download


jenkins를 설치하고 loading시키는 과정은 매우 순조로웠는데, 중간에 갑자기 당황스러웠던 점은... login id와 pw가 뭔지 기억이 안나서 login을 할 수 없었던 점이다. 구글링을 해보니, jenkins 설치된 경로에서 config.xml 찾아서 아래와 같이 변경하면 된다고 해서 겨우 해결했다. 아래와 같이 설정변경 후 Jenkins service를 reboot 하면 된다. Stack Overflow Link


<useSecurity>true</useSecurity> -> <useSecurity>false</useSecurity>





Singleton Decorator

현재 내가 만들고 있는 트레이딩 시스템의 핵심모듈인 kw(키움open api package)은 내부적으로 다양한 클래스가 구현되어 있는데, 몇몇 클래스는 singleton으로 동작해야 한다. singleton을 직접 구현해도 되지만, 혹시 decorator로 누군가 만들어 놓지 않았을까.. 싶어서 검색해봤는데, 역시 있었다 -_-(!)


singleton-decorator




사용방법은 해당 모듈을 import하고 singleton으로 만들고 싶은 class 위에 @singleton이라고 명시하면 된다. 완전 편하다.




MongoDB

데이터를 수집하고나면, 데이터가 올바르게 잘 들어갔는지 확인도 해야하고, 해당 데이터를 가져와서 차트로 만들어서 분석도 해야하고, 추가할 지표가 있다면 보정(upsert)도 해야 하는데, 이 모든 작업을 위해서 mongo db query를 잘 다룰 수 있어야 한다. 데이터 수집 작업을 하면서 필요했던 기능은 bulk insert와 upsert 였는데, 사실 bulk insert의 경우 최초 1번만 의미가 있고, 이후에는 모두 upsert 를 통해서 작업을 수행했다. 


기존 문서 Update하기

update api 의 첫번째는 업데이트할 doc를 찾는 조건, 두번째는 신규doc, 마지막 upsert=True 를 명시하면 된다.

collection.update({'date': doc['date'], 'code': doc['code']}, doc, upsert=True)



날짜로 정렬하여 주식데이터 가져오기

collection의 find를 이용하면 특정 조건에 해당하는 doc 묶음을 가져올 수 있는데, 이때 sort 를 사용하면 doc묶음을 정렬된 상태로 가져올 수 있다. 또한 limit를 chain call 하게 되면 전체가 아닌 특정 갯수만 가져올 수 있다.

cursor = col.find({'code': '066570'}).sort('date', -1).limit(100)

df = pd.DataFrame(list(cursor))

date = df['date'][-50:]
high = df['고가'][-50:]
low = df['저가'][-50:]
close = df['현재가'][-50:]
ret = ta.ATR(high, low, close)
plt.plot(date, ret[-50:], color='yellow')
plt.show()



댓글