Envelope란?
n일의 이동평균선에 +m%,-m%를 뜻한다.
분석 내용
보통 20일 이동평균선을 사용하고 m은 트레이더의 성향에 따라 많이 다르나 가장 보편적으로 사용되는 10으로 두고 분석해보겠다.
하향 envelope선에 돌파 또는 지지할시 매수 하고 m%만큼 떨어지면 손절, m%만큼 상승하면 익절하도록 세팅해 두었다.
코드
!pip install yfinance
import pandas as pd
import matplotlib.pyplot as plt
import bs4
import yfinance as yf
from urllib.request import urlopen # url의 소스코드를 긁어오는 기능
필요한 라이브러리들을 불러와 줬다.
# 종목코드 불러오기
stock_code = pd.read_html('http://kind.krx.co.kr/corpgeneral/corpList.do?method=download', header=0)[0]
stock_code = stock_code[['회사명','종목코드']]
# rename(columns = {'원래 이름' : '바꿀 이름'}) 칼럼 이름 바꾸기
stock_code = stock_code.rename(columns = {'회사명':'company','종목코드':'code'})
# 종목코드가 6자리이기 때문에 6자리를 맞춰주기 위해 설정해줌
stock_code.code = stock_code.code.map('{:06d}'.format) #6자리가 아닌 수를 앞에 0으로 채우기 위함
stock_code.tail(3)
상장된 기업정보들을 크롤링 해주었다.
# 코스피 200 종목의 이름을 웹 크롤링함
import bs4
from urllib.request import urlopen # url의 소스코드를 긁어오는 기능
#//*[@id="tab_con1"]/div[3]/table/tbody/tr[1]/td/span[1]/em
company_name = []
for i in range(1,21):
page = i
url = 'https://finance.naver.com/sise/entryJongmok.nhn?&page={page}'.format(page = page)
source = urlopen(url).read()
source = bs4.BeautifulSoup(source,'lxml')
source = source.find_all('a',target = '_parent')
for j in range(len(source)):
name = source[j].text
company_name.append(name)
네이버 금융에서 코스피 200종목들의 이름을 크롤링 하였다. 크롤링하는 방법은 블로그 글에 자세하게 나와있다.
code = []
for i in company_name:
for j in range(len(stock_code)):
if stock_code['company'][j] == i:
code.append(stock_code['code'][j])
break
code
코스피 200종목들의 종목코드들을 불러왔다.
def envelope(N,ma): #엔벨로프 설정 함수
idx = ma.index
plus = {}
minus = {}
for i in range(len(ma)):
plus[idx[i]] = ma[i]+((ma[i]*N)/100)
minus[idx[i]] = ma[i]-((ma[i]*N)/100)
return plus,minus
ma 이동평균선만큼 N의 엔벨로프선을 만드는 함수이다.
벡테스팅 함수
# 벡테스팅 함수
import yfinance as yf
import matplotlib.pyplot as plt
def buy(price,cash,finance,Average_price):
finance = cash/price
Average_price = price
cash = cash%price
return cash,finance,Average_price
def sell(price,cash,finance,Average_price):
cash = finance*price+cash
finance = 0
Average_price = 0
return cash,finance,Average_price
def backtesting(code,cash,N,min_percent):
start_cash = cash
finance = 0
Average_price = 0
data = yf.download(code)
ma20 = data['Adj Close'].rolling(window = 20).mean()
ma60 = data['Adj Close'].rolling(window = 60).mean()
ma112 = data['Adj Close'].rolling(window = 112).mean()
marker_buy = []
marker_sell = []
marker = []
plus,minus = envelope(N,ma20)
plus = pd.Series(plus)
minus = pd.Series(minus)
for i in range(1,len(data)):
if data['Adj Close'][i-1]>minus[i-1] and data['Adj Close'][i]<=minus[i]:
if finance == 0:
cash,finance,Average_price = buy(data['Adj Close'][i],cash,finance,Average_price)
line = []
line.append(data.index[i])
line.append(i)
marker.append(line)
if finance != 0 and Average_price+((Average_price*N)/100) <= data['Adj Close'][i]:
cash,finance,Average_price = sell(data['Adj Close'][i],cash,finance,Average_price)
line = []
line.append(data.index[i])
line.append(i)
marker.append(line)
print(cash)
elif finance != 0 and Average_price-((Average_price*min_percent)/100)>=data['Adj Close'][i]:
cash,finance,Average_price = sell(data['Adj Close'][i],cash,finance,Average_price)
line = []
line.append(data.index[i])
line.append(i)
marker.append(line)
print(cash)
'''
fig = plt.figure(figsize = (50,20))
fig = plt.plot(data['Adj Close'])
fig = plt.plot(minus)
fig = plt.plot(plus)
win = 0
lose = 0
for i in range(0,len(marker)-1,2):
start = marker[i]
end = marker[i+1]
if data['Adj Close'][start[1]]<data['Adj Close'][end[1]]:
fig = plt.axvspan(start[0],end[0],color = 'blue',alpha = 0.1)
win = win+1
else:
fig = plt.axvspan(start[0],end[0],color = 'red',alpha = 0.1)
lose = lose+1
plt.legend()
print(win,lose)
'''
print('백테스팅 총 수익률:',round(((cash-start_cash+(finance*data['Adj Close'][len(data)-1]))/start_cash)*100,2),'%')
print('잔고:',round(cash+(finance*data['Adj Close'][len(data)-1]),2),'원')
print('종목코드:',code)
return round(((cash-start_cash+(finance*data['Adj Close'][-1]))/start_cash)*100)
주석 부분은 그래프가 그려지는 부분이다.
결과
-89, -86, -80, -79, -79, -79, -78, -77, -66, -65, -62, -61, -60, -59, -59, -58, -55, -49, -47, -44, -42, -41, -41, -38, -37, -34, -33, -33, -31, -31, -31, -30, -29, -28, -28, -23, -22, -22, -22, -21, -21, -20, -17, -17, -16, -16, -15, -15, -15, -14, -13, -12, -12, -11, -10, -9, -7, -6, -6, -6, -4, -3, -1, 0, 0, 0, 0, 1, 1, 1, 2, 2, 4, 5, 6, 6, 7, 8, 9, 9, 10, 14, 15, 15, 16, 17, 18, 18, 19, 22, 23, 26, 26, 26, 26, 29, 29, 30, 30, 31, 31, 32, 35, 36, 40, 40, 42, 43, 45, 46, 47, 47, 47, 48, 49, 50, 53, 55, 56, 57, 57, 58, 62, 64, 66, 70, 73, 82, 84, 92, 93, 93, 96, 97, 102, 103, 105, 105, 106, 107, 115, 115, 117, 123, 135, 147, 150, 152, 160, 174, 183, 188, 190, 190, 193, 195, 214, 215, 217, 237, 247, 250, 258, 264, 272, 281, 297, 304, 324, 335, 355, 374, 398, 438, 440, 472, 523, 532, 577, 624, 698, 1209, 1240,
수익 : 37
손실 : 63
결과가 너무 안좋았다. 하지만 분석중에 알아낸 사실이 하나 있었다. envelope를 거래량이 많은 상태에서 둘파하게 된다면 대부분 손실을 본다는 사실이었다. 하지만 거래량이 터지지 않고 하향돌파하면 곧바로 반등이 나오거나 일주일이내에 수익이 나오는것을 알 수 있었다. 다음 포스팅에서는 이번에 분석한 것을 반영해서 포스팅 해보겠다.
'파이썬' 카테고리의 다른 글
[Django Project][community 만들기 - 가상환경 설정하기] (0) | 2021.12.12 |
---|---|
[파이썬][보조지표 envelope로 업비트 코인 분석] (3) | 2021.10.13 |
[파이썬][보조지표 MACD를 활용한 코스피 200 종목 분석] (0) | 2021.09.18 |
파이썬- 여러개 입력받기 (0) | 2020.10.10 |
파이썬- 리스트 정렬하기 (0) | 2020.10.10 |