2022.01.17 - [개발일지] - 업비트 코인 자동매매-1
일전에는 데이터를 Pandas로 변환해서 가져오는 것 까지 완료했다.
그렇다면 이제 구매와 판매에 대한 조건식을 걸어주는 것과 지갑에 접근하는 방법을 알아보자.
4. 조건식 만들기
개인적으로 생각하는 투자기법에서 중요한 것은 이동평균선과 RSI, BB%B로 생각했기 때문에 해당 데이터를 모두 pandas에 포함시켰다.
그럼 조건을 이용해 매수와 매도를 하도록 짜보자.
먼저 특정 데이터를 불러오는 수식을 짜도록 하자
now_data = df['close'].iloc[-1]
ma20 = df['close'].rolling(window=20).mean()
ma100 = df['close'].rolling(window=100).mean()
ma20 = ma20.iloc[-1]
ma100 = ma100.iloc[-1]
df['MA20'] = df['close'].rolling(window=20).mean()
df['stddev'] = df['close'].rolling(window=20).std()
df['upper'] = df['MA20'] + (df['stddev'] * 2) # 볼린저 밴드 상단선
df['lower'] = df['MA20'] - (df['stddev'] * 2) # 볼린저 밴드 하단선
df['PB'] = (df['close'] - df['lower']) / (df['upper'] - df['lower'])
BB = df['PB'].iloc[-1]
BB_L = df['PB'].iloc[198]
RSI_n = 14
df['updown'] = df['close'].diff()
df['RSI_U'] = df['updown'].apply(lambda x: x if x > 0 else 0)
df['RSI_D'] = df['updown'].apply(lambda x: x * (-1) if x < 0 else 0)
df['RSI_AU'] = df['RSI_U'].ewm(com=RSI_n - 1, min_periods=RSI_n).mean()
df['RSI_AD'] = df['RSI_D'].ewm(com=RSI_n - 1, min_periods=RSI_n).mean()
df['RS'] = df['RSI_AU'] / df['RSI_AD']
df['RSI'] = 100 - (100 / (1 + df['RS']))
RSI = df['RSI'].iloc[-1]
RSI_L = df['RSI'].iloc[198]
일전에 작성했던 코드에서 아래 변수에 값을 불러온다.
iloc [-1]을 사용하면 해당 테이블의 열 안의 가장 아래 값을 가져올 수 있다.
이를 이용해 20일 이동평균, 100일 이동평균, 20일 BB% B값, 그 직전 값, RSI값, RSI직전 값 이렇게 총 6개의 값을 변수에 저장한다.
ma20 = ma20.iloc[-1]
ma100 = ma100.iloc[-1]
BB = df['PB'].iloc[-1]
BB_L = df['PB'].iloc[198]
RSI = df['RSI'].iloc[-1]
RSI_L = df['RSI'].iloc[198]
그럼 저장한 해당 변수를 불러와서 if문을 이용해 비교문을 만들도록 하자.
coin_buy 함수는 들어온 coinname값을 넘겨주면서 구매 조건이 되었을 때 동작하도록 하고
coin_sell 함수는 반대로 구매 조건 달성시 동작하도록 작성을 했다.
이동평균선 20 이하 이면서 동시에 이동평균선 100 아래가 기본 조건
이후 볼린저 밴드가 BB_L이 0 이하, BB가 0 이상 일 때 이면서 동시에 RSI가 30 이상일 때로 잡았다.
직 BB_L을 이용해 직전 가격이 -이고 BB가 +일 때 즉 BB가 마이너스에서 플러스로 올라설 때 잡도록 했다.
그러면서도 RSI 역시 30 이상으로 올라와서 강도가 높을 때
풀어서 설명하면 하방 추세를 돌파하고 상승세로 돌아가려고 할 때 매수를 하도록 구성을 했다.
if now_data < ma20 and now_data < ma100:
if BB > 0 and BB_L < 0 and RSI > 30:
print("rootA / BB_L :", BB_L, " / BB :", BB, " / RSI :", RSI)
self.coin_buy(coinname)
elif RSI > 30 and RSI_L < 30 and BB > 0:
print("rootB / RSI_L :", RSI_L, " / RSI :", RSI, " / BB :", BB)
self.coin_buy(coinname)
else:
print("BB이하, 조건 미달성",coinname)
매도 조건은 elif로 추가해뒀다.
이평선 20 이상, 이평선 100 이상이면서
아까와는 정반대로 하방추세로 떨어지는 순간을 추적하도록 세팅했다.
elif now_data > ma20 and now_data > ma100:
if BB < 1 and BB_L > 1 and RSI > 70:
print("rootC / BB_L :", BB_L, " / BB :", BB, " / RSI :", RSI)
print(df)
self.coin_sell(coinname)
elif RSI_L > 70 and RSI < 70 and BB > 1:
print("rootD / RSI_L :", RSI_L, " / RSI :", RSI, " / BB :", BB)
self.coin_sell(coinname)
else:
print("BB이상, 조건 미달성",coinname)
else:
print("아직아님", coinname)
그리고 두 조건을 모두 달성하지 못하면 별도의 행동을 하지 않도록 세팅했다.
5. 매수 매도는요?
매수 함수는 coin_buy로 작성했고
upbit = pyupbit.Upbit(access_key, secret_key)
해당 구문을 통해 access_key와 secret_key를 넣어주면 내 지갑에 접근 가능해진다.
매수 기본금액을 30,000원으로 잡아뒀기 때문에 29,000원 이하일 경우 잔고가 없다는 문구가 나오도록 세팅했다.
그리고 돈이 있다면 30,000원어치를 매수하도록 세팅했다.
print(upbit.buy_market_order(coinname, 30000))
해당 구문이 입력되면 바로 매수가 이루어진다.
def coin_buy(self, coinname):
access_key = "본인키"
secret_key = "본인키"
upbit = pyupbit.Upbit(access_key, secret_key)
if upbit.get_balance("KRW") < 29000: #upbit.get_balance(coinname) > 0:
print("더이상 잔고가 없다...", coinname)
else:
print("##############매수###############",coinname)
print(upbit.buy_market_order(coinname, 30000))
매도 함수는 coin_sell로 처리했고
지갑을 불러오는 방식은 동일하다.
잔고가 있는지 여부를 먼저 확인하고 잔고가 없다면 잔고가 없다고 표현하고
있다면 전량 매도를 하도록 구성했다.
매수와 동일하지만 sell_count 변수를 만들어 현재 가진 코인 잔고를 확인하고 해당 잔고만큼 매도를 하도록 세팅했다.
def coin_sell(self, coinname):
access_key = "본인키"
secret_key = "본인키"
upbit = pyupbit.Upbit(access_key, secret_key)
if upbit.get_balance(coinname) <= 0:
print("현재 잔고가 없는 코인입니다.", coinname)
else:
print("##############매도###############",coinname)
sell_count = upbit.get_balance(coinname)
print(upbit.sell_market_order(coinname, sell_count))
6. 조건에만 반응하면 손실폭이 커지지 않을까?
아무래도 매도 조건을 상승했을 때만 이루어지도록 하면 코 인장이 전체적으로 하락장일 때의 대응이 어려워진다.
그래서 내 잔고를 확인하고 3%의 손실이 난 코인은 매도를 하도록 세팅해놓겠다.
sell_position이 불러와지면 우선 나의 모든 종목을 불러와 my_data에 저장한다.
그리고 df_data에 평균 구매 가격을 불러와 테이블을 만든다.
이후 보유한 테이블 행수만큼 for 구문을 이용해서 반복하도록 한 후 보유 중인 코인 정보를 불러온다.
보유중인 코인 가격의 평균가를 second_data에 저장하고
현재 해당 코인의 3% 빠진 가격을 value_data에 저장한다.
value_data가 second_data보다 크다면 즉시 매도를 실행한다.
def sell_position(self, coinname):
access_key = "본인키"
secret_key = "본인키"
upbit = pyupbit.Upbit(access_key, secret_key)
my_data = upbit.get_balances()
df_data = pd.DataFrame(my_data, columns=['currency', "avg_buy_price"])
df_data['currency'] = 'KRW-' + df_data['currency']
for i in df_data.index:
if df_data['currency'].iloc[i] == coinname:
value_data = float(df_data['avg_buy_price'].iloc[i]) * 0.97
second_data = pyupbit.get_current_price([coinname])
if value_data > second_data:
self.coin_sell(coinname)
else:
print("아직 손해 아닙니다.", coinname)
다음에는 매 시간마다 자동으로 매매가 될 수 있도록 세팅했던 내용을 작성하겠습니다.
'개발일지' 카테고리의 다른 글
업비트 코인 자동매매-1 (0) | 2022.01.17 |
---|