GHTS 개략 설명

GHTS 2021. 1. 13. 18:56 Posted by UnHa Kim

국내 증권사의 API는 모두 32비트에서만 호출 가능합니다.

32/64비트 경계를 넘어서 OLE/OCX 간단한 호출하는 방법이 인터넷에 나와있지만,
증권사 API 호출 후 응답을 넘겨받는 데 꼭 필요한 'OLE 이벤트'는 작동하지 않더군요.
그래서, API 호출은 무조건 32비트 프로세스에서 해야 합니다.

(DLL, OLE, OCX 무관하게 32비트이어야 합니다.)

매매 전략 구동을 비롯한 모든 코드를 32비트로 실행해도 괜찮다면,

별도의 프로세스로 분리하지 않고 단일 프로세스 내에서 사용하면 간단하고 좋습니다.

 

그러나, 여하한 이유로 매매 전략을 64비트 프로세스에서 운용해야 한다면

증권사 API 호출을 독립된 32비트 프로세스로 분리한 후 상호 연동 시켜야 합니다.

 

GHTS에서는 다수의 매매 전략을 동시에 운용하는 상황을 상정하고 작성되었습니다.

모든 동시 다중 처리는 디버깅하기 몹시 까다롭기로 유명한

데이터 동시 액세스 충돌(이하 데이터 레이스) 버그 발생 가능성이 상존합니다.

Go언어에서는 이러한 버그를 추적할 수 있는 '레이스 감지기'를 제공하지만 64비트에서만 지원됩니다.

golang.org/doc/articles/race_detector.html

 

매매 시스템의 안정적인 운용을 위해서는

데이터 레이스 상황을 적절하게 디버깅 할 수 있어야 하기에

매매 전략을 64비트 프로세스에서 실행할 수 있어야 한다고 결정했으며,

증권사 API를 호출하는 기능을 별도의 32비트 프로세스로 분리했습니다.

 

그 과정에서 32비트 프로세스와 64비트 프로세스 간 자료교환을 위한 기술적인 문제는 다음과 같이 해결했습니다.

1. Go 자료형을 []byte로 변환
https://github.com/ugorji/go

2. []byte 로 변환된 데이터를 전송 및 수신
https://github.com/nanomsg/mangos

RPC로 데이터를 전송하려면 우선 []byte로 변환하는 게 필요한 데,

여러가지 자료형 변환 중 가장 유명한 구글의 '프로토콜 버퍼'는

각 자료형을 정의하는 IDL파일을 작성해야 합니다.

구글 '프로토콜 버퍼'와 비슷한 기능을 하되 IDL 작성이 불필요한 방식으로는

(Go언어의 자료형 선언이 그 자체로 IDL 역할을 함.)

JSON과 MsgPack형식이 있는 데,

JSON은 호환성은 높지만 텍스트 방식이어서 효율성이 낮은 관계로,

바이너리 방식인 MsgPack을 선택했습니다.

Go언어에서 MsgPack 변환을 해 주는 go/codec 패키지 라이브러리를 사용했습니다.


이렇게 []byte로 변환된 데이터를 프로세스끼리 주고 받도록 해주는 기술로 가장 유명한 게 ZeroMQ입니다.

GHTS도 초반에는 ZeroMQ를 사용했습니다만,

ZeroMQ는 컴파일이 느리기로 유명한 C++언어로 작성된 관계로

ZeroMQ를 적용한 이후 컴파일이 느려져서 전체적인 개발 생산성이 너무 큰 타격을 입었습니다.

 

이를 해결하기 위해서  비슷한 기능의 순수한 Go언어로 작성된 mangos를 채택했습니다.
https://github.com/nanomsg/mangos

이상 GHTS의 내부 구조가 지금처럼 분리된 이유와

이를 위해서 사용하는 의존성 라이브러리를 선택하게 된 이유를 간략히 설명드렸습니다.

댓글을 달아 주세요

  1. 익명 2021.01.14 21:58  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • UnHa Kim 2021.01.18 15:40 신고  댓글주소  수정/삭제

      확인해 보니 C언어 컴파일 의존성을 완전히 없앨 수는 없네요.

      API호출 과정에서 얻은 C 데이터를 Go 자료형으로 변환하는 과정에서 C언어 컴파일러의 도움이 필요하네요.

      정확히 말하면 cgo 패키지의 일부 특수 함수가 필요합니다.

      좀 더 확인하지 못한 점 죄송합니다.

    • UnHa Kim 2021.07.10 06:27 신고  댓글주소  수정/삭제

      이미 많은 시간이 흘러서 별 상관 없겠지만 혹시나 해서 추가 해 놓습니다.
      기존에 사용하던 cgo 특수 함수를 모두 순수 go언어 함수로 대체해서,
      C언어 컴파일러 의존성을 없앴습니다.

      https://ghts.tistory.com/51

  2. GrayrabbiT 2021.01.17 19:40 신고  댓글주소  수정/삭제  댓글쓰기

    댓글달아 주셔서 감사합니다. 혹시 깃 코드와 설명을 보다 의문이 나면 댓글로 여쭈어보아도 될까요?

    파이썬으로 돌아가려다가 왠지 go로 해보고 싶은 의지가 생겨버려서요. golang 엄청 재미난 언어네요..ㅎ

    • UnHa Kim 2021.01.17 19:52 신고  댓글주소  수정/삭제

      가끔 블로그 사이트 들를 때마다 확인해 보도록 하겠습니다.

      저도 다른 사람에게 피드백 받아보는 게 처음이라서 얼마나 할 수 있을 지는 모르겠습니다만,
      참신한 경험이라서 아직은 할만 합니다.

      티스토리 방명록은 추가했습니다만,
      질문/답변 게시판 추가하는 걸 모르겠습니다.

    • UnHa Kim 2021.01.17 20:03 신고  댓글주소  수정/삭제

      파이썬은 나중에 성능 문제가 발생하면 고성능 언어로 처음부터 새로 작성해야 할지도 모른다는 불안감과
      동적 자료형 때문에 버그가 발생해도 모르고 지나갈 수 있다는 불안감이 존재하죠.

      Go언어는 정적 자료형이기 때문에 사소한 버그는 미리 찾아낼 수 있으면서, 속도도 C언어 절반 정도로 파이썬보다 수백배 빠르기 때문에 성능 걱정 없구요.
      컴파일이 빨라서 개발 생산성도 괜찮은 데다가,
      무엇보다 동시처리가 간편한 게 다중 매매 전략 운용에 너무 편할 것 같아서 선택했습니다.

      동시처리를 콜백함수로 짜면 거의 지옥인데, (안 당해 보면 모릅니다.) 고루틴을 이용하면 일반적인 순차적 프로그래밍을 할 수 있어서 엄청 편합니다.

      요즘 파이썬도 비동기 프로그래밍 기능을 많이 보강했다고 하니까 이건 제가 잘못 알고 있을 수도 있습니다만,
      Go언어는 preemptive 동시처리이라서 await 같은 거 신경 안 써도 되니까,
      동시처리에서는 더 편한 것 같습니다.

      대신,
      Go언어는 OLE/OCX등 윈도우 기술과 호환성이 안 좋습니다.
      무엇보다 에러처리가 X 같습니다.
      줄줄이 if문으로 확인하거나,
      panic recover defer로 try-catch 비슷한 효과를 낼려고 해도 일일이 에러 확인을 해 줘야 합니다.

      Go언어에 제너릭(Generic)이 추가되면 에러 처리가 획기적으로 편해질 거라고 다들 기대하면서 버티고 있죠.

      빠르면 올해 말이나 내년에 Go언어에 제너릭이 추가된다고 하던 데, 저도 상당히 기대 중입니다.

  3. 익명 2021.01.17 20:38  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • UnHa Kim 2021.01.17 20:57 신고  댓글주소  수정/삭제

      TR이란 TRansaction의 약자입니다.

      증권사와 사용자 컴퓨터 간의 상호작용을 의미합니다.

      사용자는 증권사 서버에게 자기가 원하는 작동을 TR코드를 통해서 명시합니다.

      예를 들면,
      현재 서버 시각을 알고 싶다면 t0167
      현재가를 알고 싶다면 t1101
      주문을 넣고 싶다면 CSPAT00600
      등이죠.

      이베스트 TR코드는 API 패키지를 설치하면 함께 설치되는 DevCenter를 참고하세요.

    • UnHa Kim 2021.01.17 21:19 신고  댓글주소  수정/삭제

      자주 사용하는 TR코드

      현재가 : t1101/t8407
      호가 : t1102
      주문 : CSPAT00600/CSPAT00700/CSPAT00800 (정상/정정/취소)
      계좌 평가액 : CSPAQ12200
      보유 수량 : CSPAQ12300
      주문 가능 금액 : CSPAQ22200
      일일 가격 정보 : t1305/t8413
      전체 종목 코드 : t8436
      현재 서버 시각 : t0167

  4. Kyu1234 2021.10.28 12:59 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요, github에도 issue 남기긴 했는데, 혹시 사용하시는 xing dll 버전이 어떻게 되시나요?

  5. UnHa Kim 2021.12.05 13:55 신고  댓글주소  수정/삭제  댓글쓰기

    답변이 늦어서 죄송합니다.

    DLL이 업데이트 되면서 구조체에 필드가 추가되는 경우가 있는 데,
    그럴 경우 헤더 파일을 업데이트 한 후,
    소스 코드도 관련 필드를 읽어들이도록 좀 수정해야 합니다.
    그게 매번 업데이트 공지 사항을 모니터링 하지 않으면 필드가 추가되었는 지 모르니까 해당 프로세스를 빼먹습니다.

    말씀하신 항목은 수정해 놨습니다.
    사용해 보시고 문제 있으면 알려주십시오.