1.
아주 오랜만의 글입니다. 더운 여름 글쓰기도 그렇고 프로젝트에 마무리하여야 하기때문에 뜸했습니다. 프로젝트참여가 비상주로 전환하는 오늘, 항상 그렇듯이 그동안 한 일을 기록차원에 정리하려고 합니다. 고객이 요구하는 비밀을 지키는 선에서(^^)
여의도 주위에 살면서 수많은 프로젝트를 했지만 프로젝트 책임자가 아닌 경우는 없습니다. 회사 대표일 경우에도 대표로써 프로젝트를 책임졌고, 외주하여야 하는 프로젝트도 PM역할을 주로 맡았습니다. 나이가 드니까 PM을 하기에는 고객의 부담이 큽니다. 아주 우연히 어떤 프로젝트에 참여할 기회가 있었는데 살면서 처음으로 PM이 아닌 프로젝트였습니다. 물론 제안작업을 할 때는 몰랐습니다. 어떤 솔류션을 제안하는데 외부에서 개발하여 공급하는 개발방식이라는 점을 알 수 없었습니다.
프로젝트를 시작하고 가장 먼저 느낀 점입니다.
“아! 그동안 내가 해온 프로젝트와 다르구나..”
“아! 내가 프로젝트 PM이 아니지..”
PM은 모든 것에 책임을 집니다. 작든 크든 이슈에 대하여 판단을 내리고 실행하여야 합니다. 어떤 상황이 닥치면 주제도 모르고 입 가까이 “이렇게 해야 하지 않나요?”라는 말이 나올 뻔 하다가 주어 담은 적이 여럿입니다. 몇 번에 걸치 착오를 거치면서 아예 귀를 닫았습니다.
하는 일은 kdb와 kdb가 제공하는 Q 언어를 이용하여 만들어진 솔류션이 다른 시스템과 통신하도록 하는 일입니다. 아주 오래 전 잠시 보았던 시스템이지만 개발이 아니었기 때문에 자세히 보지 않았던 시스템을 한달동안 분석하고 요구사항을 수행할 방안을 찾는 일입니다. 이 때 골치아프게 한 이슈는 “Q 언어와 외부 시스템을 어떻게 연동하느냐” 입니다. 당연히 TCP/IP로 연동하면 되리라 생각했는데 그것이 쉽지 않더군요. Q언어와 관련한 문서를 찾아보면 http나 websocket은 지원합니다. 그리고 kdb 접속을 위한 socket도 가능하지만 외부서버에 접속은 도통 방법이 보이지 않았습니다. 우여곡절이었습니다. 우여곡절이 있었던 이유는 R&R이 우선입니다. Q언어로 이루어진 프로그램에서 외부접속을 하는 기능(클라이언트 개발)은 당연히 Q 언어를 개발하는 팀의 역할이라는 생각이었죠. 그런데 칼로 두부 자르듯이 쉽게 나누어질 수 없는 문제였습니다. 아래 문서를 보면 Q에서 TCP서버에 접속하도록 하는 Script가 나옵니다. C로 만들어진 클라이언트를 Q에서 호출하여 사용합니다. Q언어와 관련한 문서로 보면 Shared Object를 실행하는 방법입니다.
Q언어에서 C프로그램을 실행하는 것외에 C프로그램에서 KDB에 접속하여 데이타를 처리하는 업무도 있었습니다. 앞서의 경우와 반대입니다. 지나고 보면 무척 단순합니다만 생소한 시스템을 처음 만나서 외부의 도움없이 문제를 해결하여야 하는 시간동안은 괴로운 나날입니다.
어찌되었든 아래의 문서를 잘 읽어보면 kdb와 Q언어를 사용하여야 하는 프로젝트에서 힘을 쓸 수 있습니다. AquaQ는 kdb를 이용하여 다양한 시스템을 만드는 영국회사입니다. kdb와 관련한 전문회사를 찾아보면 대부분 영국쪽입니다. kdb를 만든 회사가 아일랜드이라서 그런 듯 합니다.
2.
금융회사는 업무별로 다양한 시스템이 있고 시스템마다 도입한 솔류션이 다르지만 공통점은 DBMS입니다. 대부분 Oracle을 사용합니다. 사실상의 표준입니다. 물론 요즘 각광을 받는 카카오뱅크는 MySQL을 도입했다고 하지만 그래도 코어업무는 Oracle를 사용한다고 합니다. 그러면 금융회사에서 많이 사용하는 Oracle과 KDB. 궁합이 맞을까요? 제가 프로젝트를 하면서 가졌던 의문입니다. 관계형 DBMS이면서 범용성을 가진 Oracle과 Column DB이면서 시계열DB이고 In-Memory DB인 KDB를 어떻게 활용하는 것이 좋을까 하는 고민입니다.
자료를 조사해보면 아시겠지만 kdb를 가장 많이 사용하는 분야는 마켓데이타와 관련한 업무, 이와 기반으로 한 매매업무입니다. 그래서 kdb로 만들어진 솔류션을 보면 tickerplant라는 마스터 프로세스가 존재합니다. 외부로부터 데이타를 수신하는 프로세스입니다. 한국거래소로 이야기하면 fep와 같은 역할입니다. 조금더 거슬러가면 시세FEP와 주문FEP가 있던 시절의 FEP라고 이해하시면 비슷합니다. kdb는 database이면서 Q라는 언어를 가진 어플리케이션 서버입니다. 어플리케이션 서버이면서 Messaging Middleware 기능도 겸합니다. 이상의 기능을 이용하여 어떤 시스템을 구축하면 가장 효율적일지 떠올려보면 딱 하나가 떠오릅니다.
“Feed Hanlder”
금융에서 Feed Handler는 다음과 같은 의미입니다.
In a general sense, feed handlers are a broad class of applications and frameworks that parse, process, aggregate, and/or store market data. Different kinds of market data feeds may supply different kinds of data, such as quote or trade data, orders and order books, yield curves, etc. Some feeds originate directly at the exchanges (NYSE, LSE, …), others are aggregated from multiple sources by third-party institutions and redistributed using a normalized representation.
Using the eXtremeDB Feed Handler
Feed Handler는 시장을 통해 거래가 이루어져서 시세가 발생하는 곳이면 어디든 적용가능한 개념입니다. 시세는 단순히 가격만이 아니라 주문을 위한 호가를 포함합니다. kdb를 이용할 때 장점은 존재하면 빠른 처리속도와 publish/subcribe를 통한 외부시스템과의 연동입니다. Kdb+를 통하여 시세를 subscribe하는 C 코드로 Kdb C API Query Subscribe Example에서 확인하실 수 있습니다.
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 |
int main(int argc, char *argv[]) { // find host:port from args then connect int handle = khpu(host, port, "user:pass"); // subscribe to trade table K r = k(handle, ".u.sub[`trade;`]", (K) 0); // process ticks while(1) { r = k(handle,(S)0); if(r) { if(r->t == 0) { // r is 3 item list of format (".u.upd"; `trade; updateTable) printf("\n%s update", kK(r)[1]->s); // table name symbol atom tbl = kK(r)[2]->k; colNames = kK(tbl)[0]; colData = kK(tbl)[1]; printf(" rows: %lld cols: ", kK(colData)[0]->n); for(c=0; c < colNames->n; c++) { printf("%s,", kS(colNames)[c]); } } } r0(r); // decrement reference count, free memory } } |
위 소스에서 subscribe하는 부분은 딱 한줄입니다.
// subscribe to trade table
K r = k(handle, “.u.sub[trade;
]”, (K) 0);
보통 매매시스템은 시세와 주문외에 포지션, 손익, 고객정보, 계좌정보 등등 다양한 데이타로 이루어집니다. 그러면 모든 데이타를 kdb+로 관리하는 것이 좋을까요? 혹 프로젝트를 수행하는 회사가 알아서 결정할 일이지만 개인적으로는 추천하지 않습니다. 비용이 큽니다. 관리도 복잡하고…
3.
이번에 분석한 시스템중 Kondor+가 있습니다. 구글링하여도 관련한 자료를 찾기 힘든 시스템입니다. 대부분의 로이터가 공급하는 시스템이 그렇지만 문서는 충실하네요. 개인적으로 놀란 점은 Tibco Rendevous입니다. Publish/Subscribe와 같은 메시징 미들웨어의 대표입니다. 로이터가 공급하는 모든 제품이 기본으로 Rendevous가 깔려있네요. 그리고 모든 프로세스와 프로세스간의 Interface도 Rendevous를 통해서 합니다. 예를 들어서 Kondor+이 외부시스템과의 연동을 위해 제공하는 API중에 OK API가 있습니다. OK API를 살펴보면 크게 두가지 접근이 가능합니다.
첫째는 미들웨어에 직접 접속하는 방식입니다. Rendevous에 접속하여 메시지를 처리하는 방식입니다.
둘째는 관련한 업무를 맡는 서버와 접속하는 방식입니다. TradeKase나 KIS에 접속하는 방식입니다.
다만 어느 방식을 택하여도 Rendevous를 통하여 프로세스간에 데이타를 공유하고 처리합니다. kdb+도 비슷한 개념으로 이해하면 어떨까 합니다. 다른 점은 database라는 점입니다.