0%

0. Introduction

금융 데이터를 이런저런 방식으로 분석해서 결과를 팀원들에게 공유하면, 반드시 나오는 중요한 질문이 하나 있습니다. 해당 결과를 어떻게 전략화 할 수 있냐는 겁니다. 분석 그 자체로써 의미있는 경우도 있지만, 결과적으로 (모델이 되었든 매니저가 되었든) 누군가는 포트폴리오 구성 및 운용 방식, 즉, 어떤 자산($X$)을 언제($t$), 얼마만큼($w$) 가지고 있어야 하는지에 대한 판단을 내려야 합니다.

포트폴리오 구성과 관련된 모델 중 가장 잘 알려진 이론은 Mean-Variance Optimization Portfolio일 것입니다. 해당 모델의 로직은 논리적이고 직관적이지만, 몇 가지 문제점들이 있습니다.

  1. 입력 데이터의 작은 변화에도 도출되는 포트폴리오 구성비중이 크게 변합니다.
  2. 몇 개의 자산에 비중이 쏠리는 코너 솔루션이 나타나는 경우가 있습니다.
  3. 투자자가 가지고 있는 정보를 녹여낼 수 있는 방법 없습니다. 따라서, 시장에 대한 견해가 다른 매니저일지라도 (같은 hyperparameter를 가지고 있는 경우) 같은 MVO 포트폴리오를 얻게 됩니다.

위 문제점들은 실제 운용을 할 때 걸림돌이 됩니다. (ex. 높은 turnover ratio, 규제위반, 모델에 들어가지 않은 추가적인 정보 반영 불가 등) 이러한 문제점들을 해결하기 위해, 골드만삭스의 Fischer Black과 Robert Litterman이 1990년에 개발하고 1992년에 발표한 포트폴리오 최적화 방법론이 Black-Litterman Model입니다.

본 포스팅은 Black-Litterman Portfolio Model을 이해하고, Python으로 이를 구현해보는 과정을 정리해 놓은 글입니다. 내용에 문제나 개선점이 있는 경우, 피드백을 주시면 감사하겠습니다! 😀

더 읽어보기 »

0. Introduction

이베스트증권은 COM 형태와 dll 형태로 사용할 수 있는 xingAPI를 제공합니다. Python에서 COM object를 사용하는 라이브러리를 사용하면 xingAPI를 사용할 수 있지만, 사용법이 깔끔하지 못합니다.

개인적으로 사용하기 위하여 설탕을 팍팍쳐서 모듈을 만들었습니다. 이 모듈을 사용하면, 코드가 다음과 같이 정리가 됩니다.

>>> import ebest
>>> ebest.login()
[*] 접속 서버 ((r)eal / (D)emo / (a)ce) : # r
[*] 아이디 : # username
[*] 패스워드 : # password
[*] 공인인증서 암호 : # cert_password
[*] 로그인 성공

# XAQuery 요청
>>> ebest.query('t1101', dict(shcode='000020'))
{'t1101OutBlock': {'hname': '동화약품',
'price': 19100,
'sign': '5',
'change': 550,
# ...
'open': 19750,
'high': 19900,
'low': 18850}}

# XAQuery 요청 후 DataFrame 형태로 변환
>>> res = query('t8413', dict(
... shcode='000020', sdate='20200101', edate='20210101',
... gubun='2', qrycnt=2000, cts_date=' ', comp_yn='Y'
... ))
>>> pd.DataFrame(res.get('t8413OutBlock1')).set_index('date')
open high low close ... rate pricechk ratevalue sign
date ...
20200102 8340 8400 8290 8400 ... 0.0 0 0 2
20200103 8400 8450 8290 8360 ... 0.0 0 0 5
... ... ... ... ... ... ... ... ...
20201229 18750 19400 18750 19150 ... 0.0 0 0 2
20201230 19100 19800 18800 19650 ... 0.0 0 0 2
[248 rows x 11 columns]

# XAReal 실시간 데이터 구독 후 callback function으로 처리
>>> nws = Realtime('NWS', callback=print)
>>> nws.subscribe('NWS001')
>>> Realtime.listen()
NWS {'date': '20210104', 'time': '154734', 'title': '[포토] 코로나19 직무 교육현장 참관'}
NWS {'date': '20210104', 'time': '154752', 'title': '전성배 신임원장, "국가 디지털전환 선도"'}
NWS {'date': '20210104', 'time': '154750', 'title': '[포토] 정총리, 코로나19 교육현장 참관'}
# ...

여기를 클릭하시면 소스코드를 직접 확인하실 수 있고, 위 예시처럼 사용하실 수 있습니다. 모듈을 어떻게 구현하였는지 궁금하신 경우, 모듈의 소스코드를 실행 순서별로 설명을 해 놓은 본 포스팅의 본문을 확인하시면 되겠습니다.

개인적으로 사용하기 위해 구현한 코드인 관계로, 이런저런 문제점들이 많습니다. 😅 포스팅의 내용이나 소스에 개선이 필요한 경우, 피드백을 주시면 감사하겠습니다!

더 읽어보기 »

0. Introduction

Python을 사용해서 금융 시계열 분석을 하다보면, datetime과 관련한 처리가 까다로운 경우가 많습니다. 대표적으로, 휴일 및 공휴일 등을 계산하는 경우가 있습니다. Python pandas 라이브러리에 business day 개념이 있기는 하지만 (기본적으로는) 주말을 제외한 공휴일을 제대로 고려하지 못합니다.

조금 찾아보니, pandas에서 이러한 문제를 관리할 수 있는 방법이 있었습니다. 본 포스팅은 해당 내용을 공부하며 정리한 글 입니다. 글의 내용 중 잘못 된 부분이 있는 경우, 피드백을 주시면 감사하겠습니다. :)

더 읽어보기 »

0. Introduction

체결 데이터(틱데이터)를 사용할 때, 데이터가 지나치게 raw해서 생기는 난감한 부분들이 많습니다. 이를 해결하기 위해 “분봉”이나 “일봉”처럼, 일정한 시간을 기준으로 체결내역을 grouping하는 전처리 방법이 가장 많이 사용되는 것 같습니다. 이러한 방법의 장단점은 무엇일까요? 혹시 다른 방법은 없을까요? 어떻게 구현을 해야 할까요?

Marcos Lopez de Prado의 저서 Advances in Financial Machine Learning에 위 질문들에 대한 답변이 정리가 잘 되어있습니다. 이번 포스팅은 해당 서적의 “2.3 Financial Data Structures: Bars” 챕터를 공부하며 이해한 내용을 정리한 내용입니다. 워낙 유명한 저서인지라, 책의 내용에 대한 구현을 정리해놓은 github repo도 있습니다. 다만, 모듈화를 위해 로직이 흩어져있어서 이해하기가 쉽지 않아, Python pandas를 사용하여 직접 구현을 해보았습니다.

포스팅의 내용 혹은 코드에 개선이 필요한 경우, 피드백을 주시면 감사하겠습니다. :)

더 읽어보기 »

Introduction

Python으로 코드를 짤 때, 로그를 띄우는 방법으로 print('[*] Message')를 정말 많이 써 왔습니다. 군더더기 없고, 유연하고, dependency 없이 아무 위치에나 넣을 수 있다는 점이 좋았습니다. ‘좋았다’ 보다는 ‘편했다’ 혹은 ‘귀찮았다’가 더 적절한 것 같습니다. 혼자서 사용하는 프로그램을 짤 때는 exception 처리나 로그 처리에 신경을 쓰지 않아도 문제가 없었기 때문인 것 같습니다.

이러한 방법은 문제가 많이 있습니다. 중요도에 따라서 로그를 분류할 수도 없을 뿐더러, 코드를 수정하지 않는 이상 로그를 컨트롤 할 수도 없습니다. 정말로 print 되어야 하는 내용과 로그가 뒤섞여 버려서 화면이 지저분해지는 것도 문제입니다. (Fang’s coding note) 가끔은 조용히 프로그램을 돌리고 싶을 때도 있고, 가끔은 verbose 해지고 싶어질 때도 있잖아요?

Python에서는 logging 모듈을 기본적으로 제공합니다. 이제 print('[*] ...')만 사용하지 말고, logging 모듈을 통해 멋지고 깔끔한 로깅을 해봅시다. 이번 포스트를 통해 Python에서 제공하는 logging 모듈을 어떻게 사용하는지 알아보도록 하겠습니다. 또한, ‘좋은 로그 처리 방법’이 어떤 성질을 지니고 있을 지에 대한 고민도 해보겠습니다.

더 읽어보기 »

0. 안녕, 비동기!

Python으로 동시다발적 HTTP 요청을 보내는 작업을 해야할 필요가 생겼습니다. Python 3에서 asynchronous한 작업을 처리하기가 수월해졌다는 이야기를 어디서 들은 것 같아서 구글링을 간단히 해봤습니다…만 내용들이 이해하기가 쉽지 않았습니다. 이와 관련된 수 많은 용어들의 정의와 그 범위가 사람들마다 미묘하게 달랐기 때문입니다. 뿐만 아니라, ‘asynchronous’라는 용어 자체를 듣기만 해도 뭔가 어렵고 복잡하고 막연하게 두려운 느낌도 듭니다.

하루 날을 잡고 asynchronous python과 관련된 자료들을 왕창 읽어보았습니다. 이 글은 키워드 generator, coroutine, asyncio와 신택스 yield, yield from, async, await 에 대한 이해가 없던 제가, 나름대로 이해를 하는 과정을 기록한 것입니다. 혹시나 제가 잘못 이해하고 있는 부분이 있으면 말씀해주시면 감사하겠습니다.

더 읽어보기 »