Python data To Excel - openpyxl

앞서 업로드했던 백테스팅(1) 에서 API 에 대해서 간단히 설명하고 사용하게 될 openpyxl 라이브러리에 대해서도 간단히 설명했다. 오늘은 업비트 비공식 API "crix-api" 를 통해서 업비트 공식 api보다 더 많은 양의 데이터를 불러와 백테스팅을 진행해보고자 한다.

index = 2

def get_upbit_data(url, last_date, to_date) :
    global index

    response = ''
    while True:
        try :
            response = requests.get(url)
        except Exception as e:
            print(e)
            time.sleep(20)
            continue
        if str(response) == '<Response [200]>':
            break
        time.sleep(10)

    data = response.json()

    date = ''
    dateKst = ''
	
    # 받아온 데이터 파싱
    for i in range(len(data))  :
        dateKst = data[i]['candleDateTimeKst']
        date = data[i]['candleDateTime']
        if (last_date == '' or last_date > date) :
            if (dateKst >= to_date) :
                simpleDate = dateKst.split('+')
                datas = (simpleDate[0], "%6f"%data[i]['openingPrice'], "%6f"%data[i]['highPrice'], "%6f"%data[i]['lowPrice'], "%6f"%data[i]['tradePrice'], "%9f"%(data[i]['candleAccTradeVolume']))
                for seq, name in enumerate(datas):
                    sheet.cell(row=index, column=seq+1, value=name)

            else :
                break
        index+=1


    return date

 

처음으로 다룰 함수코드이다. url 을 Input 하고, 해당 url 에서 json 데이터를 읽어와 그 데이터를 원하는 모양으로 파싱하는 일련의 작업이다. 비공식 API 의 주소로 들어가본다면 알겠지만, 오로지 데이터만 긴 문자열로 주어진다. 그 문자열은 다음과 같다.

[{"code":"CRIX.UPBIT.KRW-ETH","candleDateTime":"2021-08-01T04:00:00+00:00","candleDateTimeKst":"2021-08-01T13:00:00+09:00","openingPrice":3038000.00000000,"highPrice":3059000.00000000,"lowPrice":3019000.00000000,"tradePrice":3039000.00000000,"candleAccTradeVolume":5515.85688760,"candleAccTradePrice":16764433793.22536000,"timestamp":1627792199283,"unit":30}

문자열의 맨 앞에 위치한 code를 보면 알 수 있듯이 KRW-ETH 의 거래 데이터 이다. 여기서 우리가 필요한 데이터는 "시간, 시가, 고가, 저가, 종가" 이다. 물론 코드에는 거래량도 포함이 되어있긴 하지만, 실제로 사용 될 데이터는 앞서 말한 5가지 데이터다.
따라서 json 형태로 받아온 각각의 데이터를 원하는 형태로 파싱하고, 우리는 각각의 위치에 파싱된 값을 입력해준다.
index 가 2 로 주어진 이유또한 Cell 에 첫째줄에는 이미 각각의 항목 이름이 입력되어있기 때문이다.

def get_coin_data_url(coinName, type, scale, cnt=400) :
    addr = 'https://crix-api-endpoint.upbit.com/v1/crix/candles/'
    if type == 'minutes' :
        basic_url = addr + type + '/' + scale + '?code=CRIX.UPBIT.KRW-' + coinName +'&count='+str(cnt)
    else :
        basic_url = addr + type + '/' + '?code=CRIX.UPBIT.KRW-' + coinName +'&count='+str(cnt)

    return basic_url

두번째 함수는 우리가 원하는 Coin Ticker의 데이터를 알기 위해 url 을 고치기엔 불편함이 있으니, url 주소를 조합하는 함수이다. 구하고자 하는 종목의 각각의 변수를 해당 함수 Input 으로 두었다.

############ 변수부 #############
coinName = "CCC"
to_date = 'YYYY-MM-DD'
num = NN
scale = '1'
#################################
# coinName 에 Ticker를 to_date에 시작날짜를
# num 에 만약 분봉이라면 원하는 분봉의 숫자를 넣어주면 된다.


if num == 0:
    type = 'days'
else:
    type = 'minutes/{}'.format(num)
last_date = '' 

############ 구동부 #############
basic_url = get_coin_data_url(coinName, type, scale)
url = basic_url

while (1) :
    last_date = get_upbit_data(url, last_date, to_date)
    tmp1 = last_date.split('T')
    if tmp1[0]  < to_date :
        break
    tmp2 = tmp1[1].split('+')
    target_date = tmp1[0] + ' ' + tmp2[0]
    url = basic_url + '&to=' + target_date
    time.sleep(1)
####################################

sheet['G1'] = 'Range'
sheet['G2'] ='=(B2+(C3-D3)*$H$1)'
sheet['H1'] ='1'
sheet['H2'] ='=IF(G2<=C2,((E2/G2)*H3)*0.9995,H3)'

wb.save('pyxl_{0}_{1}.xlsx'.format(num,coinName))

마지막 코드블럭은 변수부와 구동부로 나눠두었다. 우리가 원하는 종목의 변수를 변수부에 입력해준 후, 해당 변수를 이용해서 url 을 받아오고 비공식 API 또한 최대 400개의 데이터로 제한되기 때문에, 400개 이후에 다시 400개를 받아오는 식으로 원하는 날짜보다 더 과거의 데이터를 받아올 때 까지 해당 프로세스를 반복한다.
그 이후 sheet 에 직접 사용될 텍스트들을 입력해 주었는데, 해당 코드는 위에 get_upbit_data 함수의 cell 입력부에 새로운 항목을 추가하더라도 상관은 없다. 단순히 이 코드를 짤 때 그냥 엑셀로 더블클릭이면 다 복사가 되니 굳이 어렵게 가기 귀찮은 마음에 해당 방법을 사용했다.
openpyxl 의 workbook 을 원하는 변수이름에 맞춰 저장하는것으로 마무리했다. ( openpyxl 은 단순히 쓰기 작업을 했다고 해당 데이터가 저장되지 않고 코드의 마지막에 쓰기 한 데이터를 저장해주어야만 한다.)

만약 위 코드들을 모두 잘 사용했다면, 해당 py 파일이 위치한 폴더에 원하는 변수의 엑셀파일이 생성될 것이다.

[[ 마무리 ]]

사람들은 파이썬의 장점이자 단점을 "어쨌든 구동은 된다" 라고 하곤 한다. 이 코드를 짜던 당시에도 오로지 구동만을 위해 여러방향으로 만지작거리고, 수정을 했더니 어찌저찌 구동은 시켰었다. 아직도 공부가 많이 부족하지만 지금의 내가 보기에도 참 많이 지저분한 부분들이 많았다. ( 그나마 쳐낸게 이정도 ) 물론 위의 코드를 100% 내가 작성한것은 아니고 어느정도의 레퍼런스를 갖는 코드가 있었어서 ( 그 당시 json 까지 공부할 순 없었다 ) 그 코드를 가져온 블로그를 찾고싶었지만.... 결국 찾지는 못했다. 나중에라도 찾게된다면 꼭 추가하겠다. 해당 엑셀파일을 통해서 "H3" 에 상수값을 변화시켜가며 최적의 K 값을 찾아내는것이 이 백테스팅의 목적이라고 할 수 있겠다. 다음에는 적당한 K 값을 가지고 변동성 돌파전략을 가지고 직접 API거래를 할 코드를 짜고자 한다.

P.S. 저는 절대 자동매매를 추천드리지 않습니다. 자동매매가 돈이 됐으면 저도 이렇게 취업준비를 하고 있지 않겠지요? 재미로만 만들고 구동해보시길 추천드립니다.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기