코스닥150레버리지. 2011-01-01 ~ 2023-12-31. 점수 ±80. 뉴스단어(3000, -3000)
# 2009년 7월 15일부터
# 2023년 9월 29일까지
# 분석할 수 있음!
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
def createDataFrame(stock, start, end):
df = stock.history(start=start, end=end)
df["Change"] = df["Close"].pct_change() # 전날 대비 변화율
df.index = pd.to_datetime(df.index).strftime("%Y-%m-%d") # 날짜 형식 간단하게 만들기
df2 = pd.read_csv("/Users/ryujonghyeok/Jonghyeok/Sejong/SAI/자료모음집2.csv") # 지표 데이터
df = pd.merge(df, df2, on="Date")
df.set_index("Date", inplace=True)
return df
def buy(현금보유량, 주식보유량, 현재주가):
if 주식보유량 == 0:
주식보유량 = 현금보유량 // 현재주가
현금보유량 -= 주식보유량 * 현재주가
# print(f"Bought at {현재주가} with {주식보유량} stocks")
return 현금보유량, 주식보유량
def sell(현금보유량, 주식보유량, 현재주가):
if 주식보유량 > 0:
현금보유량 += 주식보유량 * 현재주가
주식보유량 = 0
# print(f"Sold at {현재주가} with {주식보유량} stocks")
return 현금보유량, 주식보유량
def total_asset(현금보유량, 주식보유량, 현재주가):
return 현금보유량 + 주식보유량 * 현재주가
def score_calculate(i):
bullishWords = {'rally': 0.2074, 'rise': 0.1983, 'high': 0.1416, 'gain': 0.0460, 'up': 0.0678, 'recovery': 0.0278, 'soar': 0.0056, 'bull': 0.0010, 'boom': 0.0010} # 상승 🤑
bearishWords = {'fall': 0.1103, 'low': 0.0597, 'drop': 0.0465, 'down': 0.0288, 'decline': 0.0243, 'sink': 0.0137, 'recession': 0.0101, 'loss': 0.0061, 'bear': 0.0040} # 하락 🤑
물가지수 = df.iloc[i]["물가지수"]
콜금리 = df.iloc[i]["콜금리"]
회사채금리 = df.iloc[i]["회사채"]
주택매매지수 = df.iloc[i]["주택지수"]
국민총소득 = df.iloc[i]["GNI"]
뉴스 = df.iloc[i]["Title"]
score = (-51.2)*물가지수 + 306.67*콜금리 + 40.01*회사채금리 + 26.84*주택매매지수 + 4.35*국민총소득 # 🤑
for word in 뉴스.split():
if word in bullishWords:
score += bullishWords[word] * 3000 # 🤑
elif word in bearishWords:
score -= bearishWords[word] * 3000 # 🤑
return score
buyAndHold_plt = []
# 시작시점에 매수 후 종료시점에 매도
def strategy_buyAndHold(df):
global buyAndHold_plt
현금보유량 = 1000000
주식보유량 = 0
현금보유량, 주식보유량 = buy(현금보유량, 주식보유량, df.iloc[0].Close)
buyAndHold_plt = []
for i in range(1, len(df)-1):
buyAndHold_plt.append(total_asset(현금보유량, 주식보유량, df.iloc[i].Close))
현금보유량 += 주식보유량 * df.iloc[-1].Close
print(f"그냥 가만히 - 현금보유량: {현금보유량:.2f}, profit: {(현금보유량-1000000)/1000000*100:.2f}%")
difference_plt = []
# 최고점 대비 일정 비율 하락하면 매도, 최저점 대비 일정 비율 상승하면 매수
def strategy_difference(df):
global difference_plt
현금보유량 = 1000000
주식보유량 = 0
dif1 = 0.36 # 일정 비율 하락하는 정도 🤑
dif2 = 0.02 # 일정 비율 상승하는 정도 🤑
minimum = float('inf')
maximum = float('-inf')
for i in range(2, len(df)):
price = df.iloc[i].Close
if price > maximum:
maximum = price
elif price < minimum:
minimum = price
if 주식보유량 > 0 and price < maximum * (1-dif1):
#print(f"Sold at {price(hist, i)}")
현금보유량, 주식보유량 = sell(현금보유량, 주식보유량, price)
maximum = float('-inf')
elif 주식보유량 == 0 and price > minimum * (1+dif2):
#print(f"Bought at {price(hist, i)}")
현금보유량, 주식보유량 = buy(현금보유량, 주식보유량, price)
minimum = float('inf')
difference_plt.append(total_asset(현금보유량, 주식보유량, price))
현금보유량 += 주식보유량 * df.iloc[-1].Close
주식보유량 = 0
print(f"변화율 비교 - 현금보유량: {현금보유량:.2f}, profit: {(현금보유량-1000000)/1000000*100:.2f}%")
score_plt = []
# 복합적인 요소를 분석하여 일정 조건에 따라 매수 및 매도 반복
def strategy_score(df):
global score_plt
현금보유량 = 1000000
주식보유량 = 0
#현금보유량, 주식보유량 = buy(현금보유량, 주식보유량, df.iloc[0].Close)
for i in range(len(df)):
# 점수 계산하기
score = score_calculate(i)
if i % 500 == 0: # 대략적인 'score'를 파악하기 위해 30일마다 'score' 출력
print(f"{i}일차 점수: {score}")
현재주가 = df.iloc[i].Close
# 점수가 일정 기준보다 클 때 매수하기
if score > 80:
현금보유량, 주식보유량 = buy(현금보유량, 주식보유량, 현재주가)
# 점수가 일정 기준보다 작을 때 매도하기
elif score < -80:
현금보유량, 주식보유량 = sell(현금보유량, 주식보유량, 현재주가)
score_plt.append(total_asset(현금보유량, 주식보유량, 현재주가))
현금보유량, 주식보유량 = sell(현금보유량, 주식보유량, df.iloc[-1].Close)
print(f"가중치 계산 - 현금보유량: {현금보유량:.2f} profit: {(현금보유량-1000000)/1000000*100:.2f}%")
# Stock 정의하기 🤑
stock = yf.Ticker("233740.KS")
# 데이터프레임 만들기 🤑
start="2011-01-01"
end="2023-12-31"
df = createDataFrame(stock, start, end)
strategy_buyAndHold(df)
strategy_difference(df)
strategy_score(df)
# 그래프 그리기
plt.figure(figsize=(20, 10))
plt.plot(df.index[:-2], buyAndHold_plt, label="buyAndHold", color='grey')
plt.plot(df.index[:-2], difference_plt, label="difference", color='black')
plt.plot(df.index, score_plt, label="score", color='red')
plt.legend()
plt.show()