파이썬을 이용하여 코인 자동매매 (4/4) 펌핑 감지 소스
이번 글에 모든 소스코드를 공유하고 설명하려 하였으나 길어질 듯 하여
먼저 기본적인 펌핑감지, 매수, 매도 함수를 이번글에서 작성할 것이며 다음글에서는 예외처리나 문제 회피방법등을 설명할 예정이다.
소스코드의 설명을 보며 이동평균선 수치, 거래량 증가에 감지 기준등을 변경하여 자신에 맞게 사용하기를 바란다.
참고로 짧은 시간에 한번에 작성한 소스이기 때문에 변수명이나 구조를 다듬지 못하였다.
이 소스라도 참고하여 자신에 맞는 소스를 작성하고자 하는 분들께 사용되기를 바란다.
5. 소스 및 설명
5.1. 기본 구성
기본 구성은 모든 코인의 시세와 거래량을 순차적으로 분석하고 거래량이 증가하면 구매하게 된다.
또한 일정 수준의 이득을 보았으면 매도하도록 단순히 구현하게 되었다.
(처음에는 거래량이 일정수준 이하이며 음봉이면 매도하도록 구현하였으나 부적절한 타이밍에 매도하여 손해발생, 매도 타이밍 알고리즘에 대한 아이디어 있으면 제보 바랍니다.)
import pyupbit
access = ""
secret = ""
upbit = pyupbit.Upbit(access, secret)
tickers = pyupbit.get_tickers("KRW")
while True:
print("반복문 시작")
for ticker in tickers:
sell_process(ticker) # 매도
buy_process(ticker) # 매수
time.sleep(0.05)
5.2. 매도 함수
매도하고자 하는 이득구간을 설정하기 위해서는 profit_rate의 값을 변경하면 된다.
def sell_process(ticker):
"""
10프로만 이득보면 매도.
:param ticker: 매도하고자 하는 코인명
:return: None
"""
###############10프로
now_price = pyupbit.get_current_price(ticker)
average_price = upbit.get_avg_buy_price(ticker)
profit_rate = 1.1 # 수익률 (1.1 -> 10%)
# 현재가격이 구매가보다 10프로 보다 크다면
if (average_price >0) and (now_price>=average_price * profit_rate):
print(ticker, now_price, average_price)
print('\033[30m', time.strftime('%m-%d %H:%M:%S'), ticker, "매도")
# 매도
sell_log = sell_current_price(ticker)
print(sell_log)
elif average_price == 0:
print(ticker, "가 없습니다. ")
여기서 sell_current_price함수는 현재가에 매도하는 함수인데 아래와 같다.
def sell_current_price(ticker):
"""
현재가 매도 함수
:param ticker: 매도하고자 하는 코인명
:return: None
"""
unit = upbit.get_balance(ticker)
return upbit.sell_market_order(ticker, unit)
5.3. 매수에 필요한 함수
5.3.1 양봉, 음봉 판단 함수
GRAPH_UP = 10
GRAPH_DOWN = 20
def is_up_or_down(df):
last_close = df['close'][-1]
last_open_price = df['open'][-1]
if last_close - last_open_price > 0:
return GRAPH_UP
else:
return GRAPH_DOWN
5.3.2 평균이 포함된 캔들 데이터 프레임
def make_df_add_average_volume(ticker, interval, rolling_value, count=20):
"""
거래량 평균이 추가된 데이터프레임
:param ticker: 캔들 정보를 표시할 코인
:param interval: 캔들정보 1분, 10분, 등..
:param rolling_value: 이동평균 갯수
:param count: 서버에서 취득할 데이터 수
:return: pandas dataframe
"""
try:
df = pyupbit.get_ohlcv(ticker, interval, count=count)
df['average'] = df['volume'].rolling(window=rolling_value).mean().shift(1)
return df
except:
return 1
5.3.3 매수 함수
현재 소스의 로직은 다음과 같다.
- 최근 1분봉 10개를 분석하여 거래량 평균을 구한다.
- 현재 양봉인지 판단한다.
- 현재 거래량이 평균보다 7배 이상이면 구매
def buy_process(ticker): try: if upbit.get_avg_buy_price(ticker) == 0: # 코인을 보유하지 않는다면 매수 # 1분봉 이전 평균 10개 data_count = 20 # 20개 데이터만 추출 add_average_min_df = make_df_add_average_volume(ticker, "minute1", rolling_value=10, count=data_count) average_vol = add_average_min_df['average'][data_count-1] now_vol = add_average_min_df['volume'][data_count-1] # 양봉인지 판단 up_down_value = is_up_or_down(add_average_min_df) if up_down_value == GRAPH_UP: # 거래량 배수 # 거래량이 적은경우 적은거래로도 튀기때문에 적은거래량에서는 20배만큼 상승해야 구매 compare_vol = average_vol*7 if now_vol >= compare_vol: print('\033[30m', time.strftime('%m-%d %H:%M:%S'), ticker, "구매") # 구매 시그널 buy_log = upbit.buy_market_order(ticker, total_weight) print(buy_log) if not buy_log: print("구매하려하였으나 못삼 ㅜㅠ") except: print("error")
5.4. 추가 고려해야 할 점
- 거래량이 워낙 작은 코인들은 약간의 거래량 변동이 와도 위에서 매수 기준인 7배가 넘는 사례가 많기 때문에 펌핑기준을 충족하여 매수하는 경우가 많다. 이 기준을 잘 세워야 한다.
- 매도 타이밍을 10프로만 이득보고 판매하도록 작성하였지만, 더 좋은 판매 알고리즘이 있을 것으로 판단됨
- 모든 코인을 검사하기 때문에 펌핑이 오고 많게는 30초 늦게 발견하고 구매할 수 있기 때문에 구매 타이밍이 늦는 경우가 많다. 이를 위해 여러 쓰레드로 나누어 로직을 돌리던가 불필요한 연산을 적게 하여 위의 로직을 빠르게 반복하는 방법이 있다.
5.5. 수익률과 한계
필자는 위의 로직으로 50만원정도 소액으로 프로그램을 돌려보았다.
그 결과 펌핑코인도 다량 구매하여 적절하게 판매할 수 있었으나, 위의 5.4절의 1번의 문제가 발생하여 불필요한 코인을 구매하는 경우도 발생하였다.
따라서 수익률은 거의 0프로에 근접하게 된다. 하지만 5.4의 1에 해당하는 문제를 회피하게 된다면 좋은 매수 방법이 될 것으로 보인다.
5.6 다음 글
다음 글을 작성하게 되면 사족이 될 것으로 보여 작성여부를 고민중이다.
만약 작성하게 되면 매수 여부를 미리 저장하여 속도 개선을 하거나, 제외하고자 하는 코인 리스트를 작성하거나 하는 편의 개선 코드가 될 것이다.