QUANT 3분 읽기

Interactive Brokers API로 알고리즘 트레이딩 시작하기

백테스트에서 끝나지 않고 실전 연결까지 가려면 브로커 API가 필요합니다. IBKR TWS API와 ib_insync 라이브러리로 주문 자동화를 시작하는 방법을 정리합니다.

Interactive Brokers API로 알고리즘 트레이딩 시작하기

백테스트에서 실전으로 가는 벽

IBKR 알고리즘 트레이딩 API

백테스트는 잘 나오는데 실전 연결이 어렵다는 얘기를 자주 합니다. 이유는 크게 두 가지입니다.

첫째, 브로커 API 학습 비용. 브로커마다 API 구조가 다르고, 초기 세팅이 복잡합니다.
둘째, 실시간 데이터 처리. 백테스트는 정적 데이터지만 실전은 실시간 스트림입니다.

**Interactive Brokers(IBKR)**는 진입 장벽이 높은 편입니다. 하지만 한 번 익히면 주식, 선물, 옵션, 외환, 채권을 모두 같은 API로 다룰 수 있어서 퀀트에게는 가장 실용적인 브로커입니다.


IBKR을 선택하는 이유

수수료: 미국 주식 기준 주당 $0.005 (최소 $1). 이 가격에서 이길 수 있는 브로커가 거의 없습니다.

API 지원: TWS API(Python, Java, C++)와 REST API(IBeam 통해) 모두 지원합니다. 문서화도 잘 돼 있습니다.

자산군: 전 세계 거래소 주식, 선물, 옵션, 외환, ETF, 채권을 단일 계좌로.

단점: TWS(Trader Workstation) 프로그램을 계속 실행해야 합니다. REST API를 직접 쓰려면 IBeam 게이트웨이가 필요합니다.


계좌 개설

개인 계좌와 법인 계좌 모두 가능합니다. 한국 거주자도 개설 가능하며, 절차는 온라인으로 완료됩니다.

최소 예치금:

  • 일반 계좌: $10,000 이상 권장 (미달 시 월 수수료 발생)
  • 퇴직 계좌(IRA): 없음
  • 페이퍼 트레이딩 계좌: 완전 무료 (실전 API와 동일한 환경)

중요: 처음에는 반드시 페이퍼 트레이딩 계좌로 시작하세요. 실전과 완전히 동일한 API 환경이라 코드를 충분히 테스트할 수 있습니다.


개발 환경 세팅

ib_insync를 씁니다. IBKR의 공식 ibapi보다 훨씬 Python스러운 인터페이스를 제공하고, asyncio 기반이라 실시간 처리에 적합합니다.

pip install ib_insync

TWS나 IBeam Gateway가 실행 중이어야 연결됩니다.


기본 연결과 데이터 가져오기

from ib_insync import *

# TWS에 연결 (페이퍼 트레이딩: port 7497)
ib = IB()
ib.connect('127.0.0.1', 7497, clientId=1)

# BTC 선물 계약 정의
btc = Crypto('BTC', 'PAXOS', 'USD')
ib.qualifyContracts(btc)

# 현재가 조회
ticker = ib.reqMktData(btc)
ib.sleep(2)
print(f"BTC 현재가: {ticker.marketPrice()}")

# 과거 데이터 (1시간봉 30일)
bars = ib.reqHistoricalData(
btc,
endDateTime='',
durationStr='30 D',
barSizeSetting='1 hour',
whatToShow='MIDPOINT',
useRTH=True
)
df = util.df(bars)
print(df.tail())

ib.disconnect()

주문 실행

from ib_insync import *

ib = IB()
ib.connect('127.0.0.1', 7497, clientId=1)

# SPY ETF 계약
spy = Stock('SPY', 'SMART', 'USD')
ib.qualifyContracts(spy)

# 시장가 매수 (10주)
order = MarketOrder('BUY', 10)
trade = ib.placeOrder(spy, order)

# 체결 대기
ib.waitOnUpdate(timeout=10)
print(f"주문 상태: {trade.orderStatus.status}")
print(f"체결가: {trade.orderStatus.avgFillPrice}")

ib.disconnect()

페이퍼 트레이딩 계좌로 먼저 테스트하면 실제 주문과 동일한 흐름으로 코드를 검증할 수 있습니다.


전략 자동화 구조

실전 전략은 이벤트 기반으로 설계합니다.

from ib_insync import *

class MovingAverageStrategy:
def __init__(self, symbol: str, fast: int = 20, slow: int = 50):
self.ib = IB()
self.contract = Stock(symbol, 'SMART', 'USD')
self.fast = fast
self.slow = slow
self.position = 0

def on_bar_update(self, bars, has_new_bar: bool):
if not has_new_bar:
return

closes = [b.close for b in bars]
fast_ma = sum(closes[-self.fast:]) / self.fast
slow_ma = sum(closes[-self.slow:]) / self.slow

# 골든 크로스 → 매수
if fast_ma > slow_ma and self.position <= 0:
self.ib.placeOrder(self.contract, MarketOrder('BUY', 100))
self.position = 100

# 데드 크로스 → 매도
elif fast_ma < slow_ma and self.position > 0:
self.ib.placeOrder(self.contract, MarketOrder('SELL', 100))
self.position = 0

def run(self):
self.ib.connect('127.0.0.1', 7497, clientId=1)
self.ib.qualifyContracts(self.contract)

bars = self.ib.reqRealTimeBars(
self.contract, 5, 'MIDPOINT', False
)
bars.updateEvent += self.on_bar_update

self.ib.run()  # 이벤트 루프 시작

주의사항

레이턴시: IBKR API는 초당 수십 건 주문 처리가 가능하지만, 고빈도 전략에는 적합하지 않습니다. 분 단위 이상 전략에 쓰는 게 맞습니다.

TWS 연결 유지: TWS는 24시간 연결이 불안정한 경우가 있습니다. IBeam(Docker 기반 게이트웨이)을 쓰면 더 안정적입니다.

에러 처리: 실전에서는 연결 끊김, 주문 거절, 데이터 지연 등을 모두 처리해야 합니다. 페이퍼 계좌에서 이런 케이스를 충분히 테스트하세요.


결론

IBKR은 진입 장벽이 높지만, 수수료와 자산군 커버리지 면에서 퀀트에게 가장 현실적인 브로커입니다. ib_insync로 파이썬 인터페이스가 많이 편해졌고, 페이퍼 트레이딩으로 충분히 검증할 수 있습니다.

백테스트 수익률이 좋아도 실전에서 수익이 나는지는 별개 문제입니다. 실전 연결 전에 반드시 Walk-forward 검증과 스트레스 테스트를 거치세요.


IBKR 계좌 개설 시 레퍼럴 링크를 쓰면 신규 가입 혜택이 적용됩니다. 소개자에게도 소정의 보상이 있습니다.

공유하기 X Telegram
#ibkr #interactive-brokers #algorithmic-trading #api #python

Newsletter

주간 퀀트·마켓 인사이트 구독

시장 분석, 퀀트 전략 아이디어, AI·데이터 도구 인사이트를 이메일로 받아보세요.

구독하기 →
같은 카테고리 더 보기 QUANT →