자동매매 시스템에서 주문 실행은 핵심 기능입니다. 하지만 주문 실행만으로는 완벽하지 않습니다. 주문이 제대로 처리되었는지 확인해야 합니다. 주문 상태를 실시간으로 추적하고 관리해야 합니다. 체결 여부를 확인하고 필요한 조치를 취해야 합니다. 이 섹션에서는 주문 상태 관리 및 체결 확인 로직을 구현하는 방법을 안내합니다.
주문 상태 관리의 목표는 크게 두 가지입니다. 첫째, 주문이 정상적으로 체결되었는지 확인하는 것입니다. 둘째, 미체결 주문에 대한 적절한 대응 전략을 수립하는 것입니다. 이를 통해 시스템의 안정성을 높이고, 예상치 못한 손실을 방지할 수 있습니다.
주문 상태는 거래소 API를 통해 확인할 수 있습니다. 각 거래소는 주문 상태를 나타내는 다양한 코드를 제공합니다. 예를 들어, ‘대기’, ‘체결’, ‘취소’ 등의 상태가 있습니다. 이러한 상태 코드를 정확히 이해하고, 시스템에 적용해야 합니다.
미체결 주문에 대한 대응은 매우 중요합니다. 시장 상황이 급변하면 미체결 주문이 손실로 이어질 수 있습니다. 따라서 미체결 주문을 주기적으로 확인하고, 필요에 따라 취소하거나 가격을 조정해야 합니다.
이 섹션에서는 업비트 API를 예시로 들어 설명합니다. 하지만 다른 거래소 API도 유사한 방식으로 적용할 수 있습니다. 핵심은 거래소 API 문서를 꼼꼼히 확인하고, 각 상태 코드의 의미를 정확히 파악하는 것입니다.
단계 1: 주문 상태 조회 함수 구현
가장 먼저 주문 상태를 조회하는 함수를 구현해야 합니다. 이 함수는 주문 UUID를 입력받아 거래소 API를 통해 주문 상태를 조회합니다. 조회된 주문 상태는 시스템에서 사용할 수 있도록 가공해야 합니다.
import pyupbit
import time
# API 키 설정 (본인의 키로 변경)
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"
# 업비트 객체 생성
upbit = pyupbit.Upbit(access_key, secret_key)
def get_order_status(uuid):
"""
주문 UUID를 통해 주문 상태를 조회합니다.
"""
try:
order = upbit.get_order(uuid)
if order:
return order['state'] # 주문 상태 반환 ('wait', 'done', 'cancel')
else:
return None # 주문 정보가 없는 경우 None 반환
except Exception as e:
print(f"주문 상태 조회 실패: {e}")
return None
위 코드는 get_order_status
함수를 정의합니다. 이 함수는 주문 UUID를 인자로 받습니다. upbit.get_order(uuid)
를 호출하여 주문 정보를 조회합니다. 주문 정보가 존재하면 주문 상태를 반환합니다. 주문 정보가 없거나 오류가 발생하면 None을 반환합니다.
단계 2: 주문 체결 여부 확인 함수 구현
주문 상태를 조회하는 함수를 기반으로, 주문 체결 여부를 확인하는 함수를 구현합니다. 이 함수는 주문 UUID를 입력받아 주문이 체결되었는지 확인합니다.
def is_order_filled(uuid):
"""
주문 UUID를 통해 주문이 체결되었는지 확인합니다.
"""
status = get_order_status(uuid)
if status == 'done':
return True # 주문이 체결된 경우 True 반환
else:
return False # 주문이 체결되지 않은 경우 False 반환
위 코드는 is_order_filled
함수를 정의합니다. 이 함수는 주문 UUID를 인자로 받습니다. get_order_status(uuid)
를 호출하여 주문 상태를 조회합니다. 주문 상태가 ‘done’이면 True를 반환합니다. 그렇지 않으면 False를 반환합니다.
단계 3: 미체결 주문 처리 로직 구현
미체결 주문을 처리하는 로직을 구현해야 합니다. 이 로직은 주기적으로 미체결 주문을 확인하고, 필요에 따라 취소하거나 가격을 조정합니다.
def handle_unfilled_orders(uuid):
"""
미체결 주문을 처리합니다.
"""
status = get_order_status(uuid)
if status == 'wait':
try:
upbit.cancel_order(uuid) # 주문 취소
print(f"미체결 주문 {uuid} 취소 완료")
except Exception as e:
print(f"주문 취소 실패: {e}")
else:
print(f"주문 {uuid} 상태: {status}")
위 코드는 handle_unfilled_orders
함수를 정의합니다. 이 함수는 주문 UUID를 인자로 받습니다. get_order_status(uuid)
를 호출하여 주문 상태를 조회합니다. 주문 상태가 ‘wait’이면 upbit.cancel_order(uuid)
를 호출하여 주문을 취소합니다.
단계 4: 전체 로직 통합 및 테스트
구현된 함수들을 통합하여 전체 로직을 구성하고 테스트해야 합니다. 실제 주문을 실행하고, 주문 상태를 확인하고, 미체결 주문을 처리하는 과정을 시뮬레이션합니다.
# 예시: 지정가 매수 주문 실행
order_result = upbit.buy_limit_order("KRW-BTC", 50000000, 0.0001)
uuid = order_result['uuid'] # 주문 UUID 추출
# 5초 대기 후 주문 상태 확인
time.sleep(5)
# 주문 체결 여부 확인
if is_order_filled(uuid):
print(f"주문 {uuid} 체결 완료")
else:
print(f"주문 {uuid} 미체결")
handle_unfilled_orders(uuid) # 미체결 주문 처리
위 코드는 지정가 매수 주문을 실행하고, 5초 대기 후 주문 상태를 확인합니다. 주문이 체결되었으면 “주문 체결 완료” 메시지를 출력합니다. 주문이 미체결되었으면 handle_unfilled_orders(uuid)
를 호출하여 미체결 주문을 처리합니다.
주의 사항
- API 요청 제한: 거래소 API는 요청 횟수 제한이 있습니다. 과도한 요청은 API 사용 제한으로 이어질 수 있습니다.
- 예외 처리: 네트워크 오류, API 응답 지연 등 예외 상황에 대한 처리가 필요합니다.
- 보안: API 키는 안전하게 관리해야 합니다. 노출될 경우 계정 보안에 심각한 문제가 발생할 수 있습니다.
이 섹션에서는 주문 상태 관리 및 체결 확인 로직을 구현하는 방법을 설명했습니다. 다음 섹션에서는 계좌 잔고 및 포지션 관리 방법에 대해 알아보겠습니다.