본문 바로가기

IT와 과학/주식자동매매기술

AI 3개로 주식 매매하려다 10일간 매매 0건 — 그리고 고친 이야기

728x90
반응형

 

 

POST_MORTEM AI_TRADING SYSTEM_DESIGN

AI 3개로 주식 매매하려다
10일간 매매 0건
— 그리고 고친 이야기

해외주식 자동매매 시스템에 AI 3개를 투입했다가,
오히려 아무것도 안 사는 시스템이 되어버린 경험기.
Gemini + GPT + Claude → Claude 1개 × 3인격으로 바꾸기까지의 여정.

자동매매 운용 로그 · 실제 계좌 데이터 기반 · iotnbigdata.tistory.com
10
일간 매매 0건
3
AI → 1개로 교체
+6.77%
기존 보유분 수익 (기간 중)
01

처음 설계: "AI 3개가 합의하면 매수하자"

아이디어는 단순했다. 민주주의적 AI 합의 시스템. 3개 모델 중 2개 이상이 동의(60%)해야 매수 신호로 인정한다. 한 모델만 강하게 추천해도 나머지 둘이 반대하면 매수하지 않는다. 리스크 관리가 자연스럽게 되는 구조라고 생각했다.

python
 
# 초기 설계: 3개 AI 가중 다수결
AI_PROVIDERS = {
    "gemini": {"weight": 0.33, "model": "gemini-2.0-flash"},
    "gpt":    {"weight": 0.34, "model": "gpt-4o"},
    "claude": {"weight": 0.33, "model": "claude-sonnet-4-6"},
}
# → 60% 이상 동의 시에만 매수 신호 발생
각 AI에게 같은 종목 데이터를 주고, 독립적으로 판단하게 한 뒤, 가중 다수결로 결정하는 구조. 여기까지는 꽤 그럴듯해 보였다.
02

현실: GPT가 자꾸 응답을 안 한다

배포 후 며칠간 로그를 봤다. 이상한 일이 벌어지고 있었다.

log — ERROR
 
[ERROR] oracle_event: AI 응답 생성 실패:
        Server disconnected without sending a response.

GPT-4o가 간헐적으로 응답 자체를 하지 않았다. 타임아웃이 아니라, 연결이 끊긴 채 아무 응답 없이 종료되는 케이스. 문제는 합의 로직에 있었다.

python
 
# 3개 중 1개만 응답하면 → "단독 판단" → 신뢰도 -20 감점
if len(voters) == 1:
    r = voters[0]
    return {
        "confidence": max(0, r["confidence"] - 20),  # 👈 여기가 문제
        "solo_provider": r["provider"],
    }

GPT가 죽고 + 나머지 둘 중 하나가 "관망"이면? → 1개만 "매수" → 단독 판단 → 신뢰도 -20 → 기준(60) 미달 → 매수 불가.

결과: 10일간 매매 0건.
시스템은 매일 돌아갔다. 로그도 쌓였다. 하지만 모든 종목이 합의 실패로 빠졌다.

📊 AI 적중률: 27% (3/11) — 판단 자체가 적어서 샘플도 부족
🛒 매수: 0건 / 매도: 0건
💰 계좌: 79,490,925원 (+6.77%) — 기존 보유분 덕에 수익은 있었지만
03

원인 분석: 단일 장애점 (SPOF)

문제의 핵심은 단일 장애점(Single Point of Failure)이었다. 3개 AI 합의 시스템은 이론적으로 아름답지만, 실전에서는:

상황 3AI 합의 결과
3개 모두 정상 응답 ✅ 합의 가능 매매 발생
1개 서버 다운 ⚠️ 2개만 합의 가능하지만 신뢰도 감소
1개 다운 + 1개 관망 ❌ 단독 판단 -20 감점 → 매수 불가
2개 다운 ❌ 응답 부족 매수 불가

GPT 서버의 안정성이 전체 시스템의 가동률을 결정하고 있었다. AI 3개를 쓴 이유가 안전성이었는데, 오히려 장애 확률이 3배로 늘어난 셈이다.

시스템 가동률 = P(Gemini 정상) × P(GPT 정상) × P(Claude 정상)
             = 0.98 × 0.92 × 0.99
             = 0.893 ← 89%밖에 안 된다

개별 AI의 가용성이 99%라 해도 3개를 AND 조건으로 엮으면 가용성은 떨어진다. 여기에 GPT의 간헐적 서버 끊김까지 더해지니 실질적 가동률은 더 낮았다.

04

해결: Claude 1개 × 3인격 (페르소나 방식)

발상의 전환

"AI 3개의 다양한 시각이 필요한 거지, 서로 다른 서버 3개가 필요한 게 아니었다."

Claude Sonnet 4 하나에 3개의 역할(페르소나)을 부여하면:

📊
차트분석관
temperature = 0.2
차트 패턴, 이동평균 전문. 보수적이고 일관된 기술적 판단.
🏢
기업분석관
temperature = 0.3
재무제표, 밸류에이션 분석. 균형 잡힌 펀더멘탈 시각.
⚠️
리스크분석관
temperature = 0.4
최대 손실, 포지션 사이즈. 다양한 리스크 시나리오 고려.

핵심은 temperature 분리다. 같은 모델이지만 system prompt + temperature 조합으로 사실상 다른 관점의 분석을 만들어낸다.

2라운드 토론 구조

R1
3인격 각자 독립 판단

서로의 의견을 모르는 상태에서 독립적으로 분석 및 투표

만장일치? → 바로 채택 (+5 보너스)

3인격 모두 동의하면 신뢰도 보너스 부여 후 즉시 결정

R2
이견 시 서로의 의견 공유 후 수정 기회

근거를 보여주고 한 번 더 생각할 기회 제공 — 사람의 회의와 동일한 구조

최종 가중 다수결 (60%+)

최종 의견을 바탕으로 기존 방식과 동일한 합의 기준 적용

05

함께 바꾼 것들

AI 합의 구조만 바꾼 게 아니었다. 10일간 매매 0건이라는 사태를 겪으면서 전체 전략도 다시 봤다.

듀얼 트랙: 스윙 + 코어

트랙 역할 전략
코어 AI CIO 비중 배분 우량주 장기 보유 (기존)
스윙 (신규) Claude Opus 매일 발굴 S&P500/NASDAQ100 단기 상승 유망주

스윙 익절 체계

python
 
SWING_PROFIT_TIERS = [
    {"days": 2,  "target_pct": 3.0,  "sell_ratio": 100},  # 2일+3% → 전량
    {"days": 5,  "target_pct": 5.0,  "sell_ratio": 70},   # 5일+5% → 70%
    {"days": 10, "target_pct": 7.0,  "sell_ratio": 50},   # 10일+7% → 50%
]
SWING_STOP_LOSS_PCT = -5.0  # 코어(-10%)보다 타이트

매수 파라미터 조정

파라미터 변경 전 변경 후
MAX_BUYS (하루 최대 매수) 2종목 3종목
COOLDOWN (재매수 대기) 3일 1일
06

베이지안 매도 — 국내에서 해외로

베이즈 정리 기반 추세반전 매도

국내 주식 쪽에는 이미 베이즈 정리(Bayes' theorem) 기반 추세반전 매도가 있었다.

"이 주식이 꺾이기 시작한 건가?"를 확률로 계산하는 것.
사후확률이 55% 넘으면 50% 매도, 75% 넘으면 70% 매도.

해외 적용의 벽

데이터 국내 (Kiwoom) 해외 (KIS API)
1분봉 ✅ 실시간 ❌ 미지원
체결강도 ✅ 한국 특유 지표 ❌ 개념 없음
실시간 VWAP ✅ 틱 데이터 ❌ 미지원
ATR/변동성 ✅ pykrx ✅ yfinance
시장 방향 ✅ KOSPI ✅ SPY

핵심 우도(분봉 + 체결강도 + VWAP) 3개 중 2개가 막혀있었다. 완벽하진 않지만, 가용한 데이터로 근사(approximation)하기로 했다.

python — 간소화 버전
 
# 우도 대체 전략
# 1분봉     → yfinance 15분봉 (지연 있지만 패턴은 읽힌다)
# 체결강도   → 거래량 급증 비율 (20일 평균 대비)
# 실시간 VWAP → 일봉 기반 VWAP 근사 ((H+L+C)/3 × Volume 가중)

# 사전확률은 거의 그대로 + 보유일수 추가
# (해외는 시간대 대신 보유일로 판단)
07

교훈 정리

❌ 틀렸던 가정
"AI를 많이 쓸수록 안전하다"

각 AI가 독립적 장애점이 되면서 전체 시스템의 가용성이 오히려 떨어졌다.

✅ 배운 것
단일 장애점을 없애라

외부 API 3개에 의존하는 것보다, 1개 API × 3역할이 더 안정적이었다.

❌ 틀렸던 가정
"합의(consensus)가 안전장치다"

합의 기준이 너무 엄격하면 아무 행동도 못하는 시스템이 된다. 안전장치가 아니라 마비 장치.

✅ 배운 것
"아무것도 안 하는 것"도 리스크다

10일간 기회를 전부 놓치는 것도 기회비용이라는 리스크다.

❌ 틀렸던 가정
"다양한 모델 = 다양한 시각"

진짜 다양성은 모델 종류가 아니라 역할 설정(system prompt)과 temperature에서 나왔다.

✅ 배운 것
국내/해외 데이터 차이를 먼저 확인하라

먼저 "이 데이터를 해외에서도 얻을 수 있는가?"를 확인한 뒤 설계해야 했다.

08

현재 구조 (최종 아키텍처)

[ 해외주식 자동매매 — 최종 아키텍처 ]
LAYER 1 — 종목 발굴
Claude Opus: S&P500/NASDAQ100 스캔
→ 스윙 후보 필터링 (ai_rating 7+)
LAYER 2 — AI 합의 (매수 판단)
Claude Sonnet 4 × 3 페르소나
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 차트분석 │ │ 기업분석 │ │ 리스크 │
│ T=0.2 │ │ T=0.3 │ │ T=0.4 │
└────┬─────┘ └────┬─────┘ └────┬─────┘
└──────── 2R 토론 ─────────┘
→ 가중 다수결 (60%+)
LAYER 3 — 매도 판단 (4단계)
1. 트레일링 스탑 (-5% 추적)
2. 코어 익절 (+15% → 50%)
3. 스윙 익절 (보유일+수익률 기반)
4. 베이지안 추세반전 P(반전|관측) ≥ 55%
5. 서킷브레이커 (PF -5/-8/-12%)
 
"시스템의 강건함은 AI의 개수가 아니라
아키텍처의 단순함에서 온다."
3개 AI 다수결보다, 1개 AI 3인격 토론이 더 안정적이고, 더 빠르고, 더 쌌다.
그리고 무엇보다 — 실제로 매매를 했다.

이 글에서 다룬 시스템은 실제 운용 중인 해외주식 자동매매 시스템입니다. 코드와 수치는 실제 로그와 커밋 히스토리에서 가져왔습니다.

728x90
반응형