파이썬 판다스로 주식 데이터 분석 및 기술지표 시각화하기

읽기 예상 시간: 10분

판다스 입문 시리즈의 대미를 장식할 실전 프로젝트예요. yfinance 라이브러리를 활용해 실제 주식 시계열 데이터를 수집하고, 판다스 DataFrame으로 변환하여 기초적인 데이터 가공부터 고급 시각화까지 직접 해볼 거예요. 복잡한 수식 없이 ta 라이브러리를 통해 한 줄로 기술지표를 계산하는 방법과, Matplotlib 다중 서브플롯을 이용해 주가, 거래량, 기술지표를 한눈에 볼 수 있는 종합 대시보드 시각화 코드를 완성해 내는 것이 이번 글의 핵심 목표예요.

목차

1. 실전 주식 데이터 준비하기 (yfinance)

실전 주식 데이터 수집을 보여주는 모니터 화면

드디어 판다스 입문 시리즈의 마지막 편이에요. 앞서 배운 내용들을 전부 꺼내서 써먹어볼 차례가 왔네요. 데이터 분석을 하려면 가장 먼저 뭐가 필요할까요? 당연히 분석할 실제 데이터가 있어야겠죠. 주식 데이터를 구하는 방법은 크롤링부터 유료 API까지 다양하지만, 우리는 초보자도 가장 쉽게 접근할 수 있는 yfinance를 활용한 파이썬 시계열 데이터 수집 방식을 사용할 거예요. 이 라이브러리를 쓰면 야후 파이낸스에서 제공하는 전 세계의 과거 주가 데이터를 아주 쉽게 받아올 수 있거든요.

주식 데이터는 기본적으로 시가(Open), 고가(High), 저가(Low), 종가(Close), 거래량(Volume)이라는 다섯 가지 핵심 요소로 구성돼요. 시가는 장이 열릴 때의 가격, 종가는 장이 닫힐 때의 가격이에요. 우리는 그중에서도 전 세계 시가총액 1위를 다투는 애플(AAPL) 주가 데이터를 직접 다운로드하고 판다스로 불러와 볼게요. 데이터 수집 과정을 순서대로 차근차근 따라와 보세요.

1
필수 라이브러리 설치하기

터미널이나 명령 프롬프트를 열고 파이썬 환경에 맞게 패키지를 설치해야 해요. pip install yfinance pandas 명령어를 입력하면 준비가 끝나요.

2
데이터 다운로드 및 CSV 저장

yfinance의 download 함수에 종목 코드(티커)와 기간을 넣으면 데이터를 가져와요. 가져온 데이터를 바로 써도 되지만, 학습을 위해 일단 CSV 파일로 저장해 볼게요.

python
download_data.py
import yfinance as yf
import pandas as pd

# 애플(AAPL) 주식 데이터를 2023년 1월 1일부터 2023년 12월 31일까지 다운로드해요.
aapl_data = yf.download('AAPL', start='2023-01-01', end='2023-12-31')

# 다운로드한 데이터를 CSV 파일로 내 컴퓨터에 저장해요.
aapl_data.to_csv('yfinance_aapl.csv')

# 저장한 CSV 파일을 다시 판다스 DataFrame으로 불러와요.
df = pd.read_csv('yfinance_aapl.csv')

# 데이터의 첫 5줄을 확인해봐요.
print(df.head())

이 코드를 실행하면 내 작업 폴더에 yfinance_aapl.csv 파일이 생성되고, 데이터가 화면에 출력될 거예요. 여기서 한 가지 의문이 들 수 있어요. “왜 바로 데이터를 쓰지 않고 굳이 CSV로 저장했다가 다시 불러오나요?” 좋은 질문이에요. yfinance로 바로 받은 데이터는 열 이름이나 인덱스 구조가 다중 레벨(MultiIndex)로 되어 있어서 초보자가 다루기에 꽤 까다로울 때가 많아요. 이렇게 CSV로 한번 저장했다가 다시 불러오면 데이터 구조가 평탄화되어서 입문자 입장에서 다루기가 훨씬 수월해지거든요. 이것도 실무에서 종종 쓰이는 소소한 트릭이랍니다.

2. 시계열 데이터 다루기 기초

시계열 데이터와 달력이 겹쳐진 주가 흐름 이미지

방금 불러온 주식 데이터는 전형적인 시계열 데이터예요. 시간에 따라 일정한 간격으로 기록된 데이터라는 뜻이죠. 판다스에서 시계열 분석을 할 때는 날짜가 들어있는 열을 데이터의 ‘이름표’격인 인덱스(Index)로 설정하는 것이 절대적인 규칙이에요. 그래야만 날짜를 기준으로 데이터를 자르고, 붙이고, 묶는 작업이 마법처럼 쉬워지거든요.

또한 판다스가 제공하는 resample()이라는 강력한 메서드를 쓰면 일별로 된 데이터를 월별, 분기별, 연별로 쉽게 묶어서 집계할 수 있어요. 엑셀의 피벗 테이블을 떠올리시면 이해가 빠르실 거예요. 날짜를 인덱스로 만들고 다양한 기준으로 데이터를 조작해보는 코드를 같이 살펴볼게요.

python
time_series_basics.py
# 'Date' 열을 단순 문자열에서 판다스가 인식할 수 있는 날짜(Datetime) 타입으로 바꿔요.
df['Date'] = pd.to_datetime(df['Date'])

# 'Date' 열을 DataFrame의 인덱스로 설정해요.
df = df.set_index('Date')

# 2023년 1월부터 3월까지의 데이터만 문자열로 쉽게 잘라낼 수 있어요.
q1_data = df['2023-01':'2023-03']
print("1분기 데이터 개수:", len(q1_data))

# resample을 사용해 월별('ME') 평균 종가(Close)를 구해요.
monthly_mean = df['Close'].resample('ME').mean()
print("\n월별 평균 종가:\n", monthly_mean)

# 전일 대비 수익률을 구할 때는 pct_change()를 쓰면 한 번에 계산돼요.
df['return'] = df['Close'].pct_change()

코드에서 resample('ME')라는 부분이 보이죠? 여기서 ‘ME’는 ‘Month End’의 약자로 각 월의 마지막 날을 기준으로 데이터를 묶어준다는 의미예요. 예전 버전의 판다스에서는 ‘M’을 썼지만, 최근 업데이트되면서 ‘ME’를 쓰는 것이 표준이 되었어요.

📌 Note

데이터프레임의 인덱스를 pd.to_datetime()을 거쳐 날짜 타입으로 설정하지 않으면, resample이나 '2023-01':'2023-03' 같은 편리한 슬라이싱 기능들을 전혀 쓸 수 없어요. 시계열 데이터를 다룰 때는 무조건 인덱스 변환부터 하고 시작한다고 외워두시면 편해요.

3. 이동 평균선 계산 및 결측치(NaN) 처리 전략

이동 평균선을 통해 주가 데이터를 부드럽게 분석하는 모습

증권사 앱이나 네이버 금융 등에서 주식 차트를 보면 캔들 차트 주변을 뱀처럼 부드럽게 감싸고 도는 5일선, 20일선, 60일선 같은 선들을 보셨을 거예요. 이게 바로 이동 평균선(Moving Average)이에요. 하루하루의 주가는 뉴스나 시장 심리에 따라 너무 크게 위아래로 흔들리기 때문에, 일정 기간의 평균을 구해서 전체적인 추세를 보기 쉽게 만드는 거죠.

판다스에서는 rolling()이라는 메서드를 사용하면 이동 평균선을 정말 쉽게 만들 수 있어요. 말 그대로 지정한 기간(window)만큼 창문을 씌워서 데이터를 묶고 옆으로 굴려가면서 계산한다는 뜻이에요. 이때 창 크기가 5일처럼 작으면 최근 가격 변화를 아주 빠르게 반영하지만 자잘한 노이즈에 너무 쉽게 흔들리고, 60일처럼 크면 부드럽고 묵직한 큰 흐름을 볼 수 있지만 반응 속도가 한참 느려진다는 특징이 있어요. 이동 평균선을 만들고 불필요한 값을 정리하는 과정을 코드로 확인해 볼까요?

python
moving_average.py
# 20일(중기), 60일(장기) 이동 평균선을 계산해서 새로운 열에 넣어요.
df['MA20'] = df['Close'].rolling(window=20).mean()
df['MA60'] = df['Close'].rolling(window=60).mean()

# 결측치(NaN)가 얼마나 있는지 데이터 크기를 통해 확인해요.
print("결측치 제거 전 데이터 크기:", df.shape)

# dropna()를 사용해 NaN이 하나라도 있는 행을 깔끔하게 지워요.
df = df.dropna()

# 결측치 제거 후의 데이터를 다시 확인해요.
print("결측치 제거 후 데이터 크기:", df.shape)

생각해 보세요. 20일 평균을 구하려면 당연히 20일 치의 과거 데이터가 쌓여 있어야겠죠? 그래서 데이터의 가장 첫날부터 19일째까지는 평균을 계산할 데이터가 부족해서 값이 ‘NaN(Not a Number)’으로 비워져 있게 돼요. 60일선이라면 무려 첫 59일간의 데이터가 빈 값이 되어버리죠. 그렇기 때문에 Pandas 주식 분석 시 결측치(NaN) 제거 방법을 확실히 숙지하고 dropna()를 통해 이 빈 공간들을 미리 치워두는 것이 정말 중요해요.

⚠️ Warning

결측치를 그냥 무시하고 넘어가면 어떻게 될까요? 나중에 차트를 그릴 때 그래프 선이 중간에 끊기거나 아예 렌더링되지 않는 문제가 생길 수 있어요. 심지어 머신러닝 모델에 이런 빈 값이 들어간 데이터를 넣으면 즉시 에러를 뱉고 프로그램이 뻗어버리니 주의하세요.

4. Pandas와 Matplotlib으로 데이터 시각화하기

주가 선 그래프와 거래량 막대 그래프가 위아래로 배치된 태블릿 화면

데이터를 예쁘게 다듬었으니 이제 눈으로 결과를 확인해볼 차례예요. 숫자만 빼곡한 표를 들여다보고 있으면 직관적으로 시장의 흐름을 파악하기가 너무 어렵잖아요. 판다스에는 자체적으로 `.plot()` 기능이 내장되어 있어서 코드를 한 줄만 쳐도 간단한 선 그래프 정도는 금방 그릴 수 있어요. 하지만 진짜 전문가처럼 주가 차트 아래에 거래량 막대그래프를 예쁘게 따로 배치하고 싶다면, 파이썬 시각화의 근본인 Matplotlib 라이브러리의 subplots 기능을 활용해야 해요.

subplots를 사용하면 도와지를 여러 개의 작은 창(패널)으로 쪼갤 수 있어요. 우리는 화면을 위아래 두 개로 나누어서, 위쪽 창에는 애플의 종가와 20일 이동 평균선을 겹쳐 그리고, 아래쪽 창에는 그날그날 얼마나 주식이 사고팔렸는지를 보여주는 거래량을 그릴 거예요.

python
plot_charts.py
import matplotlib.pyplot as plt

# 위아래로 2개(2행 1열)의 그래프 영역을 만들어요. sharex=True로 x축(날짜)을 공유해요.
fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, figsize=(10, 6), sharex=True)

# 첫 번째 영역(ax1)에 종가와 20일 이동 평균선을 선 그래프로 그려요.
ax1.plot(df.index, df['Close'], label='Close Price', color='black')
ax1.plot(df.index, df['MA20'], label='MA 20', color='blue', linestyle='--')
ax1.set_title('AAPL Price & MA20')
ax1.legend() # 범례(어느 선이 무엇인지 알려주는 박스)를 표시해요.

# 두 번째 영역(ax2)에 거래량을 막대 그래프로 그려요.
ax2.bar(df.index, df['Volume'], label='Volume', color='gray', alpha=0.5)
ax2.set_title('Trading Volume')
ax2.legend()

# 그래프 간 간격이 겹치지 않게 자동으로 예쁘게 정렬해줘요.
plt.tight_layout()
plt.show()

이 코드에서 가장 눈여겨봐야 할 핵심은 바로 sharex=True 옵션이에요. 만약 이 옵션이 없었다면 위쪽 그래프와 아래쪽 그래프의 날짜 눈금이 서로 따로 놀게 될 수 있어요. 하지만 이 마법의 옵션을 켜두면, 나중에 완성된 그래프 창에서 마우스로 위쪽 주가 차트를 줌인하거나 좌우로 드래그할 때 아래쪽 거래량 그래프도 완벽하게 똑같이 연동되어 움직이게 돼요. 주가와 거래량은 같은 날짜를 기준으로 비교되어야 의미가 있기 때문에, 다중 시계열 차트를 그릴 때는 무조건 넣어줘야 하는 필수 옵션이라는 점 잊지 마세요.

5. ta 라이브러리로 핵심 기술지표 한 번에 계산하기

볼린저 밴드와 여러 기술지표가 함께 그려진 화려한 주식 차트

주식을 분석하다 보면 수많은 트레이더들이 참고하는 기술적 지표라는 단어를 듣게 되실 거예요. MACD, RSI, 볼린저 밴드 같은 이름들 들어보셨죠? 이런 지표들은 통계적 공식을 바탕으로 현재 주가가 어떤 상태인지 힌트를 주는 역할을 해요. 물론 이런 지표들을 판다스 기본 함수만 가지고 처음부터 끝까지 수식을 짜서 만들 수도 있어요. 하지만 수식이 복잡해서 오타가 나기도 쉽고 너무 번거롭잖아요. 이럴 때 파이썬 생태계의 꽃인 외부 라이브러리를 활용하면 됩니다. 바로 `ta` (Technical Analysis) 라이브러리를 쓰면 복잡한 코딩 없이 단 한 줄의 코드로 이 강력한 지표들을 뚝딱 뽑아낼 수 있어요.

우리는 실무에서 가장 많이 쓰이는 세 가지 지표를 계산해볼 거예요. MACD는 단기 추세와 장기 추세가 만나는 점을 이용해 추세가 꺾이는 신호를 포착하고요, RSI는 현재 가격이 정상적인 범위를 벗어나 너무 비싸게 올랐는지(과매수) 아니면 지나치게 떨어졌는지(과매도)를 0에서 100 사이의 점수로 알려줘요. 마지막으로 볼린저 밴드는 주가가 움직일 수 있는 확률적인 상한선과 하한선을 밴드 형태로 그려서 변동성을 시각적으로 보여주는 훌륭한 지표랍니다.

python
calc_indicators.py
# 터미널에서 pip install ta 를 먼저 실행해서 라이브러리를 설치해주세요.
import ta

# 1. MACD 계산 (MACD 선과 신호선의 차이인 히스토그램 값을 구해요)
df['MACD_diff'] = ta.trend.macd_diff(df['Close'])

# 2. RSI 계산 (통상적으로 70 이상이면 과매수, 30 이하면 과매도로 해석해요)
df['RSI'] = ta.momentum.rsi(df['Close'], window=14)

# 3. 볼린저 밴드 상단과 하단 계산 (가격의 상하한 범위를 밴드 형태로 보여줘요)
bb = ta.volatility.BollingerBands(df['Close'], window=20, window_dev=2)
df['BB_upper'] = bb.bollinger_hband()
df['BB_lower'] = bb.bollinger_lband()

# 지표들이 데이터프레임에 잘 들어갔는지 끝부분(tail)을 확인해볼게요.
print(df[['Close', 'MACD_diff', 'RSI', 'BB_upper', 'BB_lower']].tail())

정말 간단하죠? 복잡한 수학 공식은 라이브러리가 알아서 처리해주기 때문에 우리는 어떤 열에 넣을지 변수명만 잘 정해주면 끝나요.

💡 Tip

RSI 수치를 해석할 때 한 가지 주의할 점이 있어요. 보통 70이 넘으면 과열이라고 해서 매도를 고려하라고 배우지만, 상승장이 강할 때는 70 이상인 상태로 주가가 몇 달이고 계속 올라가기도 해요. 보조 지표는 말 그대로 보조일 뿐이니 이 지표 하나만 믿고 즉각적인 매도 버튼을 누르는 실수는 피하셔야 해요. 여러 지표를 조합해서 확률을 높이는 것이 진짜 실력이랍니다.

6. 종합 분석 대시보드 시각화

전문 트레이더의 웅장한 종합 주식 분석 대시보드

드디어 하이라이트입니다. 지금까지 차곡차곡 준비해 둔 주가 데이터, 볼린저 밴드, MACD, RSI를 한 화면에 묶어서 멋진 대시보드 형태로 시각화해볼 거예요. 실무에서 퀀트 분석가들이나 전문 트레이더들이 모니터 여러 대에 띄워두고 종일 쳐다보는 바로 그 차트 화면을 파이썬 코드로 직접 구현해 내는 거죠.

여기서 Matplotlib의 고급 테크닉이 하나 들어갑니다. 바로 gridspec_kw 옵션인데요, 여러 개의 서브플롯을 그릴 때 각각의 세로 크기 비율을 내 마음대로 조절할 수 있게 해주는 기능이에요. 주가 차트가 가장 중요하니까 제일 크게 영역을 할당하고, 그 밑에 보조 지표들은 상대적으로 작게 3:1:1 비율로 배치해 볼 거예요.

python
dashboard.py
import matplotlib.pyplot as plt

# 3개의 그래프 영역을 만들되, 높이 비율을 3:1:1로 설정해요.
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(12, 10), sharex=True, 
                         gridspec_kw={'height_ratios': [3, 1, 1]})
ax1, ax2, ax3 = axes # 리스트 형태로 반환된 영역들을 각 변수에 나눠 담아요.

# 첫 번째 영역 (주가와 볼린저 밴드)
ax1.plot(df.index, df['Close'], label='Close', color='black', linewidth=1.5)
ax1.plot(df.index, df['BB_upper'], label='Upper Band', color='gray', linestyle='--')
ax1.plot(df.index, df['BB_lower'], label='Lower Band', color='gray', linestyle='--')
# fill_between을 사용해 상단 밴드와 하단 밴드 사이의 공간을 옅은 회색으로 칠해줘요.
ax1.fill_between(df.index, df['BB_upper'], df['BB_lower'], color='gray', alpha=0.1)
ax1.set_title('AAPL Technical Analysis Dashboard')
ax1.legend(loc='upper left')

# 두 번째 영역 (MACD 히스토그램)
# 파이썬 리스트 컴프리헨션을 써서 MACD 값이 0보다 크면 초록색, 작으면 빨간색으로 칠해요.
colors = ['green' if val >= 0 else 'red' for val in df['MACD_diff']]
ax2.bar(df.index, df['MACD_diff'], color=colors, alpha=0.5)
ax2.set_ylabel('MACD')

# 세 번째 영역 (RSI)
ax3.plot(df.index, df['RSI'], label='RSI', color='purple')
# axhline으로 과매수(70)와 과매도(30) 기준선 위치에 가로 점선을 그어줘요.
ax3.axhline(70, color='red', linestyle='--', alpha=0.5)
ax3.axhline(30, color='green', linestyle='--', alpha=0.5)
ax3.set_ylim(0, 100) # RSI는 항상 0~100 사이의 값을 가지므로 y축을 고정해요.
ax3.set_ylabel('RSI')

plt.tight_layout()
plt.show()

코드가 조금 길어 보여서 흠칫 하셨을 수도 있지만, 찬찬히 뜯어보면 우리가 앞선 4섹션에서 배웠던 서브플롯 그리기를 세 번 반복한 것에 불과해요. fill_between 같은 디테일한 기능을 사용해 밴드 사이의 색을 칠해주고, MACD 값이 양수인지 음수인지에 따라 막대그래프 색상을 다르게 주니까 차트가 훨씬 다채롭고 전문가스러워 보이죠? 이제 이 코드를 뼈대 삼아 여러분이 좋아하는 색상이나 디자인으로 조금씩 튜닝해가면서 나만의 대시보드를 완성해 보세요.

7. 시리즈 마무리 및 다음 단계 (백테스팅)

알고리즘 트레이딩과 백테스팅을 상징하는 톱니바퀴와 차트

정말 수고 많으셨어요! 이렇게 해서 총 5편에 걸쳐 숨 가쁘게 달려온 판다스 입문 시리즈가 모두 끝났어요. 1편에서 빈 껍데기 같은 데이터를 불러오는 법부터 시작해서 데이터의 일부만 선택하는 법, 골치 아픈 결측치 처리, 날짜 다루기, 여러 데이터를 하나로 합치는 결합과 그룹화(groupby)를 거쳐, 오늘의 화려한 시계열 시각화 대시보드까지 정말 많은 것을 배웠네요. 장담하건대, 지금까지 배운 이 내용들만 자유자재로 다뤄도 실무에서 주어지는 데이터 가공 업무의 80% 이상은 거뜬히 해내실 수 있을 거예요.

그런데 기껏 이렇게 멋진 지표를 계산해 놓고 단순히 눈으로만 구경하고 끝나면 너무 아쉽지 않나요? “RSI가 30 이하로 떨어졌다가 다시 30 위로 올라올 때 주식을 산다” 같은 명확한 나만의 투자 룰을 파이썬 코드로 만들 수가 있어요. 그리고 이 조건대로 매매를 했다고 가정하고 과거 수십 년 치의 데이터에 적용해 봤을 때, 내 계좌의 수익이 얼마나 났을지, 손실은 얼마나 컸을지 수학적으로 검증하는 과정을 바로 ‘백테스팅(Backtesting)’이라고 불러요.

❗ 중요

백테스팅을 할 때 절대 잊지 말아야 할 명언이 있어요. “과거의 수익이 미래의 결과를 보장하지 않는다”라는 말이에요. 과거 데이터에만 딱 맞게 전략을 과도하게 최적화(Overfitting)하면 막상 실전에서는 큰 손실을 볼 수 있으니, 항상 보수적인 관점에서 전략을 평가해야 해요.

지금까지 우리가 작성한 판다스 코드를 기반으로 주식 데이터 시각화 이후의 백테스팅 가이드를 참고해 보세요. 이 링크의 라이브러리를 활용하면 내가 만든 전략을 아주 쉽게 테스트해 볼 수 있어요. 나만의 투자 전략을 직접 검증해 보는 심화 프로젝트에 꼭 도전해 보시길 바라요. 단순한 코딩 공부를 넘어서, 코딩으로 돈을 버는 퀀트 투자의 첫걸음이 될 테니까요. 그동안 시리즈를 따라와 주셔서 감사합니다!

자주 묻는 질문

Q. 예제에 쓰인 실전 주식 데이터(CSV)는 어떻게 수집하고 생성할 수 있나요?

외부 라이브러리인 yfinance를 사용하면 매우 쉽고 빠르게 해결할 수 있어요. 종목 코드(예: AAPL)와 조회하고 싶은 시작 날짜, 종료 날짜를 지정해 최신 주식 데이터를 곧바로 다운로드할 수 있습니다. 이후 판다스 DataFrame이 기본 제공하는 to_csv() 메서드를 활용해 파일 형태로 저장해두면, 매번 인터넷 연결 없이도 분석을 진행할 수 있습니다. 본문의 1번 섹션에 작성된 파이썬 코드를 그대로 복사해서 실행해 보세요.

Q. 이동평균이나 기술지표 계산 시 발생하는 초기 결측치(NaN)는 반드시 삭제해야 하나요?

네, 가능하면 삭제하는 것을 강력하게 권장해요. 결측치가 남아 있는 채로 분석을 이어가면 시각화 시 차트 앞부분의 선이 뚝 끊겨 있거나 아예 비어 있게 됩니다. 더 심각한 건, 이 데이터를 이용해 머신러닝이나 딥러닝 모델에 넣을 때 곧바로 오류를 뿜어내며 프로그램이 정지될 수 있다는 점이에요. 기술지표 특성상 초깃값 계산을 위해 과거 N일이 필요해 발생하는 필연적인 현상이므로, 지표 연산이 모두 끝난 후 dropna()를 통해 데이터를 깔끔히 정리하고 활용하는 습관을 들이는 것이 좋습니다.

Q. Pandas로 지표를 계산하고 시각화하는 방법을 전부 배웠습니다. 이후 어떤 실전 프로젝트를 진행해 볼 수 있을까요?

가장 추천하는 다음 단계는 방금 시각화한 지표들을 코드로 구체화하여 나만의 매매 룰(Rule)을 만들어보는 거예요. 예를 들어 ‘MACD가 신호선을 상향 돌파하고, 동시에 RSI가 40 이상일 때 매수한다’와 같은 조건을 코딩하는 거죠. 이후 backtesting.py 나 Zipline과 같은 파이썬 전용 백테스팅 라이브러리를 활용하여, 해당 전략이 2010년부터 지금까지의 과거 데이터에서 실제로 돌렸다면 수익률이 얼마나 나왔을지 검증해보는 심화 프로젝트를 해보세요. 실력이 비약적으로 상승할 거예요.

이 글이 마음에 드세요?

RSS 피드를 구독하세요!

댓글 남기기