์ฝ”์Šคํ”ผ. 2020-01-01 ~ 2021-12-31. ์ ์ˆ˜ ยฑ80. ๋‰ด์Šค๋‹จ์–ด(3000, -3000)

แ„แ…ฉแ„…แ…ฉแ„‚แ…ก_แ„แ…ฉแ„‰แ…ณแ„‘แ…ต.png

# 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("^KS11")

# ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ๋งŒ๋“ค๊ธฐ ๐Ÿค‘
start="2020-01-01"
end="2022-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()