프로젝트/비트코인 자동매매

호가 계산하기 - 파이썬 업비트 비트코인 자동매매

Tech&Fin 2021. 6. 17. 18:19
반응형

지정가 매수 및 매도를 하기 위해서는 매수 또는 매도 하고자 하는 가격을 구해야 하는데요. 이번 시간에는 지정가 매수 및 매도를 하기 위해 호가 단위를 계산하는 방법 및 비율 및 범위를 이용해 원하는 가격을 계산하는  로직에  대해서  살펴 보도록  하겠습니다.

 

지정가 매도 로직은 아래 포스트를 참고 부탁 드립니다.

 

2021.06.17 - [프로젝트/비트코인 자동매매] - 지정가 매도 로직 - 파이썬 업비트 비트코인 자동매매

 

지정가 매도 로직 - 파이썬 업비트 비트코인 자동매매

이번 시간에는 가격을 지정하여 매도하는 지정가 매도 로직에 대해서 살펴 보겠습니다. 관련된 로직으로 시장가 매수 및 매도 로직은 아래 포스트를 참고 부탁 드리겠습니다. 2021.06.09 - [프로젝

technfin.tistory.com

 

 

목차 - 클릭하면 이동합니다.

     

    업비트 호가 표시 단위

    호가는 코인이 거래되는 가격의 단위이며 거래소 별로 코인의 가격 범위에 따라 호가 표시 단위가 정해져 있습니다.

     

    예를들어 현재 4000만원이 넘는 비트코인은 호가 단위가 1,000원이기 때문에 1,000원 단위로 거래가 가능하며 400원정도 하는 도지코인은 호가단위가 1원이 때문에 1원 단위로 거래가 가능합니다.

     

    오늘 살펴볼 로직은 업비트 거래소의 KRW 마켓 기준임을 참고 부탁 드리겠습니다.

     

    업비트 KRW 마켓의 호가 단위는 위의 표와 같으며 아래 링크를 클릭하여 업비트 홈페이지에서 최신 정보를 확인하실 수 있습니다.

     

    업비트 호가단위 공지 바로가기

     

    호가 계산 로직

    금액별 호가 계산 로직

    # -----------------------------------------------------------------------------
    # - Name : get_hoga
    # - Desc : 호가 금액 계산
    # - Input
    #   1) cur_price : 현재가격
    # - Output
    #   1) hoga_val : 호가단위
    # -----------------------------------------------------------------------------
    def get_hoga(cur_price):
        try:
    
            # 호가 단위
            if Decimal(str(cur_price)) < 10:
                hoga_val = 0.01
            elif Decimal(str(cur_price)) < 100:
                hoga_val = 0.1
            elif Decimal(str(cur_price)) < 1000:
                hoga_val = 1
            elif Decimal(str(cur_price)) < 10000:
                hoga_val = 5
            elif Decimal(str(cur_price)) < 100000:
                hoga_val = 10
            elif Decimal(str(cur_price)) < 500000:
                hoga_val = 50
            elif Decimal(str(cur_price)) < 1000000:
                hoga_val = 100
            elif Decimal(str(cur_price)) < 2000000:
                hoga_val = 500
            else:
                hoga_val = 1000
    
            return hoga_val
    
        # ----------------------------------------
        # Exception Raise
        # ----------------------------------------
        except Exception:
            raise

    위에서 살펴 본 업비트 호가 표시 단위를 단순히 if / else 문을 이용하여 구현한 로직입니다. 금액을 입력하면 구간에 해당하는 호가 표시 단위를 리턴 합니다.

     

    비율 및 호가 단위를 이용한 지정가 계산 로직

    # -----------------------------------------------------------------------------
    # - Name : get_targetprice
    # - Desc : 호가단위 금액 계산
    # - Input
    #   1) cal_type : H:호가로, R:비율로
    #   2) st_price : 기준가격
    #   3) chg_val : 변화단위
    # - Output
    #   1) rtn_price : 계산된 금액
    # -----------------------------------------------------------------------------
    def get_targetprice(cal_type, st_price, chg_val):
        try:
            # 계산된 가격
            rtn_price = st_price
    
            # 호가단위로 계산
            if cal_type.upper() == "H":
    
                for i in range(0, abs(int(chg_val))):
    
                    hoga_val = get_hoga(rtn_price)
    
                    if Decimal(str(chg_val)) > 0:
                        rtn_price = Decimal(str(rtn_price)) + Decimal(str(hoga_val))
                    elif Decimal(str(chg_val)) < 0:
                        rtn_price = Decimal(str(rtn_price)) - Decimal(str(hoga_val))
                    else:
                        break
    
            # 비율로 계산
            elif cal_type.upper() == "R":
    
                while True:
    
                    # 호가단위 추출
                    hoga_val = get_hoga(st_price)
    
                    if Decimal(str(chg_val)) > 0:
                        rtn_price = Decimal(str(rtn_price)) + Decimal(str(hoga_val))
                    elif Decimal(str(chg_val)) < 0:
                        rtn_price = Decimal(str(rtn_price)) - Decimal(str(hoga_val))
                    else:
                        break
    
                    if Decimal(str(chg_val)) > 0:
                        if Decimal(str(rtn_price)) >= Decimal(str(st_price)) * (
                                Decimal(str(1)) + (Decimal(str(chg_val))) / Decimal(str(100))):
                            break
                    elif Decimal(str(chg_val)) < 0:
                        if Decimal(str(rtn_price)) <= Decimal(str(st_price)) * (
                                Decimal(str(1)) + (Decimal(str(chg_val))) / Decimal(str(100))):
                            break
    
            return rtn_price
    
        # ----------------------------------------
        # Exception Raise
        # ----------------------------------------
        except Exception:
            raise

    ① cal_type : H:호가로, R:비율로
    ② st_price : 기준가격
    ③ chg_val : 변화단위

     

    지정가를 계산하기 위해 첫 번째 변수에 호가 단위로 계산할 지 비율(%)로 계산할 지 입력합니다.

     

    두 번째 변수에는 현재 코인의 가격을 입력 합니다.

     

    마지막 변수에는 변화 단위를 입력 합니다. 예를 들어 5를 입력한다면 첫 번째 변수에 호가 단위(H)를 입력한 경우 5개 위의 호가를 리턴하고 비율(R)을 입력한 경우에는 5% 위의 호가를 리턴하게 됩니다.

     

    최종 코드

    공통모듈(upbit.py)

    import time
    import logging
    import requests
    import jwt
    import uuid
    import hashlib
     
    from urllib.parse import urlencode
    from decimal import Decimal
     
    # Keys
    access_key = '업비트에서 발급받은 Access Key'
    secret_key = '업비트에서 발급반은 Secret Key'
    server_url = 'https://api.upbit.com'
     
    # -----------------------------------------------------------------------------
    # - Name : set_loglevel
    # - Desc : 로그레벨 설정
    # - Input
    #   1) level : 로그레벨
    #     1. D(d) : DEBUG
    #     2. E(e) : ERROR
    #     3. 그외(기본) : INFO
    # - Output
    # -----------------------------------------------------------------------------
    def set_loglevel(level):
        try:
     
            # ---------------------------------------------------------------------
            # 로그레벨 : DEBUG
            # ---------------------------------------------------------------------
            if level.upper() == "D":
                logging.basicConfig(
                    format='[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d]:%(message)s',
                    datefmt='%Y/%m/%d %I:%M:%S %p',
                    level=logging.DEBUG
                )
            # ---------------------------------------------------------------------
            # 로그레벨 : ERROR
            # ---------------------------------------------------------------------
            elif level.upper() == "E":
                logging.basicConfig(
                    format='[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d]:%(message)s',
                    datefmt='%Y/%m/%d %I:%M:%S %p',
                    level=logging.ERROR
                )
            # ---------------------------------------------------------------------
            # 로그레벨 : INFO
            # ---------------------------------------------------------------------
            else:
                # -----------------------------------------------------------------------------
                # 로깅 설정
                # 로그레벨(DEBUG, INFO, WARNING, ERROR, CRITICAL)
                # -----------------------------------------------------------------------------
                logging.basicConfig(
                    format='[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d]:%(message)s',
                    datefmt='%Y/%m/%d %I:%M:%S %p',
                    level=logging.INFO
                )
     
        # ----------------------------------------
        # Exception Raise
        # ----------------------------------------
        except Exception:
            raise
            
    # -----------------------------------------------------------------------------
    # - Name : get_targetprice
    # - Desc : 호가단위 금액 계산
    # - Input
    #   1) cal_type : H:호가로, R:비율로
    #   2) st_price : 기준가격
    #   3) chg_val : 변화단위
    # - Output
    #   1) rtn_price : 계산된 금액
    # -----------------------------------------------------------------------------
    def get_targetprice(cal_type, st_price, chg_val):
        try:
            # 계산된 가격
            rtn_price = st_price
    
            # 호가단위로 계산
            if cal_type.upper() == "H":
    
                for i in range(0, abs(int(chg_val))):
    
                    hoga_val = get_hoga(rtn_price)
    
                    if Decimal(str(chg_val)) > 0:
                        rtn_price = Decimal(str(rtn_price)) + Decimal(str(hoga_val))
                    elif Decimal(str(chg_val)) < 0:
                        rtn_price = Decimal(str(rtn_price)) - Decimal(str(hoga_val))
                    else:
                        break
    
            # 비율로 계산
            elif cal_type.upper() == "R":
    
                while True:
    
                    # 호가단위 추출
                    hoga_val = get_hoga(st_price)
    
                    if Decimal(str(chg_val)) > 0:
                        rtn_price = Decimal(str(rtn_price)) + Decimal(str(hoga_val))
                    elif Decimal(str(chg_val)) < 0:
                        rtn_price = Decimal(str(rtn_price)) - Decimal(str(hoga_val))
                    else:
                        break
    
                    if Decimal(str(chg_val)) > 0:
                        if Decimal(str(rtn_price)) >= Decimal(str(st_price)) * (
                                Decimal(str(1)) + (Decimal(str(chg_val))) / Decimal(str(100))):
                            break
                    elif Decimal(str(chg_val)) < 0:
                        if Decimal(str(rtn_price)) <= Decimal(str(st_price)) * (
                                Decimal(str(1)) + (Decimal(str(chg_val))) / Decimal(str(100))):
                            break
    
            return rtn_price
    
        # ----------------------------------------
        # Exception Raise
        # ----------------------------------------
        except Exception:
            raise
    
    
    # -----------------------------------------------------------------------------
    # - Name : get_hoga
    # - Desc : 호가 금액 계산
    # - Input
    #   1) cur_price : 현재가격
    # - Output
    #   1) hoga_val : 호가단위
    # -----------------------------------------------------------------------------
    def get_hoga(cur_price):
        try:
    
            # 호가 단위
            if Decimal(str(cur_price)) < 10:
                hoga_val = 0.01
            elif Decimal(str(cur_price)) < 100:
                hoga_val = 0.1
            elif Decimal(str(cur_price)) < 1000:
                hoga_val = 1
            elif Decimal(str(cur_price)) < 10000:
                hoga_val = 5
            elif Decimal(str(cur_price)) < 100000:
                hoga_val = 10
            elif Decimal(str(cur_price)) < 500000:
                hoga_val = 50
            elif Decimal(str(cur_price)) < 1000000:
                hoga_val = 100
            elif Decimal(str(cur_price)) < 2000000:
                hoga_val = 500
            else:
                hoga_val = 1000
    
            return hoga_val
    
        # ----------------------------------------
        # Exception Raise
        # ----------------------------------------
        except Exception:
            raise

     

    모듈 호출 예시

    import os
    import sys
    import logging
    import traceback
    
    # 공통 모듈 Import
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    from lib import upbit as upbit  # noqa
    
    # -----------------------------------------------------------------------------
    # - Name : main
    # - Desc : 메인
    # -----------------------------------------------------------------------------
    if __name__ == '__main__':
    
        # noinspection PyBroadException
        try:
    
            print("***** USAGE ******")
            print("[1] 로그레벨(D:DEBUG, E:ERROR, 그외:INFO)")
    
            # 로그레벨(D:DEBUG, E:ERROR, 그외:INFO)
            upbit.set_loglevel('I')
    
            # ---------------------------------------------------------------------
            # Logic Start!
            # ---------------------------------------------------------------------
            rtn_hoga = upbit.get_hoga('1000000')
            logging.info(rtn_hoga)
    
            rtn_target_price_hoga = upbit.get_targetprice('H', '1000000', '10')
            rtn_target_price_rate = upbit.get_targetprice('R', '1000000', '10')
            logging.info(rtn_target_price_hoga)
            logging.info(rtn_target_price_rate)
    
        except KeyboardInterrupt:
            logging.error("KeyboardInterrupt Exception 발생!")
            logging.error(traceback.format_exc())
            sys.exit(1)
    
        except Exception:
            logging.error("Exception 발생!")
            logging.error(traceback.format_exc())
            sys.exit(1)
    

     

    실행 결과

    ① 100만원 금액에 해당하는 호가를 출력

    get_hoga('1000000') 을 호출한 결과 100만원의 호가인 500원이 리턴 되었습니다.

     

    ② 100만원 금액 기준 10개 위의 호가를 계산해 지정가를 출력

    get_targetprice('H', '1000000', '10')로 호출하여 100만원의 호가 단위인 500원을 계산하고 10개 위의 호가인 5000원을 더해 1,005,000원이 리턴 되었습니다.

     

    ③ 100만원 금액 기준 10% 위의 호가를 계산해 지정가를 출력

    get_targetprice('R', '1000000', '10')로 호출하여 100만원의 10% 상승 가격에 대한 호가인 1,100,000원을 리턴하였습니다.

     

    활용 방법

    호가 계산 로직을 활용하여 아래와 같은 로직을 구현할 수 있습니다.

     

    ① 코인을 매수한 후에 매수 평균가격보다 3호가 높은 가격을 계산해 지정가 매도를 거는 로직에 활용할 수 있습니다.

    ② 현재 매수 호가 보다 1호가 낮은 금액으로 지정가 매수를 거는 로직을 만들 때 활용할 수 있습니다.

    반응형