스터디/Tech

[기술서적] 파이썬을 활용한 금융분석 - 데이터 시각화

_leezoee_ 2024. 2. 22. 15:07

 

 

파이썬을 활용한 금융분석 - 이브 힐피시 책 내용을 기반으로 colab, jupyter notebook 으로 직접 코드 구현해보며 공부한 내용이다.

 

 

 데이터 시각화

 

 

matplotlib, plotly 라이브러리를 사용한 시각화 기능 소개.

 

matplotlib는 PNG, JPG 등 비트맵 형식 플롯만 생성할 수 있다.

plotly는 D3.js 같은 현대적 웹 기술을 활용하는 플롯을 쉽게 만들 수 있는 라이브러리이다.

 

 

* 1차원 데이터

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

np.random.seed(1000)
y = np.random.standard_normal(20)
x = np.arange(len(y))
plt.plot(x,y)

plot 함수 사용 (주어진 x,y 값 사)

 

* 2차원 데이터

y = np.random.standard_normal((20,2)).cumsum(axis=0)

plt.figure(figsize = (10,6))
plt.plot(y, lw=1.5)
plt.plot(y, 'ro')
plt.xlabel("index")
plt.ylabel('value')
plt.title("simple plot")

 

2차원 데이터 기본 plot

 

금융데이터를 활용할때 동일한 금융 위험 요인을 여러번 시뮬레이션 할 때, 비슷한 크기의 여러 데이터를 그릴 때는 하나의 y축을 써도 되지만 크기가 전혀 다른 데이터를 그릴 때는 하나의 y축만 쓰면 적합한 시각화를 할 수 없음.

이럴 경우는

 

1. y축을 하나 더 사용 (좌/우)

2. 서브플롯 subplot을 하나 더 사용 (좌/우 혹은 상/하)

 

#y축 추가
fig, ax1 = plt.subplots()
plt.plot(y[:, 0], 'b', lw=1.5, label='1st')
plt.plot(y[:,0], 'ro')
plt.legend(loc=8)
plt.xlabel('index')
plt.ylabel('value 1st')
plt.title('simple plot')
ax2 = ax1.twinx() #x축을 공유하는 두번째 axis 객체를 생성
plt.plot(y[:,1] , 'g', lw=1.5, label='2nd')
plt.plot(y[:, 1], 'ro')
plt.legend(loc=0)
plt.ylabel('value 2nd')

 

두 개의 y축 사용

 

 

 

#두개 sub플롯 사용
plt.figure(figsize=(10,6))
plt.subplot(211) #첫번째 sub플롯 정의
plt.plot(y[:,0], lw=1.5, label='1st')
plt.plot(y[:, 0] , 'ro')
plt.legend(loc=0)
plt.ylabel('value')
plt.title('two plot')
plt.subplot(212) #두번째 서브플롯 정의
plt.plot(y[:,1], 'g', lw=1.5, label='2nd')
plt.plot(y[:,1] , 'ro')
plt.legend(loc=0)
plt.xlabel('index')
plt.ylabel('value')

 

두 개 subplot 사용

 

 

 

* 선/포인트 플롯과 바 차트 결합 형태

plt.figure(figsize=(10,6))
plt.subplot(121)
plt.plot(y[:,0] , lw=1.5, label='1st')
plt.plot(y[:,0] , 'ro')
plt.legend(loc=0)
plt.xlabel('index')
plt.ylabel('value')
plt.title('1st data set')

plt.subplot(122)
plt.bar(np.arange(len(y)), y[:,1], width=0.5, color='g', label='2nd')
plt.legend(loc=0)
plt.xlabel('index')
plt.title('2nd data set')

 

라인+바 차트

 

 

 

 

* 기타 플롯 유형

 

스캐터 플롯(산점도)으로 데이터 표현.

두 금융 시계열 데이터 수익률을 동시에 볼 때 사용 가능.

 

c = np.random.randint(0,10,len(y))

plt.figure(figsize = (10,6))

#x,y좌표  ,  c=c는 데이터포인트 색상 지정 c는 색상을 나타내는 배열, cmap은 사용할 색상지도, marker 마커모양
plt.scatter(y[:, 0] , y[:, 1], 
            c=c,
            cmap = 'coolwarm', 
            marker = 'o')
plt.colorbar()
plt.xlabel('1st')
plt.ylabel('2nd')
plt.title('scatter plot')

 

산포도

 

 

 

히스토그램 

주로 금융자산 수익률을 나타내는데 사용된다.

plt.figure(figsize = (10,6))
plt.hist(y, label=['1st', '2nd'], bins=25)
plt.legend(loc=0)
plt.xlabel('value')
plt.ylabel('frequency')
plt.title('histogram')

 

히스토그램

 

 

 

 

금융분야에서 히스토그램은 중요한 플롯 유형

 

plt.hist() 인수

인수 설명
x 리스트 객체, ndarray 객체
bins 빈도 구분값의 수
range 빈도 구분값의 위 아래 범위
normed 전체 값 합이 1이 되도록 정규화하는지 여부
weights x값에 대한 가중치
cumulative 각 빈도 구분값이 하위 빈도 구분값을 누적하는지 여부
histtype bar, barstacked, step, stepfilled
align left, mid, right
orientation horizontal, vertical
rwidth 각 막대의 상대적인 폭
log 로그 스케일
color 각 자료색
label 레이블로 사용되는 문자열 혹은 문자열 목록
stacked 여러 개 자료를 쌓아올려 표현할지 여부

 

 

박스플롯

데이터 집합의 특성을 동시에 정확하게 나타낼 수 있다.

 

fig, ax = plt.subplots(figsize=(10,6))
plt.boxplot(y)
plt.setp(ax, xticklabels=['1st', '2nd'])
plt.xlabel('data set')
plt.ylabel('value')
plt.title('Boxplot')

boxplot

 

 

 

 

* 정적 3차원 플롯

 

변동성 곡면은 일련의 만기와 행사가 조합에 대한 내재 변동성을 나타낸 것으로 3차원 플롯이 필요.

 

ex) 행사가 : 50~150, 만기 : 0.5~2.5

np.meshgrid() 사용해서 2차원 좌표 생성 예제는 아래와 같다.

import numpy as np

x = np.array([1, 2, 3])  # X 축에 해당하는 배열
y = np.array([4, 5, 6])  # Y 축에 해당하는 배열

X, Y = np.meshgrid(x, y)

X:
[[1 2 3]
 [1 2 3]
 [1 2 3]]

Y:
[[4 4 4]
 [5 5 5]
 [6 6 6]]

 

 

3차원 코드 플롯에 대한 예제는 아래와 같다.

#plot_surface 함수 사용

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D #Axes3D 임포트 필수

# 데이터 생성
strike = np.linspace(50, 150, 40) #데이터 포인트 40개, 많아지면 더 완만해짐
ttm = np.linspace(0.5, 2.5, 40)
strike, ttm = np.meshgrid(strike, ttm)
strike[:2].round(1)

iv = (strike - 100) ** 2 / (100 * strike) / ttm
iv[:5, :3]

from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize = (10, 6))

# 그래프 생성
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d') #3차원 플롯 캔버스 설정

#3차원 플롯생성
surf = ax.plot_surface(strike, ttm, iv, rstride=2, cstride=2, cmap=plt.cm.coolwarm, linewidth=0.5, antialiased=True)
ax.set_xlabel('strike')
ax.set_ylabel('time-to-maturity')
ax.set_zlabel('implied volatility')
fig.colorbar(surf, shrink=0.5, aspect=5); #우측 컬러바 생성

 

내재 변동성 3차원 곡면 플롯

 

 

같은 자료를 3차원 스캐터 플롯으로 표현하기

 

fig = plt.figure(figsize = (10,6))
ax = fig.add_subplot(111, projection='3d')
#ax.view_init(30,60) #각도를 변경해서 볼 수 있음
ax.scatter(strike, ttm, iv, zdir='z', s=25, c='b', marker='^')
ax.set_xlabel('strike')
ax.set_ylabel('time-to-maturity')
ax.set_zlabel('implied volatility')

 

내재 변동성 3차원 스캐터 플롯

 

 

 


 

 

* 상호작용형 2차원 플롯

 

plotly는 데이터 과학 커뮤니티에서 널리 쓰이는 라이브러리이다.

pandas DataFrame 객체 및 Cufflinks 패키지와 쉽게 연동하여 쓸 수 있다는 장점이 있다.

 

#colab 환경에서는 그래프 안나오고 jupyter 노트북 환경에서만 그래프 표기됨

import pandas as pd
import numpy as np
import cufflinks as cf
from IPython.display import HTML
import plotly.offline as plyo
plyo.init_notebook_mode(connected=True)

# 데이터 생성
np.random.seed(0)
a = np.random.standard_normal((250, 5)).cumsum(axis=0)
index = pd.date_range('2019-1-1', freq='B', periods=len(a))
df = pd.DataFrame(100+5*a, columns=list('abcde'), index=index)

# 그래프 렌더링 - matplotlib 라이브러리를 사용하여 그래프를 생성, 주피터 노트북 내에서 바로 표시
#df.plot()

#plotly와 cufflinks 라이브러리를 사용
plyo.iplot(
    df.iplot(asFigure = True),
    image = 'png',
    filename = 'ply_01'
)

plotly.pandas.Cufflinks 라인 플롯 시계열 데이터

 

plyo.iplot(
    df[['a' , 'b']].iplot(asFigure = True,
                          theme = 'polar',
                          title = 'A Time Series Plot',
                          xTitle = 'date',
                          yTitle = 'value',
                          mode = {'a' : 'markers', 'b' : 'lines + markers'},
                          symbol = {'a' : 'circle', 'b' : 'diamond'},
                          size = 3.5,
                          colors = {'a' : 'blue', 'b' : 'magenta'},
                          ),
    # image = 'png',
    filename = 'ply_02'
)

옵션 변경 그래프

 

plyo.iplot(
    df.iplot(kind = 'hist',
            subplots = True,
            bins = 15,
            asFigure = True),
    # image = 'png',
    filename = 'ply_03'
)

 

타입 히스토그램 그래프

 

 

plotyle, Cufflinks, pandas를 사용하면 금융 시계열 데이터를 표현하기에 용이.

Cufflinks에서 QuantFig를 사용하여 퀀트 트레이딩 데이터 시각화

사용한 데이터는 fxcm forex 환율 시계열 데이터를 다운로드 받아 진행하였다.

 

raw = pd.read_csv('fxcm_eur_usd_eod_data.csv', index_col = 0, parse_dates = True)
raw.info()

quotes = raw[['AskOpen' , 'AskHigh', 'AskLow', 'AskClose']]
quotes = quotes.iloc[-60:]

qf = cf.QuantFig(
    quotes,
    title = 'EUR/USD Exchange Rate',
    legend = 'top',
    name = 'EUR/USD'
)
plyo.iplot(
    qf.iplot(asFigure = True),
    #image = 'png',
    filename = 'qf_01'
)

QuantFig를 활용한 OHLC(시가, 고가, 저가, 종가) 캔들플롯

 

 

추가로 메서드를 활용하여 볼린저 밴드 차트 요소 그리기

 

qf.add_bollinger_bands(periods = 15, boll_std = 2) #period 볼린저밴드 기간, boll_std 표준편차
plyo.iplot(qf.iplot(asFigure = True),
          #image = 'png',
          filename = 'qf_02')

볼린저 밴드 요소 추가

 

 

RSI 금융지표 서브플롯 추가하기

qf.add_rsi(
	periods = 14, #기간변수 설정
    showbands = False #위아래 밴드 미표시
)

plyo.iplot(
	qf.iplot(asFigure = True),
    #image = 'png',
    filename = 'qf_03'
)

 

RSI 서브플롯 추가