반응형

저번 글에서 데이터를 깔끔하게 파싱하는데 성공하였다. 이제 Pandas Dataframe 형태로 변환하도록 하자.

오늘의 목표

 

저번 글 링크>>

https://trading-for-chicken.tistory.com/5

 

02. OHLCV 데이터를 파싱해 Pandas Dataframe 형태로 만들기 -1

2. Data를 파싱하여 깔끔한 출력으로 만들기 앞에서 찾은 URL을 확인하면 4가지 검색조건이 존재함을 알 수 있다. 종목코드, 검색시작 날짜, 검색종료날짜, 일봉-주봉-월봉 이다. 이를 참고하여 코

trading-for-chicken.tistory.com

 

일단 Backtrader나 키움증권 API, Mathplotlib(mplfinance)에서 사용하는 형태는 DataFrame으로 

[ 'Date' , 'Open' , 'High' , 'Low' , 'Close' , 'Volume' ] 열을 가지는 형태이다.

df = pd.DataFrame(columns=['Date','Open','High','Low','Close','Volume'])으로 이에 맞게 데이터 프레임 객체를 만든다.

def ohlcv_data(code='005930',starttime='default',endtime='today',timeframe='day'):
    url = 'https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20190624&endTime=20210901&timeframe=day'
    res = urlopen(url, context=ssl.create_default_context())
    soup = BeautifulSoup(res.read(), 'html.parser', from_encoding='utf-8')
    data    = str(soup).split('],')
    df = pd.DataFrame(columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])  # 데이터프레임 객체 생성  
    
    for i in range(1,len(data)):
        date    = data[i].split(', ')[0].split('["')[1].split('"')[0]
        open    = data[i].split(', ')[1]
        high    = data[i].split(', ')[2]
        close   = data[i].split(', ')[3]
        low     = data[i].split(', ')[4]
        volume  = data[i].split(', ')[5]

if __name__ == '__main__':
    ohlcv_data()

그럼 이렇게 빈 데이터프레임이 만들어진다. 이제 여기에 값들을 추가해주도록 하자.

 

[date, open, high, low, close, volume] 형태로 리스트를 생성해주고 생성된 빈 데이터프레임에 추가하도록한다.

def ohlcv_data(code='005930',starttime='default',endtime='today',timeframe='day'):
    url = 'https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20190624&endTime=20210901&timeframe=day'
    res = urlopen(url, context=ssl.create_default_context())
    soup = BeautifulSoup(res.read(), 'html.parser', from_encoding='utf-8')
    data    = str(soup).split('],')
    df = pd.DataFrame(columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])
    for i in range(1,len(data)):
        date    = data[i].split(', ')[0].split('["')[1].split('"')[0]
        open    = data[i].split(', ')[1]
        high    = data[i].split(', ')[2]
        close   = data[i].split(', ')[3]
        low     = data[i].split(', ')[4]
        volume  = data[i].split(', ')[5]
        list = [date, open, high, low, close, volume] # 각 값을 리스트로 병합
        df = df.append(pd.Series(list, index=df.columns), ignore_index=True) # 데이터프레임에 추가
    print(df)
if __name__ == '__main__':
    ohlcv_data()
df = df.append(pd.Series(list, index=df.columns), ignore_index=True)

위에 대해 설명하자면. 현재 생성된 빈 dataframe에 append함수를 이용해서 pandas의 Series형태의 데이터를 행으로써 추가가 가능하다. 여기서 pd.Series(list, index=df.columns)로 설정해주었는데, 이 Series의 값은 list로 하고 인덱스는 

데이터프레임의 columns인 'Date' 'Open' 'High' 'Low' 'Close' 'Volume' ] 를 그대로 사용하겠다는 뜻이다.

그리고 행은 Date값을 사용할 예정이므로 지금은 인덱스를 지정하지 않기위해 ignore_index=True를 해준다.

(그냥 0, 1, 2, 이렇게 인덱스가 자동 부여된다.)

RUN 진행하면 아래와 같이 데이터프레임으로 정리 된 것을 확인할 수 있다.

 

하지만 아직 끝난게 아닌데, backtrader나 mplfinance에서는 인덱스가 Date형태인 dataframe을 사용하므로 

[Date] 열의 형태를 datetime 형태로 변경해주고 해당 열을 인덱스로 변경할 필요가 있다.

df['Date'] = pd.to_datetime(df['Date']) 를 통해 [Date] 열의 형태를 datetime 형태로 변경해주고

df = df.set_index('Date') 를 통해 [Date] 열을 인덱스로 변환하도록 한다.

def ohlcv_data(code='005930',starttime='default',endtime='today',timeframe='day'):
    url = 'https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20190624&endTime=20210901&timeframe=day'
    res = urlopen(url, context=ssl.create_default_context())
    soup = BeautifulSoup(res.read(), 'html.parser', from_encoding='utf-8')
    data    = str(soup).split('],')
    df = pd.DataFrame(columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])
    for i in range(1,len(data)):
        date    = data[i].split(', ')[0].split('["')[1].split('"')[0]
        open    = data[i].split(', ')[1]
        high    = data[i].split(', ')[2]
        close   = data[i].split(', ')[3]
        low     = data[i].split(', ')[4]
        volume  = data[i].split(', ')[5]
        list = [date, open, high, low, close, volume]
        df = df.append(pd.Series(list, index=df.columns), ignore_index=True)
    df['Date'] = pd.to_datetime(df['Date']) # 날짜 형태로 변환
    df = df.set_index('Date') # 인덱스로 전환
    print(df)
if __name__ == '__main__':
    ohlcv_data()

위 코드를 실행해보면 Date열이 날짜로 변환되고 인덱스로 설정된 것을 확인할 수 있다.

 

그리고 backtrader나 mplfinance에서는 dataframe의 각 값이 int형태이어야 한다. 딕셔너리 형태로 각 열의 요소의 

type을 설정해주는 함수인 astype을 사용해서 int로 변경해주도록 한다.

df = df.astype({'Open':'int','High':'int','Low':'int','Close':'int','Volume':'int'})

 

또한 기본적으로 날짜 오름차순을 사용하기 때문에 sort_index 함수를 통해 오름차순 정렬을 해주도록 한다.

df = df.sort_index(ascending=True)

def ohlcv_data(code='005930',starttime='default',endtime='today',timeframe='day'):
    url = 'https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20190624&endTime=20210901&timeframe=day'
    res = urlopen(url, context=ssl.create_default_context())
    soup = BeautifulSoup(res.read(), 'html.parser', from_encoding='utf-8')
    data    = str(soup).split('],')
    df = pd.DataFrame(columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])
    for i in range(1,len(data)):
        date    = data[i].split(', ')[0].split('["')[1].split('"')[0]
        open    = data[i].split(', ')[1]
        high    = data[i].split(', ')[2]
        close   = data[i].split(', ')[3]
        low     = data[i].split(', ')[4]
        volume  = data[i].split(', ')[5]
        list = [date, open, high, low, close, volume]
        df = df.append(pd.Series(list, index=df.columns), ignore_index=True)
    df['Date'] = pd.to_datetime(df['Date'])
    df = df.set_index('Date')
    df = df.astype({'Open':'int','High':'int','Low':'int','Close':'int','Volume':'int'}) # type을 int로 변경
    df = df.sort_index(ascending=True) #인덱스를 오름차순으로 정리
    return df
if __name__ == '__main__':
    print(ohlcv_data())

 

이제 위 URL에서 OHLCV값을 뽑아내서 dataframe 으로 변경까지 완료하였다.

다음장에서는 방금 만든 함수 ohlcv_data(code='005930',starttime='default',endtime='today',timeframe='day')

에 대해 code, starttime, endtime, timeframe을 설정할 수 있도록 함수를 변경하도록 한다.

반응형

+ 최근 글