EXPANSION OF THINKING IN INVESTMENT

투자에 대한 생각의 확장

CODING/PYTHON

[Python] 5주차_백테스팅 기초(2) : 월-금 전략 (Feat. 스파르타코딩클럽)

메타닷 2022. 12. 20. 14:44
728x90
반응형

 

마지막 백테스팅 전략은 월-금 전략이다. 

 

요일을 어떻게 표기하는지, 

월요일과 금요일 가격을 어떻게 붙이는지, 

월요일에 사서 금요일에 팔 때, 수익률을 어떻게 구하는지, 

월-금 전략 최적의 종목은 무엇인지 알아보았다. 

 

이런 복잡한 전략도 쉽게 구현이 가능하다니, 

정말 코딩의 위대함을 느꼈다. 

 

5. 나만의 전략 구현하기 

1) 나만의 전략 구현하기: 월-금 전략

 * 어떤 것이든 전략이 될 수 있다. 

  - 언젠가 나만의 전략을 구상해보아도 좋다.

    · 삼성전자가 오를 때 LG전자를 사자!
    · 비오는 날에 주식을 사자!
    · 어제 10% 이상 떨어진 종목을 사서 점심 때 팔자!
     ⇒ 모두 좋다.

 * 오늘 다뤄볼 전략은
  - 간단하게, `월요일에 사서 → 금요일에 파는 걸` 해보고, 
  - 가장 적합한 종목은 무엇일지도 구해본다.

 

2) 요일 표기와 주별 가격 붙이기

 * 요일 표기하기
  - 주가 가져오기

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

 

- 요일 표기하기
    · .reset_index()를 사용하여 Date를 리셋시키면 값으로 변환시켜 사용하기 편리하다. 

    · 우리에게 필요한, `Day` , `Open` 만 가져온다.

df = fdr.DataReader('005930','2018')
df = df.reset_index()
df = df[['Date','Open']]
df


    · .to_datetime을 이용하여 Date를 변환시켜주고, .dt.day_name()를 이용해 날짜를 요일로 나타나게 한다.

df['Day'] = pd.to_datetime(df['Date']).dt.day_name()
df


 * 월, 금요일만 남기기
  - 월, 금요일만 가져오기
    · 월요일에서 사서 → 금요일에 파는 것이니까, 월요일, 금요일만 보여주도록 한다. 

df = fdr.DataReader('005930','2018')
df = df.reset_index()
df = df[['Date','Open']]
df['Day'] = pd.to_datetime(df['Date']).dt.day_name()

cond = (df['Day'] == 'Monday') | (df['Day'] == 'Friday')
df = df[cond]
df 


  - 처음 / 마지막 고려해주기
    · 첫 날이 금요일이고 마지막이 월요일이라면 안된다.
    · 그래서, 만약에 첫 날이 금요일이거나, 마지막 날이 월요일이면, .drop(index = )를 이용해 행을 없앤다.

if df.iloc[0,2] == 'Friday':
  df = df.drop(index = df.index[0])

if df.iloc[-1,2] == 'Monday':
  df = df.drop(index = df.index[-1])


  - 휴일 고려하기
    · 예를 들어 금요일이 휴일이면, 월요일 > 월요일이 연속으로 나온다. 월요일이 연속으로 나오는 날을 뽑아보면 다음과 같다. 

cond = (df['Day'] == 'Monday') & (df['Day'].shift(-1) == 'Monday')
df[cond]


    · 월요일 > 월요일이면 처음 나온 월요일을 날리고, 금요일 > 금요일이면 나중에 나온 금요일을 날리면 된다.

cond = (df['Day'] == 'Monday') & (df['Day'].shift(-1) == 'Monday')
df = df.drop(index = df[cond].index)

cond = (df['Day'] == 'Friday') & (df['Day'].shift(1) == 'Friday')
df = df.drop(index = df[cond].index)


 * 수익률 구하기
  - 주가 모으기
    · 금요일 가격을 한칸씩 위로 올린 새로운 열을 만든다. 그러면 월요일과 금요일 가격을 한 행에 나란히 볼 수 있다. 

    · 월요일 행만 뽑아서 보여주면, 월요일-금요일의 주가만 한 행에 두고 볼 수 있다. 

df['Open_fri'] = df['Open'].shift(-1)
df = df[df['Day']=='Monday']
df

    · 이제, 'Open'과 'Open_fri' 값만 보여주고, 컬럼 이름을 'buy_at', 'sell_at'으로 바꿔준다. 

df = df[['Open','Open_fri']]
df.columns = ['buy_at','sell_at']
df


  - 수익률 구하기
    · 'sell_at'에서 'buy_at'을 나눠 수익률을 구해준다. 

df['return'] = df['sell_at'] / df['buy_at']
df

    · 이제 `cumprod()`를 이용해 누적수익률을 구하면 끝!!...... 이라고 생각했지만, 아니다. 

df[['return']].cumprod().iloc[-1,-1] - 1

     · 'sell_at' 가격과 'buy_at' 가격이  0인 케이스를 없애줘야 한다. 

df['return'] = df['sell_at'] / df['buy_at']
cond = (df['sell_at'] != 0) & (df['buy_at'] != 0)
df = df[cond]

df[['return']].cumprod().iloc[-1,-1] - 1


  - 함수로 만들기
    · 함수로 만들면, 월-금 전략이 가장 잘 맞는 종목을 찾을 수도 있다. 

def get_return_mf(code):
  df = fdr.DataReader(code,'2018')
  df = df.reset_index()
  df = df[['Date','Open']]
  df['Day'] = pd.to_datetime(df['Date']).dt.day_name()

  cond = (df['Day'] == 'Friday') | (df['Day'] == 'Monday')
  df = df[cond]

  if df.iloc[0,2] == 'Friday':
    df = df.drop(index = df.index[0])

  if df.iloc[-1,2] == 'Monday':
    df = df.drop(index = df.index[-1])

  cond = (df['Day'] == 'Monday') & (df['Day'].shift(-1) == 'Monday')
  df = df.drop(index = df[cond].index)

  cond = (df['Day'] == 'Friday') & (df['Day'].shift(1) == 'Friday')
  df = df.drop(index = df[cond].index)

  df['Open_fri'] = df['Open'].shift(-1)
  df = df[df['Day']=='Monday']

  df = df[['Open','Open_fri']]
  df.columns = ['buy_at','sell_at']

  df['return'] = df['sell_at'] / df['buy_at']
  cond = (df['sell_at'] != 0) & (df['buy_at'] != 0)
  df = df[cond]

  return df[['return']].cumprod().iloc[-1,-1] - 1

    · 알맞게 나오는지 코드를 넣어 확인해본다. 


6. 최적화 종목 찾기 

1) `dart-fss` 라이브러리 사용하기

  - dart-fss 라이브러리를 설치한다. 

!pip install dart-fss

 

  -  종목 코드를 가져온다. 

import dart_fss as dart_fss
import pandas as pd

api_key = 'API키 입력하기'
dart_fss.set_api_key(api_key=api_key)

all = dart_fss.api.filings.get_corp_code()

df = pd.DataFrame(all)

df_listed = df[df['stock_code'].notnull()]

for row in df_listed.sample(10)[['stock_code','corp_name']].itertuples():
  print(row)


2) 최적화된 종목를 찾기

  - 이전에 했던 방법들과 동일하게, df를 만들어 찾는다. 

  - 여기서 .sample(10)을 빼면, 전체 상장 종목에서 월-금전략이 가장 좋은 회사를 찾을 수 있다. 

df = pd.DataFrame()
for row in df_listed.sample(10)[['stock_code','corp_name']].itertuples():
  try:
    doc = {
        'name' : row[2],
        'return' : get_return_mf(row[1])
    }
    df = df.append(doc, ignore_index = True)
  except:
    print(f'error - {row[2]}')

df.sort_values(by='return', ascending=False)

 

 

 

728x90
반응형