2010년부터 시작한 미국주식의 투자경험을 바탕으로, 매년 가트너에서 발표하는 10대 전략기술을 투자의 선행지표로 활용하여 투자하는 아이디어를 구상해 보았습니다.
목차
Langchain을 활용한 미국주식 투자하기 개요
왜 미국 IT주식인지?
시장을 초과하는 섹터는?
분석 내용
가트너 10대전략기술(2010-2024) 불러오기
랭체인을 활용하여 제 나름의 카테고리로 분류, 투자선정 기준 만들기
랭체인을 활용하여 매년 카테고리의 대장종목 뽑아내기
티커처리 등을 통해서 야후파이낸스 활 용 투자수익률 분석(1년 투자)
1천만원 투자 시뮬레이션을 통해 연평균 수익률(복리, 단리) 확인
1. Langchain을 활용한 미국주식 투자하기
1. 왜 미국 주식인지?
위 그래프에서 보는 바와 같이 미국 주식시장은 중국과 한국 대비 압도적인 퍼포먼스를 보여줍니다. 한국과 중국은 10여년간 거의 제자리인 반면 미국은 300%가 넘는 누적 수익을 가져왔습니다.
2. 시장을 초과하는 섹터는?
위 그래프에서 보는 바와 같이 최근 10년간 it 종목의 수익률은 500%로 타 섹터에 비해 압도적이므로, 지수 수익률을 상회 하는 미국 IT주식에 세부 투자 전략을 만들고자 하였습니다.
2. 분석내용
1. 가트너 10대전략기술(2010-2024) 불러오기
IT섹터의 선행지표로 매년 10대 전략기술을 발표하는 가트너의 자료를 활용(2010-2024)하여, IT카테고리를 세부 분류하기 위한 데이터를 준비하였습니다.
2. 랭체인을 활용하여 제 나름의 카테고리로 분류, 투자선정 기준 만들기
10여년 간 미국 IT주식을 투자한 경험을 바탕으로, 아래의 카테고리를 만들고 가트너 10대 트렌드를 랭체인을 활용하여 각각 분류합니다. 이를 통해 출력한 결과는 코드의 맨 아래와 같습니다.
import pandas as pd
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
# GPT 모델 설정
model = ChatOpenAI(model="gpt-4")
output_parser = StrOutputParser()
# 분류할 기술 목록에서 '기타인프라'를 제거
tech_categories = ["클라우드 인프라", "데이터분석 및 AI","블록체인", "엣지", "모바일", "가상증강현실", "3d프린팅", "디지털트윈", "보안", "기타", 'AI Hardware']
# 실제 가트너 데이터프레임 불러오기
actual_file_path = 'cleaned_gartner2022_transformed.xlsx'
actual_df = pd.read_excel(actual_file_path)
# 프롬프트 템플릿
prompt_template = ("다음 기술 트렌드를 주어진 기술 분류 중 하나로 분류하세요: {trend}\n"
"기술 분류 목록: {categories}\n"
"분류 결과만 출력해 주세요.")
def classify_trend(trend):
prompt = ChatPromptTemplate.from_template(prompt_template.format(trend=trend, categories=", ".join(tech_categories)))
chain = prompt | model | output_parser
try:
result = chain.invoke({})
return result.strip()
except Exception as e:
print(f"오류가 발생했습니다 (트렌드: {trend}): {e}")
return "기타"
# 데이터프레임에 "기술분류" 열 추가
actual_df['기술분류'] = actual_df['Trend'].apply(classify_trend)
# 'ai data'로 분류되지 않았지만 'ai'라는 단어가 포함된 트렌드에 대해 추가 분류
# def add_ai_data_category(row):
# if 'ai data' not in row['기술분류'].split(', ') and 'ai' in row['Trend'].lower():
# return row['기술분류'] + ', ai data'
# return row['기술분류']
# actual_df['기술분류'] = actual_df.apply(add_ai_data_category, axis=1)
# 변환된 데이터 확인
print("기술분류가 추가된 데이터프레임 확인:")
print(actual_df.head())
# 엑셀 파일로 저장
actual_df.to_excel("classified_gartner2022_revised.xlsx", index=False)
print("기술분류가 추가된 데이터프레임이 'classified_gartner2022_revised.xlsx' 파일로 저장되었습니다.")
# 출력 결과
기술분류가 추가된 데이터프레임 확인:
Year Number Trend 기술분류
0 2010 1 클라우드컴퓨팅 클라우드 인프라
1 2010 2 어드밴스드 애널리틱 데이터분석 및 AI
2 2010 3 클라이언트 컴퓨팅 클라이언트 컴퓨팅
3 2010 4 그린 IT 기타
4 2010 5 데이터센터의 재구성 클라우드 인프라
기술분류가 추가된 데이터프레임이 'classified_gartner2022_revised.xlsx' 파일로 저장되었습니다.이러한 기술 분류를 기반으로, 어떤 기준으로 기술 카테고리를 투자해야 할지 고민해 보았습니다.
가급적 보수적이고 안전한 투자를 위해, 기술분류 중 3년 연속 선정되고 해당연도 2회 이상 선정된 기술분류와 4년 연속 선정되고 해당연도 2회 이상 선정된 기술분류 두가지를 아래와 같이 뽑아보았습니다.
Year 3년연속_1년2회 4년연속_1년2회
0 2010
1 2011
2 2012 클라우드 인프라, 모바일, 데이터분석 및 ai
3 2013 클라우드 인프라, 모바일, 데이터분석 및 ai 클라우드 인프라, 모바일, 데이터분석 및 ai
4 2014 클라우드 인프라, 모바일 클라우드 인프라, 모바일
5 2015 클라우드 인프라, 데이터분석 및 ai 클라우드 인프라, 데이터분석 및 ai
6 2016 클라우드 인프라, 모바일, 데이터분석 및 ai 클라우드 인프라, 모바일, 데이터분석 및 ai
7 2017 데이터분석 및 ai 데이터분석 및 ai
8 2018 데이터분석 및 ai 데이터분석 및 ai
9 2019 데이터분석 및 ai 데이터분석 및 ai
10 2020 블록체인, 데이터분석 및 ai 블록체인, 데이터분석 및 ai
11 2021 클라우드 인프라, 보안, 데이터분석 및 ai 보안, 데이터분석 및 ai
12 2022 클라우드 인프라, 보안, 데이터분석 및 ai 클라우드 인프라, 보안, 데이터분석 및 ai
13 2023 클라우드 인프라, 데이터분석 및 ai 클라우드 인프라, 데이터분석 및 ai
14 2024 클라우드 인프라, 데이터분석 및 ai 클라우드 인프라, 데이터분석 및 ai위 기술분류를 살펴보면 2000년대 IT 트렌드를 이끌었던 모바일이 2010년 초반에도 등장하고 있고, 2010년대에 들어서면서 빅데이터 분석이 화두가 되고, 이를 처리하기 위한 클라우드가 등장하고 있음을 확인할 수 있습니다. 간간이 보안, 블록체인 등의 이슈 또한 등장하지만, 2010년대와 2020년대는 클라우드 인프라와 데이터분석이 테크 트렌드의 중심으로 자리하고 있음을 확인할 수 있습니다.
3. 랭체인을 활용하여 매년 카테고리의 대장종목 뽑아내기
보수적인 투자를 위해 4년연속 해당년도 1년2회 선정된 기술분류에 대한 해당년도 대장종목을 뽑아내려고 합니다. 랭체인을 활용하여 해당종목과 티커를 추출합니다.
import pandas as pd
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
# GPT 모델 설정
# model = ChatOpenAI(model="gpt-3.5-turbo")
model = ChatOpenAI(model="gpt-4")
output_parser = StrOutputParser()
# 프롬프트 템플릿
prompt_template = ("현재를 {year}년이라고 생각하고, {category} 분야에서 미국 상장주식 대장 기업 3개를 반드시 추천해줘. \
예를 들어 Amazon web service나 Microsoft Ajure와 같이 하나의 서비스라면 Amazon, Microsoft와 같이 모회사를 바로 알려줘"
"목록으로 만들어서 데이터 분석하려고 하니까 각각의 이름만 말해주되, 이름을 말했으면 ticker는 말하지마.")
def get_top_stocks(year, category):
prompt = ChatPromptTemplate.from_template(prompt_template.format(year=year, category=category))
chain = prompt | model | output_parser
try:
result = chain.invoke({})
companies = [line.strip().split('.')[1].strip() for line in result.split('\n') if line.strip()]
return companies
except Exception as e:
print(f"오류가 발생했습니다 (연도: {year}, 카테고리: {category}): {e}")
return []
def get_stock_ticker(company):
prompt = ChatPromptTemplate.from_template(f"{company}의 주식 티커를 알려줘. 티커만 말해줘.")
chain = prompt | model | output_parser
try:
result = chain.invoke({})
ticker = result.split(',')[0].strip() # 여러 티커가 나올 경우 첫 번째 티커만 선택
return ticker
except Exception as e:
print(f"오류가 발생했습니다 (기업: {company}): {e}")
return "Unknown"
def clean_company_name(name):
return ''.join([c for c in name if c.isalnum() or c.isspace()]).strip()
def save_top_stocks_to_excel_and_df(investment_df):
all_top_stocks = []
for _, row in investment_df.iterrows():
year = row['Year']
tech_categories = row['4년연속_1년2회'].split(', ')
for category in tech_categories:
if category: # 카테고리가 있는 경우만 처리
top_stocks = get_top_stocks(year, category)
for rank, stock in enumerate(top_stocks, start=1):
cleaned_stock = clean_company_name(stock)
ticker = get_stock_ticker(cleaned_stock)
all_top_stocks.append({'Year': year, 'Category': category, 'Rank': rank, 'Stock': cleaned_stock, 'Ticker': ticker})
top_stocks_df = pd.DataFrame(all_top_stocks)
top_stocks_df.to_excel("top_stocks_by_year_with_tickers_final.xlsx", index=False)
print("대장기업 목록이 'top_stocks_by_year_with_tickers_final.xlsx' 파일로 저장되었습니다.")
return top_stocks_df
# 기존에 로드된 투자대상 기술분류 데이터프레임
investment_df = investment_df_4y
# 대장기업 목록 저장 및 데이터프레임 반환
top_stocks_df = save_top_stocks_to_excel_and_df(investment_df)
# 데이터프레임 확인
print("최종 결과물 데이터프레임 확인:")
print(top_stocks_df.head())
# 데이터프레임을 변수로 저장하여 향후 사용
final_top_stocks_df = top_stocks_df
최종 결과물 데이터프레임 확인:
Year Category Rank Stock Ticker
0 2013 클라우드 인프라 1 Amazon AMZN
1 2013 클라우드 인프라 2 Microsoft MSFT
2 2013 클라우드 인프라 3 IBM IBM의 주식 티커는 IBM입니다.
3 2013 모바일 1 Apple AAPL
4 2013 모바일 2 Google GOOGL위의 결과를 확인해보면 IBM은 티커만 뽑아내지 못한 것을 확인할 수 있습니다. 티커를 추가로 가공하여 아래와 같은 결과를 얻을 수 있었습니다.
티커 추가 가공 후 데이터프레임 확인:
Year Category Rank Stock Ticker
0 2013 클라우드 인프라 1 Amazon AMZN
1 2013 클라우드 인프라 2 Microsoft MSFT
2 2013 클라우드 인프라 3 IBM IBM
3 2013 모바일 1 Apple AAPL
4 2013 모바일 2 Google GOOGL
.....
2023 클라우드 인프라 1 Amazon AMZN
2023 클라우드 인프라 2 Microsoft MSFT
2023 클라우드 인프라 3 Google GOOGL
2023 데이터분석 및 ai 1 Alphabet Inc GOOGL
2023 데이터분석 및 ai 2 Amazon Inc AMZN
2023 데이터분석 및 ai 3 Microsoft Corporation MSFT
2024 클라우드 인프라 1 Amazon AMZN
2024 클라우드 인프라 2 Microsoft MSFT
2024 클라우드 인프라 3 Google GOOGL
2024 데이터분석 및 ai 1 Amazon AMZN
2024 데이터분석 및 ai 2 Microsoft MSFT
2024 데이터분석 및 ai 3 Alphabet GOOGL2010년대 초반 IBM은 클라우드 업계에서 3위를 차지하고 있지만, 시간이 지남에 따라 그 자리를 google에게 물려주어 대장주로 등장하지 않게 됩니다. gpt가 업계의 변화에 따라 해당년도에 걸맞는 대장종목을 잘 선정하고 있음을 알 수 있습니다.
4. 티커처리 등을 통해서 야후 파이낸스 활용 각 종목 투자수익률 분석(1년씩 투자)
야후 파이낸스 라이브러리를 불러와, 해당 티커가 있는지 확인한 후, 선정된 기술분류 당 3개의 종목을 해당년도에 투자(1월초 매수, 12월말 매도)하는 전략의 각종목 투자수익율을 계산합니다.
import pandas as pd
import yfinance as yf
# final_top_stocks_df 데이터프레임 사용 (기존 데이터프레임 활용)
# 이미 존재하는 ticker_counts 데이터프레임을 사용
# ticker_counts = final_top_stocks_df.groupby(['Year', 'Ticker']).size().reset_index(name='Count')
# 투자 시작일과 종료일 설정
ticker_counts['Invest Start Date'] = ticker_counts['Year'].apply(lambda x: f"{x}-01-01")
ticker_counts['Invest Final Date'] = ticker_counts['Year'].apply(lambda x: f"{x}-12-31")
# 수익률 계산을 위한 열 추가
ticker_counts['Invest Start Price'] = 0.0
ticker_counts['Invest Final Price'] = 0.0
ticker_counts['Return'] = 0.0
# 주가 데이터 가져오기 및 수익률 계산
for index, row in ticker_counts.iterrows():
ticker = row['Updated Ticker']
start_date = row['Invest Start Date']
final_date = row['Invest Final Date']
try:
stock_data = yf.download(ticker, start=start_date, end=final_date)
if not stock_data.empty:
invest_start_price = stock_data['Adj Close'].iloc[0]
invest_final_price = stock_data['Adj Close'].iloc[-1]
ticker_counts.at[index, 'Invest Start Price'] = invest_start_price
ticker_counts.at[index, 'Invest Final Price'] = invest_final_price
ticker_counts.at[index, 'Return'] = (invest_final_price - invest_start_price) / invest_start_price
else:
print(f"주가 데이터가 없습니다: {ticker}, {start_date} to {final_date}")
except Exception as e:
print(f"오류가 발생했습니다: {ticker}, {e}")
# 결과 확인
print("연도별 티커와 수익률 데이터프레임 확인:")
print(ticker_counts.head())
# 엑셀 파일로 저장
ticker_counts.to_excel("ticker_returns_by_year.xlsx", index=False)
print("연도별 티커와 수익률 데이터가 'ticker_returns_by_year.xlsx' 파일로 저장되었습니다.")
#결과 표시
연도별 티커와 수익률 데이터프레임 확인:
Year Ticker Count Exists Updated Ticker Invest Start Date \
0 2013 AAPL 1 True AAPL 2013-01-01
1 2013 AMZN 3 True AMZN 2013-01-01
2 2013 GOOGL 1 True GOOGL 2013-01-01
3 2013 IBM 2 True IBM 2013-01-01
4 2013 MSFT 2 True MSFT 2013-01-01
Invest Final Date Invest Start Price Invest Final Price Return
0 2013-12-31 16.747730 17.340128 0.035372
1 2013-12-31 12.865500 19.668501 0.528779
2 2013-12-31 18.078600 27.732435 0.533992
3 2013-12-31 118.749161 114.925255 -0.032202
4 2013-12-31 22.492285 31.285889 0.390961
연도별 티커와 수익률 데이터가 'ticker_returns_by_year.xlsx' 파일로 저장되었습니다.5. 최초 1천만원 투자 시뮬레이션을 통해 연평균 수익률(복리, 단리 등) 확인
최초 1천만원을 원금으로 각 종목에 균등하게 투자하여, 총 수익률, 연평균 수익율(단리, 복리)를 구해봅니다. 아래의 결과와 같이 2013년 부터 2024년 까지 위 전략으로 투자하면 총 1,563%의 수익을 거두는 것을 확인하였습니다. 연평균 수익률(복리)로는 26%의 수익률을 거두는 것을 확인할 수 있습니다. 총 1,563%는 해당 기간 미국 주가지수 300%, IT주식 ETF 500%의 수익률임을 감안할 때, 더 나은 투자 결과를 확인 할 수 있었습니다.
투자 전기간 요약 데이터프레임 확인:
Invest Start Date Invest Final Date Total Investment Start \
0 2013-01-01 2024-12-31 10000000
Total Investment End Total Return Total Return (%) \
0 1.663838e+08 15.63838 1563.838007
Average Annual Return (Simple) Average Annual Return (Simple %) \
0 1.303198 130.319834
Average Annual Return (Compound) Average Annual Return (Compound %)
0 0.264035 26.403545막연하게 오래전부터, 확인하고 싶었던 투자전략 이지만, 비정형 분석, 크롤링의 번거로움 등으로 엄두를 내기 어려웠던 분석을 gpt와 랭체인을 통해 쉽게 구현할 수 있다는 사실을 확인하였습니다.
향후 RAG를 활용한 보다 안정적인 분석과, RSI, 재무정보 등 다양한 데이터를 접목하여 단기전략을 만들어 테스트 해보려고 합니다. 감사합니다.