-
파이썬으로 코인 자동매매 프로그램 만들기 - 7: RSI 전략을 이용한 매매코딩/Python 2021. 6. 25. 23:32
안녕하세요 ㅎㅎ 학교공부가 바빠서라는 핑계로.. 오랫만에 포스팅을 하게 되는 것 같네요. 종강하고 시간이 나서 이렇게 오랜만에 인사드리고 포스팅 올리게 되었습니다 ㅋㅋ
이번 포스팅은 RSI 전략을 사용해서 자동매매를 구현해보겠습니다.
RSI 전략
위키백과를 참고한 RSI의 정의는 다음과 같습니다.
일정 기간 동안 주가가 전일 가격에 비해 상승한 변화량과 하락한 변화량의 평균값을 구하여, 상승한 변화량이 크면 과매수로, 하락한 변화량이 크면 과매도로 판단하는 방식이다.
간단하게 상승한 변화량과 하락한 변화량을 계산해서 과매수면 매도, 과매도 상태면 매수하는 전략입니다.
RSI값은 다음을 거쳐 계산한다.
- 가격이 전일 가격보다 상승한 날의 상승분은 U(up) 값이라고 하고,
- 가격이 전일 가격보다 하락한 날의 하락분은 D(down) 값이라고 한다.
- U값과 D값의 평균값을 구하여 그것을 각각 AU(average ups)와 AD(average downs)라 한다.
- AU를 AD값으로 나눈 것을 RS(relative strength) 값이라고 한다. RS 값이 크다는 것은 일정 기간 하락한 폭보다 상승한 폭이 크다는 것을 의미한다.
- 다음 계산에 의하여 RSI 값을 구한다.
- RSI = RS / (1 + RS) or RSI = AU / (AU + AD)
위에서 보시는 것과 같이, 상승한 날의 상승폭 평균 값(AU)에서 전체 변화량(AU + AD)을 나눠서 RSI를 계산합니다.
RSI가 70% 이상이면 과매수, 30% 이하일 때 과매도 상태로 규정하기 때문에 RSI가 70% 이상이면 매도, 30% 이하이면 매수를 하도록 만들 수 있습니다. 하지만 과매수, 과매도 상태에서 오래 머무는 경우가 많아 이 전략만으로는 이익을 내기 어렵다는 단점이 있습니다.
이를 보완하기 위해 추세가 반전되는 순간을 포착하는 다이버전스 전략을 사용합니다.
다이버전스 전략은 전 고점, 저점과 현재 가격을 비교해서 추세를 판단하고 매매하는 방식을 말합니다.
일반 다이버전스에서는 전 고점, 저점을 돌파할 때 추세가 전환되었다고 판단해 매매하고, 히든 다이버전스는 반대로 전 고점, 저점을 돌파하지 못했을 때 추세가 전환되었다고 판단해 매매합니다.
저는 고점, 저점을 넘지 못할 때 추세가 전환되었다고 판단하는 히든 다이버전스를 사용하겠습니다.
업비트 API 불러오기
RSI 전략을 사용해서 매매를 하기 위해선 업비트 access, secret 키를 사용해 API를 불러와야 합니다.
저는 업비트 API 키를 메모장에 적어놓고, 파일로 실행해 불러왔습니다.
import pyupbit class Auto: def __init__(self): # API 연결 f = open("C:/코인자동매매/key.txt") lines = f.readlines() access = lines[1].strip() # access key secret = lines[3].strip() # secret key f.close() self.size = 200 self.upbit = pyupbit.Upbit(access, secret)
self.size는 불러올 과거 데이터의 개수를 저장합니다.
과거 데이터 블러오기
단타 매매를 하기위해 과거 데이터를 불러와서 과매수, 과매도 여부를 판단해야 합니다.
import time class Auto: (...) def main(self, coin="KRW-BTC", auto=1, spend=10000, interval=5): self.coin = coin self.spend = spend self.buyPrice = 0 # interval 처리 if interval == 10080: timeRange = "week" elif interval == 1440: timeRange = "day" else: timeRange = f"minute{interval}" # 현재 코인 잔액 표시, 출력 krwBal = self.upbit.get_balance("KRW") coinBal = self.upbit.get_balance(self.coin) coinPrice = pyupbit.get_current_price(self.coin) print(f"원화 잔고: {int(round(krwBal, 0))}원") print(f"{self.coin} 잔고: {int(round(coinPrice * coinBal, 0))}원\n") self.buy = False while 1: # 5분봉 200개 불러오기 self.df = pyupbit.get_ohlcv(ticker=self.coin, interval=timeRange, count=self.size) print("\n\n===========데이터을 입력했습니다==============") print(self.df[-5:]) # 매수, 매도 결정 self.count = 0 self.RSI() print("\n") self.trade() print("\n") if not auto: break print(f"{interval}분 후에 다시 시작합니다") time.sleep(interval * 60)
main 함수를 만들어 매매할 코인(coin), 자동 매매 여부(auto), 매매할 액수(spend), 시간 단위(interval)을 받습니다.
시간 단위는 매매할 시간 간격과 매매에 사용할 과거 데이터의 시간 간격을 정합니다.
main 함수에서 과거 데이터를 불러오고, 현재 코인의 잔액을 표시하고, 출력합니다.
self.count는 RSI 전략에서 조건이 맞으면 1이 증가하는 변수입니다. 여러 전략을 사용할 때, 각 전략의 조건이 맞을 때마다 self.count의 값을 1씩 증가시키고, self.count가 특정 값 이상이 되면 실제 매매가 발생하는 식으로 사용할 겁니다.
self.buy는 현재 매수, 매도 여부를 보여줍니다. 아직 코인을 구매하지 않은 상태이므로, self.buy는 false가 됩니다.
지금은 RSI 전략만 사용하니까 self.count가 1이 되면 실제 매매가 이뤄집니다.
RSI 전략 사용하기
과거 데이터를 바탕으로 RSI를 계산하고, 매매를 결정하는 함수를 만듭니다.
class Auto: def RSI(self): n = 14 # 사용할 데이터 수 up, down = [0, 0], [0, 0] # 기준이 될 상승량, 하락량 # rsi 값 계산 for i in range(1, n+1): var = self.df["close"][-i] - self.df["close"][-i-1] if var > 0: up[0] += var up[1] += 1 else: down[0] += -var down[1] += 1 au = up[0] / up[1] ad = down[0] / down[1] rsi = (au / (au + ad)) * 100 # rsi 값 출력, 매수매도 결정 print(f"RSI: {round(rsi, 1)}%") print("RSI:", end=" ") if rsi > 70 and self.df["close"][-1] < max(self.df["close"][-n:]) and self.buy == True: print("매도합니다") self.count += 1 elif rsi < 30 and self.df["close"][-1] > min(self.df["close"][-n:]) and self.buy == False: print("매수합니다") self.count += 1 else: print("매매하지 않습니다")
아까 설명드린 공식대로 과거데이터에서 RSI값을 계산해서, RSI가 70 초과이고, 전 고점을 돌파하지 못했으면 하락추세라고 판단하고 매도, RSI가 30 미만이고, 전 저점을 돌파하지 못했으면 상승추세라고 판단하고 매수합니다.
매매하기
RSI에서 판단한 조건이 맞으면 실제 매매가 되야 합니다.
매매를 위한 trade 함수를 추가합니다.
def trade(self): if self.count == 1: if self.upbit.get_balance("KRW") > self.spend: if self.buy == False: self.buy = True self.buyPrice = pyupbit.get_current_price(self.coin) self.upbit.buy_market_order(self.coin, self.spend) print(f"매수합니다\n매수금액: {self.spend}") else: self.buy = False currPrice = pyupbit.get_current_price(self.coin) if self.buyPrice == 0: sellPrice = self.spend else: sellPrice = self.spend * (self.buyPrice / currPrice) * (1/0.9995) self.upbit.sell_market_order(self.coin, sellPrice / currPrice) print(f"매도합니다\n매도금액: {sellPrice}") else: print("잔액이 부족합니다") else: print("매매하지 않습니다")
RSI의 조건에 맞아서 self.count가 1이 되면 매수, 매도를 합니다.
지금까지 적은 코드를 실행시켜 보겠습니다.
성공적으로 작동하는 모습을 볼 수 있습니다. RSI가 계산되어 출력되고, RSI가 30~70사이기 때문에 매매가 되지 않았습니다.
다음 포스팅에서는 스토캐스틱(Stochastic) 전략으로 찾아뵙겠습니다!
참고한 사이트
https://ko.wikipedia.org/wiki/RSI_(%ED%88%AC%EC%9E%90%EC%A7%80%ED%91%9C)
RSI (투자지표) - 위키백과, 우리 모두의 백과사전
상대강도지수(相對强度指數, 영어: relative strength index, RSI)는 주식, 선물, 옵션 등의 기술적 분석에 사용되는 보조 지표이다. RSI는 가격의 상승압력과 하락압력 간의 상대적인 강도를 나타낸다. 19
ko.wikipedia.org
반응형'코딩 > Python' 카테고리의 다른 글
파이썬으로 코인 자동매매 프로그램 만들기 - 6: 지정가, 시장가 주문하기, 주문 취소하기 (1) 2021.04.30 파이썬으로 코인 자동매매 프로그램 만들기 - 5: API키 발급받기, 잔고 확인하기 (0) 2021.03.14 파이썬으로 코인 자동매매 프로그램 만들기 - 4: 코인의 현재가와 호가 (0) 2021.03.05 파이썬으로 코인 자동매매 프로그램 만들기 - 3: pyupbit로 시세 가져오기 (2) 2021.02.28 파이썬으로 코인 자동매매 프로그램 만들기 - 2 : pyupbit 모듈 설치, 사용하기 (2) 2021.02.25