코스피 시황 자동화 파이프라인 — Python·n8n·Ollama로 비용 0원 만들기

업데이트2026년 5월
난이도중급
스택Python · n8n · Ollama · WordPress
비용서버비만 (API 0원)
코스피 시황 자동화 n8n 워크플로우 Ollama AI 분석 WordPress 자동 발행 Python 파이프라인 홈랩 서버
매일 오후 3시 40분, 코스피 장이 마감되면 제 홈랩 서버는 조용히 일을 시작합니다. 지수 데이터 수집 → 뉴스 헤드라인 크롤링 → Ollama AI 분석 → 블로그 초안 생성 → WordPress 저장까지, 사람 손이 전혀 닿지 않고 자동으로 완성됩니다. 이 파이프라인이 3개월 이상 쌓이면 어떤 블로그도 흉내 낼 수 없는 나만의 데이터 자산이 됩니다. 외부 AI API 비용은 0원입니다.
SECTION01

이 파이프라인으로 무엇을 할 수 있는가

주식 블로그를 운영하면서 가장 힘든 게 뭔지 아시나요? 매일 장 마감 후 직접 시황을 확인하고, 글을 쓰고, 발행하는 반복 노동입니다. 이 파이프라인은 그 작업 전체를 자동화합니다.

🎯 매일 자동으로 생성되는 것들

📊 정제된 지수 데이터
시가·고가·저가·종가·거래량·등락률이 SQLite DB에 누적 저장됩니다. 6개월이 쌓이면 180일치 시계열 데이터가 완성됩니다.
📰 뉴스 헤드라인 아카이브
당일 네이버 금융 주요 뉴스가 자동 수집·저장됩니다. 어떤 뉴스가 어느 날 시장을 움직였는지 나중에 분석할 수 있습니다.
🤖 AI 투자 심리 점수
Ollama가 매일 뉴스를 읽고 1~100점의 투자 심리 점수를 생성합니다. 이 점수 시계열이 쌓이면 독자적인 시장 센티먼트 지표가 됩니다.
✍️ WordPress 블로그 초안
검토만 하면 되는 완성된 HTML 블로그 포스팅이 draft 상태로 저장됩니다. 발행 버튼 하나로 완료입니다.

💎 장기 데이터 축적의 진짜 가치

처음 1주일은 그냥 “오늘 코스피 시황” 블로그입니다. 하지만 3~6개월이 지나면 완전히 다른 이야기가 됩니다.

📈 데이터가 쌓이면 가능한 독점 콘텐츠
  • 심리점수 70 이상인 날 다음날 코스피 평균 수익률은? (백테스팅)
  • 반도체 키워드가 등장한 날의 평균 등락률 분석
  • 외국인 순매수 상위 10일 — 어떤 뉴스가 공통적으로 있었나?
  • 월요일 vs 금요일 코스피 평균 성과 비교 (6개월치)
  • 나만의 KOSPI 심리 지수 차트 (경쟁 블로그 전혀 없음)
비용 구조 — 외부 AI API 비용 0원

Ollama를 홈랩 서버에서 실행하기 때문에 ChatGPT API나 Claude API 비용이 전혀 없습니다. qwen2.5:14b 모델은 RTX 3060 12GB에서 충분히 실행 가능합니다. 추가 비용은 서버 전기세뿐입니다.

SECTION02

전체 시스템 아키텍처

5개 서비스가 순서대로 연결되어 매일 자동 실행됩니다. 각 단계는 독립적으로 재실행할 수 있어 중간에 실패해도 해당 단계부터 다시 시작할 수 있습니다.

🗺️ 전체 데이터 흐름

1
n8n Cron — 평일 15:40 자동 트리거
장 마감(15:30) 후 10분의 여유를 두고 파이프라인을 시작합니다. 데이터 확정 시간을 고려한 타이밍입니다.
2
Python: KOSPI 지수 수집
FinanceDataReader로 당일 시가·고가·저가·종가·거래량을 가져옵니다. 실패 시 Yahoo Finance로 자동 전환됩니다.
3
Python: 뉴스 헤드라인 수집
네이버 금융 뉴스 페이지를 BeautifulSoup으로 파싱, 최대 15개 헤드라인을 수집합니다. RSS 피드가 대체 수단으로 대기합니다.
4
Ollama: AI 시황 분석
수집된 지수+뉴스를 qwen2.5:14b에 입력해 핵심 요약 3줄, 투자 심리 점수(1~100), 키워드, 시황 해석, 내일 관전 포인트를 JSON으로 받습니다.
5
WordPress: 블로그 초안 자동 저장
모든 데이터를 HTML로 조합해 WordPress REST API로 draft 저장. Telegram으로 완료 알림이 발송됩니다.

🔧 서비스별 역할 분담

서비스역할위치대체 수단
n8n전체 오케스트레이션 · 스케줄링 · 알림192.168.1.253:5678cron + systemd
Python데이터 수집 · DB 저장 · HTML 생성홈랩 서버
FinanceDataReaderKRX KOSPI 지수 데이터pip 라이브러리Yahoo Finance (yfinance)
BeautifulSoup네이버 금융 뉴스 파싱pip 라이브러리RSS 피드 파싱
Ollama + qwen2.5:14bAI 시황 분석 · 블로그 제목 생성192.168.1.253:11434llama3.1:8b (빠름)
SQLite모든 데이터 영속 저장kospi.db 파일PostgreSQL
WordPress REST API블로그 초안 자동 등록agibop.com수동 복붙
SECTION03

DB 스키마 설계 — 데이터 창고 만들기

이 파이프라인의 핵심은 데이터를 구조화해서 쌓는 것입니다. 잘 설계된 스키마가 나중에 백테스팅과 통계 분석을 가능하게 합니다.

🗄️ 5개 테이블 구조

테이블저장 내용핵심 컬럼
market_daily일별 KOSPI 지수 OHLCVtrade_date, close_price, change_rate, foreign_net
news_raw당일 뉴스 헤드라인 원문trade_date, title, url, source
ai_analysisOllama AI 분석 결과sentiment_score, summary_3line, keywords, market_context
blog_posts생성된 블로그 초안title, content_html, wp_post_id, wp_status
pipeline_log파이프라인 실행 기록step, status, message, duration_sec
📁 schema.sql — DB 초기화 명령
sql — 핵심 테이블 구조 (발췌)
-- 일별 지수 데이터 (파이프라인의 핵심 원본)
CREATE TABLE IF NOT EXISTS market_daily (
    trade_date      DATE     NOT NULL UNIQUE,  -- 거래일 (중복 방지)
    open_price      REAL,                      -- 시가
    high_price      REAL,                      -- 고가
    low_price       REAL,                      -- 저가
    close_price     REAL     NOT NULL,         -- 종가 (필수)
    change_rate     REAL,                      -- 등락률 % (+상승/-하락)
    foreign_net     BIGINT   DEFAULT 0,        -- 외국인 순매수 (억원)
    created_at      DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- AI 분석 결과 (심리 점수가 핵심)
CREATE TABLE IF NOT EXISTS ai_analysis (
    trade_date      DATE     NOT NULL UNIQUE,
    summary_3line   TEXT,                      -- 핵심 3줄 요약
    sentiment_score INTEGER                    -- 투자 심리 1~100
                    CHECK(sentiment_score BETWEEN 1 AND 100),
    keywords        TEXT,                      -- JSON 배열
    market_context  TEXT,                      -- 시황 인과관계 해석
    tomorrow_watch  TEXT                       -- 내일 관전 포인트
);

-- 30일 통합 뷰 (분석용 — 조인 없이 한 번에)
CREATE VIEW IF NOT EXISTS v_daily_summary AS
SELECT m.trade_date, m.close_price, m.change_rate,
       a.sentiment_score, a.keywords, b.wp_status
FROM market_daily m
LEFT JOIN ai_analysis a ON m.trade_date = a.trade_date
LEFT JOIN blog_posts  b ON m.trade_date = b.trade_date
ORDER BY m.trade_date DESC LIMIT 30;
bash — DB 초기화 (최초 1회)
# SQLite DB 생성 + 스키마 적용
sqlite3 kospi.db < schema.sql

# 제대로 만들어졌는지 확인
sqlite3 kospi.db ".tables"
# 출력: ai_analysis  blog_posts  market_daily  news_raw  pipeline_log
SECTION04

Python 파이프라인 완전 해설

kospi_pipeline.py는 856줄짜리 단일 파일로, 수집부터 블로그 초안 생성까지 모든 로직이 담겨 있습니다. 각 단계별로 어떻게 동작하는지 핵심만 짚겠습니다.

📥 1단계 — KOSPI 지수 수집

python — 지수 수집 핵심 로직 (자동 fallback 포함)
import FinanceDataReader as fdr

# 1순위: FinanceDataReader (KRX 공식 데이터)
df = fdr.DataReader("KOSPI", trade_date, trade_date)

# 자동 fallback: FDR 실패 시 Yahoo Finance로 전환
# ^KS11 = KOSPI 티커 (Yahoo Finance 코드)
import yfinance as yf
ticker = yf.Ticker("^KS11")
df = ticker.history(start=trade_date, end=trade_date)

📰 2단계 — 뉴스 헤드라인 수집

python — 네이버 금융 뉴스 파싱
from bs4 import BeautifulSoup

url  = "https://finance.naver.com/news/news_list.naver?mode=HEAD"
resp = requests.get(url, headers=headers, timeout=10)
soup = BeautifulSoup(resp.text, "html.parser")

# 헤드라인 최대 15개 수집
items = soup.select(".realtimeNewsList .articleSubject a")[:15]
for item in items:
    title = item.get_text(strip=True)
    db.execute("INSERT OR IGNORE INTO news_raw ...")
    # OR IGNORE: 같은 날 중복 제목 자동 방지

🤖 3단계 — Ollama AI 분석 (가장 중요한 단계)

수집된 지수 데이터와 뉴스를 하나의 프롬프트로 조합해 Ollama에 보냅니다. 핵심은 출력 형식을 JSON으로 강제해서 파싱을 쉽게 만드는 것입니다.

python — Ollama 분석 프롬프트 & 응답 파싱
prompt = f"""당신은 한국 주식 시장 전문 애널리스트입니다.
{trade_date} 코스피 데이터를 분석하고 JSON으로만 답변하세요.

## 코스피 데이터
- 종가: {close_price:,.2f}p ({change_rate:+.2f}%)
## 오늘 주요 뉴스
{news_text}

## 요청 형식 (JSON만, 다른 텍스트 금지)
{{
  "summary_3line": "요약1\\n요약2\\n요약3",
  "sentiment_score": 1~100 정수,
  "keywords": ["키워드1", ..., "키워드5"],
  "market_context": "인과관계 3~4문장",
  "tomorrow_watch": "내일 관전 포인트",
  "blog_title_candidates": ["제목1", "제목2", "제목3"]
}}"""

payload = {
    "model":  "qwen2.5:14b",
    "prompt": prompt,
    "stream": False,
    "options": {"temperature": 0.3}  # 낮을수록 일관된 분석
}

resp = requests.post(f"{OLLAMA_URL}/api/generate",
                     json=payload, timeout=180)

# 마크다운 코드블록 제거 후 JSON 파싱
clean    = re.sub(r"```(?:json)?|```", "", result_text).strip()
analysis = json.loads(clean)
💡
temperature 0.3으로 설정하는 이유

AI 분석에서 창의성보다 일관성이 중요합니다. temperature가 낮을수록 매일 비슷한 형식으로 분석이 나와 DB 파싱이 안정적으로 됩니다. 블로그 제목 후보 생성만 살짝 높은 온도(0.5)를 써도 좋습니다.

📝 4단계 — HTML 블로그 초안 자동 생성

수집된 모든 데이터를 조합해 바로 WordPress에 붙여넣을 수 있는 HTML을 생성합니다. 투자 심리 점수에 따라 색상도 자동으로 바뀝니다.

심리 점수레이블색상
1 ~ 30😨 비관적■ 빨강
31 ~ 45🟡 다소 약세■ 주황
46 ~ 55⚖️ 중립■ 회색
56 ~ 70🟢 다소 강세■ 초록
71 ~ 100🚀 낙관적■ 진초록

⚡ CLI 단계별 실행 옵션

bash — 단계별 실행 (중간 실패 시 재개용)
# 전체 실행 (기본)
python kospi_pipeline.py

# 특정 날짜 지정
python kospi_pipeline.py --date 2026-05-29

# 수집만 (뉴스·지수)
python kospi_pipeline.py --step collect

# AI 분석만 (수집은 이미 됐을 때)
python kospi_pipeline.py --step analyze

# 블로그 초안만 재생성
python kospi_pipeline.py --step post
SECTION05

n8n 워크플로우 구성 — 오케스트레이터

Python 스크립트가 일을 하는 일꾼이라면, n8n은 매니저입니다. 언제 실행할지, 성공했는지, 실패하면 누구에게 알릴지를 n8n이 담당합니다.

🔗 워크플로우 노드 구성 (9개 노드)

순서노드유형역할
1⏰ 평일 15:40 실행Schedule TriggerCron: 40 15 * * 1-5
2📊 1단계: 수집Execute CommandPython 수집 스크립트 실행
3✅ 수집 성공 확인IFexit code 0 여부 분기
4🤖 2단계: AI 분석Execute CommandPython 분석 스크립트 실행
5📝 3단계: 초안 생성Execute CommandPython 포스팅 생성 스크립트
6🗄️ DB 데이터 읽기SQLiteblog_posts 테이블에서 초안 조회
7🌐 WordPress 발행HTTP RequestREST API로 draft 저장
8💾 Post ID 저장SQLiteWordPress 반환 Post ID를 DB에 기록
9📱 Telegram 알림Telegram완료/오류 알림 전송

🔑 크리덴셜 설정 (3개 필요)

1
SQLite 크리덴셜
n8n Settings → Credentials → New → SQLite
DB 파일 경로: /opt/kospi-pipeline/kospi.db
2
WordPress HTTP Basic Auth
WordPress 관리자 → 프로필 → Application Passwords → 새 비밀번호 생성
n8n: HTTP Basic Auth → 아이디 + Application Password 입력
3
Telegram Bot
@BotFather에서 /newbot → 토큰 발급
본인 Chat ID: @userinfobot에 아무 메시지 → ID 확인
n8n: Telegram API → 토큰 입력

📤 n8n 워크플로우 임포트 방법

text — n8n 임포트 순서
1. http://192.168.1.253:5678 접속
2. 왼쪽 메뉴 → Workflows → New Workflow
3. 우측 상단 ⋮ 메뉴 → Import from File
4. n8n_kospi_workflow.json 선택
5. 각 노드 클릭 → 크리덴셜 선택 (SQLite / WordPress / Telegram)
6. 우측 상단 토글 → Active ON
7. 내일 15:40까지 기다리거나 → Test workflow로 즉시 테스트
⚠️ 서버 시간대 주의
  • n8n 서버가 UTC로 실행 중이라면 Cron을 30 06 * * 1-5로 설정하세요 (UTC+9 보정)
  • 서버 시간대 확인: docker exec n8n date
  • KST로 맞추려면: Docker Compose에 TZ=Asia/Seoul 환경변수 추가
SECTION06

실제 결과물 확인 & 발행 프로세스

📋 자동 생성되는 블로그 포스팅 구성

섹션내용데이터 소스
헤더 배지날짜 · 코스피 시황 · AI 자동 분석 레이블trade_date
핵심 지표 카드종가 · 등락률 · 투자 심리 점수 · 거래량market_daily + ai_analysis
키워드 배지당일 AI 추출 핵심 키워드 5개ai_analysis.keywords
핵심 요약AI 생성 3줄 요약ai_analysis.summary_3line
시황 해석뉴스 근거 기반 인과관계 분석ai_analysis.market_context
OHLCV 테이블시가·고가·저가·종가 정리표market_daily
내일 관전 포인트AI 생성 2~3가지 주목 사항ai_analysis.tomorrow_watch
면책 조항투자 면책 문구 (자동 삽입)하드코딩
이미지 프롬프트ComfyUI용 대표 이미지 생성 프롬프트ai_analysis.keywords 기반

📱 Telegram 완료 알림 예시

코스피 시황 파이프라인 완료

📅 날짜: 2026년 05월 29일
📊 종가: 2,687.25p (▲1.24%)
🧠 심리점수: 72/100
📝 초안: agibop.com/?p=1234

검토 후 발행 예정

✅ 발행 프로세스 (하루 5분이면 완료)

1
Telegram 알림 확인
15:40 이후 Telegram에서 완료 알림을 받습니다. 링크를 클릭하면 WordPress draft 페이지로 이동합니다.
2
초안 빠른 검토
AI 분석이 이상하거나 뉴스가 잘못 파싱된 부분이 있으면 수정합니다. 대부분 그대로 발행 가능합니다.
3
대표 이미지 생성
포스팅 하단의 HTML 주석에서 ComfyUI 프롬프트를 복사해 이미지 생성 후 업로드합니다.
4
발행!
WordPress에서 Publish 클릭. 끝입니다.
SECTION07

지금 바로 시작하기 — 설치 & 실행

📦 패키지 설치

bash — 필수 패키지 설치
# 필수 패키지
pip install FinanceDataReader requests beautifulsoup4 python-dotenv

# fallback용 (FinanceDataReader 실패 시)
pip install yfinance

# 설치 확인
python -c "import FinanceDataReader; print('FDR OK')"

⚙️ 환경변수 설정

bash — .env 파일 생성 및 필수 항목 설정
cp .env.example .env
nano .env

# 반드시 수정할 항목:
DB_PATH=./kospi.db
OLLAMA_URL=http://192.168.1.253:11434  # 본인 Ollama 주소
OLLAMA_MODEL=qwen2.5:14b

# WordPress (선택, 설정하면 자동 발행)
WP_URL=https://agibop.com
WP_USER=admin
WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx

🚀 첫 실행 & 결과 확인

bash — DB 초기화 → 테스트 실행 → 결과 확인
# 1. DB 초기화
sqlite3 kospi.db < schema.sql

# 2. 최근 거래일로 테스트 실행
python kospi_pipeline.py --date 2026-05-29

# 정상 출력 예시:
# [15:41:02] [INFO] [collect_market] ✓ 수집 완료 | 종가: 2,687.25 | 등락: +1.24%
# [15:41:05] [INFO] [collect_news] ✓ 뉴스 12건 수집 완료
# [15:42:18] [INFO] [ollama_analyze] ✓ 분석 완료 | 심리점수: 72 | 소요: 73.2s
# [15:42:19] [INFO] [generate_post] ✓ 블로그 초안 생성 완료
# [15:42:19] [INFO] [main] ✅ 전체 파이프라인 완료 | 총 소요: 77.4초

# 3. DB 결과 확인
sqlite3 kospi.db "SELECT trade_date, close_price, change_rate, sentiment_score FROM v_daily_summary LIMIT 5;"

# 4. 생성된 블로그 HTML 확인
sqlite3 kospi.db "SELECT title, substr(content_html, 1, 200) FROM blog_posts ORDER BY created_at DESC LIMIT 1;"
  • Python 3.10+ 필요 (3.12 권장)
  • Ollama 실행 중 확인: curl http://192.168.1.253:11434/api/tags
  • qwen2.5:14b 모델 다운로드: ollama pull qwen2.5:14b
  • !주말·공휴일에 실행하면 데이터 없음 경고가 뜨지만 오류는 아닙니다
  • iOllama 분석은 RTX 3060 기준 약 60~90초 소요됩니다
SECTION08

데이터 축적 후 가능한 심화 활용

처음 한 달은 그냥 “일일 시황 블로그”입니다. 하지만 데이터가 쌓일수록 다른 블로그가 절대 못 따라하는 콘텐츠가 생깁니다.

📊 3개월 후 가능한 분석 쿼리 예시

sql — 데이터가 쌓이면 바로 쓸 수 있는 분석 쿼리
-- 1. 심리점수 70 이상인 날의 다음날 평균 수익률 (백테스팅)
SELECT
    AVG(m2.change_rate) AS avg_next_day_return,
    COUNT(*)            AS sample_count
FROM ai_analysis a1
JOIN market_daily m1 ON a1.trade_date = m1.trade_date
JOIN market_daily m2 ON m2.trade_date = (
    SELECT trade_date FROM market_daily
    WHERE trade_date > a1.trade_date ORDER BY trade_date LIMIT 1
)
WHERE a1.sentiment_score >= 70;

-- 2. 반도체 키워드 등장일 평균 등락률
SELECT
    AVG(m.change_rate) AS avg_return,
    COUNT(*)           AS days_count
FROM market_daily m
JOIN ai_analysis a ON m.trade_date = a.trade_date
WHERE a.keywords LIKE '%반도체%';

-- 3. 요일별 평균 코스피 등락률
SELECT
    CASE strftime('%w', trade_date)
        WHEN '1' THEN '월요일'
        WHEN '2' THEN '화요일'
        WHEN '3' THEN '수요일'
        WHEN '4' THEN '목요일'
        WHEN '5' THEN '금요일'
    END AS weekday,
    ROUND(AVG(change_rate), 3) AS avg_return,
    COUNT(*)                   AS count
FROM market_daily
GROUP BY strftime('%w', trade_date)
ORDER BY strftime('%w', trade_date);

-- 4. 월별 심리점수 평균 추이
SELECT
    strftime('%Y-%m', trade_date) AS month,
    ROUND(AVG(sentiment_score), 1) AS avg_sentiment,
    ROUND(AVG(close_price), 2)     AS avg_close
FROM v_daily_summary
GROUP BY strftime('%Y-%m', trade_date)
ORDER BY month;

🚀 6개월 후 가능한 독점 콘텐츠 아이디어

📈 나만의 심리 지수 차트
6개월치 AI 심리점수 시계열을 차트로 시각화. 코스피 지수와 오버레이해서 “심리점수가 선행 지표인가?”를 검증하는 포스팅. 어떤 블로그도 갖고 있지 않은 독점 지표입니다.
🔍 키워드 빈도 분석
“반도체”, “금리”, “외국인”, “중국” 등 키워드가 언제 가장 많이 등장했고, 그 시기 코스피는 어떻게 움직였는지 통계 분석 포스팅.
📅 요일 효과 검증
월요일 코스피가 가장 약하다는 속설을 실제 6개월 데이터로 검증. “우리 DB에서 직접 확인한 결과…”로 시작하는 신뢰도 높은 콘텐츠.
🤖 자동 월간 리포트
매월 말일에 n8n이 해당 월 전체 데이터를 Ollama에 넣어 월간 시황 리포트를 자동 생성. 하나의 포스팅으로 한 달 분석 완성.
🎯 파이프라인 확장 로드맵
  • 1개월차: 일일 시황 자동화 완성. 발행 시간을 15분 → 5분으로 단축
  • 3개월차: 심리점수 시계열 차트 포스팅 가능. 요일 효과 검증 포스팅
  • 6개월차: 나만의 백테스팅 포스팅. 월간 자동 리포트. 키워드 트렌드 분석
  • 1년차: KOSPI 심리 지수를 실제 독자들이 참고하는 지표로 브랜딩

💡 시작이 곧 데이터입니다. 오늘 설치하고 내일부터 데이터가 쌓이기 시작합니다. 6개월 뒤에 이 데이터로 무엇을 할 수 있는지는 그 때 가서 알게 됩니다. 파이프라인 구성 중 막히는 부분은 댓글로 남겨 주세요!

Leave a reply

Please enter your comment!
Please enter your name here