[실무 강의] 파이썬으로 업비트(Upbit) API 연동: 실시간 코인 가격 추적 및 목표가 도달 시 자동 매수/매도 주문 스크립트 만들기 완벽 마스터 튜토리얼

학습 목표

여러분은 이 강의를 통해 파이썬을 활용하여 국내 대표 암호화폐 거래소인 업비트(Upbit)의 API를 완벽하게 연동하는 방법을 학습하게 됩니다. 단순히 가격 정보를 조회하는 것을 넘어, 실시간으로 특정 코인의 가격을 추적하고, 미리 설정한 목표가에 도달했을 때 자동으로 매수 또는 매도 주문을 실행하는 스크립트를 직접 구축하게 될 것입니다. 이 실습을 통해 API 연동의 핵심 원리를 이해하고, 실제 자동 트레이딩 시스템 구축의 기반을 다질 수 있습니다. 2026년 현재, 이러한 자동화 기술은 빠르게 변화하는 시장에서 여러분의 경쟁력을 한층 높여줄 것입니다.

사전 준비 사항

본격적인 실습에 앞서, 원활한 학습을 위한 개발 환경을 먼저 구축해야 합니다. 다음 권장 사항을 따르시면 문제없이 실습을 진행할 수 있습니다.

  • 권장 개발 환경: Visual Studio Code (VS Code)
  • 권장 운영체제(OS): Windows 10/11, macOS Ventura 이상, 또는 Ubuntu 22.04 LTS 이상
  • 권장 파이썬(Python) 버전: Python 3.10 이상 (2026년 기준 최신 안정 버전)
  • 필수 설치 라이브러리:
pip install pyupbit PyJWT requests pandas uuid

pyupbit 라이브러리는 업비트 API를 파이썬에서 편리하게 사용할 수 있도록 도와주는 강력한 래퍼(wrapper)입니다. PyJWT는 API 인증에 필요한 JWT 토큰 생성에 사용되며, requests는 HTTP 통신을 담당합니다. pandas는 데이터 처리에 유용하며, uuid는 고유한 요청 식별자 생성에 사용됩니다. 터미널(또는 명령 프롬프트)을 열고 위 명령어를 실행하여 필요한 라이브러리를 설치해 주세요.

단계별 실습 과정

1단계: Upbit API 키 발급 및 설정

업비트 API를 사용하기 위해서는 먼저 API 키를 발급받아야 합니다. 업비트 웹사이트에 로그인 후 ‘MY’ 페이지에서 ‘Open API 관리’ 메뉴로 이동합니다. 이곳에서 ‘API Key 발급받기’를 클릭하고, 필요한 권한(조회 권한은 필수, 주문 권한은 자동 매매를 위해 필요)을 선택한 후 발급받습니다. 이때 발급되는 ‘Access Key’와 ‘Secret Key’는 매우 중요하며, 외부에 노출되지 않도록 각별히 주의해야 합니다. 이 키들은 여러분의 자산에 직접적인 영향을 미칠 수 있으므로, 반드시 안전하게 관리해야 합니다. 발급받은 키는 별도의 파일(예: config.py)에 저장하여 관리하는 것이 좋습니다.

# config.py 예시UPBIT_ACCESS_KEY = "YOUR_UPBIT_ACCESS_KEY"UPBIT_SECRET_KEY = "YOUR_UPBIT_SECRET_KEY"

실제 사용 시에는 환경 변수나 더 안전한 방법으로 관리하는 것을 권장합니다.

2단계: Python 환경 설정 및 필수 라이브러리 설치

이전 ‘사전 준비 사항’에서 안내드린 대로 VS Code를 열고 새로운 파이썬 프로젝트 폴더를 생성합니다. 해당 폴더 내에서 터미널을 열고 다음 명령어를 다시 한번 실행하여 모든 라이브러리가 올바르게 설치되었는지 확인합니다. 이미 설치했다면 ‘Requirement already satisfied’ 메시지가 나타날 것입니다.

pip install pyupbit PyJWT requests pandas uuid

이 과정은 파이썬 스크립트가 업비트 API와 통신하는 데 필요한 모든 도구를 갖추는 단계입니다.

3단계: Upbit API 연동을 위한 기본 모듈 작성 (pyupbit 활용)

pyupbit 라이브러리는 Upbit API 연동을 매우 간편하게 해줍니다. 별도의 JWT 토큰 생성 로직을 직접 구현할 필요 없이, pyupbit.Upbit 객체를 통해 쉽게 인증하고 API를 호출할 수 있습니다. config.py 파일에 저장한 키를 불러와 pyupbit 객체를 초기화합니다.

# upbit_api_client.pyimport pyupbitfrom config import UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY# Upbit 객체 초기화upbit = pyupbit.Upbit(UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY)def get_upbit_client():    """초기화된 Upbit 클라이언트 객체를 반환합니다."""    return upbitdef get_account_balances():    """현재 계좌 잔고를 조회합니다."""    try:        balances = upbit.get_balances()        return balances    except Exception as e:        print(f"잔고 조회 실패: {e}")        return Noneif __name__ == "__main__":    print("Upbit API 클라이언트 모듈 테스트...")    my_balances = get_account_balances()    if my_balances:        print("현재 잔고:")        for balance in my_balances:            print(f"  {balance['currency']}: {balance['balance']} (locked: {balance['locked']})")    else:        print("잔고 정보를 가져올 수 없습니다. API 키를 확인하세요.")

위 코드를 upbit_api_client.py로 저장하고 실행하여 여러분의 계좌 잔고가 올바르게 출력되는지 확인해 보세요. 이는 API 키가 제대로 설정되었고 pyupbit가 정상적으로 작동하는지 검증하는 중요한 단계입니다.

4단계: 실시간 코인 가격 조회 스크립트 작성

이제 특정 코인의 실시간 가격을 조회하는 스크립트를 작성해 보겠습니다. pyupbit.get_current_price() 함수를 사용하면 간편하게 현재가를 가져올 수 있습니다. 특정 코인(예: 비트코인 – ‘KRW-BTC’)의 가격을 주기적으로 조회하여 출력하는 로직을 만들어 봅시다.

# price_tracker.pyimport timeimport pyupbit # pyupbit를 직접 임포트하여 사용def track_coin_price(ticker, interval_sec=5):    """    지정된 코인의 실시간 가격을 추적하고 출력합니다.    :param ticker: 추적할 코인의 티커 (예: 'KRW-BTC')    :param interval_sec: 가격 조회 간격 (초)    """    print(f"[실시간 가격 추적 시작] 코인: {ticker}, 간격: {interval_sec}초")    try:        while True:            current_price = pyupbit.get_current_price(ticker)            if current_price:                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {ticker} 현재가: {current_price:,.0f} KRW")            else:                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {ticker} 가격 정보를 가져올 수 없습니다.")            time.sleep(interval_sec)    except KeyboardInterrupt:        print("[실시간 가격 추적 종료]")    except Exception as e:        print(f"가격 추적 중 오류 발생: {e}")if __name__ == "__main__":    # 비트코인(BTC) 가격을 5초마다 추적    track_coin_price("KRW-BTC", 5)

이 스크립트를 실행하면 5초마다 비트코인의 현재 가격이 터미널에 출력되는 것을 확인할 수 있습니다. Ctrl+C를 눌러 스크립트를 중지할 수 있습니다.

5단계: 목표가 도달 시 자동 매수/매도 로직 구현

이제 실시간 가격 추적에 자동 매수/매도 로직을 추가해 보겠습니다. 특정 목표가(target_price)와 매수할 금액(buy_amount), 또는 매도할 수량(sell_volume)을 설정하고, 현재 가격이 목표가에 도달하면 자동으로 주문을 실행하도록 구현합니다. 실제 거래 시에는 소액으로 충분히 테스트하거나 모의 투자를 활용하는 것을 강력히 권장합니다.

# auto_trader_example.pyimport timeimport pyupbitfrom config import UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY # API 키 불러오기# Upbit 클라이언트 초기화upbit_client = pyupbit.Upbit(UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY)# 설정 값 (실제 사용 시에는 config.py나 환경 변수로 관리)TARGET_TICKER = "KRW-ETH" # 이더리움BUY_TARGET_PRICE = 3_000_000 # 매수 목표가 (300만원)SELL_TARGET_PRICE = 3_500_000 # 매도 목표가 (350만원)BUY_AMOUNT_KRW = 5000 # 매수할 원화 금액 (최소 주문 금액 5000원 이상)SELL_VOLUME = 0.001 # 매도할 코인 수량 (예시)CHECK_INTERVAL_SEC = 10 # 가격 확인 간격# 거래 상태 플래그 (중복 주문 방지)is_bought = Falseis_sold = Falsedef auto_trade_strategy_example():    global is_bought, is_sold    print(f"[자동 트레이딩 시작] 코인: {TARGET_TICKER}")    print(f"  매수 목표가: {BUY_TARGET_PRICE:,.0f} KRW, 매도 목표가: {SELL_TARGET_PRICE:,.0f} KRW")    print(f"  매수 금액: {BUY_AMOUNT_KRW:,.0f} KRW, 매도 수량: {SELL_VOLUME}개")    try:        while True:            current_price = pyupbit.get_current_price(TARGET_TICKER)            if not current_price:                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {TARGET_TICKER} 가격 정보를 가져올 수 없습니다. 재시도합니다.")                time.sleep(CHECK_INTERVAL_SEC)                continue            print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {TARGET_TICKER} 현재가: {current_price:,.0f} KRW")            # 매수 로직            if not is_bought and current_price <= BUY_TARGET_PRICE:                print(f"[매수 조건 충족] 현재가({current_price:,.0f} KRW) <= 매수 목표가({BUY_TARGET_PRICE:,.0f} KRW)")                try:                    # 실제 매수 주문을 원할 경우 아래 주석을 해제하고 사용하세요.                    # resp = upbit_client.buy_market_order(TARGET_TICKER, BUY_AMOUNT_KRW)                    # print(f"매수 주문 시도: {resp}")                    print(f"[모의 매수] {TARGET_TICKER} {BUY_AMOUNT_KRW}원 매수 주문.")                    is_bought = True # 매수 완료 플래그 설정 (중복 매수 방지)                except Exception as e:                    print(f"매수 주문 실패: {e}")            # 매도 로직            if not is_sold and current_price >= SELL_TARGET_PRICE:                print(f"[매도 조건 충족] 현재가({current_price:,.0f} KRW) >= 매도 목표가({SELL_TARGET_PRICE:,.0f} KRW)")                try:                    # 실제 매도 주문을 원할 경우 아래 주석을 해제하고 사용하세요.                    # resp = upbit_client.sell_market_order(TARGET_TICKER, SELL_VOLUME)                    # print(f"매도 주문 시도: {resp}")                    print(f"[모의 매도] {TARGET_TICKER} {SELL_VOLUME}개 매도 주문.")                    is_sold = True # 매도 완료 플래그 설정 (중복 매도 방지)                except Exception as e:                    print(f"매도 주문 실패: {e}")            time.sleep(CHECK_INTERVAL_SEC)    except KeyboardInterrupt:        print("[자동 트레이딩 종료]")    except Exception as e:        print(f"자동 트레이딩 중 예상치 못한 오류 발생: {e}")if __name__ == "__main__":    auto_trade_strategy_example()

이 스크립트는 TARGET_TICKER에 지정된 코인의 가격을 CHECK_INTERVAL_SEC 간격으로 확인하며, BUY_TARGET_PRICE보다 낮거나 같으면 매수 주문을, SELL_TARGET_PRICE보다 높거나 같으면 매도 주문을 시도합니다. 현재는 실제 주문 코드가 주석 처리되어 있으므로, 반드시 충분히 이해하고 테스트한 후에 주석을 해제하여 사용해야 합니다.

6단계: 전체 스크립트 통합 및 자동화

앞서 작성한 요소들을 활용하여 전체 자동화 스크립트를 완성합니다. 실제 환경에서는 여러 코인을 동시에 추적하거나, 더 복잡한 전략을 구현할 수 있습니다. 이 예제에서는 단일 코인에 대한 간단한 목표가 매매 전략을 통합하여 보여줍니다.

# main_autotrade.pyimport timeimport pyupbitfrom config import UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY# Upbit 클라이언트 초기화upbit = pyupbit.Upbit(UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY)# --- 트레이딩 설정 ---TARGET_TICKER = "KRW-XRP" # 리플BUY_TARGET_PRICE = 800 # 매수 목표가 (800원)SELL_TARGET_PRICE = 950 # 매도 목표가 (950원)BUY_AMOUNT_KRW = 10000 # 매수할 원화 금액 (최소 주문 금액 5000원 이상)SELL_VOLUME_RATIO = 0.5 # 보유 코인의 몇 %를 매도할지 (0.5 = 50%)CHECK_INTERVAL_SEC = 5 # 가격 확인 간격# 거래 상태 플래그 (중복 주문 방지 및 매수/매도 상태 추적)current_holding_state = "NONE" # "NONE", "HOLDING_COIN"def get_krw_balance():    """현재 보유 KRW 잔고를 조회합니다."""    balances = upbit.get_balances()    for balance in balances:        if balance['currency'] == 'KRW':            return float(balance['balance'])    return 0.0def get_coin_balance(ticker):    """특정 코인의 보유 수량을 조회합니다."""    balances = upbit.get_balances()    for balance in balances:        if balance['currency'] == ticker.replace('KRW-', ''):            return float(balance['balance'])    return 0.0def execute_trade_strategy():    global current_holding_state    print(f"\n[자동 트레이딩 시스템 가동] {time.strftime('%Y-%m-%d %H:%M:%S')}")    print(f"  대상 코인: {TARGET_TICKER}")    print(f"  매수 목표가: {BUY_TARGET_PRICE:,.0f} KRW, 매도 목표가: {SELL_TARGET_PRICE:,.0f} KRW")    print(f"  매수 금액: {BUY_AMOUNT_KRW:,.0f} KRW, 매도 비율: {SELL_VOLUME_RATIO*100}%")    try:        while True:            current_price = pyupbit.get_current_price(TARGET_TICKER)            krw_balance = get_krw_balance()            coin_balance = get_coin_balance(TARGET_TICKER)            if not current_price:                print(f"[{time.strftime('%H:%M:%S')}] {TARGET_TICKER} 가격 정보를 가져올 수 없습니다.")                time.sleep(CHECK_INTERVAL_SEC)                continue            print(f"[{time.strftime('%H:%M:%S')}] {TARGET_TICKER} 현재가: {current_price:,.0f} KRW | KRW 잔고: {krw_balance:,.0f} | {TARGET_TICKER.replace('KRW-', '')} 잔고: {coin_balance:.4f} | 상태: {current_holding_state}")            # 매수 로직            if current_holding_state == "NONE" and current_price <= BUY_TARGET_PRICE:                if krw_balance >= BUY_AMOUNT_KRW:                    print(f"[매수 조건 충족] 현재가({current_price:,.0f} KRW) <= 매수 목표가({BUY_TARGET_PRICE:,.0f} KRW)")                    try:                        # 실제 매수 주문 (시장가 매수)                        # resp = upbit.buy_market_order(TARGET_TICKER, BUY_AMOUNT_KRW)                        # print(f"매수 주문 시도: {resp}")                        print(f"[모의 매수] {TARGET_TICKER} {BUY_AMOUNT_KRW}원 매수 주문.")                        current_holding_state = "HOLDING_COIN" # 매수 완료 상태로 변경                        print(f"-> 상태 변경: {current_holding_state}")                    except Exception as e:                        print(f"매수 주문 실패: {e}")                else:                    print(f"[경고] KRW 잔고 부족! (보유: {krw_balance:,.0f}, 필요: {BUY_AMOUNT_KRW:,.0f})")            # 매도 로직            elif current_holding_state == "HOLDING_COIN" and current_price >= SELL_TARGET_PRICE:                if coin_balance > 0:                    sell_volume = coin_balance * SELL_VOLUME_RATIO                    if sell_volume * current_price < 5000: # 최소 주문 금액 확인                        print(f"[경고] 매도할 {TARGET_TICKER.replace('KRW-', '')} 수량({sell_volume:.4f}개)이 최소 주문 금액(5000원) 미달입니다. 매도 보류.")                    else:                        print(f"[매도 조건 충족] 현재가({current_price:,.0f} KRW) >= 매도 목표가({SELL_TARGET_PRICE:,.0f} KRW)")                        try:                            # 실제 매도 주문 (시장가 매도)                            # resp = upbit.sell_market_order(TARGET_TICKER, sell_volume)                            # print(f"매도 주문 시도: {resp}")                            print(f"[모의 매도] {TARGET_TICKER} {sell_volume:.4f}개 매도 주문.")                            # 매도 후 잔고를 다시 확인하여 상태 업데이트                            time.sleep(2) # 주문 처리 대기                            updated_coin_balance = get_coin_balance(TARGET_TICKER)                            if updated_coin_balance <= 0.0001: # 거의 전부 매도된 경우 (잔고 오차 감안)                                current_holding_state = "NONE" # 모든 코인 매도 후 초기 상태로 복귀                            print(f"-> 상태 변경: {current_holding_state}")                        except Exception as e:                            print(f"매도 주문 실패: {e}")                else:                    print(f"[경고] 매도할 {TARGET_TICKER.replace('KRW-', '')} 잔고가 없습니다.")            time.sleep(CHECK_INTERVAL_SEC)    except KeyboardInterrupt:        print("[자동 트레이딩 시스템 종료]")    except Exception as e:        print(f"예상치 못한 오류 발생: {e}")if __name__ == "__main__":    execute_trade_strategy()

main_autotrade.py 스크립트는 config.py에서 API 키를 직접 불러와 pyupbit 클라이언트를 초기화하고, 지정된 코인에 대한 매수/매도 전략을 실행합니다. get_krw_balanceget_coin_balance 함수를 추가하여 현재 잔고를 확인하고, current_holding_state 변수를 통해 현재 거래 상태를 추적하여 중복 주문을 방지합니다. 실제 거래를 시작하기 전에 반드시 BUY_AMOUNT_KRW를 소액으로 설정하고, 주석 처리된 실제 주문 코드를 해제하기 전에 충분히 검증해야 합니다. 이 스크립트의 실행은 python main_autotrade.py 명령어로 가능합니다.

결과 확인

작성된 스크립트(main_autotrade.py)를 실행하면, 터미널에 실시간 코인 가격과 현재 잔고 정보, 그리고 매수/매도 조건 충족 여부가 지속적으로 출력됩니다. 만약 여러분이 설정한 목표가에 도달하면, 스크립트는 설정된 로직에 따라 매수 또는 매도 주문을 시도하고, 그 결과를 터미널에 메시지로 표시할 것입니다. 실제 주문이 성공했다면, 업비트 거래소 앱이나 웹사이트에서 ‘거래 내역’을 통해 주문이 정상적으로 체결되었는지 확인할 수 있습니다. 모의 주문 상태에서는 ‘모의 매수/매도’ 메시지만 출력되며 실제 거래는 발생하지 않습니다.

주의사항:
자동 매매 스크립트는 24시간 작동해야 할 수 있으므로, 안정적인 네트워크 환경과 전원이 공급되는 컴퓨터에서 실행하는 것이 중요합니다. 또한, 시장의 급격한 변동성으로 인해 예상치 못한 손실이 발생할 수 있으므로, 항상 리스크 관리에 유의하고 충분한 이해와 테스트 후에 실거래에 적용해야 합니다. 전략을 개선하고 다양한 기능을 추가하여 여러분만의 강력한 자동 트레이딩 봇을 만들어 보세요. 축하드립니다! 이제 여러분은 파이썬으로 업비트 API를 연동하여 자동 매매 시스템을 구축할 수 있는 실무 역량을 갖추게 되었습니다.

댓글 남기기