투자자/알고리즘

개발첫걸음_ 파이썬으로 모든 주식종목 차트 업데이트 하기

나그네_즈브즈 2021. 5. 30. 16:37

상장된 모든 종목의 리스트를 만들었고, 차트 불러오는 함수를 설계했다. 이제 첫 단계에서 남은 마지막 작업은 모든 주식종목의 차트를 차례차례 불러들여 파일로 저장하고 업데이트 하는 코드를 만드는 순서다. 오늘 소개할 함수는 두 가지인데, 하나는 최초로 차트를 저장하는 함수이다. 다른 하나는 시간이 지났을 때 차트를 업데이트 해주는 함수다.

 

def chart_save (tgt) :
    ''' 최초 : 일봉 차트를 csv파일로 저장, tgt=set_tgt()를 먼저 해줘야 함'''
    for code in list(tgt['code']):
        df = gen_raw(code)
        df.to_csv(저장할 경로 + code + '.csv', sep=',', encoding='utf-8')
    ### 차트는 일단 저장완료
    
    mark_update = str(gen_raw('A005930')['date'].iloc[-1].date())
    대표종목인 삼성전자의 최근 거래일을 가져와서
    
    f = open(저장할 경로 + 'mark_update.txt', 'w')
    f.write(mark_update)
    f.close()  
    tgt.to_excel(저장할 경로 + 'tgt__' + mark_update + '.xlsx')
    차트 저장한 날짜와 그 날의 종목 리스트를 저장해준다.

chart_save(tgt)

종목 리스트를 입력받게 되는 이 함수는 두 부분으로 이루어져 있다. 종목리스트(tgt)의 code 열을 따라 반복문을 돌면서 gen_raw 함수를 이용해 불러온 차트를 .to_csv 로 저장하는 부분이 있다. 너무나 간단해서 설명할 게 없다. 두번째 부분에서는 차트를 저장한 날의 정보를 기록해두는 순서다. 그날의 날짜 그대로는 장이 열리지 않은 날일 수도 있기 때문에, 국민종목이라 할 수 있는 삼성전자의 최근 거래일자를 가져와 file 오브젝트에 기록했다. 그리고 나중에 차트를 업데이트 하는 시기에는 신규 상장 또는 상장 폐지로 인해 종목 리스트가 달라질 수 있으니까, 이 순간의 tgt도 엑셀파일로 기록해둘 필요가 있다.

 

def read_chart(code) :
    return pd.read_csv(저장한 경로 + code + '.csv', engine='python', index_col=0, encoding='utf-8').drop_duplicates()
    ### csv로 저장된 차트 불러오는 함수. chart_update에서 필요함.

def chart_update () :
    f = open(저장한 경로 + 'mark_update.txt', 'r')
    read_update = f.readlines()[-1]
    f.close()
    from datetime import timedelta
    last = int(''.join(str(p(read_update).date() + timedelta(days=1)).split('-')))
    tgt_last = pd.read_excel(저장한 경로 + 'tgt__' + read_update + '.xlsx', engine='openpyxl')
    print(tgt_last)
    ### last는 차트 기록을 시작할 날짜니까 [저장된 마지막 날짜 +1일]
    ### 그리고 지난번 차트를 저장하던 때의 종목 리스트를 tgt_last에 일단 불러온다
    
    for i in tgt.index :
        print(i)
        code = tgt['code'].iloc[i]
        if code in list(tgt_last['code']) : raw = read_chart(code)
        else : raw = DataFrame([], columns=['date', 'open', 'high', 'low', 'close', 'volume')
        ### 종목코드가 tgt_last에도 존재하면 csv로 저장해뒀던 차트를 불러오고
        ### 종목코드가 tgt_last에 없으면(신규상장) 빈 차트를 만든다
        
        df = gen_raw(code, bgn=last)
        df['date'] = df['date'].apply(lambda x: x.date())
        ### last 날짜부터 현재까지의 신규 차트 조각을 만든다.        
        
        raw = pd.concat([raw, df], ignore_index=True).drop_duplicates('date')
        raw.to_csv(저장할 경로 + code + '.csv', sep=',', encoding='utf-8')
        ### 기존 차트(raw)에 새 차트(df)를 이어붙이고(concat), 지난 번처럼 csv로 저장한다.
      
        
    mark_update = str(p(read_chart('A005930')['date'].iloc[-1]).date())
    f = open(저장할 경로 + 'mark_update.txt', 'w')
    f.write(mark_update)
    f.close()
    tgt.to_excel(저장할 경로 + 'tgt__' + mark_update + '.xlsx', index=False)
    ### 차트 저장 다 끝났으면 날짜와 종목리스트를 다시 저장한다

#add_update()

차트를 새로 업데이트하는 함수는 세 부분으로 이루어져 있지만 역시 복잡하지 않다. 우선 가장 최근에 차트가 기록된 상황(날짜와 종목 리스트)을 확인한다. 남은 부분은 chart_save와 똑같다. 반복문에 종목코드를 넣어 차트를 업데이트한다. 이번에는 기존차트(raw)에 신규차트(df)를 붙이는 작업이 필요하다. 그러고나면 역시 차트를 기록한 날짜와 종목 리스트를 저장해 주어야 한다. 

 

가령 1부터 100까지 숫자를 적는데, 만약 지난번에 36(=mark update)까지 적어두었다면 37(=last)부터 쓰면 간편하다. 그러려면 오늘 어디까지 숫자를 적었는지를 따로 기록해두어야 한다. 여기서 숫자는 차트가 되고, 기록해두는 건 최근 차트의 마지막 날짜(=mark update)가 된다.

 

그런데 gen_raw() 함수에 입력할 인자 중에 차트를 불러올 범위를 시작할 날짜 ~ 끝나는 날짜의 형태로 설정해주게 되므로 시작할 날짜를 mark update 다음날로 계산된 last로 해주면, 일봉 데이터의 중복 없이 신규차트 조각을 보다 빠르게 만들어내는 게 가능하다.

 

여기까지 차트를 다루는 기초적인 코드의 연재였다. 내용은 많아 보이지만, 싄박한 아이디어가 필요한 것은 아니다. API를 이용해 종목코드를 저장하고, 클래스 인스턴스를 이용해 차트를 기록하고, 파일로 저장하고, 그런 것들 뿐이다. 전반부의 뒤쪽으로 가면, 이제 이 차트를 이용해 몇 가지 보조지표를 계산하는 작업이 요구된다. 그 부분은 성격이 반대다. 내용은 짧지만 이해할 것들이 더 있다. 그래도 재밌을 것이다.

반응형