알토란7 2023. 9. 30. 02:22

최근 ChatGPT를 활용하여 주식 투자에 관한 다양한 시도가 증가하고 있습니다.

그 중 하나의 예시로, 2023년 8월 7일에 Medium에 게시된 기사를 국내 주식 시장에 맞게 수정하여 활용해보았습니다.

원래 글의 ChatGPT를 활용하는 아이디어도 참신하지만, 이 기사를 통해 pandas_ta 패키지와 이 패키지의 기술적 분석(TA) 지표를 시각화하는 코드는 매우 유용해 보입니다.

아래는 원문 기사의 내용입니다.

https://medium.com/@kokhua81/stocks-technical-analysis-ta-with-python-chatgpt-a-comprehensive-guide-871a756ebc7c

 

Stocks Technical Analysis (TA) with Python & ChatGPT: A Comprehensive Guide

Unlock stock insights using Python & ChatGPT. Analyze TA indicators, forecast trends, and gain valuable market sentiment.

medium.com

다음은 원문 기사를 국내 주식 종목 중 올 여름 가장 주목받는 에코프로 주식에 대한 분석으로 변형한 내용입니다. 이를 위해 OHLCV 데이터를 얻는 방법을 yfinance 패키지를 이용하던것에서 pykrx로 변경하였습니다.

OHLCV 데이터 얻기

google colab에서 수행하기 위해서 패키지를 설치합니다.

!pip install pandas_ta
!pip install pykrx

종목 데이터를 얻고난후에는 pandas_ta 분석 도구가 영문 OHLCV 컬럼이름을 사용하기 때문에 컬럼 이름 변경이 필요합니다.

import matplotlib.pyplot as plt
import pandas as pd
from pykrx import stock
import pandas_ta as ta
import matplotlib.dates as mdates
from datetime import datetime, timedelta

# 에코프로 종목 현재일 기준으로 120일 전부터의 종목 데이터 얻음
symbol = "086520"
end_date = datetime.today()
start_date = end_date - timedelta(days=120)  # 4 달전

# 시작일과 종료일 사이의 symbol의 OHLCV 데이터를 얻음
stock_data = stock.get_market_ohlcv(start_date, end_date, symbol)

# 한글 컬럼과 인덱스 이름을 TA 라이브러리를 사용하기 위해 영문으로 바꿈
stock_data.rename(columns={
    '시가': 'Open',
    '고가': 'High',
    '저가': 'Low',
    '종가': 'Close',
    '거래량': 'Volume',
    '등락률': 'Change'
}, inplace=True)
# Index 이름을 'Date'로 변경
stock_data.rename_axis('Date', inplace=True)

 위 코드를 실행하면 `stock_data`에는 다음과 같은 데이터가 얻어집니다.

DataFrame에 기술적 분석 지표 넣기

`pandas_ta` 패키지 설치시 pandas DataFrame에 래퍼를 제공해서 stock_data.ta 형식으로 TA API 접근이 가능합니다.

# Calculate technical indicators using pandas-ta
stock_data.ta.macd(append=True)
stock_data.ta.rsi(append=True)
stock_data.ta.bbands(append=True)
stock_data.ta.obv(append=True)

# Calculate additional technical indicators
stock_data.ta.sma(length=20, append=True)
stock_data.ta.ema(length=50, append=True)
stock_data.ta.stoch(append=True)
stock_data.ta.adx(append=True)

# Calculate other indicators
stock_data.ta.willr(append=True)
stock_data.ta.cmf(append=True)
stock_data.ta.psar(append=True)

#convert OBV to million
stock_data['OBV_in_million'] =  stock_data['OBV']/1e7
stock_data['MACD_histogram_12_26_9'] =  stock_data['MACDh_12_26_9'] # not to confuse chatGTP

# Summarize technical indicators for the last day
last_day_summary = stock_data.iloc[-1][['Close',
    'MACD_12_26_9','MACD_histogram_12_26_9', 'RSI_14', 'BBL_5_2.0', 'BBM_5_2.0', 'BBU_5_2.0','SMA_20', 'EMA_50','OBV_in_million', 'STOCHk_14_3_3',
    'STOCHd_14_3_3', 'ADX_14',  'WILLR_14', 'CMF_20',
    'PSARl_0.02_0.2', 'PSARs_0.02_0.2'
]]

print("에코프로 종목 가장 최근의 기술적 분석 자료:")
print(last_day_summary)

ChatGPT 프롬프트 만들기

ChatGPT 채팅창에 입력할 프롬프트를 생성하는 코드입니다.

## 프롬프트 작성
sys_prompt = """
아래는 한국 에코프로 종목의 가장 최근의 기술적 분석 자료입니다. 이 분석 자료를 통해 1주일후의 주가 전망을 말해주기 바랍니다.

에코프로 종목 가장 최근의 기술적 분석 자료:
{}""".format(last_day_summary)

print(sys_prompt)

위 코드가 생성한 프롬프트 입니다.

아래는 한국 에코프로 종목의 가장 최근의 기술적 분석 자료입니다. 이 분석 자료를 통해 1주일후의 주가 전망을 말해주기 바랍니다.

에코프로 종목 가장 최근의 기술적 분석 자료:
Close                     901000.000000
MACD_12_26_9              -55587.564421
MACD_histogram_12_26_9     -5199.206170
RSI_14                        39.140796
BBL_5_2.0                 844817.428309
BBM_5_2.0                 919400.000000
BBU_5_2.0                 993982.571691
SMA_20                    982200.000000
EMA_50                    992085.869665
OBV_in_million                 0.979703
STOCHk_14_3_3                 11.040074
STOCHd_14_3_3                 16.975701
ADX_14                        28.374610
WILLR_14                     -80.254777
CMF_20                        -0.141652
PSARl_0.02_0.2                      NaN
PSARs_0.02_0.2            985000.000000
Name: 2023-09-27 00:00:00, dtype: float64

ChatGPT에게 분석 의뢰하기

생성된 프롬프트의 제일 마지막 라인을 제외하고 내용 전체를 클립보드에 복사하여 ChatGPT 채팅창에 붙여넣기를 합니다.

다음은 ChatGPT의 위 프롬프트에 대한 답변입니다.

참고로 구글 bard에게도 동일하게 물었더니 짧은 답변을 줍니다.

둘 다 대답이 단기적으로 하락한다고 하니 1주일후 주가가 어떻게 되는지 추후 이 포스트에 업데이트 하겠습니다.

분석 결과 시각화

좌측 상단에 주가와 설정했던 지표 값을 차례대로 시각화 하는 코드입니다.

# Plot the technical indicators
plt.figure(figsize=(14, 8))

# Price Trend Chart
plt.subplot(3, 3, 1)
plt.plot(stock_data.index, stock_data['Close'], label='Close', color='blue')
plt.plot(stock_data.index, stock_data['EMA_50'], label='EMA_50', color='green')
plt.plot(stock_data.index, stock_data['SMA_20'], label='SMA_20', color='orange')
plt.title("Price Trend")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size
plt.legend()

# On-Balance Volume Chart
plt.subplot(3, 3, 2)
plt.plot(stock_data['OBV'], label='On-Balance Volume')
plt.title('On-Balance Volume (OBV) Indicator')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size
plt.legend()

# MACD Plot
plt.subplot(3, 3, 3)
plt.plot(stock_data['MACD_12_26_9'], label='MACD')
plt.plot(stock_data['MACDh_12_26_9'], label='MACD Histogram')
plt.title('MACD Indicator')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size
plt.title("MACD")
plt.legend()

# RSI Plot
plt.subplot(3, 3, 4)
plt.plot(stock_data['RSI_14'], label='RSI')
plt.axhline(y=70, color='r', linestyle='--', label='Overbought (70)')
plt.axhline(y=30, color='g', linestyle='--', label='Oversold (30)')
plt.legend()
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size
plt.title('RSI Indicator')

# Bollinger Bands Plot
plt.subplot(3, 3, 5)
plt.plot(stock_data.index, stock_data['BBU_5_2.0'], label='Upper BB')
plt.plot(stock_data.index, stock_data['BBM_5_2.0'], label='Middle BB')
plt.plot(stock_data.index, stock_data['BBL_5_2.0'], label='Lower BB')
plt.plot(stock_data.index, stock_data['Close'], label='Close', color='brown')
plt.title("Bollinger Bands")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size
plt.legend()

# Stochastic Oscillator Plot
plt.subplot(3, 3, 6)
plt.plot(stock_data.index, stock_data['STOCHk_14_3_3'], label='Stoch %K')
plt.plot(stock_data.index, stock_data['STOCHd_14_3_3'], label='Stoch %D')
plt.title("Stochastic Oscillator")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size
plt.legend()

# Williams %R Plot
plt.subplot(3, 3, 7)
plt.plot(stock_data.index, stock_data['WILLR_14'])
plt.title("Williams %R")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size

# ADX Plot
plt.subplot(3, 3, 8)
plt.plot(stock_data.index, stock_data['ADX_14'])
plt.title("Average Directional Index (ADX)")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size

# CMF Plot
plt.subplot(3, 3, 9)
plt.plot(stock_data.index, stock_data['CMF_20'])
plt.title("Chaikin Money Flow (CMF)")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b%d'))  # Format date as "Jun14"
plt.xticks(rotation=45, fontsize=8)  # Adjust font size

# Show the plots
plt.tight_layout()
plt.show()

시각화 결과