본문 바로가기
AutoBot

업비트 자동매매 - Upbit Auto Trading No.5 (전략별 백테스팅)

by zemba 2021. 12. 18.
반응형
SMALL

안녕하세요~ 한동안 백테스팅과 개인 사정(?)으로 인하여 한동안 포스팅을 못했다가 이제야 다시 작성하게 되었네요~ ㅎㅎㅎ
사실 백테스팅 알고리즘이랑 전략들을 구상해 보려고 알아보다 그런부분도 있고 백테스팅 툴을 검증해보고 하는 그런 부분들도 조금씩 손대면서 하다 보니 여차여차하여 시간이 좀 많이 소요되었습니다. ㅎ

아무튼 그동안의 결과를 정리해보자면 지난 포스팅에서 백테스팅으로 전략들을 검증하여 거래 전략을 다시 설정하기로 했었습니다.
( 참고 : https://zemba.tistory.com/27 )

 

Upbit Auto Trading No.4 (백테스팅과 신규전략준비)

한동안 제가 공황장애 때문에 신경을 잘 못쓰고 포스팅을 미뤄왔지만 작업을 멈추진 않았습니다. ㅎㅎ 한편으로는 계속 이 알고리즘과 수익률에 대한 계획을 계속적으로 그리면서 결과를 예측

zemba.tistory.com

네 우선 그렇게하여 백테스팅 툴을 나름대로 구현해 보았습니다. 일단은 현재 python에서 사용할 수 있는 백테스팅 툴이 있지만 뭐 금액 설정 등 제가 진행하는 그런 테스팅과 달랐기 때문에 별도로 백테스팅을 위한 코드를 작성했습니다. 우선 전체 투자금 대비로 1회에 얼마씩 매수를 하고 매도를 진행하면서 전략의 수익을 검증하는 코드를 구현해보았습니다.

def process(all_tickers, period, day, total_price, buy_once_price):
    ohlcv_df = create_ohlcv(all_tickers, period, day)
    print("OHLCV Complete!")

    rsi14_analysis = rsi14_avg_under_test(all_tickers, ohlcv_df, total_price, buy_once_price)
    rsi1428_analysis = rsi1428_agv_under_test(all_tickers, ohlcv_df, total_price, buy_once_price)
    macd_analysis = macd_test(all_tickers, ohlcv_df, total_price, buy_once_price)
    mr14_analysis = macd_rsi_test(all_tickers, ohlcv_df, total_price, buy_once_price)
    mr1428_analysis = macd_rsi1428_test(all_tickers, ohlcv_df, total_price, buy_once_price)

    print("TESTING Complete!")

    rsi14_analysis = pd.DataFrame(rsi14_analysis)
    rsi14_analysis.set_index("Ticker", inplace=True)
    rsi1428_analysis = pd.DataFrame(rsi1428_analysis)
    rsi1428_analysis.set_index("Ticker", inplace=True)
    macd_analysis = pd.DataFrame(macd_analysis)
    macd_analysis.set_index("Ticker", inplace=True)
    mr14_analysis = pd.DataFrame(mr14_analysis)
    mr14_analysis.set_index("Ticker", inplace=True)
    mr1428_analysis = pd.DataFrame(mr1428_analysis)
    mr1428_analysis.set_index("Ticker", inplace=True)

    result = pd.merge(rsi14_analysis, rsi1428_analysis, how='outer', on='Ticker')
    result = pd.merge(result, macd_analysis, how='outer', on='Ticker')
    result = pd.merge(result, mr14_analysis, how='outer', on='Ticker')
    result = pd.merge(result, mr1428_analysis, how='outer', on='Ticker')

    print("Process Complete!")

    return result

코드의 일부분이긴 하지만 정리를 해보자면 우선 RSI14전략을 완전히 버리지 않았습니다. 지난 포스팅에서 문제가 되었던 부분들을 어떤 방식으로 커버를 할 수 있을까 다시 생각을 좀 해보았고 기존에 240봉을 기준으로 했었기 때문에 30, 60분 봉에서도 어떠한 수익률이 있었는지에 대해서는 확인해보지 못했기 때문에 테스트를 보완을 좀 해보았습니다. 그래서 최종적으로 테스팅을 하게 된 전략을 정리해보았습니다.

  • 거래 알고리즘 전략 테스트항목
    • RSI 14
    • RSI 1428
    • MACD
    • MR14 (MACD + RSI14)
    • MR1428 (MACD + RSI1428)

우선 5가지로 백테스팅을 진행해보았습니다. 여기서 대부분 아실만한 전략들이 있지만 생소한 전략이 몇 개 보이실 거 같아서 ㅋㅋㅋㅋㅋ 뭐 궁금하시지는 않겠지만 그래도 나름 제가 지표를 섞어서 눈대중으로 검증한 전략이라 ㅋㅋ 한번 테스팅을 돌려보고 싶었습니다. 그것은 바로...... 바로바로.... RSI 1428에 대한 내용인데요! 요것이 어떻게 해서 나온 전략인지를 한번 말씀드리겠습니다. ㅎㅎ

출처 업비트 앱 오미세고 차트

우선 지난번에 오미세고를 보고 문제점을 파악했으니 다시 오미세고 차트를 보면서 설명을 드리자면.... 위 차트를 보시면 최고가에서 급격히 한번 폭락했고 이후에 지속적인 하락 추세를 계속하다 RSI14의 지표가 30 이하로 떨어지는 모습을 볼 수 있었습니다. 그렇기 때문에 이 구간에 대한 보완책으로 좀 더 평균적으로 경과를 더 판단하기 위해서 RSI28지표를 추가하였습니다. 다들 아시겠지만 RSI에 대표적으로 14일을 기준으로 사용하며 14일간의 변동의 추세의 강도를 백분율로 나타낸 지표입니다. 그렇기 때문에 저는 14일뿐만이 아니라 좀더 긴 변동의 추세를 확인하기 위해서 28일로 지정했습니다. (그냥 감각적으로 대충 14일 지표를 많이 쓰니까 2배 정도 더 보면 되지 않을까라고 생각해서 적용해보았습니다. ㅋㅋ)

오.... 그런데 약간 흥미가 생기게 되었습니다. 차트의 빨간 상자로 표시한 부분을 유심히 지켜보시면 240분 봉 기준에 최고점일 때 14, 28의 지표가 둘다 70의 선을 넘기게 되었고 최저점일 때 14, 28의 지표가 둘다 30의 선이하로 떨어지는 모습을 보였습니다. 또한 지난번 포스팅의 문제점으로 논의된 폭락이후 머리쯤에서 구매한 14지표의 30선이하일 경우에 28선은 30이하로 떨어지지 않았습니다. 결국 이 두개의 지표를 컴바인해서 전략을 세워본다면 지금 보시는 차트에서 최고점일때는 매도를 했을것이고 그이후에 지표 2개가 모두 30이하로 떨어질 경우에 매수를 진행했을것이기 때문에 위 차트로만 보면 최고점일때 매도, 최저점일때 매수를 하는 전략을 그려볼 수 있을 것 같아 보였습니다. (ㅋㅋㅋㅋ 때려 맞췄는데 이상하게 묘한 기대감 폭발 )

그래서 RSI1428의 전략을 테스팅해보게 된 것입니다. ㅋㅋ 이제는 해당 전략이 왜 생겨났는지 이해가 되셨을 것 같네요. 그런데 여기서 마침 전략을 찾는 도중에 MACD와 RSI가 궁합이 잘 맞는다는 이런 내용들이 많이 보이는 것 같아서 내용을 좀 찾아보았습니다. 흠.. 이것도 왠지 끌리게 되었고 테스팅을 해보기로 결심했습니다. ( 사실 지난 포스팅에서도 말씀드렸었지만 제가 자동매매를 진행하기 전에 가장 많이 본 지표가 MACD였기 때문에 혼합 전략에 관심이 많아지게 되었습니다 ㅎㅎ )

하지만 전에는 MACD GC, DC에 매수 매도 전략으로 생각했지만 이번에는 MACD는 추세를 확인하는 지표로 확인하며 추세의 강도에 따라서 매매하는 전략으로 테스팅을 좀 해보려고 했습니다. 그 이유는 또 뭐 별거 아니지만 대강 눈대중으로 때려 ㅋㅋㅋㅋㅋㅋ ( 이쯤 되면 이 눈이 문제라고 봐도 될듯합니다. ㅋㅋㅋ ) 확인해본 결과 RSI 30, 70일 경우에 MACD의 Cross는 대부분 발생하지 않기 때문에 그 시점의 타이밍을 구현하는 것은 약간 난해한 부분이 분명히 있었습니다. 그렇기 때문에 둘 중의 한 개의 지표는 추세를 확인하는 지표로 사용하며 나머지 지표를 통해서 매매를 판단하는 기준으로 결정하기로 하였고 그 추세를 확인하는 지표가 MACD로 결정되었습니다. ㅎㅎ ( 혹시 MACD + RSI 지표를 이용한다는 것이 이런 방법이 아니라면 조언을 주셔도 괜찮습니다!! 잘 배워보겠습니다!!! ㅎ)

사실 이렇게 돌려보았지만 ㅋㅋ 수익률이 진짜 처참했습니다. 아.... 또 멘붕에 빠지기 전에 흠 다시 고민을 해보았고 모든 전략에 추가적인 매수와 매도 시 조건을 조금씩 손보았습니다. 그래서 최종적인 전략 테스트는 다음과 같습니다.

  • 거래 알고리즘 전략 테스트 항목
    • RSI 14
      • 매수 30, 매도 70
    • RSI 1428
      • 매수 30, 매도 70 (14, 28 지표 두다의 경우)
    • MACD
      • 0선 기준으로 30 이상일 경우 매도, -30 이하일 경우 매수
    • MR14 (MACD + RSI14)
      • MACD 0선 기준으로 30 이상, RSI 70 이상 매도
      • MACD 0선 기준으로 -30 이하, RSI 30이하 매수
    • MR1428 (MACD + RSI1428)
      • MACD 0선 기준으로 30 이상, RSI 70 이상 매도 (14, 28 지표 둘다의 경우)
      • MACD 0선 기준으로 -30 이하, RSI 30 이하 매수 (14, 28 지표 둘다의 경우)
    • 모든 전략에 추가
      • 평단 이하일 경우 매수
      • 매도 시에는 전량이 아닌 30%의 수량만 판매

네 최종적으로 테스트를 진행한 항목은 위와 같습니다. 여기서 달라진 점은 처참한 수익률을 극복하고자 지속적인 평단을 확인하여 평단가를 내리는 전략을 추가하였고 수익이 났을 경우에도 평단가를 내리는 전략을 추가했기 때문에 전체를 팔지 않고 분할 매도를 통해서 시드를 조금이라도 늘리서 재거래를 진행하는 방식으로 전략을 수정해 보았습니다.

결과가 어떻게 되었냐고요? 처음보다는 만족할만한 수익률이 나오는 것 같았습니다. ㅎㅎ 그렇기 때문에 좀 더 다양한 비교군으로 수익률을 측정하기 위해서 모든 티커를 대상으로 백테스팅을 진행해 보았고 모든 티커의 240, 30, 60 분봉을 300일, 600일, 900일 기준으로 다양하게 데이터를 테스팅 해보았습니다. 

all_tickers = get_tickers("KRW")
all_tickers.remove("KRW-ALGO")
all_tickers.remove("KRW-NEAR")

result_300_day_240m = process(all_tickers, 'minute240', 300, 500000, 5100)
result_600_day_240m = process(all_tickers, 'minute240', 600, 500000, 5100)
result_900_day_240m = process(all_tickers, 'minute240', 900, 500000, 5100)

result_300_day_60m = process(all_tickers, 'minute60', 300, 500000, 5100)
result_600_day_60m = process(all_tickers, 'minute60', 600, 500000, 5100)
result_900_day_60m = process(all_tickers, 'minute60', 900, 500000, 5100)

result_300_day_30m = process(all_tickers, 'minute30', 300, 500000, 5100)
result_600_day_30m = process(all_tickers, 'minute30', 600, 500000, 5100)
result_900_day_30m = process(all_tickers, 'minute30', 900, 500000, 5100)

 초기 금액은 모두 동일하게 50만 원으로 시드를 정하였고 한번 매수하는 금액은 5100원으로 정하였습니다.
그리고  30, 60, 240분 봉을 기준으로 300, 600, 900일의 데이터로 전체 티커를 분석하는 코드를 작성했습니다.
여기서 30, 60, 240분봉 조회 시에 1일 기준으로 각 분봉이 몇 개를 가지는지를 계산하여 날짜와 계산하여 데이터를 계산했습니다.
또한 최근에 추가된 KRW-ALGO, KRW-NEAR는 테스팅 대상에서 제외하였습니다.

우선 결과를 공개합니다.

백테스팅 결과

우선 가장 수익률이 많은 티커 상위 2개는 UPP, STEEM 이 두 개였고 각각 900일 기준일 때 수익률이 1000%가 넘었습니다.
UPP는 rsi1428의 전략에서 30분 봉일 때 수익률이 가장 높았고, STEEM은 macd 전략 30분 봉에서 가장 수익이 높았습니다.
900일이면 약 3년이라는 시간이라 좀 존버 하고 장기로 가야 하겠지만 이대로만 수익이 나와준다면 3년 정도면 괜찮지 않을까요? ㅎㅎ 하지만 300일 기준으로만 봐도 두 개의 티커가 278%, 163%까지도 수익이 나기 때문에 나쁘지는 않다고 생각합니다.
또한 결과에 BJ 칼럼 항목을 보시면 대체적으로 티커 별로 Max 수익률을 표기한 부분인데 대부분 400%가 넘는 게 많이 있습니다.
테스팅 결과가 그리 나쁘지는 않은 것 같아서 이제는 최종 전략을 정하고 진짜로 돌려보려고 합니다. ㅎㅎ

저는 전문 투자자도 아니고 그냥 일개 개미에 불과하면 그냥 개발자이기 때문에 전문적인 지식이 없어 귀동냥과 리서치로만 전략을 세우기 때문에 만약 잘못된 부분들이나 문제점이 있다면 그런 부분들을 수정해서 적용하시면 더  좋은 결과를 얻으실 수 있을 것이라 생각됩니다. ㅎㅎ 제 개인의 생각의 전략이기 때문에 저는 리스크를 가지고 진행해보려고 합니다!!

다음 포스팅에서는 최종 전략 및 코드 구현 등을 포스팅하도록 하겠습니다~

반응형
LIST

댓글