전문가칼럼

DBMS, DB 구축 절차, 빅데이터 기술 칼럼, 사례연구 및 세미나 자료를 소개합니다.

이제는 말할 수 있다: 주식 자동매매 프로그램(하)

전문가칼럼
DBMS별 분류
Oracle
작성자
dataonair
작성일
2015-10-14 00:00
조회
21043




◎ 연재기사 ◎


물탱크 구조로 알아본 오라클의 블록 옵션 ‘PCTFREE와 PCTUSED’


이산가족 찾기 생방송을 통해 배우는 DB 원리


개발자에게 맞는 DB 공부방법 찾기: 물리적 분류와 논리적 분류 그리고 인덱스


데이터베이스 인덱스의 오해와 진실


쉬운 것이 올바른 것이다. ‘인덱스 끝장리뷰’ (상)


쉬운 것이 올바른 것이다. ‘인덱스 끝장리뷰’ (하)


누구도 알려주지 않았던 ‘오라클 인덱스 생성도’의 비밀


누구도 알려주지 않았던 ‘오라클 쿼리 작성의 비법’


퀴리 최적화 및 튜닝을 위한 오라클 공정쿼리 작성법


만능 쿼리와 한 방 쿼리


오라클 옵티마이저 ‘CBO와 RBO’ 이해하기


재미있는 DB 이야기 ‘60갑자와 쿼리’


그림으로 배우는 ‘오라클 조인의 방식’ 이야기


반드시 알아야 하는 오라클 힌트절 7가지


오라클 플랜을 보는 법


개발자들의 영원한 숙제 ‘NULL 이야기’


알면 유용한 오라클 기능 ‘GATHER_PLAN_STATISTICS’


알면 유용한 오라클 기능들


오라클 DICTIONARY를 활용한 DB툴 프로그램 ‘FreeSQL’


이제는 말할 수 있다: 주식 자동매매 프로그램(상)


이제는 말할 수 있다: 주식 자동매매 프로그램(하)


개발자들이 자주 접하는 오라클 에러 메세지


재미있는 DB 이야기 ‘사라진 날짜를 찾아라’


오라클 랜덤 함수와 사용자 정의 함수


그림으로 배우는 ‘공정쿼리와 인덱스 생성도’


이병국의 개발자를 위한 DB 이야기: 디폴트 세팅의 함정과 오라클 파라미터


재미있는 DB 이야기 ‘놀라운 마방진의 세계’


오라클 운반 최소 단위 BLOCK


이병국의 개발자를 위한 DB 이야기: 이세돌과 알파고의 세기의 대결


이병국의 개발자를 위한 DB 이야기(30회) : DB 엔지니어의 가볍게 읽는 세상 이야기


이병국의 개발자를 위한 DB 이야기: 튜닝(31회) : 개발자를 위한 DB 튜닝 실전(1편)


이병국의 개발자를 위한 DB 이야기: 튜닝(32회) : 개발자를 위한 튜닝 실전(2편)


이병국의 개발자를 위한 DB 이야기: 튜닝(33회) : 개발자를 위한 튜닝 실전(3편)


이병국의 개발자를 위한 DB 이야기: 튜닝(34회) : 개발자를 위한 DB 튜닝 실전(4편)


이병국의 개발자를 위한 DB 이야기: 튜닝(35회) : 개발자를 위한 튜닝 실전(5편)


이병국의 개발자를 위한 DB 이야기: 페이징 처리에 대한 이해 (36회)


보기 좋은 떡이 먹기도 좋다 - 좋은 쿼리 좋은 성능


테이블의 수직분할과 수평분할에 대한 이해


DB 성능 제고를 위한 채번의 이해와 방식별 장단점 비교


이병국의 개발자를 위한 DB 이야기: 마지막회 : ‘개발자를 위한 DB 이야기’ 연재를 마치며



이병국의 개발자를 위한 DB 이야기: 프로그램 (21회)

이제는 말할 수 있다: 주식 자동매매 프로그램(하)



성공과 실패의 경험을 나누자, 용기와 희망을 나누자

개발업무를 시작으로 IT 업계에 입문했던 필자가 10년 가까이 DB 엔지니어로 활동하면서 얻은 경험과 지식을 나누고자 한다. DB를 자주 접하는 SW 개발자뿐 아니라, DB 전문가를 꿈꾸는 대학생에서 DB 분야에 입문한 지 1~2년이 된 기 입문자가 쉽게 이해할 수 있도록 비유를 통해 접근해볼 계획이다. 물론 전문가들이라도 다시 한번 개념을 정립하는 의미에서 필요한 내용이 될 수 있다.

전체적으로 DB의 기본 원리와 개념을 이해하고 테이블, 인덱스, 쿼리, 튜닝, 플랜 등 개발자들이 알아야 하는 DB 전분야에 대해 쉽게 이해하도록 설명하겠다. DB 기술서적이나 번역서보다는 조금 더 부드럽게 접근할 계획이다. 그렇다고 흔히 서점에서 만날 수 있는 개발자 위주의 SQL 소개서도 아니다. 이 연재는 시리즈로 나갈 것이다. 연재를 끝까지 읽는 독자가 준전문가 수준으로 DB 원리를 알 수 있게 하는 것이 목표다.



주식 자동매매 프로그램은 크게 다음과 같이 3가지로 나눌 수 있다.

1. 공시나 뉴스를 수집하는 프로그램 (수집 프로그램)
2. 수집된 공시나 뉴스를 분석하는 프로그램 (분석 프로그램)
3. 분석된 내용에 따라 주식을 자동으로 매수하는 프로그램 (매매 프로그램)



공시-뉴스 수집 프로그램

먼저 첫번째 프로그램인 수집 프로그램에 대한 설명이다. 공시나 뉴스 정보는 여러 경로를 통하여 수집할 수 있다. 대표적으로 증권사에서 제공하는 주식매매 프로그램인 HTS(Home Trading System)가 있고, 인터넷 포털 사이트인 네이버-다음-기타 여러 뉴스 사이트가 있다.

column_img_2118.jpg

[그림 1] 공시-뉴스 수집 프로그램 구성

공시-뉴스 수집 프로그램은 각각의 수집 경로에 대해서 1:1로 대응할 수 있게 개발됐다. 위 그림의 예에서는 5개의 수집 프로그램이 있어야 할 것이다. 이는 각 수집 매체의 정보 수집 시점이나 방법이 다르고 또한 수집 매체의 특성에 따라 프로그램 구현 방법이 다르기 때문이다.

각각의 수집 프로그램은 타이머를 이용해 0.1~1초 이내의 시간 간격으로 주기적으로 정보를 수집한다. 네이버와 같은 웹사이트는 HTML 소스를 읽어서 파싱하여 정제된 뉴스를 DB에 저장하는데 타이머 시간은 1초로 설정한다. 주식 매매 프로그램인 증권사 HTS는 Spy++ 프로그램을 이용해 핸들 값을 미리 구한 후, 윈도우 API를 활용해 공시-뉴스 정보를 수집해 DB에 저장한다. 이때 타이머 설정 값은 0.1초다.

column_img_2119.jpg

[그림 2] 공시-뉴스 수집 프로그램 흐름

사이트에서 HTML 소스를 읽어서 파싱하는 방법은 웹 검색으로 쉽게 찾을 수 있으므로 여기서는 설명하지 않겠다. 참고적으로 사이트에서 공시-뉴스가 제공되는 시점보다 증권사 HTS를 통해 제공되는 시점이 휠씬 빠르다. 그 중에서도 현대증권의 HTS에서 제공하는 공시-뉴스 시점이 가장 빨랐다. 그래서 필자가 개발한 프로그램을 통한 매수 주문은 대부분 현대증권을 통해 이뤄졌다.

여러 수집 매체에서 동일한 뉴스가 연달아 제공될 때에는 가장 먼저 수집된 정보만 DB에 저장하고 나머지는 SKIP 처리했다. 그 당시 여러 증권사 HTS에서 동일한 뉴스가 1초 이내의 시간에 거의 동시적으로 수집되었다. 1초라는 시간은 큰 차이가 아닌 것으로 생각할 수 있지만 주식시장의 초단타 매매에서는 천당과 지옥을 오가기에 충분한 시간이다.

위에서 언급한 핸들값, Spy++, API의 의미와 기능은 다음과 같다.

핸들값
핸들은 윈도우가 보호하는 곳에 생성된 객체의 값을 가리키는 값이라고 보면 된다. 프로그램의 입력필드나 조회필드, 동작버튼은 각각 고유한 값을 가지고 있다. 즉 화면을 구성하는 객체에는 윈도우 고유의 값이 있는데, 이것이 바로 핸들값이다.

Spy++
핸들값을 알고자 할 때 사용하는 프로그램이 Spy++이다. Spy++는 비주얼 베이직(Visual Basic)을 설치하면 추가적으로 생기는 부가 프로그램이다. Spy++를 그냥 사용해도 되고 아니면 검색으로 더 좋은 핸들값을 구하는 프로그램을 다운받아 사용해도 된다.

API
핸들값을 알면 타 프로그램의 각종 입력필드, 조회필드, 동작버튼을 통제할 수 있다. 타 프로그램의 입력필드에 값을 줄 수도 있고, 조회필드의 값을 읽어 올 수도 있으며, 동작 버튼을 클릭 할 수도 있다는 의미다. 이러한 기능을 수행할 수 있게 하는 것이 바로 API(Application Programming Interface)이다.

가남사에서 나온 『Windows API 정복』이란 책을 참고 하였다. 이 책은 1,500페이지 이상의 두꺼운 책이지만 실제로 사용한 예는 일부분에 지나지 않는다. 주로 다음과 같은 API 기능을 사용했다.

GetCursorPos - 마우스 커서의 위치값을 구하는 API
WindowFromPoint - 마우스 좌표에 위치한 윈도우 핸들값을 알아내는 API
FindWindow - 부모 객체의 핸들값을 구할 때 사용하는 API
FindWindowEx - 자식 객체의 핸들값을 구할 때 사용하는 API
SetForegroundWindow - 지정된 객체에 포커스 줄 때 사용한다. (창을 맨 앞에 오게 하는 API)
SendMessage - 지정된 메시지를 보내는 API (값 읽기, 값 쓰기, 버튼 클릭하기 등)
GetWindowText - 윈도우나 컨트롤의 캡션(또는 텍스트)을 가져오는 API

이 중에서 공시-뉴스 정보를 수집할 때 사용한 API는 SendMessage다. 자세한 사용 방법은 책에 자세히 기술되어 있다. 인터넷 검색으로도 충분히 내용을 알 수 있을 것이다.

column_img_2120.jpg

[그림 3] API 이용해 타 프로그램 제어하기

위의 [그림 3]은 뉴스를 수집하는 프로그램에 대한 간략한 설명이며 그 순서는 아래와 같다. (단, 현대증권 HTS 프로그램의 뉴스 화면은 실시간으로 Refresh 되는 뉴스 티커창 화면임)

ㅇ Spy++ 를 이용해 사전에 현대증권 HTS 프로그램의 뉴스창 객체에 대한 핸들값을 구한다.
ㅇ 뉴스수집 버튼(API 호출)을 클릭해 뉴스 내용을 구한 후 새로운 뉴스이면 DB에 저장한다.
ㅇ 타이머를 설정해 0.1초 간격으로 뉴스수집 버튼을 클릭하게 한다.



공시-뉴스 분석 프로그램

수집된 공시-뉴스를 분석하는 프로그램을 말한다. 공시-뉴스 분석 쿼리를 통해 정보의 호재성 여부를 판단한다. 또한 종목코드의 종목 분석을 통해 주문 가능한 종목인지 검토해 매수 여부를 결정한다.

column_img_2121.jpg

[그림 4] 공시-뉴스 분석 프로그램 구성

수집된 공시-뉴스 내용의 호재성 여부를 사람이 직접 보고 판단한다면 쉽게 매수 결정을 할 수 있겠지만, 주식자동매매 프로그램에서는 호재성 뉴스인지 악재성 뉴스인지 프로그램이 스스로 판단해서 매수 여부를 결정해야 한다.
결국 공시-뉴스 내용에 대한 분석 알고리즘이 좋아야 한다. 필자는 검색단어 테이블과 분석 쿼리를 이용해 뉴스의 호재성 여부를 다음과 같이 간단히 해결 했다.

‘검색단어’ 테이블의 칼럼 구성 및 내용은 아래와 같다.



--------------------------------------------------------------------------------------
번호 단어 구분 점수(10점 만점) …
--------------------------------------------------------------------------------------
1 최초 긍정 5
2 특허 긍정 7
3 수출 긍정 3
4 무산 부정 0
5 취소 부정 0
6 무상증자 긍정 5
7 부도 부정 0
… … … …
--------------------------------------------------------------------------------------



뉴스 내용은 아래와 같다고 가정하자.



--------------------------------------------------------------------------------------
[종목 041460] 한국전자인증
--------------------------------------------------------------------------------------
핀테크 관련하여 정부는 향후 10년간 3,000억 원의 기술 지원금을
책정하였고 정책적으로 기술 진입에 대한 불합리한 제도적 장벽을
조기에 없애기로 국무회의에서 논의하였다.
이와 관련하여 최대 수혜주로 한국전자인증이 떠오르고 있다.
세계 최초로 모바일과 생체인식에 기반한 비접촉 결제 방식을 특허
출원하였다고 회사 관계자는 전하였다.
….
--------------------------------------------------------------------------------------



분석 쿼리의 내용은 아래와 같이 작성한다.



--------------------------------------------------------------------------------------
SELECT NVL(SUM(점수),0) AS 점수
FROM 검색단어
WHERE '뉴스내용' LIKE '%' || 단어 || '%‘
AND NOT EXISTS (
SELECT 'X'
FROM 검색단어
WHERE '뉴스내용' LIKE '%' || 단어 || '%‘
AND 구분 = ‘부정’
)
--------------------------------------------------------------------------------------



우리가 평소에 경험하는 일반적인 LIKE 구문은 다음과 같다. WHERE 칼럼 LIKE ‘%값%’ 칼럼이 왼쪽에 위치하고 값은 오른쪽에 위치한다.

분석 쿼리에서는 LIKE 구문이 가장 핵심인데, LIKE 구문을 다음과 같이 특이하게 사용했다. WHERE ‘값’ LIKE ‘%’ || 칼럼 || ‘%’값이 왼쪽에 위치하고 칼럼은 오른쪽에 위치한다.

위의 분석 쿼리는 간단하게 구현한 것이다. 필자가 실제로 사용한 쿼리는 좀 더 다양한 조건들이 포함되어 있다. 이처럼 분석 쿼리를 통해 호재성 뉴스 여부를 판단했다고 해도 바로 주문을 해서는 안된다. 왜냐하면 매수 종목에 대한 분석도 병행해야 하기 때문이다. 매수 종목에 대한 분석은 프로시저로 구현했는데 아래와 같은 내용들로 이루어져 있다.

1. 매수종목의 거래량이 일정 기준 이상이어야 한다. 거래량이 많지 않은 종목을 자동 주문하면 스스로 상한가를 만드는 경우가 있기 때문이다.
2. 매수 종목의 거래금액이 일정 기준 이상이어야 한다.
3. 공시나 뉴스에 대한 매수 종목의 민감도 수치가 기준치 이상이어야 한다. 예를 들어 삼성전자의 경우 특허 취득 공시에 대한 민감도는 아주 낮아 주가의 변동이 거의 없다. 이처럼 대기업의 경우는 특허 취득 공시에 대한 민감도가 낮은 편이다.
4. 최근 수일간 주가 변동폭이 큰 종목은 배제한다. 공시-뉴스에 이미 반영 되었을 가능성이 크다.
5. 거래 정지나 유의 종목은 배제한다.
6. 동일한 내용의 뉴스가 최근에 발생했는지 확인한다. 공시 이후에 뉴스가 나오기도 하고, 뉴스 이후에 공시가 발표되기도 하기 때문이다. 공시-뉴스의 소재가 재탕일수도 있기 때문이다.
7. 수출 계약 체결 등과 같은 경우 체결 금액의 수치가 중요하다. 매출액 대비 체결 금액의 비율에 따라 대규모 수출 계약일 수도 있고, 미미한 수출 계약이 될 수도 있기 때문이다.
8. 특허 취득 보다는 세계 최초 특허 취득이 더 좋은 공시-뉴스다. 내용에서 호재성 단어의 복합적인 부분에 가중치를 부여할 필요가 있다. (쿼리로 구현 가능함)
9. 기타 수많은 분석 케이스에 대한 적합성 여부를 확인한다. (이하 생략)
10. 최종적으로 주식 자동매수 가능 여부 및 적절한 매수 규모를 결정한다.

column_img_2122.jpg

[그림 5] 공시-뉴스 분석 프로그램 흐름



주식 자동매매 프로그램

수집된 공시-뉴스 내용에 대한 분석쿼리 결과가 호재성이고, 해당 종목코드에 대한 종목 분석이 매수 가능으로 판단되면 이제 주식을 자동으로 매수해야 한다.

column_img_2123.jpg

[그림 6] 주식 자동매매 프로그램 구성

증권사 HTS을 제어할 수 있도록 사전에 핸들값은 Spy++ 프로그램을 이용해 구해 놓아야 한다. 필요한 핸들값 대상 객체는 다음과 같다.

매수창: 종목코드, 매수수량, 매수단가, 매수버튼 등
매도창: 종목코드, 매도수량, 매도단가, 매도버튼 등
챠트창: 종목코드, 조회버튼 등

주식 자동매매 프로그램에서는 다음과 같은 API 기능을 사용했다.

FindWindow - 부모 객체의 핸들값을 구할 때 사용하는 API
FindWindowEx - 자식 객체의 핸들값을 구할 때 사용하는 API
SetForegroundWindow - 지정된 객체에 포커스 줄 때 사용한다. (창을 맨 앞에 오게 하는 API)
SendMessage - 지정된 메시지를 보내는 API (값 읽기, 값 쓰기, 버튼 클릭하기 등)
GetWindowText - 윈도우나 컨트롤의 캡션(또는 텍스트)을 가져있다. 혹은 인터넷 검색으로도 충분히 내용을 알 수 있다.

column_img_2124.jpg

[그림 7] 주식 자동매매 프로그램 흐름

정해진 규칙에 따라 자동매수가 성공적으로 이루어지면 음악 파일을 실행하여 매수 사실을 알린다. 그 당시 다른 개발 업무를 병행하고 있었기 때문에 주식 화면만 계속해서 쳐다볼 수 없었기 때문이다. 이후 매수한 수량만큼 매도 준비를 API를 통해 자동 설정하고, 해당 종목의 주가 차트 그래프를 API를 통해 조회한다. 여기까지 프로그램이 자동으로 진행한다. 이후 매도는 사람의 판단(감)에 따라 적절한 시점에 매도한다. 주식매도까지 전 과정을 프로그램이 자동으로 진행하기엔 위험 부담이 너무 크기 때문이다. 매수 및 매도가 끝나면 최종적으로 수익정산 데이터를 DB에 저장한다.



테이블 구성에 대한 이해

프로그램 규모에 비해 사용하는 테이블은 의외로 많지 않다. 사용된 주요 테이블은 아래와 같다.

종목코드 - 주식 종목 코드에 대한 기본적인 정보
종목정보 - 종목코드의 기본 정보 이외에 추가적인 정보 및 종목 분석에 관련한 내용
공시 - 수집 매체별 공시 정보를 보관하는 테이블
뉴스 - 수집 매체별 뉴스 정보를 보관하는 테이블
매수내역 - 매수 내역을 기록한 테이블
매도내역 - 매도 내역을 기록한 테이블
수익정산 - 수익 정산한 결과를 기록한 테이블
검색단어 - 호재성 및 악재성 단어를 등록해 공시-뉴스 분석에 사용되는 중요한 핵심 테이블
핸들 - 타 프로그램을 제어하기 위해 해당 객체의 핸들값을 저장하는 테이블
사용자 - 프로그램을 사용하는 사용자에 대한 권한을 관리하는 테이블

column_img_2125.jpg

[그림 8] 주식자동매매 프로그램 ERD

그 외 사용된 DB 자원은 다음과 같다.

프로시저: 종목 정보를 분석하는 단계에서 사용하는 프로시저 다수 제작
디비링크: 종목 정보를 구성하기 위해 MS-SQL에서 제공하는 디비링크 사용

주식 자동매매 프로그램에서 디비링크는 아주 요긴하다. 종목정보 테이블에 필요한 정보를 증권사 HTS에서 조회하여 정보 내역을 엑셀 파일로 내려 받은 후에 이 파일을 디비링크로 등록하면 엑셀 파일의 각각의 탭은 마치 테이블과 같은 개념으로 인식되기 때문에 쿼리에서 테이블처럼 사용 가능하다. 디비링크 사용법은 인터넷에서 흔하게 조회할 수 있으므로 이 연재에서는 제외한다.



API를 알면 보이는 것들

지금까지 주식 자동매매 프로그램에 대해서 설명했다. 10여 년 전에 개발할 당시와 지금의 상황은 많이 달라졌다. 요즘은 상용 판매되는 주식 자동매매 프로그램도 있고, 자동매매 기능을 증권사에서 제공하기도 한다. 또한 증권사에서 자체적으로 제공하는 전용 API를 활용해 프로그램을 제작할 수도 있다. 예전보다 제작 환경이 더 좋아졌다. 그래서 혹시나 주식 자동매매 프로그램을 제작하고자 하는 개발자가 있다면 말리고 싶다. 연재는 연재일뿐 따라 하지 않았으면 좋겠다.

자동매매 프로그램은 독학으로 제작하기도 무척 힘들지만, 주식에 대해 전문가적인 지식을 갖추는 것도 많은 시간이 필요하다. 필자는 여러분의 아까운 시간이 낭비 되는걸 바라지 않는다.

지난 19회 연재글인 ‘오라클 DICTIONARY를 활용한 DB툴 프로그램 FreeSQL‘에서 DB툴인 FreeSQL보다는 딕셔너리에 대해 더 많은 의미를 부여했다. 딕셔너리는 오라클 시스템에 대한 정보의 보고이며 데이터 사전이라고 설명하면서 딕셔너리의 중요성을 강조했다. 이번 연재에서도 주식매매 프로그램 보다는 API에 더 초점을 맞추고 그 중요성을 강조하고 싶다. 여러분이 API를 안다는 것은 타 프로그램을 제어 할 수 있다는 것을 의미한다. 개발자들이라면 API가 어떤 중요한 의미를 지니고 있으며, 다방면에서 활용할 수 있는지 충분히 이해 할 것이다.

공시-뉴스 정보를 이용한 주식 자동매매 시장에서는 매일 치열한 시간(초) 단위 경쟁이 일어난다. 그 당시 기억으로 1~3위 정도의 순위는 수익을 낼 수 있지만 그 외의 순위에서는 오히려 손해를 보는 경우가 훨씬 많았다. 필자가 선두권을 유지했던 기간은 불과 서너 달에 불과했다. 0.001초의 순위 싸움은 지금도 치열하게 일어나고 있을 것이다. 1년간의 외도()에서 돌아온 필자는 프로그래머의 삶을 지금까지 살고 있다. 현재는 튜닝 관련 일을 하고 있다. 허황된 꿈은 날아갔지만 후회는 하지 않는다. 또한 지금의 일상이 나에겐 더 소중하다.

다음 연재에서는 개발자들이 흔히 접하는 오라클 에러 메시지에 대한 내용을 연재하고자 한다. 가장 빈번하게 접하는 오라클 에러에 대한 설명과 그 대처 방안을 제시할 것이다. (다음 회에 계속)



[지난 문제의 정답과 풀이]

원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제

지난 연재에 출제한 ‘원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제’에 대한 정답과 해설은 아래와 같다. 문제를 풀면서 DB 원리를 하나씩 배우고 이해할 수 있을 것이다.

column_img_2126.jpg

column_img_2127.jpg



[이번 호 문제]

원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제 각 연재의 말미에 간단하면서도 재미있고, 생각해볼 수 있는 문제를 출제하려 한다. 모든 문제는 DB의 원리를 이해할 수 있는 문제로 출제할 예정이다. 문제를 풀면서 DB 원리를 하나씩 배우고 이해할 수 있을 것이다. 정답과 그에 대한 설명은 다음 회 연재에서 한다. column_img_2128.jpg