초반에 3가지 설치해야 한다.

!pip install yfinance pandas-datareader finance-datareader

설치 후 코드 스니팻 복사 후 붙여넣기

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()

그래프

df.plot(y=['Close'])

df.plot(y=['Close'],figsize=[15,8])
좀 더 크게 나온다

df.plot(y=['Close'],figsize=[15,8],grid=True)
좀더 크게 격자선넣기

df.plot(y=['Open','Close'],figsize=[15,8],grid=True)
Open, Close가 같이 나온다.

df.plot()
df에 있는걸 다 그러준다

1) 두 회사를 같이 보고싶을때

최근 100일을 그래프로 그려라

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

2) 이동평균 값만들기

먼저

참고 : 여기서 rolling(3)은 위에서부터 3개씩 묶는다. 예시) 0,1,2 / 1,2,3, / 2,3,4 이런순으로 묶는다고 생각하면 된다.

그런다음 ma값을 한칸씩 내려야 비교대상이 되므로

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df

shift를 넣어 내려준다.

그 후 비교대상과 비교 후 구매할지 판매할지 표시

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df

2. 수익률구하기

buy → buy → buy 이면, 사는 게 아니다.
즉, buy와 sell이 바뀌는 순간이 중요하다.

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

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

df
즉 action_temp는 shift가 1인것과 나 자신을 비교하는 것이다.

1) 사는 시점, 파는시점

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

cond = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')

df['real_buy'] = np.where(cond,'buy','')

df

real_buy에 표기된 'buy'시기를 모으면 사는 시점이 될것이다.

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df[cond1]

반대로 'sell'시기를 모으면 파는 시점이 될것이다.

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df[cond2]

이 것을 한데 모으면

마지막에 df_buy 또는 df_sell을 넣으면 입력값이 나온다.
또한 수익률이기때문에 맨 마지막은 무조건 판매(sell)이 나와야 되므로

df.iloc[-1,-1] = 'sell'

이것을 넣어줘야된다.

여기서 concat을 옆으로 붙여줄려면

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1]
df_sell = df[cond2]

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result.head(30)

그렇지만 한줄이 밑에 있기 때문에 이걸 합쳐줄려면

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_sell = df[cond2].reset_index()

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result.head(30)

이렇게 하면 깔끔하게 볼 수 있다. 여기서 중요한 부분은 close 인데 두개가 있으므로 이름을 바꿔주자

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result.head(30)

수익률은 종가(sell)/종가(buy)로 하면 된다.

df = fdr.DataReader('066570','2018')

df = df[['Close']]

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']

df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_result

수익률자료만 가져오자 (오류가 뜰텐데 그 뒤에 자료가 중복되어서 위험하다고 알려주는것이므로 copy를 넣어주자)

df = fdr.DataReader('066570','2018')

df = df[['Close']].copy()

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']

df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_result[['수익률']]

그 후 전체를 곱해주면된다.

df = fdr.DataReader('066570','2018')

df = df[['Close']].copy()

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']

df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_result['수익률cumprod'] = df_result[['수익률']].cumprod()

df_result

수익률cumprod는 그 라인부터 위쪽으로 전부 곱하게 된것이다.

거기서 맨 마지막것을 가져와서 -1을 해주면 수익률이 나온다.

df = fdr.DataReader('066570','2018')

df = df[['Close']].copy()

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']

df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_result[['수익률']].cumprod().iloc[-1,-1]-1

이것을 함수로 나타낼려면?

def get_return(code,n):
df = fdr.DataReader(code,'2018')

df = df[['Close']].copy()

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

df['action'] = np.where(df['Close'] > df['ma'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']

df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

return df_result[['수익률']].cumprod().iloc[-1,-1]-1

code는 회사주식코드이고 n은 날짜이다.

예시) 삼성전자 005930

예시) LG전자 066570

3. 단기 이평선, 장기 이평선

먼저 사용했던 곳에서 코드를 뽑아오면

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

df = df[['Close']].copy()

df.iloc[-1,-1] = 'sell'

df['ma1'] = df.rolling(3).mean().shift(1)
df['ma2'] = df.rolling(30).mean().shift(1)

df['action'] = np.where(df['ma1'] > df['ma2'], 'buy','sell')

df
이렇게 하면 오류가 뜨는데 위에 함수가 없는 곳이 있기 때문이다.
df = fdr.DataReader('005930','2018')

df = df[['Close']].copy()

df['ma1'] = df['Close'].rolling(3).mean().shift(1)
df['ma2'] = df['Close'].rolling(30).mean().shift(1)

df['action'] = np.where(df['ma1'] > df['ma2'], 'buy','sell')

df
이렇게 해야 오류가 안뜬다.

그 후 하나씩 가져오면서 검토해보면

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

df = df[['Close']].copy()

df['ma1'] = df['Close'].rolling(3).mean().shift(1)
df['ma2'] = df['Close'].rolling(30).mean().shift(1)

df['action'] = np.where(df['ma1'] > df['ma2'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값1','이평값2','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값1','이평값2','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_result[['수익률']].cumprod().iloc[-1,-1]-1

단기는 며칠이고 장기는 며칠이고 수익률은 나는지를 만들어보자

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

df = df[['Close']].copy()

df['ma1'] = df['Close'].rolling(3).mean().shift(1)
df['ma2'] = df['Close'].rolling(30).mean().shift(1)

df['action'] = np.where(df['ma1'] > df['ma2'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값1','이평값2','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값1','이평값2','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_final = (df_result[['수익률']].cumprod().tail(1)-1)*100
df_final['단기'] = 3
df_final['장기'] = 30

df_final

이것을 가지고 함수로 만들어보자.(def get_return_sl(code,short,long)

def get_return_sl(code, short, long):

df = fdr.DataReader(code,'2018')

df = df[['Close']].copy()

df['ma1'] = df['Close'].rolling(short).mean().shift(1)
df['ma2'] = df['Close'].rolling(long).mean().shift(1)

df['action'] = np.where(df['ma1'] > df['ma2'], 'buy','sell')

df.iloc[-1,-1] = 'sell'

cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')

df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값1','이평값2','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값1','이평값2','액션']

df_result = pd.concat([df_buy, df_sell],axis=1)

df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']

df_final = (df_result[['수익률']].cumprod().tail(1)-1)*100
df_final['단기'] = short
df_final['장기'] = long

return df_final

이렇게 하면 한 종목에서 최적의 단기종목과 최적의 장기종목을 알 수 있다.

숙제
한 종목에 대해 최적의 단기/장기이평선

단기 : 3일~10일
장기 : 30일~60일

dfs = []
for short in range(3,11):
for long in range(30,61):
df = get_return_sl('005930',short, long)
dfs.append(df)

df_result = pd.concat(dfs)
df_result.sort_values(by='수익률', ascending = False)

처음 dfs.append(df)로 데이터를 축적해야되는데 그걸 까먹었다.
최적의 이평선을 구해야 되므로 수익률로 내림차순하면 볼 수 있다.

profile
코딩배우려고합니다

0개의 댓글