Update app.py
Browse files
app.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1 |
-
# ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น ๋ฐ ์
๋ฐ์ดํธ๋ฅผ ์ต์๋จ์ ๋ฐฐ์น
|
2 |
import subprocess
|
3 |
|
4 |
# ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น ๋ฐ ์
๋ฐ์ดํธ
|
5 |
subprocess.run(["pip", "install", "--upgrade", "pip"])
|
6 |
subprocess.run(["pip", "install", "--upgrade", "openai", "yfinance", "gradio", "matplotlib", "Pillow"])
|
7 |
|
8 |
-
# ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ
|
9 |
import yfinance as yf
|
10 |
import os
|
11 |
import matplotlib.font_manager as fm
|
@@ -47,41 +45,33 @@ API_KEY = "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" # ์ฌ๊ธฐ์ P
|
|
47 |
|
48 |
# ๋ด์ค ์์ฝ์ ๊ฐ์ ธ์ค๋ ํจ์ (๊ธฐ์กด ์ฝ๋ ์ ์ง)
|
49 |
def get_real_news_summary(company, date):
|
50 |
-
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
51 |
client = OpenAI(api_key=API_KEY, base_url="https://api.perplexity.ai")
|
52 |
|
53 |
-
# ๋ ์ง
|
54 |
target_date = datetime.strptime(date, '%Y-%m-%d')
|
55 |
start_date = (target_date - timedelta(days=1)).strftime('%Y-%m-%d')
|
56 |
end_date = (target_date + timedelta(days=1)).strftime('%Y-%m-%d')
|
57 |
|
58 |
-
# API ์์ฒญ์ ์ํ ๋ฉ์์ง ๊ตฌ์ฑ - ํ๊ตญ์ด๋ก๋ง ์๋ต์ ๋ฐ๋๋ก ์ง์
|
59 |
messages = [
|
60 |
{"role": "system", "content": "You are a helpful assistant that summarizes stock news strictly in Korean."},
|
61 |
{"role": "user", "content": f"Summarize the stock news for {company} between {start_date} and {end_date} in Korean. Only focus on news within this date range."}
|
62 |
]
|
63 |
|
64 |
try:
|
65 |
-
# API ์์ฒญ
|
66 |
response = client.chat.completions.create(
|
67 |
model="llama-3.1-sonar-large-128k-online",
|
68 |
messages=messages
|
69 |
)
|
70 |
-
|
71 |
-
# ์๋ต์์ ์์ฝ ์ถ์ถ
|
72 |
summary = response.choices[0].message.content
|
73 |
|
74 |
# ํ๊ธ, ์ซ์, ๊ณต๋ฐฑ, ํน์ ๊ธฐํธ๋ง ๋จ๊ธฐ๋ ์ ๊ท ํํ์
|
75 |
korean_only_summary = re.sub(r'[^\w\s#.,!%()\-\[\]]', '', summary)
|
76 |
-
|
77 |
-
# ##๋ก ์์ํ๋ ๋ถ๋ถ์ **์ผ๋ก ๊ฐ์ธ์ Bold ์ฒ๋ฆฌ
|
78 |
formatted_summary = re.sub(r'##\s*(.+)', r'**\1**', korean_only_summary)
|
79 |
|
80 |
return formatted_summary
|
81 |
except Exception as e:
|
82 |
return f"๋ด์ค ์์ฝ ์ค ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}"
|
83 |
|
84 |
-
# ๋ด์ค ์์ฝ์ ๊ฐ์ ธ์ค๋ ํจ์
|
85 |
def handle_click(company_name, date_clicked):
|
86 |
return get_real_news_summary(company_name, date_clicked)
|
87 |
|
@@ -90,16 +80,11 @@ def update_news(input_value, selected_date):
|
|
90 |
if selected_date == "" or selected_date is None:
|
91 |
return "๋ ์ง๋ฅผ ์ ํํด์ฃผ์ธ์."
|
92 |
else:
|
93 |
-
# ์ข
๋ชฉ๋ช
์ ๊ฐ์ ธ์์ Perplexity๋ก ๊ฒ์
|
94 |
ticker = get_dynamic_ticker(input_value)
|
95 |
-
company_name =
|
96 |
return handle_click(company_name, selected_date)
|
97 |
|
98 |
-
#
|
99 |
-
ticker_to_name = {}
|
100 |
-
name_to_ticker = {}
|
101 |
-
|
102 |
-
# ๋ชจ๋ ์์ ๋ฅผ ๋์ ์ผ๋ก ๋งค์นญํ๊ธฐ ์ํ ํจ์
|
103 |
def get_dynamic_ticker(input_value):
|
104 |
if input_value == "๋์ค๋ฅ ์์ด 1์":
|
105 |
return get_top_market_cap_stock("๋์ค๋ฅ")
|
@@ -112,18 +97,15 @@ def get_dynamic_ticker(input_value):
|
|
112 |
elif input_value == "์ฝ์ค๋ฅ ์์ด 1์":
|
113 |
return get_top_market_cap_stock("์ฝ์ค๋ฅ")
|
114 |
else:
|
115 |
-
# ์ฌ์ ์ ๋ฑ๋ก๋ ์ข
๋ชฉ๋ช
๋ฐํ
|
116 |
return name_to_ticker.get(input_value, input_value)
|
117 |
|
118 |
-
# ์๊ฐ์ด์ก ์์
|
119 |
def get_top_market_cap_stock(market, sector=None, industry=None):
|
120 |
-
# yfinance๋ ์ข
๋ชฉ ๋ชฉ๋ก์ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก, ETF๋ฅผ ํ์ฉ
|
121 |
if market == "๋์ค๋ฅ":
|
122 |
-
etf_ticker = "QQQ"
|
123 |
elif market == "์ฝ์คํผ":
|
124 |
-
etf_ticker = "EWY"
|
125 |
elif market == "์ฝ์ค๋ฅ":
|
126 |
-
# ์ฝ์ค๋ฅ ์ข
๋ชฉ์ ์ ๊ทผํ๊ธฐ ์ด๋ ค์ฐ๋ฏ๋ก ์ฌ์ ์ ์๋ ๋ฆฌ์คํธ ์ฌ์ฉ
|
127 |
tickers = ["035420.KQ", "068270.KQ", "035720.KQ"]
|
128 |
else:
|
129 |
return None
|
@@ -158,10 +140,9 @@ def get_top_market_cap_stock(market, sector=None, industry=None):
|
|
158 |
# ์ฃผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์กฐ๊ฑด์ ๋ง๋ ๋ ์ง์ ๊ทธ๋ํ๋ฅผ ๋ฐํํ๋ ํจ์
|
159 |
def display_stock_with_highlight(input_value, change_type, percent_change):
|
160 |
try:
|
161 |
-
# ์
๋ ฅ๊ฐ์ ํฐ์ปค๋ก ๋ณํ
|
162 |
ticker = get_dynamic_ticker(input_value)
|
163 |
stock = yf.Ticker(ticker)
|
164 |
-
stock_data = stock.history(period="5y")
|
165 |
|
166 |
if stock_data.empty:
|
167 |
return "์ฃผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.", []
|
@@ -189,7 +170,6 @@ def display_stock_with_highlight(input_value, change_type, percent_change):
|
|
189 |
plt.text(index, row['Close'], index.strftime('%Y-%m-%d'), fontsize=10, fontweight='bold', color=color, ha='right')
|
190 |
plt.axvline(x=index, color=color, linestyle='--', linewidth=1)
|
191 |
|
192 |
-
# ์ข
๋ชฉ๋ช
+ '์ฃผ๊ฐ ์ถ์ด'๋ก ์ ๋ชฉ ์ค์ (์ข
๏ฟฝ๏ฟฝ๏ฟฝ๋ช
๊ธฐ๋ฐ)
|
193 |
company_name = ticker_to_name.get(ticker, input_value)
|
194 |
plt.title(f'{company_name} ์ฃผ๊ฐ ์ถ์ด', fontproperties=font_prop)
|
195 |
plt.xlabel('๋ ์ง', fontproperties=font_prop)
|
|
|
|
|
1 |
import subprocess
|
2 |
|
3 |
# ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น ๋ฐ ์
๋ฐ์ดํธ
|
4 |
subprocess.run(["pip", "install", "--upgrade", "pip"])
|
5 |
subprocess.run(["pip", "install", "--upgrade", "openai", "yfinance", "gradio", "matplotlib", "Pillow"])
|
6 |
|
|
|
7 |
import yfinance as yf
|
8 |
import os
|
9 |
import matplotlib.font_manager as fm
|
|
|
45 |
|
46 |
# ๋ด์ค ์์ฝ์ ๊ฐ์ ธ์ค๋ ํจ์ (๊ธฐ์กด ์ฝ๋ ์ ์ง)
|
47 |
def get_real_news_summary(company, date):
|
|
|
48 |
client = OpenAI(api_key=API_KEY, base_url="https://api.perplexity.ai")
|
49 |
|
50 |
+
# ๋ ์ง ํ์ ์กฐ์
|
51 |
target_date = datetime.strptime(date, '%Y-%m-%d')
|
52 |
start_date = (target_date - timedelta(days=1)).strftime('%Y-%m-%d')
|
53 |
end_date = (target_date + timedelta(days=1)).strftime('%Y-%m-%d')
|
54 |
|
|
|
55 |
messages = [
|
56 |
{"role": "system", "content": "You are a helpful assistant that summarizes stock news strictly in Korean."},
|
57 |
{"role": "user", "content": f"Summarize the stock news for {company} between {start_date} and {end_date} in Korean. Only focus on news within this date range."}
|
58 |
]
|
59 |
|
60 |
try:
|
|
|
61 |
response = client.chat.completions.create(
|
62 |
model="llama-3.1-sonar-large-128k-online",
|
63 |
messages=messages
|
64 |
)
|
|
|
|
|
65 |
summary = response.choices[0].message.content
|
66 |
|
67 |
# ํ๊ธ, ์ซ์, ๊ณต๋ฐฑ, ํน์ ๊ธฐํธ๋ง ๋จ๊ธฐ๋ ์ ๊ท ํํ์
|
68 |
korean_only_summary = re.sub(r'[^\w\s#.,!%()\-\[\]]', '', summary)
|
|
|
|
|
69 |
formatted_summary = re.sub(r'##\s*(.+)', r'**\1**', korean_only_summary)
|
70 |
|
71 |
return formatted_summary
|
72 |
except Exception as e:
|
73 |
return f"๋ด์ค ์์ฝ ์ค ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}"
|
74 |
|
|
|
75 |
def handle_click(company_name, date_clicked):
|
76 |
return get_real_news_summary(company_name, date_clicked)
|
77 |
|
|
|
80 |
if selected_date == "" or selected_date is None:
|
81 |
return "๋ ์ง๋ฅผ ์ ํํด์ฃผ์ธ์."
|
82 |
else:
|
|
|
83 |
ticker = get_dynamic_ticker(input_value)
|
84 |
+
company_name = ticker_to_name.get(ticker, input_value)
|
85 |
return handle_click(company_name, selected_date)
|
86 |
|
87 |
+
# ์ข
๋ชฉ ๋์ ๋งค์นญ ํจ์
|
|
|
|
|
|
|
|
|
88 |
def get_dynamic_ticker(input_value):
|
89 |
if input_value == "๋์ค๋ฅ ์์ด 1์":
|
90 |
return get_top_market_cap_stock("๋์ค๋ฅ")
|
|
|
97 |
elif input_value == "์ฝ์ค๋ฅ ์์ด 1์":
|
98 |
return get_top_market_cap_stock("์ฝ์ค๋ฅ")
|
99 |
else:
|
|
|
100 |
return name_to_ticker.get(input_value, input_value)
|
101 |
|
102 |
+
# ์๊ฐ์ด์ก ์์ ์ข
๋ชฉ ๊ฐ์ ธ์ค๊ธฐ
|
103 |
def get_top_market_cap_stock(market, sector=None, industry=None):
|
|
|
104 |
if market == "๋์ค๋ฅ":
|
105 |
+
etf_ticker = "QQQ"
|
106 |
elif market == "์ฝ์คํผ":
|
107 |
+
etf_ticker = "EWY"
|
108 |
elif market == "์ฝ์ค๋ฅ":
|
|
|
109 |
tickers = ["035420.KQ", "068270.KQ", "035720.KQ"]
|
110 |
else:
|
111 |
return None
|
|
|
140 |
# ์ฃผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์กฐ๊ฑด์ ๋ง๋ ๋ ์ง์ ๊ทธ๋ํ๋ฅผ ๋ฐํํ๋ ํจ์
|
141 |
def display_stock_with_highlight(input_value, change_type, percent_change):
|
142 |
try:
|
|
|
143 |
ticker = get_dynamic_ticker(input_value)
|
144 |
stock = yf.Ticker(ticker)
|
145 |
+
stock_data = stock.history(period="5y")
|
146 |
|
147 |
if stock_data.empty:
|
148 |
return "์ฃผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.", []
|
|
|
170 |
plt.text(index, row['Close'], index.strftime('%Y-%m-%d'), fontsize=10, fontweight='bold', color=color, ha='right')
|
171 |
plt.axvline(x=index, color=color, linestyle='--', linewidth=1)
|
172 |
|
|
|
173 |
company_name = ticker_to_name.get(ticker, input_value)
|
174 |
plt.title(f'{company_name} ์ฃผ๊ฐ ์ถ์ด', fontproperties=font_prop)
|
175 |
plt.xlabel('๋ ์ง', fontproperties=font_prop)
|