주식-차트
주식-차트

이동평균선 정배열은 단기 이동평균선이 장기보다 높은 상태로 주식이 상승 추세에 있다는 것을 의미합니다. 여러 가지 기술적 지표 중에 그래도 의미 있는 지표 중의 하나로 알려져 있는데요. 파이선을 이용하면 이평선 정배열 주식을 쉽게 찾고, 수익률도 트래킹 해 볼 수 있습니다.

 

 

주식 투자에서 데이터를 활용하는 방법에 대한 관심이 많아졌습니다. 요즘에는 퀀트 투자에 대한 강의나 자료도 쉽게 접할 수 있는데요. 그 정도까지는 아니지만 적절한 매수, 매도 타이밍을 잡기 위한 기술적 분석에 관심이 생겼습니다. 제가 관심을 갖게 된 것은 정배열인데요. 정배열 주식인지를 판단하고, 수익률을 트래킹 하는 작업을 해 보았습니다. 정배열의 의미는 링크를 참조하시기 바랍니다.


전체 코드는 제일 아래에 파일로 첨부하였습니다.

 

1. 정배열 주식 정의

먼저 종목코드를 받아서, 정배열 여부를 판단하는 코드를 작성하였습니다. 함수로 만들어서 다른 종목에 대한 판단도 쉽게 할 수 있게 하였습니다.

주식 가격 데이터는 FinanceDataReader를 이용해서 수집했고 5일, 10일, 20일, 60일, 120일 이동 평균선을 구해서 정배열 상태인지 확인하도록 하였습니다. 너무 과거 기준까지는 확인할 필요가 없어서 최근 10일 이내에 정배열 상태에 있으면 결과를 제공하도록 하였습니다.

def get_maar(ticker, days=10):
    """
    이동평균 정배열인지 확인
    """

    global ticker_dict

    df = fdr.DataReader(ticker, '2022')

    df["ma5"]=df["Close"].rolling(5).mean()
    df["ma10"]=df["Close"].rolling(10).mean()
    df["ma20"]=df["Close"].rolling(20).mean()
    df["ma60"]=df["Close"].rolling(60).mean()
    df["ma120"]=df["Close"].rolling(120).mean()

    df['maar'] = 0
    df.loc[(df["ma5"]>df["ma10"]) & (df["ma10"]>df["ma20"])
           & (df["ma20"]>df["ma60"]) & (df["ma60"]>df["ma120"]), 'maar'] = 1

    if datetime.now() - timedelta(days=days) < df.query('maar==1').index.max():
        message = f'{ticker} has found. max(Date): {df.query("maar==1").index.max()}'
        print(message)
        return [1, df, message]
    else:
        return [0, df, ""]

 

 

2. 백테스팅 정의

백테스트팅이라고 하였지만 수익률 트래킹 정도입니다. 별도의 모듈로 만들었고요. 매수 시점이 1로 표기된 칼럼이 있으면, 해당 날자에 매수했다고 보고 이후 수익률을 트래킹 하는 코드입니다.

def backtest(df, col, ticker):
    """
    매수 여부에 따라 평가 금액을 계산한다. get_buy_1d로 매수
    :param df: 데이터프레임 매수여부가 있어야 함
    :param col: 매수여부가 있는 칼럼
    :param ticker: 종목코드 기록용
    :return:
    """
    import matplotlib.pyplot as plt

    temp = df.query(f'{col}==1')
    temp.index.to_list()

    tot = pd.DataFrame()
    for t in tqdm(temp.index.to_list()):
        b1 = get_buy_1t(df,t)
        b1['ticker'] = ticker
        tot = pd.concat([b1, tot], axis=0)

    temp = tot['days'].value_counts()
    sns.countplot(data=tot, x='days').set(title='days after signal')
    plt.show()

    tot_gr = tot.groupby('days')['yrate'].mean()
    sns.lineplot(x=tot_gr.index, y=tot_gr).set(title='yield rate by closed price')
    plt.show()

    tot['updown'] = tot['yrate'].apply(lambda x: 'up' if x >= 100 else 'down')
    sns.countplot(data=tot, x='days', hue='updown').set(title='up down cnt')
    plt.show()

    return tot

 

그 외에도 시그널 발생회수와 이후 상승, 하락 비율을 체크하도록 하였습니다.

 

아래에 상기 두 코드를 모두 첨부하였습니다.

 

maar.py
0.00MB
stkutils.py
0.00MB

 

통계적으로 의미를 갖기 위해서는 여러 종목과 긴 기간에 걸쳐서 테스트해 보는 것이 필요합니다. 하지만 제가 전종목을 상대로 투자를 할 수 있는 것은 아니어서, 제가 관심 있거나 보유한 종목만 테스트해 보았습니다. 결과는 나쁘지 않았는데요. 이를 실제 투자와 연결하는 것은 또다른 얘기인 것 같습니다.


이제 파이썬 정배열 외에도 다른 지표를 이용해서도 여러가지 작업을 해 볼 수 있을 것 같은데요. 이는 다음에 또 다뤄보겠습니다.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기