본문 바로가기
Python/업비트 자동매매

(Python) 업비트 자동 매매 프로그램 만들기(4) - 중간 점검

by 미니몬 2023. 8. 20.

목차

    728x90
    반응형

    Summary

    이번 게시물에서는 지난 게시물에서 작성한 코드들을 하나로 모아 보도록 하겠습니다.

    그전에 각 기능들을 함수로 구현했을 때 호출 실패시 대응 방법을 먼저 추가해보겠습니다.


    1) fetch_data 함수 구현

    • fetch_data 함수로 안정적으로 기능들을 호출하도록 구현
    def fetch_data(fetch_func, max_retries=20, delay=0.5):
        for i in range(max_retries):
            res = fetch_func() # fetch_func() 함수를 호출하여 데이터
            if res is not None: # 가져온 데이터가 None이 아닌 경우 루프를 종료
                return res
            time.sleep(delay) # 데이터를 가져오지 못한 경우 0.5초 동안 대기
        return None

    fetch_data() 함수를 이용해서 구현한 함수들의 안정적인 호출을 보장하도록 합니다.

    재시도 할 시간 지정을 위해 time 모듈이 필요하여 import 해주도록 하겠습니다.

    import time

     

    fetch_data() 함수의 사용방법은 아래와 같습니다.

    def get_cur_price(ticker):
        return fetch_data(lambda: pyupbit.get_current_price(ticker))

     

     

    fetch_data() 함수는 주어진 fetch_func 함수를 호출하여 데이터를 가져오는 역할을 합니다. 
    만약 첫 번째 시도에서 데이터를 성공적으로 가져오지 못한다면, 함수는 최대 max_retries 횟수만큼 재시도합니다. 
    각 시도 사이에는 delay 초만큼 대기합니다.

     

     

    이 함수의 필요성은 다음과 같습니다:

    1. 네트워크 불안정: API 호출은 네트워크를 통해 이루어지므로, 일시적인 네트워크 문제나 서버의 일시적인 오류로 인해 첫 번째 시도에서 데이터를 가져오지 못할 수 있어 재시도 하는 기능을 합니다.
    2. API 제한: API는 요청 횟수에 제한을 둡니다. 이러한 제한을 초과하면 일시적으로 데이터를 가져오지 못할 수 있어 재시도 하는 기능을 합니다.

     

    fetch_data() 함수를 생략하게 되면:

    일시적인 네트워크 문제나 서버 오류로 인해 데이터를 가져오지 못할 경우, 프로그램은 즉시 실패하게 됩니다.
    API 호출 제한을 초과할 경우, 프로그램은 추가 대기 시간 없이 실패하게 됩니다.


    2) 함수 종합

    • fetch_data 함수로 안정적으로 기능들을 호출하도록 구현
    import pyupbit
    import time
    
    # Configuration
    coin = "KRW-XRP"
    with open("key.txt") as f:
        access_key, secret_key = [line.strip() for line in f.readlines()]
    
    # Upbit Initialization
    upbit = pyupbit.Upbit(access_key, secret_key)
    
    
    def fetch_data(fetch_func, max_retries=20, delay=0.5):
        for i in range(max_retries):
            res = fetch_func() # fetch_func() 함수를 호출하여 데이터
            if res is not None: # 가져온 데이터가 None이 아닌 경우 루프를 종료
                return res
            time.sleep(delay) # 데이터를 가져오지 못한 경우 0.5초 동안 대기
        return None
    
    def get_cur_price(ticker):
        return fetch_data(lambda: pyupbit.get_current_price(ticker))
    
    def get_balance_cash():
        return fetch_data(lambda: upbit.get_balance("KRW"))
    
    def get_balance_coin(ticker):
        return fetch_data(lambda: upbit.get_balance(ticker))
    
    def get_buy_avg(ticker):
        return fetch_data(lambda: upbit.get_avg_buy_price(ticker))
    
    def get_order_info(ticker):
        try:
            orders = fetch_data(lambda: upbit.get_order(ticker))
            if orders and "error" not in orders[0]:
                return orders[-1]
        except Exception as e:
            print(e)
        return None
    
    # 시장가 매수
    def order_buy_market(ticker, buy_amount):  
        """
        : ticker : 코인 이름
        : buy_amount : 매수할 금액
        """
        if buy_amount < 5000:  
            print("amount is better than 5000")
            return 0
        
        res = fetch_data(lambda: upbit.buy_market_order(ticker,buy_amount))
    
        if 'error' in res:
            print(res)
            res = 0
    
        return res
    
    # 시장가 매도
    def order_sell_market(ticker, volume):
        """
        : ticker : 코인 이름
        : volume : 매도할 수량
        """
        res = fetch_data(lambda: upbit.sell_market_order(ticker, volume))
    
        if 'error' in res:
            print(res)
            res = 0
    
        return res
    
    # 지정가 매수
    def order_buy_limit(ticker, price, volume):
        """
        : ticker : 코인 이름
        : price : 매수할 가격
        : volume : 매수할 수량
        """
        res = fetch_data(lambda: upbit.buy_limit_order(ticker, price, volume))
    
        if 'error' in res:
            print(res)
            res = 0
    
        return res
    
    # 지정가 매도
    def order_sell_limit(ticker, price, volume):
        """
        : ticker : 코인 이름
        : price : 매도할 가격
        : volume : 매도할 수량
        """
        res = fetch_data(lambda: upbit.sell_limit_order(ticker, price, volume))
        if 'error' in res:
            print(res)
            res = 0
        return res
    
    # 주문 취소
    def order_cancel(ticker):
        order_info = get_order_info(ticker)
        try:
            order_uuid = order_info['uuid']
            res = upbit.cancel_order(order_uuid)
            if 'error' in res:
                print(res)
                res = 0
                return res
            print(res)
        except Exception as e:
            res = 0 
            print(e)
        return res

     

     

    현재는 실제로 거래를 하기 전 필요 기능만 구현 해놓은 상황입니다.

    다음 게시물에서는 유명한 전략 중 하나인 볼린저밴드(Bollinger band)를 이용해서 매수/매도 시점을 구현 해보도록 하겠습니다.

     

     

     

     

     

    728x90
    반응형