pandas 주가 데이터: 시간축을 검증하고 신호 계산하기

English version

TECH INSIGHT / EXPLAINED

지표를 계산하기 전에 시간축과 결측 처리 규칙을 정합니다. 정렬된 CSV는 출발점이지만 관측값·신호·실행 가능한 주문을 구분해야 전략 검증으로 이어집니다.

세 사람이 관측값을 정렬하고 이동 구간·결측·낙폭을 점검합니다.
AI로 제작한 설명용 일러스트. 세 사람이 관측값을 정렬하고 이동 구간·결측·낙폭을 점검합니다.

실제 프로젝트의 로컬 실행 화면

기존 프로젝트의 화면 또는 함수를 로컬에서 실행해 촬영했습니다. 개인정보 없는 샘플 입력을 사용했으며, 실행한 범위는 각 이미지 아래에 설명했습니다.

LLMStockTrading/lib/indicators.py의 원본 함수를 합성한 48개 가격에 실제 실행한 결과입니다. 새로 만든 실행 리포트를 브라우저에서 캡처했으며 거래 화면은 아닙니다. 원본은 RSI 단순평균·밴드 ddof=1·첫 값 기반 EWM을 사용하므로 본문의 Wilder·ddof=0 예제와 값이 다를 수 있습니다. 시간축 정제나 주문 체결을 검증한 화면은 아닙니다.
LLMStockTrading/lib/indicators.py의 원본 함수를 합성한 48개 가격에 실제 실행한 결과입니다. 새로 만든 실행 리포트를 브라우저에서 캡처했으며 거래 화면은 아닙니다. 원본은 RSI 단순평균·밴드 ddof=1·첫 값 기반 EWM을 사용하므로 본문의 Wilder·ddof=0 예제와 값이 다를 수 있습니다. 시간축 정제나 주문 체결을 검증한 화면은 아닙니다.

작게 재현되는 데이터로 시작

아래 세 행은 순서를 섞어 둔 가상 데이터입니다. 지수는 1.0에서 시작하고 100→110→99의 마지막 값은 0.99, 110 고점 대비 낙폭은 10%입니다. 시작값을 포함해야 첫 손실이 낙폭 기준에서 사라지지 않습니다.

import pandas as pd
from io import StringIO
csv = """date,close,volume
2026-01-07,99,300
2026-01-05,100,100
2026-01-06,110,200
"""
df = pd.read_csv(StringIO(csv))  # replace with a CSV file path
df['date'] = pd.to_datetime(df['date'], errors='raise')
df = df.set_index('date').sort_index()
if not df.index.is_unique:
    raise ValueError('duplicate observation dates')
for col in ['close', 'volume']:
    df[col] = pd.to_numeric(df[col], errors='raise')
if df[['close', 'volume']].isna().any().any() or not (df.close > 0).all():
    raise ValueError('missing or invalid observations')
df['ma2'] = df.close.rolling(2, min_periods=2).mean()
df['ret'] = df.close.pct_change(fill_method=None)
df['index_value'] = df.close / df.close.iloc[0]
df['drawdown'] = df.index_value / df.index_value.cummax() - 1
assert abs(df.index_value.iloc[-1] - .99) < 1e-12
assert abs(df.drawdown.min() + .10) < 1e-12

dtype보다 더 확인할 것

중복·유한한 숫자·음수가 아닌 거래량, OHLC가 있으면 고저가 일관성을 확인합니다. 앞에 0이 있는 종목 코드는 문자열로 보존합니다. 실제 종목은 분할·분배금 조정 기준도 기록하세요. 위 가격 지수가 자동으로 총수익률 지수가 되지는 않습니다.

rolling(20)은 20개 관측값이지 달력의 20일이 아닙니다. 휴장일은 거래 데이터 누락과 다릅니다. 기대하는 거래일 달력과 실제 인덱스를 비교한 뒤 오류인지, 값을 채울지 판단합니다.

필터의 미래 정보 사용 방지

t봉 거래량 급증을 판단하려면 volume.rolling(20).mean().shift(1)처럼 그 이전 이력으로 기준을 만듭니다. 파일 전체 평균을 쓰면 뒤의 관측값이 앞의 판단에 섞입니다. 사후 기술 통계에서는 전체 평균을 사용할 수 있지만 목적이 다름을 표시해야 합니다.

교차는 현재·직전 이동평균을 함께 사용해 계산합니다. 준비 구간은 정보 없음으로 두고 필요한 위치에서 해당 지표를 지정한 dropna(subset=...)를 사용하세요. 결측이 하나라도 있는 모든 행을 지우면 무관한 계산 기간도 달라질 수 있습니다.

신호 시점과 체결 모델 맞추기

완료된 종가를 사용한 신호는 그 종가를 안 뒤에 얻습니다. 이후 실행 가능한 가격과 비용을 모델링하세요. shift(1)은 정렬 도구이지 가정한 다음 봉 체결이 가능하다는 증거가 아닙니다. 행 시각이 봉 시작·끝·거래소 거래일 중 무엇인지도 명시합니다.

정리한 데이터와 변환 설정을 함께 저장하세요. 프로그램에는 UTF-8 CSV, 일부 스프레드시트에는 BOM을 포함한 UTF-8이 편리할 수 있습니다. 원본 사본을 보관해야 정제 결정을 다시 검토할 수 있습니다.

공식 자료와 함께 읽기

pandas percentage change · pandas time series

내용·예제 검토: 2026-09-29

댓글