본문 바로가기

[Toy Project] 자동매매

[Toy Project] 자동매매 프로그램 만들기 - 5. RSI 지표 이용하여 매매하기

728x90
반응형

 

[목차]

 

1. 여러 암호화폐 RSI값 받아오기

 

2. RSI 지표 이용하여 매매 기능과 연동

 

 

  1. 여러 암호화폐 RSI값 받아오기

 

이전 글에서 특정 암호화폐의 RSI값을 계산하는 방법을 알아보았다. 

RSI값을 계산하기 위해서는 pyupbit 모듈의 get_ohlcv 함수를 이용하여 해당 암호화폐의 이전 데이터들을 불러와야 한다. 

하지만 get_ohlcv 함수로는 여러 암호화폐에 대한 데이터를 한 번에 받아올 수 없어서, 여러 암호화폐 RSI값을 계산하기 위해서는 각 암호화폐별로 get_ohlcv 함수를 각각 호출해야 한다. 

따라서, 원하는 암호화폐 ticker를 리스트에 모아놓고, 차례대로 RSI를 계산하기로 했다. (더 나은 방법이 있는지는 잘 모르겠다)

coinlist = ["KRW-BTC", "KRW-XRP", "KRW-ETC", "KRW-ETH", "KRW-BCH", "KRW-EOS"]

while(True): 
    for i in range(len(coinlist)):
        data = pyupbit.get_ohlcv(ticker=coinlist[i], interval="minute3")
        now_rsi = rsi(data, 14).iloc[-1]
        print("코인명: ", coinlist[i])
        print("현재시간: ", datetime.datetime.now())
        print("RSI :", now_rsi)
        print()
    time.sleep(0.5)

 

 

이처럼 직접 반복문을 통해서 매번 계산을 해주는 방식을 이용하면, 평균적으로 약 0.08초 ~ 0.1초 정도마다 API를 호출하게 된다. 

 

 

 

다만, 이 빈도는 컴퓨터의 성능이나 네트워크 환경에 따라서 꽤 차이가 많이 나는 것 같다. 노트북에서 와이파이를 이용하여 실행했을 땐 평균적으로 0.4~0.5초 정도마다 API를 호출했다. 그래서 굳이 time.sleep을 걸어줄 필요가 없었는데, 데스크톱에서 실행한 경우 빠른 주기로 API를 호출해서, 0.5초마다 for문을 실행하게 하여 과도한 호출을 막아주었다. 

 

 

  2. RSI 지표 이용하여 매매 기능 연동

 

이제 이 RSI 지표를 이용하여 여러 암호화폐에 대해 동시에 매매할 수 있도록 해보자. 

 

우선, RSI를 이용한 나의 매매 전략은 다음과 같다. 

 

1. 매수 : RSI 값이 28 이하를 찍고 다시 33 이상이 되었을 때 

2. 매도 : RSI 값이 70 이상을 찍었을 때

 

따라서, 각 암호화폐별로 RSI값이 어떤 상태였는지를 보관하기 위해서 아래와 같은 리스트를 만들어 준다. 

 

# 이용할 코인 리스트
coinlist = ["KRW-BTC", "KRW-XRP", "KRW-ETC", "KRW-ETH", "KRW-BCH", "KRW-EOS"] # Coin ticker 추가
lower28 = []
higher70 = []

# initiate
for i in range(len(coinlist)):
    lower28.append(False)
    higher70.append(False)

 

lower28은 이전에 28 이하를 찍었는지, higher70은 70 이상을 찍었는지를 담고 있는 리스트이다. 

 

그다음 매매 코드는 다음과 같이 구현된다.

while(True): 
    for i in range(len(coinlist)):
        data = pyupbit.get_ohlcv(ticker=coinlist[i], interval="minute3")
        now_rsi = rsi(data, 14).iloc[-1]
        print("코인명: ", coinlist[i])
        print("현재시간: ", datetime.datetime.now())
        print("RSI :", now_rsi)
        print()
        if now_rsi <= 28 : 
            lower28[i] = True
        elif now_rsi >= 33 and lower28[i] == True:
            buy(coinlist[i])
            lower28[i] = False
        elif now_rsi >= 70 and higher70[i] == False:
            sell(coinlist[i])
            higher70[i] = True
        elif now_rsi <= 60 :
            higher70[i] = False
    time.sleep(0.5)

 

RSI가 28 이하가 된다면 lower28을 true로 바꿔준다. 

만약 lower28[i]가 true이고, 현재 RSI값이 33 이상이라면, 매수 조건을 만족한 경우이므로 매수를 진행한다. 

그리고 매도는 RSI값이 70 이상이 되었을 때 한번 매도를 한다면, 이후에는 RSI가 적어도 60까지는 내려갔다가 다시 올라오는 경우에 매도하는 방식으로 설정하였다. 

 

매매 함수 코드는 아래와 같다. 현재 보유 중인 원화 또는 보유 중인 암호화폐의 수량에 따라서 차등적으로 매매하도록 설정하였다. 

이는 현재 보유 중인 총 자산 또는 사용자의 매매 전략에 따라 임의로 설정할 수 있는 부분이고, 이익 실현에 크게 영향을 줄 수 있는 부분이다. 

따라서 각자 매매 전략에 따라서 잘 설정하면 될 것이다. 

 

# 시장가 매수 함수
def buy(coin):
    money = upbit.get_balance("KRW")
    if money < 20000 :
        res = upbit.buy_market_order(coin, money)
    elif money < 50000:
        res = upbit.buy_market_order(coin, money*0.4)
    elif money < 100000 :
        res = upbit.buy_market_order(coin, money*0.3)
    else :
        res = upbit.buy_market_order(coin, money*0.2)
    return

# 시장가 매도 함수
def sell(coin):
    amount = upbit.get_balance(coin)
    cur_price = pyupbit.get_current_price(coin)
    total = amount * cur_price
    if total < 20000 :
        res = upbit.sell_market_order(coin, amount)
    elif total < 50000:
        res = upbit.sell_market_order(coin, amount*0.4)
    elif total < 100000:
        res = upbit.sell_market_order(coin, amount*0.3)        
    else :
        res = upbit.sell_market_order(coin, amount*0.2)
    return

 

매매는 현재 RSI값에 따라 실시간으로 진행되어야 하므로 시장가 매매를 이용한다. 

기본적으로 보유 중인 원화의 20%씩 매수하도록 하되, 보유 중인 원화가 많지 않은 경우에는 최소 어느 정도는 매매할 수 있도록 비율을 점점 높여간다. 

매도 역시 마찬가지이다. 해당 암호화폐의 자산을 화폐 시가*화폐 수량으로 구한 다음, 매수와 동일하게 차등적으로 비율을 매겨 매도를 진행한다. 

 

이제 자동매매 기능은 완성이 되었으므로, 잘 돌아가는지 테스트할 일만 남았다. 다만 그전에, 현재 매매 전략이 유효한지를 판단하기 위해서 매매한 경우 이를 기록할 필요가 있다. 

따라서, 다음 글에서는 파이썬을 이용하여 엑셀에 실시간으로 저장하는 기능을 알아볼 예정이다.

 

 

PC로 보시는 것을 권장합니다. 

피드백은 언제나 환영입니다. 댓글로 달아주세요 ^-^

 

 

728x90
반응형
  • 비밀댓글입니다

  • 비밀댓글입니다

  • lotto 2021.06.06 16:44 댓글주소 수정/삭제 댓글쓰기

    It failed JSONDecodeError
    TypeError
    Traceback (most recent call last):
    File "/Users/kim/python/test/test_v1.py", line 79, in <module>
    now_rsi = rsi(data, 14).iloc[-1]
    File "/Users/kim/python/test/test_v1.py", line 18, in rsi
    ohlc["close"] = ohlc["close"]
    TypeError: 'NoneType' object is not subscriptable

    위에서 처리 할 수 있는 방법이 있을까요?

    • https://m.blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=simjk98&logNo=221593437857&proxyReferer=

      위 링크 한번 참고해보세요!

  • 비밀댓글입니다

  • 웨이 2021.07.15 21:03 댓글주소 수정/삭제 댓글쓰기

    RSI 값이 28 이하를 찍고 다시 33 이상이 되었을 때 매수 되는데 횡보구간에서는 계속 매수를 하는데 한번 매수한 것은 패스할려면 어떻게 해야 하나요?

    • 저같은 경우엔, 매수 후 적어도 RSI가 45이상을 찍고나서 다시 매수할 수 있도록 리스트를 하나 더 선언하였습니다.
      각자 매매 기준에 따라 다를 것 같네요!

  • 웨이 2021.07.15 22:00 댓글주소 수정/삭제 댓글쓰기

    RSI 45까지 가기전에 여러번 매수해 버리던데요.
    그래서 봇 중지 시켰습니다. 이 부분 수정해서 돌려 볼려구요

    • 제가 코드를 못봐서 말씀드리긴 어렵네요
      사실 매매기준 부분은 각자 기준이 정말 다양해서 이 글은 참고로만 이용하시고 직접 구현하시는게 좋습니다

  • 웨이 2021.07.17 20:48 댓글주소 수정/삭제 댓글쓰기

    감사합니다.
    저는 그냥 이부분은 time.sleep 으로 처리 했습니다.

  • 웨이 2021.07.17 20:48 댓글주소 수정/삭제 댓글쓰기

    그리고 지금 코드에서 지정가 매수 코드 짤려고 하는데 잘 안되네요. (아직 실력이 부족해서~)
    혹시 지정가 매수 코드 도움 받을 수 있을까요?