페이스북 Prophet 을 이용한 주가 폭락 자동 감지

주식 차트가 만능은 아니지만 ‘차트가 갑자기 떨어지면 공포심에 다시 오르지 않을까’ 라는 근거 없는 기대는 버릴 수가 없다. 그래서 실제로 폭락을 감지해서 매매를 해보면 어떨까 싶어, 기계적으로 폭락을 감지하는 방법을 찾아보았다. 여러 방법들이 있지만, 그 중에 페이스북에서 개발한 Prophet을 간단히 소개하고자 한다.

Prophet 알고리즘 개요

Prophet은 한마디로 요약하면, 시계열 데이터를 모델링하기 위한 파이썬 모듈이다. (‘모델링 할 수 있다’라는 내용을 쉽게 설명하면, 시계열 데이터 내 순차적 데이터를 모방할 수 있는 블랙박스를 구성할 수 있다라는 의미로 생각할 수 있다. 블랙박스는 몇 개의 또는 경우에 따라서는 수백, 수천만개의 파라미터를 포함하고 있다.)

시계열 데이터를 예측(모델링)하는 방법론에는 머신러닝 방법론 그리고 고전적인 기법 ARIMA가 있다. Prophet은 머신러닝 기법은 아니며, ARIMA라고 하는 알고리즘 방법론을 응용하고 있다. ARIMA를 이용하면, 계절마다의 반복성이나 여름철에 증가하는 전기 사용료를 모델링할 수 있다.

Prophet 은 한층 더 진보적인 방법으로, 트렌드와 주기적 특성뿐 아니라 예외적이고 이벤트와 같은 휴가철 상황까지도 모델링할 수 있도록 ARIMA 알고리즘을 확장한 것이다. 시계열 데이터는 인간 생활과 밀접한 관계가 있는 데이터이기에 결국 모델링 가능한 데이터 범주와 정확도를 높이기 위해 그런 부분까지 확장한 것이 아닐까 생각이 든다.

y(t) = g(t) + s(t) + h(t) + e(t)

with g(t) representing the trend.
s(t) represents periodic changes (weekly, monthly, yearly).
h(t) represents the effects of holidays (recall: Holidays impact businesses).
e(t) is the error term.

Prophet 설치

우선 Prophet 을 설치해보자. 아나콘다(Anaconda) 환경이 설치되어 있으면 설치는 간단하다. 그렇지만 파이썬 환경은 Cython 등 몇 가지 사전 설치 등이 더 필요하다. (아래는 아나콘다에서 설치하는 방법이며 용량이 다소 크긴 하지만 간단하게 설치하고자 한다면 아나콘다 환경을 권장) 자세한 설치 방법은 여기 참조

conda install -c conda-forge fbprophet

Prophet 사용법

사용법은 간단한다. Prophet이라는 객체를 생성한 후, 시계열 데이터를 학습(fit)하면 된다. 머신러닝에 꼭 필요한 패키지가 scikit-learn 이라는 것인데 Prophet은 scikit-learn 패키지와 인터페이스가 유사하다. 객체 생성에 필요한 여러 가지 설정값과 더불어 해당 객체를 선언하고 데이터를 이용해 학습하면 된다.

m = Prophet(daily_seasonality = True) # create Prophet class 
m.fit(data) # fit the model using time series data

Prophet 시계열 data 의 구성은 단순하다. ds 라는 컬럼에 날짜값을, y라는 컬럼에는 실제 시계열 데이터값을 삽입하면 된다.

데이터를 학습(위 코드에서 m 이라는 객체 변수가 생성되고 객체 내 학습 결과 파라미터들을 포함)했으니 이제 예측이 가능하다. 예측을 원하는 날짜수만 입력하기만 하면 된다.

future = m.make_future_dataframe(periods=365) # days in future
pred = m.predict(future)

예측한 값을 출력하면 아래와 같은 멋진 그래프를 얻을 수 있다.

m.plot(pred)
plt.title("Prediction of the Google Stock Price using the Prophet")
plt.xlabel("Date")
plt.ylabel("Close Stock Price")
plt.show()

보다 자세한 내용은 Prophet 문서 사이트 참고하길 바란다.

이상치 검출

주가 폭락은 시계열 데이터 관점에서는 이상치이다. 평균이나 기대값보다는 한참이나 벗어난 값들이라는 의미이다. Prophet을 이용하면 이러한 이상치 검출을 쉽게 할 수 있다. 위 함수 predict를 하고나면 여러 가지 컬럼들이 생성되는 데, 그 중에 yhat이 예측값이고 yhat_lower는 최소치 그리고 yhat_upper가 최대치 값들이 있다. 이러한 값들을 이용해서 이상치 검출을 한다. 즉, 이상치 검출은 단지 실제 시계열 값 y와 yhat_lower나 yhat_upper와 비교만으로 가능하다. 아래 관련 코드를 살펴보자 (pred, andf 는 파이썬 pandas DataFrame)

andf = pred[['ds', 'trend', 'yhat', 'yhat_lower', 'yhat_upper']]
andf['y'] = y # y는 실제 시계열 리스트

andf['anomaly'] = 0  # anomaly 감지 태그 컬럼 생성
andf.loc[andf['y'] > andf['yhat_upper'], 'anomaly'] = 1
andf.loc[andf['y'] < andf['yhat_lower'], 'anomaly'] = -1

이제 andf[‘anomaly’] 컬럼으로, 비정상적인 (이상치) upper (1)인 시점과 lower (-1) 인 시점들 확인이 가능해졌다.

이상치 중요도 측정

이상치 여부만으로는 조금 부족하다. 여부뿐 아니라 이상치의 정도를 의미하는 중요도(importance)를 측정해 보자. 쉽게 설명하면 약간 이상한 정도와 심하게 이상한 정도를 구별하고자 하는 것이다. 중요도는 y 값과 yhat_upper 과의 차이 또는 y값과 yhat_lower 와의 차이를 y값으로 나눠서 구한다. 다시 말해, 실제 시계열 값과 예측 최대치(또는 최소치)와의 차이에 비례한다. 아래 소스 부분을 확인하면 이해가 될 것이다.

andf['importance'] = 0  # 이상치 중요도 컬럼 추가
andf.loc[andf['anomaly'] == 1, 'importance'] = \
    (andf['y'] - andf['yhat_upper']) / andf['y']
andf.loc[andf['anomaly'] == -1, 'importance'] = \
    (andf['yhat_lower'] - andf['y']) / andf['y']
andf['score'] = andf['anomaly'] * andf['importance']

마무리…

어제까지의 데이터를 이용해 Prophet으로 학습한 후에, 오늘 현재 시점에서의 y값과 비교해, 이상치 여부와 중요도 수치를 구할 수 있다. 이로써, 금일 (특정 종목의) 주식이 폭락한 여부를 자동으로 알 수 있고 그에 따라, 자동으로 매수를 하는 프로그램도 가능하다. (위 설명에 사용된 간단한 샘플 소스)

혹시 위 내용이 도움이 되셨거나 대박 나신 분들을 댓글 공유 좀 해주시면 감사하겠습니다. ㅎ

참고 사이트

Anomaly detection in time series with Prophet library
Time-Series Forecasting: Predicting Stock Prices Using Facebook’s Prophet Model
시계열 예측을 위한 Facebook Prophet 사용하기

LSTM 기반 주가 예측의 실상

주가 예측은 주식을 처음 접하는 분들 그리고 머신러닝을 처음 접하는 분들이 어쩌면 가장 관심있어 하는 분야이다. 왜냐하면 주가 예측을 잘하면 수익을 낼수 있다는 기대감 때문이다. 주가 예측에 대한 방법은 여러 가지가 있지만 가장 흔하게 접할 수 있는 방법이 바로 오늘 주제인 LSTM 기반의 주가 예측에 대한 내용들이다. LSTM의 주가 예측 기법은 텐서플로우를 이용하면 쉽게 LSTM 모델을 이용할 수 있고 또한 예측 결과 그래프를 보면 놀랍게도 잘 예측하는 것처럼 보인다. 하지만 실제로는 전혀 적용할 수 없는 부분도 있고 이해가 좀 필요한 부분이 있다. 혹시나 LSTM으로 주가 예측을 잘 하면 돈을 벌 수 있지 않을까 하는 초보자들이 있을까 염려하여 제가 아는 범위 내에서 LSTM 주가 예측에 대한 실상(허상)을 정리하고자 한다. 그렇다고 전혀 부정하는 것은 아니지만 조금이나마 LSTM 주가 예측에 대한 이해를 정확히 실상을 이해하는 데 도움이 되었으면 한다

LSTM 기반 주가 예측의 어려움

기존 신경망에 비해 시계열 처리나 학습에 유리한 LSTM을 이용하면 간단한 시를 학습하기도 한다. 그럴싸해 보인다. 문자 단위의 시계열 패턴을 학습해 문장을 스스로 작성하는 능력을 배울 수 있다. 문법이 정확한 것은 아니지만 그러한 문장을 시계열 데이터 학습이 가능한 LSTM 알고리즘 만으로 배울 수 있다는 사실이 놀랍다. 그럼 오늘의 주제는 LSTM 주가 예측은 어떨까 결론부터 언급하면 영 형편없다. LSTM으로 주가 예측이 어려운 이유는 첫째, 주가는 실수이다. 연속적인 값의 시계열 처리를 학습해야 되기 때문에 위에서 언급한 문자 패턴을 학습하는 난이도와 차원이 다르다. 쉽게 말해, 문자 단위의 시계열 학습은 카테고리가 있는 디지털 세계 학습이고 주가 시계열 학습은 실수 체계의 아날로그 세계 학습이다. 아날로그의 시계열 처리 패턴 정보를 LSTM 신경망 내 패러미터가 담아내기에는 한계가 있다. 두번째 이유는 주가는 거의 랜덤 워크 (random walk) 형태로 움직인다. 랜덤으로 움직이는 패턴은 제 아무리 신경망일지라도 잡아내기 어렵다. 따라서 주가 예측은 거의 랜덤으로 움직이는 실수 체계의 시계열 패턴을 잡아내야 하는 것이다. 신경망이 마치 더하기나 곱하기 실수 체계 학습이 어려운 이유도 비슷한 이유이다. 신경망 계열은 디지털 즉, 카테고리 학습에는 강하지만 실수 체계 학습에는 매우 약하다. 랜덤 워크 이면서 자유도가 높은 실수 체계를 LSTM이 학습하고자 하면 LSTM 모델에서는 패턴 발견이 어렵기에 그래서 애매모호한 중간값으로 예측하는 경향도 발생한다. 그레디언드 기반 학습 방법은 패턴에 대해서 그래서 어느 정도 일관된 모습이 있어야 하는데 그렇지 않은 데이터를 보여주면서 학습해라 하면 LSTM이라 해도 결국 혼란스러워 하는 것이다. 뭐가 정답인지 모르는 것이며 쉽게 말해 학습을 조금만 시켜도 애매한 의미 없는 값(가령 제로)을 리턴하는 경향이 강해진다.

LSTM 의 주가 예측 결과가 우수해 보이는 이유

유투브나 블로그에서 LSTM 주가 예측에 대한 소스와 마지막에 그래프를 그려서 결과 예측이 잘 되는 것처럼 보인다. 하지만 실상은 그렇지 않다. LSTM 기반의 주가 예측은 과거 시계열 데이터(i-N:i)를 이용해 내일(i+1)의 주가 예측을 한다. 이 때 그 다음날(모레)의 예측은 또 과거 시계열 데이터(i-N+1:i+1)를 이용해 모레(i+2)의 주가 예측을 한다. 그러니까 모레의 주가 예측에 사용되는 시계열 데이터는 주가 예측한 내일(i+1) 값과는 별개로 과거 시계열 데이터를 이용한다. 이렇게 누적해서 그린 것이 LSTM 기반 그래프이다. 정리하면, 완전한 예측이 아니고 바로 그 다음날만을 예측해서 누적해서 그린 것이다. 바로 그 다음날만을 예측하면서 그리기에 실제 주가변동과 별 차이가 없는 듯 보이지만, 예측된 수치값을 보면 별 의미 있게 예측이 되는 듯한 느낌은 별로 없다.

‘그 간의 연구 노력이 전부 엉텅리다’ 라고 말하는 것은 절대 아니며, 그만큼 어렵다는 것을 말씀드리고 실상을 정확히 공유해 드리고 싶다는 의미로 작성하게 되었습니다. 틀린 부분이나 다른 의견 있으신 분 댓글로 주시면 감사하겠습니다.

32/64비트 파이썬 프로세스 통신 2nd(소스 공개)

파이썬 64비트 환경이 보편화되었지만 아직도 32비트 환경 파이썬 과의 연동이 필요한 부분이 있다. 대표적으로는 64비트 텐서플로우(tensorflow)나 파이토치(pytorch) 환경에서 32비트 대신증권 CybosPlus API 를 연동하고자 할 경우이다. 주식 트레이딩 알고리즘을 개발하고자 한다면, 대부분 딥러닝 파이썬 소스는 64비트 환경만 지원하는데, 대신증권 파이썬 모듈은 여전히 32비트 환경에서 구동되어, 32/64비트 환경간 통신이 필요해진다.

위 내용으로 이미 본 블로그의 32/64비트 파이썬 프로세스 통신 게시를 하였으나, 소스 관련 문의글이 많아 소스를 공개하고자 한다. 다만 예전 설명과는 조금은 소스 구성이 다르점도 있고 또한 모든 32/64비트 환경 연동 관점에서 공개한 것이지 대신증권 API 모두를 사용할 수 있도록 연동한 것은 아니다.

32/64비트 파이썬 프로세스 통신 관련 소스는 fipc 패키지로 구성되어있다. 각 소스 파일의 구성은 다음과 같다.

fipc/dsapi.py: 대신증권 API 모듈 파이썬 연동 부분
fipc/fakeipc.py: 32/64 비트 파이썬 연동 모듈 (import subprocess)
fipc/fcfg.py: fipc 환경 설정
fipc/fsutb.py: 32비트 파이썬 호출 모듈
fipctst.py: 테스트 파일

사용법

import fipc
print('종목수:', len(fipc.get_tot_items()))
tsdf = fipc.get_tseries('A000210', count=100)
print(tsdf)

환경 설정

fcfg.py 파일 내 32비트 파이썬 모듈 경로, fstub 경로, 그리고 acc (대신증권 계정 번호)를 설정해야 한다.

주식 고수 투자법 (격언 등)

주식을 하는 사람들이 항상 머리속에 습관처럼 지켜야 할 투자법 내지는 격언에 대해서 간단히 정리해보고자 합니다. 머신러닝 기반 알고리즘 트레이딩을 하고자 할 때, 제가  느끼는 점은 머신러닝으로 학습된 결과물은 항상 ‘개발자(창조자)의 투자 스킬 수준을 넘어서지는 않는구나’. 결국 개발자가 데이터를 구성해주고 학습하는 알고리즘도 결정하기에, 머신러닝도 그 수준이거나 또는 아래 수준으로 학습하게 됩니다. 따라서 제대로 된 머신러닝을 위해서는, 주식 시장을 이길 수 있는 방법을 연구하는 것도 필요하다고 생각합니다.  아직도 계속 공부중인것이 아쉽긴 합니다만…

주식 고수들의 지혜와 통찰력 (투자 격언 60개 중에서 아래 발췌)

  • 주식을 사지 말고 때를 사라
  • 산이 높으면 그만큼 골도 깊다
  • 주가는 거래량의 그림자다
  • 생활 주변에서 정보를 찾아라
  • 사고, 팔고, 쉬고 세 박자 리듬을 타라
  • 최고의 예언자는 과거다
  • 자신만의 투자기법을 스스로 개발하라
  • 손절매를 잘하면 주식투자에 성공할 수 있다

 

여러분들은 어떤 주식 투자 원칙을 가지고 계신지 궁금합니다~^^

참고자료

  • 원칙을 지키는 주식 고수들의 투자법, 박용선, 원앤원북스

주식 투자 기법

매입 보유법

  • 주식을 투자하는 가장 단순한 방법
  • 일단 매입을 하면 매도할 때까지 계속 보유하는 방식
  • 손절매하는 규칙도 없음
  • 운이 좋아서 이득을 볼 수도 있지만, 결국에는 돈이 궁해져서 파는 형태
  • 비가 올 때까지 마냥 기다리는 인디언 기우제 투자법이라고 하기도 함

정액 투자법

  • 주식 보유 비중을 일정 금액 기준으로 맞추면서 투자하는 방법
  • 수익이 나면 일정 금액까지 매도를 하고 손실이 나면 오히려 일정 금액이 될 때까지 매수
  • 추세 국면에서는 불리하지만 변동 국면에서는 유리

추세 투자법

  • 시장 추세에 따른 주식 투자법 (오른 주식은 다음에도 오를 가능성이 있다는 특징을 이용)
  • 상승 추세라고 판단되면 매수, 그렇지 않을 경우 전량 매도 (상승 추세 판단은 가령 3개월 이동평균보다 주가가 높다면 상승 추세)
  • 추세로 판단될 경우에만 매입하는 방법, 추세가 아니면 전량 매도하고 다시 추세가 올 때까지 기다리는 전략

추세/정액 전환법

  • 시장의 추세 여부에 따라 추세 구간에서는 추세 투자법을, 비추세 구간에서는 정액 투자법으로 전환하면서 투자하는 방법 (추세 투자법으로 손실을 본 경우, 비추세 구간으로 전환)
  • 추세 투자법에서는 비추세 구간에서는 투자를 전혀 안하지만 (이미 전량 매도한 상태) 추세/정액 전환법에서는 비추세 구간에서도 정액 투자를 고수
  • 시장이 어떻게 변화하든 비교적 잘 적응하면서 안전한 주식 투자법

정액 매수 적립식

  • 시장 상황에 상관없이 매달 일정 금액을 규칙적으로 매수하는 방법
  • 시장이 등락을 거듭할수록 평균 매입가를 낮추는 효과 발생

피라미드pyramiding (점증 적립식)

  • 이익이 발생할 때 주식 보유 비중을 점차 증가시키는 투자 기법
  • 최초 적립식으로 1백만원 투자하였다면 이익이 발생할 때 (발생 기준은 매월이나 매년 또는 매주) 같은 금액 1백만원을 더 투자하는 방법
  • 최초 적립식이 1백만원인데 이익이 발생할 때 최초 금액 대비 2백만원, 3백만원처럼 점차 증가시켜면서 투자하는 방법을 체증식 피라미드 또는 마팅게일(martingale) 방식이라고 함
  • 피라미딩과 대조되는 개념으로 물타기(역피라미딩)가 있음. 물타기는 손실이 발생할 때 보유 금액을 증가시키는 방법으로 평균 매입 단가를 낮추는 효과가 있음

위 내용은 아래 참고서적에 발췌한 내용임을 밝히며 위 내용 외에도 여러 가지 투자법이 있으니 더 궁금하신 분은 아래 참고 서적을 보시면 됩니다. (책 광고하려는 것은 아님 ㅎ)

참고 서적

  • ValueTimer의 전략적 가치 투자, 이콘

강화학습 기반 주식 트레이딩 시스템

머신러닝 알고리즘 분류(유형)는 크게 목적(라벨) 변수 유무에 따라 지도학습과 비지도학습으로 분류한다. 또 하나  재미있는 분류로는 강화학습이 있다. 강화학습은 에이전트와 환경이 주어질 때, 에이전트가 행하는 행위에 대한 보상(reward)으로 학습한다. 데이터 1건1건마다 라벨링값이 주어지는 지도학습과 달리 강화학습에서는 행위에 대한 보상(지도학습에서의 라벨링 역할)이 매번 주어질 필요가 없다. 이를 지연 보상(delayed reward)이라고 한다. 따라서 매번 행위 때마다 reward를 할 필요없이 행위가 여러번 시행된 이후 결과만 보상해도 학습이 된다라는 사실이다. 강화학습을 사용한 바둑을 생각하면 이해가 될 것이다. 매수하다 보상이 아니라 승패 결과만 보상해도 된다.

트레이딩 관점에서의 강화학습

트레이딩 관점에서 강화학습을 생각하면 에이전트는 트레이더(trader)이고 에이전트의 행위는 사고 팔고 그리고 아무런 행위도 안하는 것이다. 사고 나서 아무런 행위를 안하면 산 종목을 보유하겠다는 것으로 해석 가능하다. 에이전트가 구별할 수 있는 환경(에이전트가 인식할 수 있는 상태값)은 주식에서 얻을 수 있는 데이터들이다. 가장 기본적으로 차트 데이터가 있고 기타로는 지표 (PER 등), 뉴스 등 다양한 것들이 있을 수 있다. 강화학습이 제대로 학습만 된다면 너무나도 좋다. 사고 팔고 할 때 매번 보상을 줄 필요 없이 일정 기간 동안의 수익률(바둑에서의 승패)만 가지고도 학습이 왠지 쉬워 보일 듯 하다. 지도학습처럼 살 때 팔 때 따로 따로 모델을 만들어서 학습할 필요없이 강화학습 에이전트의 행위 자체가 사고 파는 그리고 보유(무행위)하는 인공지능 모델이 한번에 만들어지니 얼마나 좋겠는가…

실전 경험

강화학습을 접한지는 오래되었지만, 주식에 접하면 어떨까 싶어 시도를 해본 경험은 몇년 전이다. 뉴스나 논문을 봐도 강화학습을 이용한 로봇 트레이딩 시스템이 종종 있다. 그러나 필자가 시도한 바로는 학습이 쉽지 않았다. 사고 팔고 보유하는 단일 모델로 트레이딩 시스템을 구현해보고 싶었으나 현재까지도 보류(지금은 강화학습보다는 지도학습으로 변경) 상태이다. 강화학습에 대한 이해가 부족해서인지 아니면 에이전트 입력값(환경 상태)을 잘 못 잡아서인지 어려웠다. 강화학습 구현에는 텐서플로우 기반 오픈 소스를 활용해 DQN 이라는 딥러닝 강화학습 알고리즘을 사용했다. 시중에 나와있는 책을 사서도 봤지만 학습이 되질 않았다. 왜 학습이 안될까? 여기서 학습이 안된다는 의미는, 에이전트가 보지 못한 테스트 데이터셋에 적용을 해서 수익률이 나지 않음을 의미한다.  내 나름 주식 환경에서 강화학습이 어려운 점을 정리해 본다.

  1. 상태 공간이 너무 커 DQN 망 학습이 어려움.
    결국 DQN의 입력값은 상태값이 되며, 출력값은 가치(value) 값인데 상태에 대한 가치 추정이 어려움
  2. 에이전트 독립적인 환경
    보통 강화학습에서의 에이전트와 환경의 관계에는 에이전트 행위에 따라 환경이 상태값을 리턴하며 최종 목적지에 도착할 경우 보상을 준다. 그리드(grid) 월드나 바둑을 생각하면 된다. 그러나 주식 환경에서는 에이전트 행위와 거의 상관없이 환경이 변한다. 수십만 수백만 에이전트가 환경에 물려 있어 실제 거래하고 있는 에이전트는 환경에 거의 영향을 줄 수 없다는 의미다. 다시 말해, 목적 지향적인 패스가 주어지고 최종 보상이 주어지는 환경이 아니라는 것이다. 랜덤워크로 변화하는 차트를 기반으로 에이전트 입장에서는 마구 잡이로 보상하는 환경에 대해서 에이전트가 과연 학습을 할 수 있겠는가?

필자의 실전 경험과 이해를 바탕으로 작성한 글이니 잘못 작성된 부분도 있을 것이다. 혹시 다른 의견을 가지고 계신 분이나 주식 환경에서의 강화학습이 가능하다라고 주장하시는 분, 기타 등등 관련 내용을 공유해 주시면 정말 고마울 것이다. ㅎ 정말로 궁금하다 과연 강화학습으로 수익이 날 수 있는지… 가끔 강화학습 기반 로보트레이더 기사를 보면 더욱 궁금해진다. 세계 최고 강화학습 기술을 보유하고 있는 그 유명한 딥마인드(DeepMind)는 왜 주식에 적용하지 않을까? ㅎㅎ

(강화학습에 관심있는 여러분의 의견 내지는 조언을 듣고 싶습니다.)

배당 종목 배당률 순위 및 영구연금 배율 (2018년 3월 기준)

주식 투자에 대한 수익은 매수/매도 차익에 의한 수익 그리고 배당에 의한 수익으로 구성된다. 주식 투자를 하면서 배당에 대해서 소홀히 하면 안 된다. 관심있게 지켜봐야 할 사항이다. 특히 정기적으로 돌아오는 배당 시점을 잘 활용하면 남들보다 조금은 더 수익을 낼 수 있지 않을까 싶다. 통상적으로 배당 시점이 다가오면 주가가 상승으로 특성이 있기 때문이다. (물론 항상 그렇지만은 않다)

배당(Dividend)이란

배당은 일정기간 영업활동을 해 벌어드린 이익 중 일부를 그 회사 주주들한테 돌려주는 것을 말한다. 그렇기 때문에 재무상태표 상 이익잉여금의 범위 안에서 배당을 할 수 있다. 당기순손실이 쌓여서 이익잉여금이 결손금의 형태로 나타날 경우엔 배당 불가.

배당을 주는 회사가 그렇지 않은 회사보다 재무적으로 안정적인 경우가 많다. 배당을 지급하는 회사의 주가상승률이 그렇지 않은 회사보다 평균적으로 높은 것으로 나타났다. (나무위키에서 자료 발췌)

영구연금(Perpetuity)

동일한 금액을 영원히 받을 수 있는 현금 흐름을 영구연금이라고 한다. 죽기 전까지 제공되는 연금의 특수한 형태라고 이해할 수 있다.

가령 배당을 영구적으로 받는다고 가정하고 영구연금을 구하면 어떨까. 영구연금의 현재 가치를 구하는 방법은 다음과 같다.

 (Investopedia에서 자료 발췌)

그리고 영구연금과 기업의 현재 가치인 주가와 비교해보면 어떨지 궁금해서 파이썬으로 확인해보았다. (2018년 3월 기준)

확인 결과, 1등으로 ‘씨엠에스에듀’ 종목이 차지했으며 현재 주가 대비 영구연금 배율이 2.6배나 되었다. 주식 투자에 참고하길 바란다.

———————————————————

idx  종목 이름   현재가  배당률  영구연금  배율(=영구연금/현재가*100)

25   씨엠에스에듀    9080  13.32   24189  266.398678
14     이라이콤    6680  11.49   15350  229.790419
15     유아이엘    6760  10.31   13939  206.198225
20     서원인텍    7220   9.32   13458  186.398892
1      천일고속   89200   9.10  162344  182.000000
18     네오티스    4445   8.03    7138  160.584927
3      성보화학    6050   7.40    8954  148.000000
11      BGF   13300   6.60   17555  131.992481
7    푸른저축은행    7710   6.48    9992  129.597925
23    한솔씨앤피    8050   6.41   10320  128.198758
10     한국전력   33100   6.30   41706  126.000000
24    삼양옵틱스   17350   5.88   20403  117.596542
16   고려신용정보    3060   5.83    3567  116.568627
13  정상제이엘에스    7440   5.81    8645  116.196237
6    대림씨엔에스   10650   5.80   12354  116.000000
4      유화증권   14900   5.80   17284  116.000000
2     한국쉘석유  349500   5.70  398429  113.999714
8      일정실업   21900   5.70   24965  113.995434
19   연이정보통신    2590   5.62    2911  112.393822
5      진양산업    3290   5.60    3684  111.975684
22     한전산업    4000   5.50    4400  110.000000
12   에스에이엠티    1855   5.45    2021  108.948787
27     앤디포스    7530   5.43    8177  108.592297
17    와이비엠넷    2890   5.30    3063  105.986159
0        두산  105500   5.20  109719  103.999052
21     청담러닝   15650   5.16   16150  103.194888
26     동양파일    4930   5.11    5038  102.190669
9     S-Oil  125000   5.09  127250  101.800000

32/64비트 파이썬 프로세스 통신

필자는 대신증권 API(파이썬)으로 이용하고 있는 사용자 중 하나이다. 실제 파이썬 코드를 이용해 자동으로 매수/매도하는 프로그램을 운영하고 있다. 주식장이 열리는 날이면 매일 HTS 와 파이썬 모듈을 구동시키고 출근한다.

수익률이 크지는 않지만 (계속 보완/테스트 진행 중) 그래도 포기할만큼은 아니고 간간히 매수/매도로 수익이 나면 기분도 좋아지곤 한다.

이제는 2차 버전을 생각하고 있다. 수익률 때문은 꼭 아니지만 계속 새로운 것을 시도하면서 학습하고자 하는 목적도 있다. 바로 강화 학습 기반의 트레이딩 시스템이 다음 목표이다.

32/64비트 파이썬 통신이 필요한 이유

문제는 강화학습(DQN)을 하기 위해서는 텐서플로우(tensorflow)가 필요한데 대신증권 파이썬 모듈하고 돌리려니 문제가 발생했다. 텐서플로우는 64비트 환경에서 돌고 대신 증권은 32비트 환경에서만 구동해야 된다는 것이다. 텐서플로우를 32비트 환경에서 돌리는 것도 문제 해결은 될 수 있으나 32비트 환경에서 텐서플로우를 돌리기 위해서는 소스를 다운받아 컴파일해야 된다. 인터넷을 찾아보면 쉽지 않아 보인다. 한참을 좌절하고 있다가 우연히 IPC(Inter Process Communication)  관련 내용을 활용해보자라는 생각이 들었고 관련 자료를 찾아보기로 했다.

그러나 파이썬 기반 IPC 모듈이 딱히 마음에 드는 것이 없어 내 마음대로 필요한 내용을 구현해보고 사용해보고 있다. IPC도 아닌 fake IPC라고 스스로 명명해놓고 있다.

32/64비트 파이썬 기반 IPC 통신 방법

원리는 간단하다. 64비트 환경의 파이썬 모듈(예. 텐서플로우)에서 32비트 환경의 파이썬 모듈(대신증권 파이썬 모듈)을 호출한다. 그러면 대신증권의 파이썬 모듈에서 처리를 하고 나서 결과를 파일로 저장하고 이를 64비트 파이썬 모듈에서 읽어서 처리한다. 호출부 소스와 실행부 소스 일부는 아래와 같다.

호출부 (64비트 파이썬 환경)

# ...
from sytrap import fakeipc as fipc

sipc = fipc.SytrapFakeIpc()
p = sipc.call('get_item', itcode='A168330')  # get_item는 32비트 환경에서 구동
# ...

실행부 (32비트 파이썬 환경)

# ...
ret = syc.get_item(itcode)   
p.dump(ret, open(ippath, 'wb'))  # 처리 결과를 미리 약속된 경로에 저장
# ...

다만 호출할 때 64비트 환경에서 32비트 파이썬 실행기와 파이썬 모듈 경로를 정확히 제시해주어야 한다. 아래는 호출 방법의 예이다.

 <64비트 환경 python.exe> 64비트.py <32비트 환경 python.exe> 32비트.py

구현해야 할 양이 조금은 많아졌지만 (함수 옵션 처리, 파일 입출력 등) 드디어 64비트 텐서플로우를 이용해 32비트 대신증권 모듈을 호출할 수 있게 되어 마음껏 딥러닝 기반 트레이딩 시스템을 돌릴 수 있게 되었다. 수익률까지 좋아지길 기대하고 있다. ㅎ

저와 비슷한 고민을 하시는 분들에게 조금이나마 도움이 되길 바란다.

LDA 토픽 모델링

가끔 주식 관련 특징주 기사를 보면 주가에 영향을 줄만한 기사가 뜨는 경우가 있다. 물론 좋은 기사가 뜬다고 해서 주가가 항상 오르지는 않는다. 다만 테스트를 해보고 싶었다.

데이터 수집

먼저 기계 학습을 위해 관련 데이터 수집이 필요하다. 특정 사이트 URL를 선정해서 인터넷 기사와 주가와의 연관성 분석을 위해 5년간의 특징주 관련 기사를 수집했다. 그런 다음 기사가 뜬 시점의 주가와 2일 후 변동 주가를 기록하여 데이터를 수집하였다.

데이터 학습

데이터 학습은 LDA(Latent Dirichlet Allocation)라는 토픽 모델링 방법을 사용하였다. 신규 기사가 뜰 경우 LDA 토픽 벡터와 유사한 기사들을 검색하고 검색된 기사들의 주가 전후 변동값을 비교한 후, 신규 기사에 대한 주가 변동량으로 추정하는 방법을 이용하였다.

아래는 pseudo code


if new_article:
    tpv = lda_topic_vec(new_article)
    sims = find_similarity(tpv)
    ss = sort(sims, 10)  # get top 10 of similarity
    for article in ss:
        sumret += calc_change_rate(article)
    avgret = sumret/N
    if avgret > 0.02
        buy(ar)

LDA 란…

LDA는 잠재 디리클레 할당이라고 하는데, 문서에 잠재되어 있는 토픽(topic)을 이용해 분류(cluster)하는 방법론이다. 비지도 학습(unsupervised learning)의 일종이다. 나이브분류기(Naive Classifier)와 같은 예전 방법에는  문서를 포함하고 있는 단어들의 확률적인 분포로 문서를 분류했는데 LDA에서는 보이지 않은 토픽이라는 잠재(latent, hidden) 변수를 더 활용하는 점이 다르다. 단어는 직접적으로 확인 가능하지만 토픽은 추상적인 존재이기에 잠재라는 단어를 사용한다. 또 LDA는 디리클레라는 확률적인 분포를 가정하는 것이 특징이다. 반면 pLSA 와 같은 방법론은 확률적인 분포를 가정하지 않는다.

LDA 의 확률 분포는 다시 말해, 토픽 벡터의 요소가 양수이며 모든 요소를 더한 값이 1인 경우에 대해서 확률값이 정의되는 분포이다.

가령 토픽이 경제, 정치 2가지 뿐이라면 경제와 정치 2가지 토픽을 더해서 1이 되는 경우라 이해할 수 있다. 즉, 경제가 0.9, 정치가 0.1 정도의 토픽 비율의 문서는 가능한데, 경제 0.9, 정치 0.9 비율로 토픽이 구성된 문서는 사전 가정에서 배제하는 것이다.

위키에서 발췌한 아래 그림은 토픽 3개인 경우로 이해하면 되고 중앙이 큰 값을 가진다는 의미는 토픽이 어느정도 골고루 섞힌 문서가 많이 존재한다.(확률적으로 높은 값을 가짐)라는 의미로 해석할 수 있다.

(위키 그림 발췌)

 

LDA 토픽 모델링 결과, 주가에 긍적적인 기사 예

결과로만 보면, 신약 개발 관련 기업들의 기사 관련 내용들이 주가에 단기적으로 긍정적인 영향을 주는 것으로 파악되었다. 그래서 필자는 LDA 토픽 모델링 기법을 써서 특정 사이트를 모니터링 하다가 신약 개발 관련 기사들이 뜰 때는 자동으로 매수하도록 프로그램을 돌리기도 했다. 하지만 역시 소문에 팔고 기사에 팔라는 말이 맞는 듯…ㅎ