[Pandas]Rolling Statistics

반응형
    반응형

    논문이 끝난 줄 알았는데 어디에 내야한다며 영어를 아주 제대로 해오라는 교수님의 말씀에 저의 모든 계획이 무너지고 있습니다. 더 잘 만들어서 포스팅을 하려고 했는데 좀 아쉽지만 어쨋든 이번 포스팅에서는 판다스의 rolling을 이용한 분석 예제을 할까 합니다.

    영원히 안 올릴 수도 있을 것 같아서 준비가 덜 되었지만 맛보기로 올립니다. 

    이게 코딩이라기보다 금융 데이터 분석에 가까워서 카테고리에 안 맞을 수 있습니다.

     

    어쨋든 앞선 포스팅에서 이동평균선을 rolling으로 구했었는데 이걸 가지고 다양한 각도에서 볼 수 있는 통계적 분석을 할까 합니다.

     

    CJ제일제당의 데이터를 가지고 해보겠습니다.

    편의를 위해 날짜와 종가만 가지고 오겠습니다.

     

    df

     

    통계 수치

    window를 20으로 해서 할 수 있는 몇가지 통계적 수치를 내보겠습니다.

    window= 20
    data['min'] = data['Close'].rolling(window=window).min()
    data['mean'] = data['Close'].rolling(window=window).mean()
    data['std'] = data['Close'].rolling(window=window).std()
    data['median'] = data['Close'].rolling(window=window).median()
    data['max'] = data['Close'].rolling(window=window).max()
    data['ewma'] = data['Close'].ewm(halflife=0.5, min_periods=window).mean()
    data.dropna()

     

    ewma 는 exponentially weighted moving average로 log 곡선에 맞춘 이동평균선이라 보면 됩니다.

    이론적 배경은 추후에 포스팅을 하겠습니다.

    NaN은 모두 떨구고 보면 이렇게 통계수치를 자동으로 계산해주는 걸 볼 수 있습니다.

    이걸 plot으로도 볼 수 있는데 일부만 보이겠습니다. 

    판다스 같은 경우 컬럼을 기준으로 바로 plot을 할 수 있어서 그걸로 보이겠습니다. 

    min,mean,max를 종가와 비교하면 무엇을 구했는지 정확히 알 수 있습니다.

     

    ax = data[['min','mean','max']].iloc[-200:].plot(figsize=(10,6),style=['g--','r--','b--'],lw=0.8)
    data['Close'].iloc[-200:].plot(ax=ax,lw=2.0)

     

    너무 길어서 일부만 떼어서 그렸습니다. 보시는바와 같이 max,min,mean이 밴드를 이루어서 종가를 감싸는게 보일 겁니다. 학문적으로 접근할지 돈을 버는 관점으로 접근할지는 본인이 원하는 방향으로 분석을 해서

    뭐가 정답이라 말할 수는 없지만 적어도 max와 min은 계속 증가,감소해서 새로운 선을 그리긴 하지만

    그 안의 mean은 종가의 평균이 되어서 그런지 선을 갱신하지는 않은 것 같습니다. 

    그리고 모든 수치가 종가의 큰 방향성을 알려주기는 합니다. 

    종가만 본다면 큰 방향성은 사실 보기 어렵습니다.

    그런 의미에서는 의미가 있다고 할 수 있지만 주식으로 돈을 벌기위해 20선을 갖다 쓰려고 한다면

    종가가 오르고 20선이 오르는 후행현상을 극복해야만 합니다.

    무심코 매매에 임했다가는 돈을 벌지 못할 것 같습니다.

     

    기술적 분석 예제

    보통 rolling statistics은 기술적 분석툴로써 많이 쓰입니다.

    기술적 분석이 무엇이냐 하면 회사의 가치보다는 차트나 그래프를 보고서 저가인지 고가인지를 나름 판단을 하거나 특정 포지션에서 매수를 해야할지 매도를 해야할지를 분석하는 방법입니다. 

    제가 하고 싶은 얘기는 기술적 분석이 좋다 나쁘다가 아니라 rolling으로 어느정도 전략을 구현할 수 있다, 코딩이 된다 이정도 입니다.

     

    옛날에 유행했던 20,60선 돌파 매매를 구현해보겠습니다. 

    60선이 수급선이라고 해서 주가가 60선을 돌파하면 상승세에 접어들었다는 판단과 

    20선은 생명선이라고 하는데 주가가 20선을 회귀하는 현상이 발생해

    20선이 60선을 돌파했을 때라는 것은 주가가 20선으로 돌아올테니 완벽한 상승장이라 판단해 매수를 하는 그런 매매 방법입니다.

    큰 방향은 볼 수 있는데 요즘에는 이 매매법으로 단순하게 매매해서는 성공하기가 어려운것같습니다. 

    무튼 전략의 성능을 논하는 게 아니라 구현이 목적이니 구현을 해보겠습니다.

    단순 이동평균선(Simple Moving Averages) 20일과 60일을 rolling을 통해 수치로 만들고 매수,매도 순간을 만들어 그려보면 눈으로 확인이 가능합니다. 

     

    data['SM20'] = data['Close'].rolling(window=20).mean()
    data['SM60'] = data['Close'].rolling(window=60).mean()
    data.dropna(inplace=True)
    data['positions'] = np.where(data['SM20']>data['SM60'],1,0) #20선>60선이면 1, 아니면 0
    ax = data[['Close','SM20','SM60','positions']].iloc[-400:].plot(figsize=(10,6), secondary_y='positions')
    ax.get_legend().set_bbox_to_anchor((0.25,0.85))

    너무 커서 400개만 잘라서 그렸습니다.

    빨간색이 1에 있으면 매수상태이고 0에 있으면 매도 상태인 겁니다. 

    실제 종목을 선택하거나 수익률을 구하는 수치 계산은 또다른 문제지만 

    일단은 차트를 봐서 영감을 받기에는 좋은 툴이 되지 않을까 싶습니다.

     

    관련 포스팅

    [Python/Pandas] - Pandas에서 이동평균선 구하기

    [Python/Numpy] - [Numpy] np.where()

     

    댓글

    Designed by JB FACTORY

    ....