EXPANSION OF THINKING IN INVESTMENT

투자에 대한 생각의 확장

CODING/PYTHON

[Python] 4주차_백테스팅 기초(1) : 골든/데드크로스 전략 구현 (1편) (Feat. 스파르타코딩클럽)

메타닷 2022. 12. 13. 13:42
728x90
반응형

 

4주차 강의에서는 이동평균선에 대해 알아보고, 

그와 관련한 전략을 세워 백테스팅하는 과정을 배운다. 

 

구체적으로 4주차 1편에서는

백테스팅 전략을 세우고, 

주가를 가져오고, 

그래프를 그려보고, 

이동평균값을 구해보고, 

Buy & Sell을 표기하는 방법을 배우는데, 

차근차근 실습 했던 것을 정리해보도록 하겠다.

 

참고로, 이 백테스팅 전략을 하기에 앞서

이동평균선과 골든크로스·데드크로스에 대한 개념을 

충분히 숙지하고 넘어가야 모든 과정이 이해된다. 

 

1. 백테스팅 전략 세우기 

1) 이동평균선이란?

  - 이전 며칠(3일, 5일, 20일, 50일 등) 간의 가격을 평균하여 움직이는 선이다.
  - 일수가 커질수록 곡선이 완만해진다.

[이동평균선]
일정기간 동안의 주가를 산술 평균한 값인 주가이동평균을 차례로 연결해 만든 선이다.
주식시장에서 주가와 거래량 및 거래대금은 매일 매일 변하지만 특정기간을 놓고 보면 일정한 방향성을 지닌다. 이를 수치화한 것이 이동평균선으로 장기(120일), 중기(60일), 단기(5, 20일) 이동평균선이 있다.
주가이동평균선은 일정기간 동안의 주가를 산술 평균한 값인 주가이동평균을 차례로 연결해 만든 선으로, 주가의 평균치를 나타내는 지표가 된다.
이동평균선을 그려나가다 보면 서로 교차하게 된다. 단기선이 장기선을 뚫고 오르거나 내리거나 한다. 교차로처럼 평균선들이 만나기에 크로스라고 하며 골든크로스나 데드크로스가 나타나는 것이다

출처 : [네이버 지식백과] 이동평균선(시사상식사전, pmg 지식엔진연구소)


2) 우리가 쓸 전략 : 골든크로스, 데드크로스 전략

  - 골든크로스 : 주가가 높아질 가능성이 있다는 신호
  - 데드크로스 : 주가가 낮아질 가능성이 있다는 신호

[골든크로스]
주가나 거래량의 단기 이동평균선이 중장기 이동평균선을 아래에서 위로 돌파해 올라가는 현상을 말한다. 이는 강력한 강세장으로 전환함을 나타내는 신호로 받아들여진다. 이동평균선이란 특정 기간 동안의 주가의 평균치를 이어놓은 선을 말한다. 보통 '단기 골든크로스'는 5일 이동평균선이 20일 이동평균선을 상향 돌파하는 것을 말하며, '중기 골든크로스'는 20일선과 60일선을, '장기 골든크로스'는 60일선과 100일선을 비교한다. 예를 들어 단기 골든크로스가 나타났다면 5일간 주가의 평균가격(5일 이동평균선)이 20일간 주가의 평균가격(20일 이동평균선)을 넘어서는 현상을 말한다. 이것은 최근 5일간 투자심리가 지난 20일간 투자심리보다 좋아지면서 주가가 올라갈 가능성이 높아졌음을 나타내는 신호가 된다. 따라서 일반적으로 증권시장에서는 골든크로스 출현을 향후 장세의 상승신호로 해석한다. 하지만 단기 골든크로스만 가지고서는 상승 추세라고 해석하기에는 이르며, 보통 5일선과 20일선이 60일선을 뚫고 다시 120일선을 뚫으면 추세적 상승세로 해석한다. 또 골든크로스 발생 시 거래량이 많을수록 강세장으로의 전환 가능성이 높다는 의미를 지닌다.

한편 골든크로스와 반대되는 현상으로 '데드크로스(dead cross)'가 있다. 단기 이동평균선이 장기 이동평균선 아래로 떨어지는 현상이 데드크로스인데, 보통 약세장으로 전환하는 신호로 해석된다.

출처 : [네이버 지식백과] 골든크로스 (시사상식사전, pmg 지식엔진연구소)

 

 

2. 주가 가져오기 

1) 라이브러리 설치

  - `pandas-datareader` 와 `finance-datareader` 라이브러리를 활용해서 주가를 바로 가져와본다.

!pip install yfinance pandas-datareader finance-datareader

['pandas-datareader`와 `finance-datareader` 라이브러리 설치]


2) 주가 가져오기

  - 필요한 라이브러리들을 import 한다.
  - 다른 코드를 넣으면, 종목 별로 모두 가져올 수 있다. 

from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override()
import numpy as np
import pandas as pd
import FinanceDataReader as fdr

df = fdr.DataReader('005930','2018')
df.head()

[라이브러리 import 및 업체 정보 표로 만들기]

 

3) 살펴보기

  - `Open: 시초가`, `High: 고가`, `Low: 저가`, `Close: 종가`, `Volume: 거래량`, `Change: 변동`
  - 종가만 가져와보기

df[['Close']]

[종가 불러오기]


  - 변동이 20% 이상인 날들만 가져와보기

df[abs(df['Change']) > 0.05]

[변동이 20% 이상인 날만 불러오기]

 

3. 간단한 그래프 그려보기 

1) 주가 그래프 그려보기

  - .plot(y=['컬럼명']) 을 이용하여 그래프를 그려본다.

df = fdr.DataReader('005930','2018')
df.plot(y=['Close'])

[주가 그래프 그리기]


  - 좀 더 크게 보려면, figsize=()를 이용한다.

df.plot(y=['Close'],figsize=(15,8))

[주가 그래프 크게 그리기]


  - 격자 추가하기는 grid=True를 쓴다.

df.plot(y=['Close'],figsize=(15,8),grid=True)

[주가 그래프 격자 추가하기]

 

- 두 개 그래프를 동시에 그리고 싶을 때, 컬럼명을 추가해주면 된다.

[그래프 두 개 동시에 그리기]

 

  - 모든 그래프를 다 그려주고 싶다면, df.plot()만 써주면 된다.

[모든 그래프 그리기]


2) 종목 두 개의 주가 변동 그래프를 그려보기

  - 삼성전자와 LG전자의 변동 그래프를 그려본다. 

df_1 = fdr.DataReader('005930','2018')
df_2 = fdr.DataReader('066570','2018')

df = pd.DataFrame()
df['Samsung'] = df_1[['Change']]
df['LG'] = df_2[['Change']]

df.plot(figsize=(15,8))

[삼성전자와 LG전자의 변동 그래프 그리기]


  - 그래프 보기가 복잡하여, 최근 100일만 해본다.

df_1 = fdr.DataReader('005930','2018')
df_2 = fdr.DataReader('066570','2018')

df = pd.DataFrame()
df['Samsung'] = df_1[['Change']]
df['LG'] = df_2[['Change']]

df.tail(100).plot(figsize=(15,8))

[변동 그래프 최근 100일만 그리기]

 

4. 이동평균값 만들기(3일) 

1) 우선 종가만 모아보기

  - `Close` 만 가져와본다.

df = fdr.DataReader('005930','2018')
df = df[['Close']]
df

[종가만 모아보기]


2) 3일마다 평균 값을 구하기

  - `.rolling` 을 사용해 지정 날짜의 평균값을 구해본다.

df.rolling(3).mean()

[3일 이동평균값 구하기]


  - 붙여서 함께 본다. Close의 3개 값 평균이 ma로 들어온 것을 확인 할 수 있다. 

df = fdr.DataReader('005930','2018')
df = df[['Close']]
df['ma'] = df.rolling(3).mean()
df

[이동평균값 열 추가하기]


5. buy & sell 표기 

1) `shift` 를 가지고 열을 맞춰보기

  - 비교 대상은 다음 날 값(파란 부분)과, 최근 3일의 ma 값(노란 부분)이다. 

  - 종가가 3일전 이평선 값을 뚫고 올라가면 매수한다.
  - 이 때, 비교 값을 같은 행에 두면 넘었는지 / 안 넘었는지 쉽게 알 수 있는데, ma 값(노란부분)을 한 칸씩 내려야 한다. 
   

[비교값 확인하기]


  - 컬럼값 한 칸 내리기는 .shift()를 이용한다.

df = fdr.DataReader('005930','2018')
df = df[['Close']]

df['ma'] = df.rolling(3).mean().shift(1)
df

[비교값 열 맞추기]


2) buy & sell 표기하기

  - Close값이 ma값을 넘었으면 buy, 아니면 sell 로 표기한다.

df = fdr.DataReader('005930','2018')
df = df[['Close']]

df['ma'] = df.rolling(3).mean().shift(1)
df['action'] = np.where(df['Close'] > df['ma'], 'buy', 'sell')
df

[buy & sell 표기하기]

 

 

728x90
반응형