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

(Python) 업비트 자동 매매 프로그램 만들기(3) - 주문 하기

by 미니몬 2023. 8. 16.

목차

    728x90
    반응형

    Summary

    이번 게시물에서는 업비트 사이트에서 매수/매도 주문을 하거나 주문을 취소하는 방법을 알아보겠습니다.
    주문하는 것은 입력값과 응답값을 잘 이해해서 사용해야 하므로 두 가지를 같이 설명하겠습니다.

     

    그 전에

    알아야 할 사항이 있습니다.

    매수 / 매도 주문의 경우 시장가 주문지정가 주문 두 가지로 나뉘는데요.

    시장가 주문은 현재 체결 가능한 가격으로 즉시 체결 되고,

    지정가 주문은 원하는 가격으로 주문을 걸어서 해당 가격이 되면 체결됩니다.

     

    거래함에 있어서 사실 이 것만 알면 큰 문제는 없으나 거래 이용에 대한 좀 더 자세한 사항은 아래 페이지를 참고해주세요.

     

    [업비트-거래 이용 안내] 주소

    https://upbitcs.zendesk.com/hc/ko/articles/4403838454809-%EA%B1%B0%EB%9E%98-%EC%9D%B4%EC%9A%A9-%EC%95%88%EB%82%B4

     

     

     

     

    그리고 지난번과 마찬가지로 아래 코드는 기재한 뒤 필요한 기능들은 함수로 구현하도록 하겠습니다.

    import pyupbit
    
    ### 거래할 코인 symbol
    coin = "KRW-XRP" 
    
    ### API 키 파일 참조
    with open("key.txt") as f:
        access_key, secret_key = [line.strip() for line in f.readlines()]
    
    ### 업비트 연동
    upbit = pyupbit.Upbit(access_key, secret_key)

     


    1) 시장가 매수 주문

    • 시장가 매수 : 현재 체결가능한 가격(시장가)으로 매수하는 주문
      upbit.buy_market_order(ticker, buy_amount)

    • 시장가 매수 주문은 두 가지 입력값이 필요
      ticker - 거래할 화폐
      buy_amount - 구매할 금액
      (거래 최소 금액은 5,000원 인데, 5,000원으로 주문 했을 시 에러가 발생하는 경우가 있어 10,000원으로 함)
    # 시장가 매수
    def order_buy_market(ticker, buy_amount):  
        """
        : ticker : 코인 이름
        : buy_amount : 매수할 금액
        """
        if buy_amount < 5000:  
            print("amount is better than 5000")
            return 0
        try:
            res = upbit.buy_market_order(ticker,buy_amount)
            if 'error' in res:
                print(res)
                res = 0
                return res
            print(res)
        except Exception as e:
            res = 0
            print(e)
        return res
        
    # 매수 함수 호출
    order_buy_market(coin, 10000)

    위 코드에서 살펴볼 부분은 세가지 정도 입니다.

    1. 거래금액이 5000원 미만인 경우 order_buy_market()을 종료

    2. 업비트 사이트와 통신이 정상적인 경우 try 구문 실행, 통신 실패시 except 구문이 실행

    3. try 구문이 실행되었을 때 주문이 정상적으로 요청되었음에도 에러가 발생한 경우 에러 출력 후 종료

    • 응답값은 uuid 값을 포함한 딕셔너리 형태
    {
     'uuid': '4f2c1ac8-6256-4db0-9047-012d35d7adc2',
     'side': 'bid',
     'ord_type': 'price',
     'price': '10000',
     'state': 'wait',
     'market': 'KRW-XRP',
     'created_at': '2023-03-24T13:00:18.356888+09:00',
     'reserved_fee': '5',
     'remaining_fee': '5',
     'paid_fee': '0',
     'locked': '10005',
     'executed_volume': '0',
     'trades_count': 0
    }

     


    시장가 매수 주문의 경우 딱히 확인해야 할 정보가 있지 않은 거 같네요.

    각 필드의 설명은 글 마지막에 같이 하도록 하겠습니다.

     

    실제로 정상적으로 주문이 완료되면 거래내역에서 

    체결된 정보를 확인 할 수 있습니다.

     

     

     

     

     

     

     

     


    2) 시장가 매도 주문

    • 시장가 매도 : 현재 체결가능한 가격(시장가)으로 매도하는 주문
      upbit.sell_market_order(ticker, volume)

    • 시장가 매도 주문은 두 가지 입력값이 필요
      ticker - 거래할 화폐
      volume - 판매할 수량
    # 시장가 매도
    def order_sell_market(ticker, volume):
        """
        : ticker : 코인 이름
        : volume : 매도할 수량
        """
        try:
            res = upbit.sell_market_order(ticker, volume)
            if 'error' in res:
                print(res)
                res = 0
                return res
            print(res)
        except Exception as e:
            print(e)
            res = 0 
        return res
    
    # 현재 거래가능한 보유 코인수량 조회
    volume = get_balance_coin(coin)
    
    # 매도 함수 호출
    order_sell_market(coin, volume)

     

    • 응답값은 uuid 값을 포함한 딕셔너리 형태
    {
     'uuid': '76e59439-9d86-4889-a469-e7a015a4434a', 
     'side': 'ask', 
     'ord_type': 'market', 
     'state': 'wait', 
     'market': 'KRW-XRP', 
     'created_at': '2023-03-21T21:43:01.271654+09:00', 
     'volume': '38.91109496', 
     'remaining_volume': '38.91109496', 
     'reserved_fee': '0', 
     'remaining_fee': '0', 
     'paid_fee': '0', 
     'locked': '38.91109496', 
     'executed_volume': '0', 
     'trades_count': 0
    }

     

     

    사실 시장가 주문은 정상적으로 실행되는 즉시 체결 되기에 필요한 정보는 크게 없고,

    주문 처리가 잘 되었는지만 확인하시면 됩니다.

     

    잘 되었는지는 'res' 변수에 담긴 결과로도 확인할 수 있고, 업비트 사이트의 알림, 거래내역에서 확인할 수 있습니다.

     


    3) 지정가 매수 주문

    • 지정가 매수 : 지정한 가격(지정가)으로 매수하는 주문
      upbit.sell_market_order(ticker, volume)

    • 지정가 매수 주문은 세 가지 입력값이 필요
      ticker - 거래할 화폐
      price - 매수할 가격
      volume - 매수할 수량
    # 지정가 매수
    def order_buy_limit(ticker, price, volume):
        """
        : ticker : 코인 이름
        : price : 매수할 가격
        : volume : 매수할 수량
        """
        try:
            res = upbit.buy_limit_order(ticker, price, volume)
            if 'error' in res:
                print(res)
                res = 0
                return res
            print(res)
        except Exception as e:
            print(e)
            res = 0 
        return res
    
    # 지정가 매수 호출 리플을 100원에 100개 매수 주문
    order_buy_limit(coin, 100, 100)

     

    • 지정가 매수 주문시 중요하게 봐야할 정보는 아래와 같습니다.
      uuid - 주문에 대한 식별값(uniq 값)으로 주문 취소 및 주문 정보 조회시 사용
      state - 주문의 상태를 체크하여 주문이 정상적으로 처리 되었는지 확인
    {
     'uuid': '66235586-b03e-4c0f-9589-fe95d609d07a',
     'side': 'bid',
     'ord_type': 'limit',
     'price': '100',
     'state': 'wait',
     'market': 'KRW-XRP',
     'created_at': '2023-08-16T14:57:37.989658+09:00',
     'volume': '100',
     'remaining_volume': '100',
     'reserved_fee': '5',
     'remaining_fee': '5',
     'paid_fee': '0',
     'locked': '10005',
     'executed_volume': '0',
     'trades_count': 0
    }

     


    4) 지정가 매도 주문

    • 지정가 매도 : 지정한 가격(지정가)으로 매도하는 주문
      upbit.sell_limit_order(ticker, price, volume)

    • 지정가 매수 주문은 세 가지 입력값이 필요
      ticker - 거래할 화폐
      price - 매도할 가격
      volume - 매도할 수량
    # 지정가 매도
    def order_sell_limit(ticker, price, volume):
        """
        : ticker : 코인 이름
        : price : 매도할 가격
        : volume : 매도할 수량
        """
        try:
            res = upbit.sell_limit_order(ticker, price, volume)    
            if 'error' in res:
                print(res)
                res = 0
                return res
            print(res)
            res = 1
        except Exception as e:
            print(e)
            res = 0
        return res
        
        
    # 지정가 매도 주문 호출 - 리플 1000원에 100개 판매 주문
    order_sell_limit(coin, 1000, 100)

     

    • 응답값은 uuid 값을 포함한 딕셔너리 형태
      지정가 매수 주문과 마찬가지로 uuid 값과 state 두 가지만 확인하면 됩니다.
    {
     'uuid': '54f2d151-9e45-4e1f-bf75-96082b9efd64',
     'side': 'ask',
     'ord_type': 'limit',
     'price': '1000',
     'state': 'wait',
     'market': 'KRW-XRP',
     'created_at': '2023-08-16T15:15:59.467948+09:00',
     'volume': '10',
     'remaining_volume': '10',
     'reserved_fee': '0',
     'remaining_fee': '0',
     'paid_fee': '0',
     'locked': '10',
     'executed_volume': '0',
     'trades_count': 0
     }

     


    5) (미체결)주문 취소

    • 주문 취소 는 당연히 미체결 상태, 즉 state 값이 wait 인 주문에 대해서 가능
      upbit.cancel_order(uuid)

      미체결 상태인 주문을 취소하기 위해서는 uuid를 알아야 하는데
      이는 이전 게시물에서 알아본 get_order_info() 함수를 통해 uuid를 검색해서 취소할 수 있습니다.
      이 코드에서는 미체결 주문이 1건 이상 없다는 가정하에 가장 최근 주문의 uuid만 조회하여 주문을 취소합니다.
    def get_order_info(info):
        # 서버와 소켓 통신이 정상적이면 try, 비정상적이면 except 구문 실행
        try:
            res = upbit.get_order(info)
            
            # 통신은 정상이고, error 를 응답받은 경우
            if "error" in res[0]:
                res = 0
            else:
                # 주문 내역이 여러개인 경우 모두 출력
                for i in range(0,len(res)):
                    res = res[i] # 조회된 주문내역 중 가장 마지막(최근) 정보 리턴
        except Exception as e:
                res = 0
                print(e)
        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
    
    
    ret = order_cancel(coin)
    if ret == 0:
        print('error')

     

    • 응답값은 uuid 값을 포함한 딕셔너리 형태
    {
     'uuid': '54f2d151-9e45-4e1f-bf75-96082b9efd64',
     'side': 'ask',
     'ord_type': 'limit',
     'price': '1000',
     'state': 'wait',
     'market': 'KRW-XRP',
     'created_at': '2023-08-16T15:15:59+09:00',
     'volume': '10',
     'remaining_volume': '10',
     'reserved_fee': '0',
     'remaining_fee': '0',
     'paid_fee': '0',
     'locked': '10',
     'executed_volume': '0',
     'trades_count': 0
     }

     

     

     

    응답값들은 딕셔너리 형태로 되어 있으며, 각 필드의 의미는 아래와 같습니다.

    항목(키) 설명(값)
    uuid 주문의 고유 식별자
    side 주문 타입 ('ask'는 매도 / 'bid'는 매수 주문을 의미)
    ord_type 주문 유형 (예: 'limit'는 지정가 주문을 의미 / 'market'은 시장가 주문을 의미)
    price 주문 가격
    state 주문 상태 (예: 'wait'는 대기 중인 주문을 의미 / 'done'은 완료된 주문을 의미)
    market 주문이 발생한 시장 (예: 'KRW-XRP'는 한국 원화로 리플을 거래하는 시장을 의미)
    created_at 주문 생성 시간
    volume 주문 수량
    remaining_volume 남아있는 주문량
    reserved_fee 예약된 수수료
    remaining_fee 남아있는 수수료
    paid_fee 지불된 수수료
    locked locking 금액 또는 자산
    executed_volume 실행된 주문량
    trades_count 거래 횟수

     


    이상으로 업비트 사이트에서 직접 주문하는 방법과 취소하는 방법을 알아 보았습니다.

    이제는 실제 내 현금이 들어가기 때문에 조심 조심 하게 되네요.

     

    이렇게 각종 정보를 조회하는 방법과, 주문하는 방법은 알았으니,

    앞으로는 언제 얼마나 매수/매도 할지에 대한 구조만 만들면 되겠네요. 하하하;;;

    사실 가장 어려운 부분이 남았다고 보시면 됩니당..

     

    앞으로 차차 여러 전략들을 같이 알아보기로 하고,

    다음 게시물에서는 일단 전체적인 코드를 취합해 하나로 묶는 작업을 해보도록 하겠습니다.

    728x90
    반응형