비트코인 자동매매에 기본적인 소스코드는
'조코딩(비트코인 자동매매-https://youtu.be/5vofEMqMyGk)'에서 가져왔습니다.
코드들은 github에 업로드되어있습니다.
https://github.com/JaeYeongSong/Blog/tree/main/BTC_Pyupbit-Autotrade
오늘은 저번시간에 이어서 비트코인이 매수시점보다 떨어졌을 때 막을수 있는 프로그램을 만들어보았습니다.
저번시간에 만든거 알고리즘 약간만 수정한거라서 저와 같이 수정하실 거라면, 약간만 바꿔주시면 됩니다.
시장 상황과 전략에 따라 손실이 발생할 수 있다는 점 알려드립니다.
투자의 책임은 본인에게 있습니다.
오늘의 목적은 매수시점보다 비트코인 가격이 떨어졌을때 매도하는걸 알려드리도록 하겠습니다.
비트코인의 가격이 매수시점보다 떨어졌다는 것을 저도 잘 못찾아서, 어제 저가보다 떨어졌을 시에
매도하는 알고리즘을 알려드리도록 하겠습니다.
오늘 파일 이름은 cell_bitcoinAutoTradeWithAISlack.py 입니다.
지금부터 무엇이 바뀌었는지 알려드리도록 하겠습니다.
전체 소스 코드를 알려드리겠습니다.
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)
# 시작 메세지 슬랙 전송
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)
last_df = pyupbit.get_ohlcv(interval="day", count=2)
last_low = last_df.iloc[0]['low']
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 last_low > current_price:
btc = get_balance("BTC")
if btc > 0.00008:
sell_result_low = upbit.sell_market_order("KRW-BTC", btc*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(sell_result_low))
else:
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:
post_message(myToken,"#stock", e)
time.sleep(1)
▲ cell_bitcoinAutoTradeWithAISlack.py
이게 알고리즘을 수정한 비트코인 자동매매 파일입니다.
수정된 부분만 가져오도록 하겠습니다.
# 자동매매 시작
while True:
try:
now = datetime.datetime.now()
start_time = get_start_time("KRW-BTC")
end_time = start_time + datetime.timedelta(days=1)
last_df = pyupbit.get_ohlcv(interval="day", count=2)
last_low = last_df.iloc[0]['low']
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 last_low > current_price:
btc = get_balance("BTC")
if btc > 0.00008:
sell_result_low = upbit.sell_market_order("KRW-BTC", btc*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(sell_result_low))
else:
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:
post_message(myToken,"#stock", e)
time.sleep(1)
▲ cell_bitcoinAutoTradeWithAISlack.py 중 자동매매 코드
여기서 바뀐 것은 새로운 함수, 그리고 if문 수정입니다.
첫번째로 바뀐건 last_df, last_low입니다.
last_df 같은 경우에는 upbit에 OHLCV는 open-high-low-close-volume 이 5가지 데이터를 받아오는걸 뜻합니다.
open(시가) - high(고가) - low(저가) - close(종가) - volume(거래량) 이 5가지 데이터를 받아옵니다.
last_df 같은 경우에는
last_df = pyupbit.get_ohlcv(interval="day", count=2)
이렇게 'count=2'라고 적혀있으므로 2일치 ohlcv를 가져와서 last_df에 저장하고,
그 다음 last_low같은 경우에는
last_low = last_df.iloc[0]['low']
last_df 에서 받아온 ohlcv 정보 중에 low(저가) 0번째 (0, 1, 2, 3, 4...순) 데이터를 인덱싱합니다.
여기서 0번째란 받아온 정보가 DataFrame으로
이렇게 과거가 맨 위에 있으므로 2일치 데이터를 불러온다면 전날 데이터가 0번째겠죠?
사진에선 low(저가)가 0번째 있는 데이터를 인덱싱하면 '36901000.0'이라는 값이 불러와지겠죠?
그래서 어제 저가를 불러오는 방법입니다.
그 다음 이제 if문에 대해 설명을 해드려야 겠죠.
if문을 불러와보겠습니다.
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 last_low > current_price:
btc = get_balance("BTC")
if btc > 0.00008:
sell_result_low = upbit.sell_market_order("KRW-BTC", btc*0.9995)
post_message(myToken,"#stock", "BTC buy : " +str(sell_result_low))
else:
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)
여기서 첫번째 if문은 저번과 동일하게 되어있고, 그 다음 if문이 바뀌었습니다.
아까전에 제가 설명했던 last_low(어제 저가)보다 현재가가 더 낮다면 매도를 진행합니다.
이 부분이 오늘의 핵심입니다.
그리고 그 다음 'else:' 해석하자면 last_low(어제 저가)보다 현재가가 더 높다면 아래에 있는 구문을 실행해라 입니다.
아래에 있는 구문은 저번시간에 매수 알고리즘을 담고 있습니다.
저번에 설명했듯이 변동성 돌파 전략으로 구한 매수가 보다 현재가가 높다면,
그리고 15일 이동평균선 보다 현재가가 더 높다면 매수를 진행하는 구문입니다.
다음 if문과 eles문 및 자세한 내용은 https://xsop.tistory.com/3
저번시간 매수진행하는 알고리즘에서 확인해보시기 바랍니다.
비트코인 자동매매가 좀더 완성에 가깝게 다가갔네요.
다음시간에 돌아오도록 하겠습니다.
지금까지 알고리즘 수정한 비트코인 자동매매 코드였습니다.