이번 포스팅에서는 기존에 나누어 작성했던 업비트 연동 및 주문 관련 코드를 하나로 합쳐보고, 함수별로 어떻게 재활용할 수 있는지 살펴보겠습니다. 최종적으로는 불안정한 API 호출을 보완하기 위해 재시도(재요청) 로직을 포함한 fetch_data() 함수를 추가하여 전체적인 안정성을 높여보겠습니다.
주요 기능 설명
본격적으로 코드 합치기에 앞서, 코드를 간단히 정리해보겠습니다.
1. 업비트 연동
- access_key, secret_key를 활용하여 업비트 객체 생성
- 잔고 조회, 주문(매수/매도), 주문 조회 등
2. 주요 함수
- fetch_data() : 네트워크 혹은 서버 이슈로 인해 데이터가 None으로 반환될 경우, 지정된 횟수만큼 재시도 하는 함수
- get_cur_price() : 현재가 조회
- get_balance_cash() : 보유 원화 조회
- get_balance_coin() : 보유 코인 수량 조회
- get_buy_avg() : 코인 매수 평균가 조회
- get_order_info() : 주문 상세 정보 조회 (주문 내역)
- order_buy_market() : 시장가 매수
- order_sell_market() : 시장가 매도
- order_buy_limit() : 지정가 매수
- order_sell_limit() : 지정가 매도
- order_cancel() : 진행 중인 주문 취소
코드 전체 합치기
- 꾸준히 말씀드리지만 pip install pyupbit가 되어 있어야 하며, access_key와 secret_key를 준비해둬야 합니다.
- 코드 제일 하단에 테스트 주문이 있는데, order_buy_market, order_sell_market 등 주문 함수를 사용 시 실제로 거래가 발생하니, 처음 테스트 할 때에는 소액으로 진행하시길 바랍니다.
import pyupbit
import requests
import time # 필요 시 사용 (재시도, 딜레이 등)
# =========================================
# 1. Upbit API 키 정보 읽기
# -----------------------------------------
# - ApiKey.txt (또는 key.txt)에 다음과 같은 형태로 저장:
# 첫째 줄: Access Key
# 둘째 줄: Secret Key
with open("ApiKey.txt", "r") as f:
access_key = f.readline().strip()
secret_key = f.readline().strip()
# =========================================
# 2. Upbit 인스턴스 생성
upbit = pyupbit.Upbit(access_key, secret_key)
# =========================================
# 3. 사용할 코인 티커 지정
# 예) "KRW-BTC", "KRW-XRP", "KRW-ETH" 등
coin = "KRW-BTC"
# =========================================
# 4. 조회용 함수들
def get_balance_cash():
"""
보유 원화(KRW) 조회
"""
return upbit.get_balance("KRW")
def get_cur_price(ticker):
"""
특정 코인 현재 시세 조회
"""
return pyupbit.get_current_price(ticker)
def get_balance_coin(ticker):
"""
특정 코인 보유 수량 조회
"""
return upbit.get_balance(ticker)
def get_buy_avg(ticker):
"""
특정 코인의 평균 매수 단가 조회
"""
return upbit.get_avg_buy_price(ticker)
def get_order_info(ticker_or_uuid):
"""
특정 티커(KRW-XXX) 또는 주문 UUID에 대한
미체결 주문 정보를 조회한다.
(최근 주문부터 [0], 가장 마지막 주문은 [-1])
"""
try:
orders = upbit.get_order(ticker_or_uuid)
if orders and "error" in orders[0]:
return None
return orders[-1] if orders else None
except Exception as e:
print("[get_order_info] 에러:", e)
return None
def get_ticker_list():
"""
업비트 전체 마켓 정보 조회 후,
KRW-마켓만 추려서 {한글이름: 티커} 형태로 리턴
예: {'비트코인': 'KRW-BTC', '리플': 'KRW-XRP', ...}
"""
url = "https://api.upbit.com/v1/market/all"
res = requests.get(url).json()
ticker_dict = {}
for item in res:
market = item["market"]
if market.startswith("KRW-"):
kr_name = item["korean_name"]
ticker_dict[kr_name] = market
return ticker_dict
def get_open_orders(ticker: str = ""):
"""
:param ticker: 코인 티커 (예: "KRW-BTC")
없으면 전체 미체결 주문 조회
:return: 미체결 주문 목록(list)
"""
try:
orders = upbit.get_order(ticker)
return orders
except Exception as e:
print("[get_open_orders] 에러:", e)
return []
# (옵션) OHLCV 조회 함수 - 최근 일자별 시가/고가/저가/종가/거래량
def get_ohlcv_data(ticker, count=7):
"""
지정된 count(일)만큼의 OHLCV(시가/고가/저가/종가/거래량) 정보를 DataFrame으로 반환
"""
return pyupbit.get_ohlcv(ticker, count=count)
# =========================================
# 5. 주문 관련 함수들 (시장가 / 지정가 / 주문취소)
def order_buy_market(ticker: str, buy_amount: float):
"""
시장가 매수
:param ticker: 코인 티커 (예: "KRW-BTC")
:param buy_amount: 매수 금액 (KRW 기준, 예: 10000.0)
"""
if buy_amount < 5000:
print("[order_buy_market] 최소 매수 금액은 5000원 이상 권장합니다.")
return None
try:
print(f"[order_buy_market] {ticker} 시장가 매수 요청 - 금액: {buy_amount}")
res = upbit.buy_market_order(ticker, buy_amount)
if not res or 'error' in res:
print("[order_buy_market] 매수 주문 실패:", res)
return None
print("[order_buy_market] 매수 주문 성공:", res)
return res
except Exception as e:
print("[order_buy_market] 에러 발생:", e)
return None
def order_sell_market(ticker: str, volume: float):
"""
시장가 매도
:param ticker: 코인 티커 (예: "KRW-BTC")
:param volume: 매도할 코인 수량
"""
try:
print(f"[order_sell_market] {ticker} 시장가 매도 요청 - 수량: {volume}")
res = upbit.sell_market_order(ticker, volume)
if not res or 'error' in res:
print("[order_sell_market] 매도 주문 실패:", res)
return None
print("[order_sell_market] 매도 주문 성공:", res)
return res
except Exception as e:
print("[order_sell_market] 에러 발생:", e)
return None
def order_buy_limit(ticker: str, price: float, volume: float):
"""
지정가 매수
:param ticker: 코인 티커 (예: "KRW-BTC")
:param price: 매수 희망 가격
:param volume: 매수할 수량
"""
try:
print(f"[order_buy_limit] {ticker} 지정가 매수 요청 - 가격: {price}, 수량: {volume}")
res = upbit.buy_limit_order(ticker, price, volume)
if not res or 'error' in res:
print("[order_buy_limit] 지정가 매수 주문 실패:", res)
return None
print("[order_buy_limit] 지정가 매수 주문 성공:", res)
return res
except Exception as e:
print("[order_buy_limit] 에러 발생:", e)
return None
def order_sell_limit(ticker: str, price: float, volume: float):
"""
지정가 매도
:param ticker: 코인 티커 (예: "KRW-BTC")
:param price: 매도 희망 가격
:param volume: 매도할 수량
"""
try:
print(f"[order_sell_limit] {ticker} 지정가 매도 요청 - 가격: {price}, 수량: {volume}")
res = upbit.sell_limit_order(ticker, price, volume)
if not res or 'error' in res:
print("[order_sell_limit] 지정가 매도 주문 실패:", res)
return None
print("[order_sell_limit] 지정가 매도 주문 성공:", res)
return res
except Exception as e:
print("[order_sell_limit] 에러 발생:", e)
return None
def order_cancel(uuid_val: str):
"""
미체결 상태의 주문(wait)만 취소 가능
:param uuid_val: 주문 시 반환되는 uuid 문자열
"""
try:
print(f"[order_cancel] 주문 취소 요청 - UUID: {uuid_val}")
res = upbit.cancel_order(uuid_val)
if not res or 'error' in res:
print("[order_cancel] 주문 취소 실패:", res)
return None
print("[order_cancel] 주문 취소 성공:", res)
return res
except Exception as e:
print("[order_cancel] 에러 발생:", e)
return None
# =========================================
# 6. 메인 실행부 (직접 테스트할 때 사용)
if __name__ == "__main__":
# -- 기본 조회 예시 --
print("보유 KRW:", get_balance_cash())
print(f"{coin} 현재 시세:", get_cur_price(coin))
print(f"{coin} 보유 수량:", get_balance_coin(coin))
print(f"{coin} 매수평단가:", get_buy_avg(coin))
print(f"{coin} 최근 미체결 주문 정보:", get_order_info(coin))
# -- 전체 KRW-마켓 티커 조회 예시 --
all_tickers = get_ticker_list()
print(f"\n전체 KRW-마켓 코인 개수: {len(all_tickers)}")
if '리플' in all_tickers:
print("리플의 티커:", all_tickers['리플'])
# -- 원화마켓 목록 간단 조회 (중복 방법) --
# (실제 코드 중복은 제거했지만 참고용)
resp = requests.get("https://api.upbit.com/v1/market/all")
data = resp.json()
krw_tickers = [c['market'] for c in data if c['market'].startswith("KRW")]
print("\nKRW-마켓 티커 리스트:", krw_tickers)
# -- OHLCV 데이터 예시 (최근 7일)
df = get_ohlcv_data("KRW-BTC", count=7)
print("\n최근 7일 OHLCV:")
print(df)
# -- 주문 관련 함수 테스트 예시 (필요 시 주석 해제) --
# 1) 시장가 매수 (예: 1만 원)
#buy_result = order_buy_market(coin, 10000)
# 2) 시장가 매도 (예: 0.001 BTC)
#sell_result = order_sell_market(coin, 0.001)
# 3) 지정가 매수 (예: BTC를 1,000만원에 0.001개 걸기)
#limit_buy_result = order_buy_limit(coin, 10000000, 0.001)
# 4) 지정가 매도 (예: BTC를 5,000만원에 0.001개 걸기)
#limit_sell_result = order_sell_limit(coin, 50000000, 0.001)
# 5) 미체결 주문 목록 조회 후 취소
#open_orders = get_open_orders(coin)
#if open_orders:
# print("\n미체결 주문 목록:", open_orders)
# recent_uuid = open_orders[0]['uuid']
# cancel_result = order_cancel(recent_uuid)
참조한 분과 코드의 맥락은 비슷하나 조금 다른 부분이 있을 수 있습니다. 그리고 참조한 분이 아주 상세히 잘 알려주셔서 방문 해보시는 걸 추천드립니다.
참조
https://mcc96.tistory.com/32
'프로그래밍 > Python' 카테고리의 다른 글
[Python] 3. 업비트 자동매매 프로그램 만들기 - 코인 주문(매수/매도) (0) | 2025.01.10 |
---|---|
[Python] 2. 업비트 자동매매 프로그램 만들기 - 업비트 API 연동 (자산 및 코인 조회, 티커 csv생성) (2) | 2024.12.28 |
[Python] 1. 업비트 자동매매 프로그램 만들기 - 환경구성 (1) | 2024.12.26 |
[Python] 파이썬 시작 및 파이썬 환경 구축 (14) | 2024.11.13 |