AI 주식 파이프라인 시리즈 — 4편. 코스피·코스닥 전 종목을 대상으로 기술적 신호를 감지해 상위 25개 후보 종목을 추려내는 1단계 로직의 설계 이유와 구현 방식을 다룹니다.

퀀트 신호 감지 시스템 구조


왜 전 종목을 스캔하나

“오늘 살 주식을 찾는다”는 목표에서 첫 번째 질문은 간단합니다. 어디서부터 시작하나.

관심 종목 리스트를 미리 고정해두면 편하지만, 그 바깥에서 발생하는 강력한 신호를 놓칩니다. 코스피와 코스닥 전 종목(약 2,700~3,000개)을 매일 장 마감 후 전부 스캔하는 이유가 여기 있습니다. 목표는 “오늘 뭔가 움직임이 시작된 종목”을 하나도 빠짐없이 후보군에 올리는 것입니다.


어떤 기술적 신호를 감지하고, 왜 그 신호인가

무상증자·액면분할·배당락 등이 반영된 수정주가(Adjusted Price) 전처리 데이터를 기반으로 스캔합니다. 수정주가를 쓰지 않으면 액면분할 당일 차트가 폭락한 것처럼 보여 볼린저밴드 하단 이탈 같은 오신호가 대량 발생합니다.

시장의 서로 다른 국면을 포착하기 위해 5가지 기술적 신호를 사용합니다.

1. 단기 골든크로스 (추세 시작)

5일 이평선이 20일 이평선을 아래에서 위로 뚫는 시점. 핵심은 “크로스되는 바로 그날”만 잡는 것입니다. 이미 크로스된 채 며칠 지난 종목은 제외합니다. 타이밍이 생명인 단기 매매에서 늦은 진입은 추격 매수일 뿐입니다.

# 전일에는 아니었다가 오늘 처음 크로스된 당일만 포착
if ma5 > ma20 and ma5_prev <= ma20_prev:
    signals.append("골든크로스")

2. 중기 골든크로스 (추세 강화)

20일선이 60일선을 뚫는 신호입니다. 단기 크로스보다 발생 빈도는 낮지만, 출현 시 추세 전환의 강도가 훨씬 큽니다. 시간축이 다른 두 모멘텀을 같이 보며 신호의 신뢰도를 높입니다.

3. 거래량 급증 (시장 관심도)

오늘 거래량이 20일 평균의 1.5배 이상 터진 종목을 잡습니다. 거래량은 그 자체보다 시장의 관심도 변화를 감지하는 레이더입니다. 갑자기 돈이 몰린 이유는 다음 단계(뉴스 필터)에서 검증합니다.

if volume / avg_volume_20d >= 1.5:
    signals.append("거래량급증")

4. 52주 신고가 (강한 모멘텀)

52주 고점의 98% 이상에 도달한 종목입니다. 매물대 저항이 아닌, 위가 열린 추진력으로 해석하는 게 모멘텀 전략의 관점입니다.

5. 볼린저밴드 하단 + RSI 과매도 (역추세 반등)

앞의 네 가지가 추세 추종이라면, 이건 역추세 신호입니다. 과매도 구간에서 밴드 하단에 걸린 종목은 기술적 반등 강도가 셉니다. 시장 국면마다 유효한 전략이 다르므로 두 성향의 신호를 모두 감지합니다.

if price <= bb_lower * 1.02 and rsi <= 35:
    signals.append("볼린저밴드")

신호가 나왔다고 다 같은 신호가 아니다: 가중치 점수화

단순히 신호 유무가 아니라 신호의 압착 강도가 중요합니다. 알고리즘 기반 점수판을 설계했습니다.

def compute_signal_score(t: dict, signals, cap: float = 6.0) -> float:
    score = 0.0

    # 1. 기술적 신호별 기본 점수 + 시너지 가중치
    if "골든크로스" in signals:
        vol_ratio = t.get("volume_ratio", 1.0)
        score += 1.5 + (0.5 if vol_ratio > 1.5 else 0)  # 거래량 동반 시 보너스
    if "MA장기골든크로스" in signals:
        score += 1.2
    if "거래량급증" in signals:
        score += 1.0
    if "신고가" in signals:
        score += 1.3
    if "볼린저밴드" in signals:
        score += 1.0
    if "골든크로스" in signals and "거래량급증" in signals:
        score += 1.0  # 복합 신호 시너지

    # 기술적 신호에만 상한선 적용 — 수급·리스크는 캡 이후에 결합
    score = min(score, cap)

    # 2. 수급 데이터 결합 (캡 이후 가산, 최대 +1.7점)
    if t.get("foreign_net_buy_3d", 0) > 0 and t.get("inst_net_buy_3d", 0) > 0:
        score += 0.7  # 외인+기관 동시 순매수
    elif t.get("foreign_net_buy_3d", 0) > 0:
        score += 0.5  # 외인 단독 순매수
    if t.get("in_top30", False):
        score += 0.5  # KIS API 기준 당일 순매수 상위 종목

    # 3. 리스크 감점 (캡 이후 차감)
    if t.get("short_sell_ratio", 0) > 5.0:
        score -= 1.0  # 공매도 급증
    if t.get("credit_ratio", 0) > 3.0:
        score -= 0.5  # 신용잔고 과다

    return score

캡(6.0)을 기술적 신호에만 먼저 적용한 뒤, 수급 가산과 리스크 감점을 그 다음에 결합합니다. 이렇게 해야 공매도가 심한 종목이 캡에 가려 감점 효과를 잃는 일이 없고, 진짜 A+ 종목과 평범한 A 종목의 변별력도 수급 점수로 살아납니다.


잘못된 신호를 억제하는 필터링 설계

점수를 올리는 것만큼 가짜 신호(Trap)에 속지 않는 역설계가 더 중요합니다.

역배열 볼린저밴드 신호 제거 — 하락 추세 한가운데에서 밴드 하단에 닿는 건 반등이 아니라 추락의 연장선입니다. 완전히 무너진 차트 구조에서는 신호 자체를 무효화합니다.

# 역배열(MA5 < MA20 < MA60) 구조에서의 볼린저 신호는 제거
if "볼린저밴드" in signals and ma5 < ma20 < ma60:
    signals.remove("볼린저밴드")

시장 국면에 맞춘 동적 임계치 운영

매일 3,000개 종목을 스캔하면 평소엔 50~150개 내외의 신호 종목이 잡힙니다. 시장 상황에 따라 이 숫자는 요동칩니다.

시장 상황신호 종목 수이유
상승장200개 이상신고가·골든크로스 대량 발생
하락장20개 이하지표 수렴 조건 미달로 신호 급감

통과 기준점수를 고정하면 하락장엔 후보가 전멸하고, 상승장엔 노이즈 신호까지 딸려옵니다. 상한 기준을 유연하게 조율해 최종 스코어 상위 25개 종목만 정제해 다음 단계인 뉴스 필터로 넘깁니다.


3,000개 종목을 단 3분 만에 처리하는 병렬화

처리 속도는 설계의 실질적인 제약 조건입니다. 직렬로 돌리면 장 시작 전에 결과가 나오지 않습니다.

# KIS API 네트워크 I/O 바운드 작업 병렬 처리
with ThreadPoolExecutor(max_workers=5) as pool:
    futures = {
        pool.submit(_scan_one, sym, name, sig_cap, top30): (sym, name)
        for sym, name in universe
    }

종목당 KIS API 수급 조회 등 네트워크 I/O 바운드 작업이 포함되어 있어, CPU 연산 중심의 멀티프로세싱 대신 ThreadPoolExecutor를 채택했습니다. 워커 5개로 병렬 처리한 결과 3,000개 종목 스캔을 3~4분에 완수합니다.


이 로직의 명확한 한계

기술적 지표는 태생이 과거 데이터의 후행성 조합입니다. 오늘 신호가 떴다고 내일 오른다는 보장이 없습니다. 특히 세 가지 함정이 도사립니다.

  1. 갭업 오픈형 훼이크 — 밤사이 뉴스로 시가가 이미 급등하며 발생한 착시형 신호
  2. 동전주/품절주 오류 — 평소 거래량이 적어 소액 매매에도 거래량 급증이 뜨는 유동성 함정
  3. 테마주 불나방 — 단기 과열 테마의 끝물에서 잡히는 고점 신고가

이 한계를 보완하기 위해 1단계에서 걸러낸 25개 종목을 뉴스 필터(1.5단계)와 LLM AI 판단(2~3단계)으로 추가 검증합니다. 차트 뒤에 숨은 실시간 호재와 재무 실체를 발라내는 과정은 다음 편에서 계속됩니다.


시리즈 목차

  • 1편 · AI 두 개로 역할 나눠 운영비 줄이기
  • 2편 · 2개월 실전 운영, 삽질의 기록
  • 3편 · 데이터 소스 변천사 (yfinance → KIS)
  • 4편 · 퀀트 신호 감지 (현재 글)
  • 5편 · AI 판단 파이프라인
  • 6편 · 성장주·저평가주 스크리너