본문 바로가기

카테고리 없음

4주차 개발일지

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.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]

백테스팅 전략 세우기& 주가 가져오기

라이브러리 설치

⇒ pandas-datareader 와 finance-datareader 라이브러리를 활용

!pip install yfinance pandas-datareader finance-datareader

 

살펴보기

⇒ Open: 시초가 High: 고가 Low: 저가 Close: 종가 Volume: 거래량 Change: 변동

 

종가가져오기

df[['Close']]

 

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

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

 

간단한 그래프 그려보기

네이버금융 https://finance.naver.com/

 

주가 그래프 그려보기

⇒  .plot(y=['컬럼명'])

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

 

⇒ 크게 그리기

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

 

⇒ 격자 추가하기

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

 

  • 종목 두 개의 주가 변동 그래프를 그려보기⇒ 최근 100일
  • ⇒ 삼성전자와 LG전자
df_1 = fdr.DataReader('005930','2018')
df_2 = fdr.DataReader('066570','2018')

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

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

 

 

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

 

종가 Close 가져오기

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

df = df[['Close']]

df

3일마다 평균 값 구하기

.rolling 을 사용

df.rolling(3).mean()

⇒ 붙여서 함께 보기

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

df = df[['Close']]

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

df

 

 

buy & sell 표기

 

shift 를 가지고 열을 맞춰보기

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

df = df[['Close']]

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

df

 

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

 

 

수익률 구하기

1) 생각하기1 - 실제로 사는 시점

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

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

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

df

⇒ 사는 순간

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

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

df[cond]

 

2) 생각하기2 - 실제로 파는 시점

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

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_sell

 

3) 생각하기3 - 마지막은?

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.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]

 

4) 사고, 파는 시점을 붙이기

concat 을 이용

,axis=1 를 붙이기

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.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

5) 전략 세워보기

⇒ buy 때의 Close와 sell 때의 Close

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.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

 

6) 수익률 구하기

⇒ 먼저 Close라는 컬럼명을 다르게 수정

⇒ 그리고 수익률 = 판 값 / 산 값 을 구하기

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.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

7) 오류해결하기

⇒ dataframe 을 아래처럼 바꾸기

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

8) 수익률 계산하기

⇒ 누적 곱

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

⇒ 마지막 값

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

⇒ 1(원금)을 빼주고 100을 곱해줘야 수익률

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

 

9) 함수로 만들기

⇒ 코드만 입력하면 될 수 있도록!

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
get_return('005930',3)

get_return('066570',6)

 

 

단기/장기이평선 적용하기

 

1) 단기/장기이평선 구하기

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

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

df['ma_1'] = df['Close'].rolling(3).mean().shift(1)
df['ma_2'] = df['Close'].rolling(10).mean().shift(1)

df.head(30)

2) 적절한 값으로 수정하기

⇒ Close, ma_1, ma_2 를 고려

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

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

df['ma_1'] = df['Close'].rolling(3).mean().shift(1)
df['ma_2'] = df['Close'].rolling(10).mean().shift(1)

df['action'] = np.where(df['ma_1'] > df['ma_2'], '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)*100

 

3) 함수로 만들어두기

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
get_return_sl('005930',3,30)

 

 

한 종목에 대해 최적의 단기/장기이평선을 구하기

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)