
| 항목 | 내용 |
|---|---|
| 환경 | Python 3.10 이상 |
| 증상 | 인증·주문 단계에서 중단 |
| 원인 | 키·검증·위험 제한 누락 |
| 해결 | 백테스트 후 모의주문 |
| 바로가기 | Alpaca-py 문서 |
AI 자동매매를 처음 연결하면 ModuleNotFoundError: No module named 'alpaca', 401 Unauthorized, 주문은 보냈는데 체결 결과를 기록하지 못하는 현상에서 자주 멈춘다.
모델 정확도부터 높이기보다 데이터 시점, 주문 API, 손실 제한을 분리해야 원인을 찾기 쉽다.
ModuleNotFoundError: No module named 'alpaca'
401 Unauthorized
이 글의 예제 환경은 Ubuntu·Windows·macOS에서 사용할 수 있는 Python 3.11과 2026년 9월 PyPI 최신판 alpaca-py 0.44.0이다.
패키지는 Python 3.10 이상을 지원하며 모의투자는 무료지만, 실거래 수수료·규제 비용과 시장 데이터 조건은 별도로 확인해야 한다.
증상부터 분리해야 하는 이유

자동매매는 데이터 수집, 특징 계산, 매수·매도 판단, 주문 실행의 네 구간으로 나뉜다.
예측값이 정상이어도 오래된 시세를 읽거나 동일 신호를 두 번 처리하면 주문 결과는 달라진다.
첫 점검은 AI 모델이 아니라 어느 구간에서 멈췄는지 기록하는 것이다.
수익률이 과장되는 원인
일반적인 무작위 분할은 미래 데이터를 학습 세트에 섞을 수 있다.
scikit-learn의 TimeSeriesSplit 공식 문서도 시간 순서가 있는 표본에는 과거로 학습하고 이후 구간으로 평가하는 방식을 안내한다.
수수료, 스프레드, 주문 지연을 빼고 종가 그대로 체결했다고 계산하는 것도 흔한 오류다.
정확도 대신 기간 밖 수익률, 최대 낙폭, 거래 횟수와 비용 차감 후 손익을 함께 저장해야 한다.
| 방법 | 사용 시점 | 핵심 확인값 |
|---|---|---|
| 규칙 전략 | 주문 연결 첫 검증 | 신호·체결 일치 |
| 지도학습 | 라벨 기준이 명확할 때 | 기간 밖 손익 |
| LLM 보조 | 뉴스 분류가 필요할 때 | 출력 형식·지연 |
처음에는 단순 규칙을 기준선으로 만들고 AI가 비용 차감 후에도 개선하는지 비교한다.
1단계 백테스트와 모델 검증

가격을 시간 오름차순으로 정렬하고, 예측 대상보다 늦게 발표된 데이터는 특징에서 제외한다. 다음 코드는 마지막 20%를 한 번도 학습하지 않은 평가 구간으로 남기는 최소 구조다.
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
df = pd.read_csv("prices.csv", parse_dates=["date"]).sort_values("date")
df["ret1"] = df["close"].pct_change()
df["ma5"] = df["close"].rolling(5).mean() / df["close"] - 1
df["target"] = (df["close"].shift(-1) > df["close"]).astype(int)
df = df.dropna()
cut = int(len(df) * 0.8)
X, y = df[["ret1", "ma5"]], df["target"]
model = RandomForestClassifier(n_estimators=200, random_state=42)
model.fit(X.iloc[:cut], y.iloc[:cut])
print(model.score(X.iloc[cut:], y.iloc[cut:]))
정확도가 높다는 이유만으로 주문하지 않는다. 거래별 비용을 반영한 순손익이 기준 전략보다 나은지, 하락 구간에서도 최대 낙폭이 허용 범위 안인지 확인할 때 쓰는 해결책이다.
2단계 Alpaca 모의주문 연결
Paper Trading 계정에서 발급한 키를 환경 변수로 저장한다.
공식 SDK는 TradingClient(..., paper=True)로 모의 환경을 선택하며, Paper 키와 Live 키를 섞으면 인증에 실패한다.
python -m pip install "alpaca-py==0.44.0"
export APCA_API_KEY_ID="발급받은_PAPER_KEY"
export APCA_API_SECRET_KEY="발급받은_PAPER_SECRET"
아래 예제는 계좌 상태를 조회한 뒤 미국 주식 SPY 1주를 모의 시장가로 제출한다.
실제 주문으로 전환하지 않도록 paper=True를 고정했으며, 시장가는 주문 가격이 보장되지 않는 주문 방식이다.
import os
from alpaca.trading.client import TradingClient
from alpaca.trading.enums import OrderSide, TimeInForce
from alpaca.trading.requests import MarketOrderRequest
client = TradingClient(
os.environ["APCA_API_KEY_ID"],
os.environ["APCA_API_SECRET_KEY"],
paper=True,
)
account = client.get_account()
if account.trading_blocked:
raise RuntimeError("Trading is blocked")
order = client.submit_order(MarketOrderRequest(
symbol="SPY", qty=1,
side=OrderSide.BUY,
time_in_force=TimeInForce.DAY,
))
print(order.id, order.status)
주문 ID와 상태를 저장할 수 있을 때까지는 AI 신호를 자동 실행에 연결하지 않는다.
실거래 전 재발 방지 점검

하루 최대 손실, 종목별 최대 보유액, 주문당 수량, 중복 주문 방지 키, 전체 주문 취소 스위치를 코드 밖 설정값으로 둔다.
프로세스 재시작 후에도 마지막 신호와 주문 ID를 읽을 수 있도록 SQLite 같은 영속 저장소를 사용한다.
실시간 체결 상태는 폴링만 하지 말고 TradingStream 공식 문서의 주문 업데이트 스트림으로 대조한다.
네트워크가 끊기면 신규 주문을 중단하고 미체결 주문과 실제 포지션을 다시 조회한 뒤 재개해야 한다.
모의투자는 API 흐름을 검증하는 해결책이고 실제 체결 품질이나 수익을 보장하지 않는다.
최소 수 주 동안 로그·비용·낙폭을 검토한 뒤에도 실거래 전환은 paper=False 한 줄만 바꾸지 말고 별도 키, 별도 설정, 작은 주문 한도로 승인 절차를 거치는 편이 안전하다.
AI 자동매매의 완성 기준은 높은 예측 점수가 아니라 손실 제한과 복구 절차가 실제로 작동하는 상태다.
사진: RDNE Stock project, AlphaTradeZone, Mikhail Nilov, Liza Summer · Pexels
'AI·개발 도구' 카테고리의 다른 글
| Claude로 커머스 에이전트 구축하기|상품 조회부터 주문 승인까지 (1) | 2026.09.03 |
|---|---|
| Terraform CI 실패 뒤 LLM 실행 오류|게이트 차단 순서 (0) | 2026.09.03 |
| 크롬이 자동 설치한 2GB 파일 정리|온디바이스 AI 삭제 방법 (0) | 2026.09.03 |
| 에이전트 메모리를 파일로 이식하는 방법|JSONL 설계와 검증 순서 (0) | 2026.09.02 |
| AI 소프트웨어 팩토리 운영법|Uber가 검증한 비용 최적화 4단계 (0) | 2026.09.02 |