File size: 5,826 Bytes
b9cf696
687d3dc
b8aa6cf
 
b9cf696
b8aa6cf
b9cf696
b8aa6cf
b9cf696
2bdbf95
b9cf696
b8aa6cf
b9cf696
 
8130080
 
 
 
b9cf696
b8aa6cf
 
 
 
 
b9cf696
b8aa6cf
 
 
 
 
b9cf696
b8aa6cf
b9cf696
 
b8aa6cf
 
 
 
 
b9cf696
b8aa6cf
 
b9cf696
e9fe77c
b8aa6cf
 
b9cf696
 
 
 
 
 
 
 
 
b8aa6cf
b9cf696
ac80e92
b9cf696
97a16e9
 
b9cf696
97a16e9
e9fe77c
97a16e9
 
b9cf696
97a16e9
 
 
 
 
 
 
 
 
 
 
b9cf696
97a16e9
b9cf696
 
97a16e9
 
 
 
 
 
b9cf696
b8aa6cf
97a16e9
b8aa6cf
b9cf696
 
 
aee3e85
97a16e9
 
 
 
 
 
 
 
 
b9cf696
97a16e9
b9cf696
 
97a16e9
 
 
467f517
97a16e9
 
b9cf696
97a16e9
 
 
 
 
c17ae48
 
 
b8aa6cf
c17ae48
8d3265b
97a16e9
 
b9cf696
97a16e9
 
 
b9cf696
aee3e85
97a16e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2bdbf95
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# ν•„μš”ν•œ 라이브러리 μ„€μΉ˜ 및 μ—…λ°μ΄νŠΈ
import subprocess

subprocess.run(["pip", "install", "--upgrade", "pip"])
subprocess.run(["pip", "install", "--upgrade", "yfinance", "gradio", "matplotlib", "Pillow"])

# 라이브러리 μž„ν¬νŠΈ
import yfinance as yf
import gradio as gr
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import numpy as np
import pandas as pd
import re
import io
from PIL import Image
from datetime import datetime, timedelta

# λ‚˜λˆ”κ³ λ”• 폰트 μ„€μΉ˜ 및 적용
def install_nanum_font():
    try:
        subprocess.run(["apt-get", "update"], check=True)
        subprocess.run(["apt-get", "install", "-y", "fonts-nanum"], check=True)
        subprocess.run(["fc-cache", "-fv"], check=True)
        plt.rcParams['font.family'] = 'NanumGothic'
    except Exception as e:
        print(f"폰트 μ„€μΉ˜ 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {e}")

install_nanum_font()

# λ‰΄μŠ€ μš”μ•½ ν•¨μˆ˜ (μ—¬κΈ°μ„œλŠ” κ°„λ‹¨νžˆ μ˜ˆμ‹œλ‘œ 처리)
def get_real_news_summary(company, date):
    # μ‹€μ œ APIλ₯Ό μ‚¬μš©ν•  수 μ—†λŠ” ν™˜κ²½μ΄λ―€λ‘œ, κ°„λ‹¨ν•œ λ¬Έμžμ—΄λ‘œ λŒ€μ²΄ν•©λ‹ˆλ‹€.
    return f"{company}의 {date} μ£Όλ³€ λ‰΄μŠ€ μš”μ•½μž…λ‹ˆλ‹€."

def handle_click(company_name, date_clicked):
    return get_real_news_summary(company_name, date_clicked)

def update_news(input_value, selected_date):
    if not selected_date:
        return "λ‚ μ§œλ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”."
    else:
        ticker = name_to_ticker.get(input_value, input_value)
        company_name = ticker_to_name.get(ticker, input_value)
        return handle_click(company_name, selected_date)

# μ’…λͺ©λͺ…κ³Ό 티컀 λ§€ν•‘ λ”•μ…”λ„ˆλ¦¬
name_to_ticker = {
    "SKλ°”μ΄μ˜€νŒœ": "326030.KS",
    "λ‚˜μŠ€λ‹₯ μ‹œμ΄ 1μœ„": "AAPL",
    "λ‚˜μŠ€λ‹₯ λ°”μ΄μ˜€ν… μ‹œμ΄ 1μœ„": "AMGN",
    "λ‚˜μŠ€λ‹₯ ν—¬μŠ€μΌ€μ–΄ μ‹œμ΄ 1μœ„": "JNJ",
    "μ½”μŠ€ν”Ό μ‹œμ΄ 1μœ„": "005930.KS",
    "μ½”μŠ€λ‹₯ μ‹œμ΄ 1μœ„": "247540.KQ",  # μ—μ½”ν”„λ‘œλΉ„μ— 
}

ticker_to_name = {v: k for k, v in name_to_ticker.items()}

# μ£Όκ°€ 데이터λ₯Ό κ°€μ Έμ˜€κ³  κ·Έλž˜ν”„λ₯Ό κ·Έλ¦¬λŠ” ν•¨μˆ˜
def display_stock_with_highlight(input_value, change_type, percent_change):
    try:
        ticker = name_to_ticker.get(input_value, input_value)
        stock = yf.Ticker(ticker)
        stock_data = stock.history(period="5y")

        if stock_data.empty:
            return "μ£Όκ°€ 데이터λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.", gr.Dropdown.update(choices=[])

        stock_data['Change'] = stock_data['Close'].pct_change() * 100
        percent_change = float(percent_change)

        if change_type == "μƒμŠΉ":
            highlight_data = stock_data[stock_data['Change'] >= percent_change]
            color = "darkorange"
        elif change_type == "ν•˜λ½":
            highlight_data = stock_data[stock_data['Change'] <= -percent_change]
            color = "purple"
        else:
            return "Invalid change type", gr.Dropdown.update(choices=[])

        dates = stock_data.index
        closing_prices = stock_data['Close']

        plt.figure(figsize=(10, 6))
        plt.plot(dates, closing_prices, color='gray', label=input_value)
        plt.scatter(highlight_data.index, highlight_data['Close'], color=color, label=f'{change_type} 포인트')

        for index, row in highlight_data.iterrows():
            plt.text(index, row['Close'], index.strftime('%Y-%m-%d'), fontsize=8, color=color, ha='right')
            plt.axvline(x=index, color=color, linestyle='--', linewidth=1)

        company_name = ticker_to_name.get(ticker, input_value)
        plt.title(f'{company_name} μ£Όκ°€ 좔이')
        plt.xlabel('λ‚ μ§œ')
        plt.ylabel('μ’…κ°€')
        plt.legend()

        buf = io.BytesIO()
        plt.savefig(buf, format='png')
        plt.close()
        buf.seek(0)
        img = Image.open(buf)

        highlight_dates = highlight_data.index.strftime('%Y-%m-%d').tolist()

        return img, gr.Dropdown.update(choices=highlight_dates)
    except Exception as e:
        print(f"Error: {e}")
        return f"데이터 처리 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {e}", gr.Dropdown.update(choices=[])

# Gradio μΈν„°νŽ˜μ΄μŠ€ 생성 (3μ—΄ λ ˆμ΄μ•„μ›ƒ)
with gr.Blocks() as demo:
    gr.Markdown("## μ£Όκ°€ κ·Έλž˜ν”„μ™€ λ‰΄μŠ€ μš”μ•½")

    with gr.Row():
        with gr.Column():
            input_value = gr.Textbox(label="μ’…λͺ©λͺ… λ˜λŠ” 티컀 μž…λ ₯", placeholder="예: SKλ°”μ΄μ˜€νŒœ, AAPL")
            change_type = gr.Dropdown(choices=["μƒμŠΉ", "ν•˜λ½"], label="μƒμŠΉ λ˜λŠ” ν•˜λ½ 선택", value="μƒμŠΉ")
            percent_change = gr.Textbox(label="변동 νΌμ„ΌνŠΈ (%)", placeholder="예: 10", value="10")
            submit_btn = gr.Button("Submit")

            examples = [["SKλ°”μ΄μ˜€νŒœ"],
                        ["λ‚˜μŠ€λ‹₯ μ‹œμ΄ 1μœ„"],
                        ["λ‚˜μŠ€λ‹₯ λ°”μ΄μ˜€ν… μ‹œμ΄ 1μœ„"],
                        ["λ‚˜μŠ€λ‹₯ ν—¬μŠ€μΌ€μ–΄ μ‹œμ΄ 1μœ„"],
                        ["μ½”μŠ€ν”Ό μ‹œμ΄ 1μœ„"],
                        ["μ½”μŠ€λ‹₯ μ‹œμ΄ 1μœ„"]]
            gr.Examples(examples=examples, inputs=[input_value])

        with gr.Column():
            plot = gr.Image(label="μ£Όκ°€ κ·Έλž˜ν”„")
            date_dropdown = gr.Dropdown(label="쑰건에 ν•΄λ‹Ήν•˜λŠ” λ‚ μ§œ 선택", choices=[])

        with gr.Column():
            news_output = gr.Markdown(label="λ‰΄μŠ€ μš”μ•½", value="")  # 빈 칸으둜 κΈ°λ³Έ ν‘œμ‹œ

    # Submit λ²„νŠΌ 클릭 μ‹œ κ·Έλž˜ν”„ 및 λ‚ μ§œ λ“œλ‘­λ‹€μš΄ μ—…λ°μ΄νŠΈ
    submit_btn.click(
        fn=display_stock_with_highlight,
        inputs=[input_value, change_type, percent_change],
        outputs=[plot, date_dropdown]
    )

    # λ‚ μ§œ 선택 μ‹œ λ‰΄μŠ€ μš”μ•½ μ—…λ°μ΄νŠΈ
    date_dropdown.change(
        fn=update_news,
        inputs=[input_value, date_dropdown],
        outputs=[news_output]
    )

demo.launch()