티스토리 뷰

반응형

Ollama + CrewAI + FastAPI를 활용한 한국 주식 분석 블로그

📌 [2-1] 주식 데이터 수집 및 DB 저장 (최적화)

이번 글에서는 FinanceDataReader를 활용하여 한국 주식 데이터를 수집하고 데이터베이스(DB)에 저장하는 과정을 최적화합니다. 특히 데이터가 없으면 처음부터, 있으면 최신 데이터만 추가로 수집하여 효율성을 높입니다.

최초 데이터 수집과 추가 수집 구분
FinanceDataReader 및 PostgreSQL 활용
.env 파일로 DB 보안 관리


🔸 1. 필요한 라이브러리 설치

conda install -c conda-forge finance-datareader pandas sqlalchemy psycopg2 python-dotenv

🔸 2. FinanceDataReader를 활용한 종목코드 가져오기

먼저, 한국 주식 종목의 코드(티커)를 수집합니다.

1-1 종목 코드 가져오기

반응형
import FinanceDataReader as fdr

kospi = fdr.StockListing('KOSPI')
kosdaq = fdr.StockListing('KOSDAQ')

stock_codes = pd.concat([kospi, kosdaq])
print(stock_codes.head())

🔸 2. 주식 데이터 최적화 수집 및 DB 저장

기존 DB에 데이터가 있으면 최근 날짜 + 1일부터 데이터를 추가하고, 데이터가 없으면 2024-01-01부터 오늘까지 데이터를 가져오는 방식을 사용합니다.

📍 최적화된 데이터 수집 및 저장 코드

import FinanceDataReader as fdr
import pandas as pd
from sqlalchemy import create_engine, text
import os
from dotenv import load_dotenv
from datetime import datetime, timedelta

load_dotenv()
DB_URL = os.getenv("DB_URL")
engine = create_engine(DB_URL)

def get_last_date(code):
    query = f"SELECT MAX(date) FROM stock_data WHERE code = '{code}'"
    with engine.connect() as conn:
        result = conn.execute(text(query)).scalar()
    return result

def fetch_and_store_stock_data(code):
    last_date = get_last_date(code)

    if last_date is None:
        # 데이터가 없으면 초기 데이터 수집 (2024년 1월 1일부터)
        start_date = "2024-01-01"
    else:
        # 가장 최근 데이터 다음 날부터 수집
        start_date = (pd.to_datetime(last_date) + timedelta(days=1)).strftime('%Y-%m-%d')

    end_date = datetime.today().strftime('%Y-%m-%d')

    if start_date > end_date:
        print(f"{code}: 이미 최신 데이터입니다.")
        return

    df = fdr.DataReader(code, start_date, end_date)
    df.reset_index(inplace=True)
    df['code'] = code  # 코드 추가

    # DB에 저장
    df.to_sql('stock_data', engine, if_exists='append', index=False)
    print(f"{code}: {start_date}부터 {end_date}까지 데이터 저장 완료.")

if __name__ == "__main__":
    # 삼성전자 예시 코드 (005930)
    fetch_stock_data('005930')

🔸 3. 주식 데이터 수집 자동화

자동화를 위한 스크립트 예제입니다.

자동화 스크립트 예제(update_all_stocks.py)

import FinanceDataReader as fdr
import pandas as pd
from sqlalchemy import create_engine, text
import os
from dotenv import load_dotenv
from datetime import datetime, timedelta

load_dotenv()
DB_URL = os.getenv("DB_URL")
engine = create_engine(DB_URL)

def get_last_date(code):
    query = f"SELECT MAX(date) FROM stock_data WHERE code = '{code}'"
    result = engine.execute(text(query)).scalar()
    return result

def fetch_and_store_stock_data(code):
    last_date = get_last_date(code)

    if last_date:
        start_date = (pd.to_datetime(last_date) + timedelta(days=1)).strftime('%Y-%m-%d')
    else:
        start_date = '2024-01-01'

    end_date = datetime.today().strftime('%Y-%m-%d')

    if start_date > end_date:
        print(f"{code}: 업데이트할 데이터가 없습니다.")
        return

    df = fdr.DataReader(code, start_date, end_date)
    if df.empty:
        print(f"{code}: 해당 기간 데이터 없음.")
        return

    df.reset_index(inplace=True)
    df['code'] = code

    df.to_sql('stock_data', engine, if_exists='append', index=False)
    print(f"{code}: {start_date} ~ {end_date} 데이터가 저장되었습니다.")

def update_all_stocks():
    stock_codes_df = pd.read_sql('stock_codes', engine)
    codes = stock_codes_df['Code'].tolist()

    for code in codes:
        try:
            fetch_and_store_stock_data(code)
        except Exception as e:
            print(f"{code} 에러: {e}")

if __name__ == "__main__":
    update_all_stocks()

🔸 3. 데이터 수집 자동화 설정 (cron 사용)

매일 오전 9시에 데이터를 업데이트하는 방법입니다.

crontab -e

다음 명령을 추가합니다:

0 9 * * * /home/user/miniconda3/bin/python /home/user/project/update_all_stocks.py

📌 정리 및 다음 단계

  • ✅ FinanceDataReader로 주식 데이터 수집
  • ✅ PostgreSQL 데이터베이스 관리
  • ✅ .env를 이용한 보안 강화
  • ✅ 데이터 수집 자동화 설정 완료

다음 글에서는 CrewAI가 DB에 저장된 데이터를 활용하여 분석하는 방법을 다루겠습니다.


🚀 추천 태그 (SEO 최적화)

FinanceDataReader,주식데이터수집,주식데이터베이스,PostgreSQL주식DB,Python금융분석,주식자동업데이트,Python자동화,주식크롤링,데이터기반투자,CrewAI활용,데이터분석블로그

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함
반응형