비트코인 자동매매에 기본적인 소스코드는
'조코딩(비트코인 자동매매-https://youtu.be/5vofEMqMyGk)'에서 가져왔습니다.
코드들은 github에 업로드되어있습니다.
https://github.com/JaeYeongSong/Blog/tree/main/BTC_Pyupbit-Autotrade
첫번째 bitcoinAutoTradeWithAISlack.py 파일 같은 경우에는 '조코딩' 유튜브에 가 보시면 보실 수 있습니다.
구매 시 Slack으로 알림받기, 이동평균선 15일 이상일 때 매수, 인공지능(Prophet)
이렇게 총 3가지를 한 코드에 합쳐놓았습니다.
시장 상황과 전략에 따라 손실이 발생할 수 있다는 점 알려드립니다.
투자의 책임은 본인에게 있습니다.
import time
import pyupbit
import datetime
import schedule
import requests
from fbprophet import Prophet
access = "your access"
secret = "your secret"
myToken = "your key"
def post_message(token, channel, text):
"""슬랙 메시지 전송"""
response = requests.post("https://slack.com/api/chat.postMessage",
headers={"Authorization": "Bearer "+token},
data={"channel": channel,"text": text}
)
upbit_Token = pyupbit.Upbit(access, secret)
def get_target_price(ticker, k):
"""변동성 돌파 전략으로 매수 목표가 조회"""
df = pyupbit.get_ohlcv(ticker, interval="day", count=2)
target_price = df.iloc[0]['close'] + (df.iloc[0]['high'] - df.iloc[0]['low']) * k
return target_price
def get_start_time(ticker):
"""시작 시간 조회"""
df = pyupbit.get_ohlcv(ticker, interval="day", count=1)
start_time = df.index[0]
return start_time
def get_ma15(ticker):
"""15일 이동 평균선 조회"""
df = pyupbit.get_ohlcv(ticker, interval="day", count=15)
ma15 = df['close'].rolling(15).mean().iloc[-1]
return ma15
def get_balance(ticker):
"""잔고 조회"""
balances = upbit.get_balances()
for b in balances:
if b['currency'] == ticker:
if b['balance'] is not None:
return float(b['balance'])
else:
return 0
return 0
def get_current_price(ticker):
"""현재가 조회"""
return pyupbit.get_orderbook(tickers=ticker)[0]["orderbook_units"][0]["ask_price"]
predicted_close_price = 0
def predict_price(ticker):
"""Prophet으로 당일 종가 가격 예측"""
global predicted_close_price
df = pyupbit.get_ohlcv(ticker, interval="minute60")
df = df.reset_index()
df['ds'] = df['index']
df['y'] = df['close']
data = df[['ds','y']]
model = Prophet()
model.fit(data)
future = model.make_future_dataframe(periods=24, freq='H')
forecast = model.predict(future)
closeDf = forecast[forecast['ds'] == forecast.iloc[-1]['ds'].replace(hour=9)]
if len(closeDf) == 0:
closeDf = forecast[forecast['ds'] == data.iloc[-1]['ds'].replace(hour=9)]
closeValue = closeDf['yhat'].values[0]
predicted_close_price = closeValue
predict_price("KRW-BTC")
schedule.every().hour.do(lambda: predict_price("KRW-BTC"))
# 로그인
upbit = pyupbit.Upbit(access, secret)
print("비트코인 자동화 시작합니다.")
# 시작 메세지 슬랙 전송
post_message(myToken,"#stock", "비트코인 자동화 시작합니다.")
# 자동매매 시작
while True:
try:
now = datetime.datetime.now()
start_time = get_start_time("KRW-BTC")
end_time = start_time + datetime.timedelta(days=1)
schedule.run_pending()
if start_time < now < end_time - datetime.timedelta(seconds=10):
target_price = get_target_price("KRW-BTC", 0.5)
ma15 = get_ma15("KRW-BTC")
current_price = get_current_price("KRW-BTC")
if target_price < current_price and ma15 < current_price:
krw = get_balance("KRW")
if krw > 5000:
# 비트코인 매수하기
buy_result = upbit.buy_market_order("KRW-BTC", krw*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(buy_result))
else:
btc = get_balance("BTC")
if btc > 0.00008:
sell_result = upbit.sell_market_order("KRW-BTC", btc*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(sell_result))
time.sleep(1)
except Exception as e:
print(e)
post_message(myToken,"#stock", e)
time.sleep(1)
▲ bitcoinAutoTradeWithAISlack.py
수정해야 할 것은
8~9번째 줄은 upbit에서 제공하는 openAPI 발급받은 키를 적어주시고
10번째 줄은 Slack api를 통해 봇을 만드시고 봇의 Token를 적어주시면 됩니다.
그리고 post_message함수를 불러올 때 "#stock"이라고 되어있는 부분을 Slack 봇이 있는 채널을 작성해주시면 됩니다.
자동매매 코드가 어떻게 돌아가는지 알려드리자면
# 자동매매 시작
while True:
try:
now = datetime.datetime.now()
start_time = get_start_time("KRW-BTC")
end_time = start_time + datetime.timedelta(days=1)
schedule.run_pending()
if start_time < now < end_time - datetime.timedelta(seconds=10):
target_price = get_target_price("KRW-BTC", 0.5)
ma15 = get_ma15("KRW-BTC")
current_price = get_current_price("KRW-BTC")
if target_price < current_price and ma15 < current_price:
krw = get_balance("KRW")
if krw > 5000:
# 비트코인 매수하기
buy_result = upbit.buy_market_order("KRW-BTC", krw*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(buy_result))
else:
btc = get_balance("BTC")
if btc > 0.00008:
sell_result = upbit.sell_market_order("KRW-BTC", btc*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(sell_result))
time.sleep(1)
except Exception as e:
print(e)
post_message(myToken,"#stock", e)
time.sleep(1)
▲ bitcoinAutoTradeWithAISlack.py 중 자동매매 코드
처음 while True: 로 반복문을 실행시켜 줍니다.
그리고 try: 로 오류가 발생하면 아래에 있는 코드
except Exception as e:
print(e)
post_message(myToken,"#stock", e)
time.sleep(1)
로 오류가 일어난다면 Slack 메신저로 오류가 났다는 메시지를 보냅니다.
그리고 다시 반복문을 실행합니다.
그 다음 현재 시간, 그리고 시작 시간, 끝나는 시간을 불러와 줍니다.
시작 시간은 매일 9시로 시작하고 끝나는 시간은 8시 59분 50초에 끝납니다. (이 부분은 if문 시작해서 설정됩니다.)
현재 끝나는 시간은 9시에 1일을 더해준 그 다음날 9시로 세팅이 되어있습니다.
그 다음 if문이 시작하는데 첫번째 if문에 조건을 설명해드리면
현재시간이 9시 보다 크고, 그 다음날 8시 59분 50초 보다 작냐 라는 뜻을 담고 있습니다.
여기서
end_time - datetime.timedelta(seconds=10)
은 아까전에 끝나는 시간이 그 다음날 9시라고 세팅되어있다고 했죠.
하지만 그럼 시작시간과 끝나는시간이 중첩되기 때문에 오류가 발생할 겁니다.
그래서 10초 정도 텀을 주기 위해 위 코드가 '끝나는 시간에 10초를 빼라'라는 뜻을 가지고 있습니다.
즉 그 다음날 8시 59분 50초에 끝나는 시간이라고 되어있습니다. 그리고 그 10초 동안 우리는 매도를 할겁니다.
그럼 그 다음에 target_price는 매수 목표가를 정해줍니다.
매수 목표가를 구하는 함수는
def get_target_price(ticker, k):
"""변동성 돌파 전략으로 매수 목표가 조회"""
df = pyupbit.get_ohlcv(ticker, interval="day", count=2)
target_price = df.iloc[0]['close'] + (df.iloc[0]['high'] - df.iloc[0]['low']) * k
return target_price
이 함수입니다.
해석을 해드리자면 target_price는 오늘 시가 + 어제 고가 - 어제 저가 *(곱하기) k 라는 뜻입니다.
변동성 돌파 전략으로 단기적으로 수익을 올릴수 있는 알고리즘입니다.
여기서 이 글을 읽고 계시는 독자님들이 이 코드를 수정하면 비트코인 매매 알고리즘을 수정하실 수 있습니다.
변동성 돌파 전략의 자세한 내용은은 (조코딩 - https://youtu.be/Y01D2J_7894?t=298)
4분 58초부터 5분 17초 까지 설명되어있습니다.
그다음 함수는 15일 이동평균선을 호출하는 함수입니다.
코인 가격이 상승할때 이동평균선도 같이 올라가고, 코인 가격이 내려갈 때는 이동평균선도 같이 내려갑니다.
이동평균선 보다 현재 코인가격이 위에 있을땐 상승세가 될 경우가 높고,
이동평균선 보다 현재 코인가격이 아래에 있을땐 하락세가 될 경우가 높습니다.
이러한 규칙을 통해 이동평균선 보다 현재 코인가격이 위에 있을때를 구하기 위해 이동평균선을 호출하는 코드입니다.
그리고 그 다음 함수는 비트코인에 현재가격을 불러오는 함수입니다.
그 다음부터 매수 코드가 시작됩니다.
if target_price < current_price and ma15 < current_price:
krw = get_balance("KRW")
if krw > 5000:
# 비트코인 매수하기
buy_result = upbit.buy_market_order("KRW-BTC", krw*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(buy_result))
이 코드를 해석하자면 if문에서 변동성 돌파 전략으로 목표가 구하는 함수에서 얻어낸 매수 가격보다
현재가격이 더 높다면 그리고 이동평균선 보다 현재가격이 더 높다면 이 아래 코드를 실행해라는 구문입니다.
그 다음 krw 변수는 내가 가지고 있는 원화(\)가 얼마인지 가져오는 변수입니다.
다음 if문이 하나 더 있는데 있는 이유가 뭐냐면 비트코인을 매수나, 매도하려면 5000원 이상이여야 하니까 내가 가지고 있는 돈이 5000원 이상이라면 아래 코드를 실행해라는 if문이 있습니다.
이제 이 부분이 매수하는 코드입니다.
지금까지 말한 if문이 True(사실[맞다면])라면 매수를 하라는 코드가 작성되어있습니다. 여기서 krw*0.9995는 수수료가 제외된 가격을 매수해야 하기 때문에 0.9995를 곱해 주었습니다.
그리고 post_message를 통해 매수가 진행되었다는걸 Slack 메신저로 보내는 구문이 작성되어있습니다.
지금까지 매수를 진행하는 코드를 해 보았고요.
이제부터 매도를 진행하는 코드를 설명해드리겠습니다.
else:
btc = get_balance("BTC")
if btc > 0.00008:
sell_result = upbit.sell_market_order("KRW-BTC", btc*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(sell_result))
여기서 else는 맨 처음에 알려드렸듯이 9시 부터 다음날 8시 59분 50초가 아닐 경우에는 이 구문은 실행하라는 뜻이 담겨있습니다. 그러면 지금 부턴 8시 59분 50초 부터 9시 사이까지 매도를 진행하는 코드가 작성되어있습니다.
그러면 여기서 btc 변수는 내가 가지고 있는 비트코인을 가져오는 것입니다.
그 다음 if문에서 내가 가지고 있는 비트코인이 5000원 이상이라면 아래 구문을 실행해라는 if문이 있습니다.
if btc > 0.00008:
여기서 0.00008은 무엇을 나타낼까요?
비트코인은 비트코인으로 계산을 해야되기 때문에 0.00008이 약 5000원 정도 되므로 0.00008을 적었습니다.
5000원 이상만 매수, 매도를 할 수 있기 때문이죠.
그럼 내가 가지고 있는 비트코인이 5000원 이상이면 매도를 진행하라는 코드가 있습니다.
여기서도 매수처럼 수수료를 위해 0.9995를 곱해주었고,
post_message로 Slack 메신저를 통해 매도가 되었다는 메세지를 보내게 됩니다.
비트코인 자동 매매 코드는 끝났는데 여기서 단점이 있지 않을까요?
그 다음날 8시 59분 50초가 되지 않았는데 어제 매수시간에 구매한 가격보다 떨어진다면 어떻게 막아야 할까요?
이걸 막을수 있는 코드는 다음시간에 업로드 하도록 하겠습니다.
지금까지 비트코인 자동 매매 코드였습니다.