molba2see commited on
Commit
304941e
·
verified ·
1 Parent(s): 4a35861

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +34 -47
src/streamlit_app.py CHANGED
@@ -139,45 +139,36 @@ def generate_llm_report(investor_style, ticker):
139
  {news_text}
140
  """
141
  system_prompt = """You are an expert financial analyst. Your mission is to write a concise, objective investment report for a client based on their specific risk profile.
142
-
143
  ANALYSIS INSTRUCTIONS:
144
  - Use BOTH the provided financial metrics ("Facts") and recent news headlines ("News").
145
  - Always include the metrics listed under `core_metrics` in Facts. These are the most important indicators for the company/sector.
146
  - Each Key Highlight should integrate at least one financial fact and one news item together (not listed separately).
147
  - Do not hallucinate numbers that are not in Facts.
148
  - Adjust the focus and tone strictly based on the investor's style:
149
-
150
  If the style is SAFE (Conservative):
151
  * Focus: Capital preservation and stable income.
152
  * Highlight: Balance sheet strength, liquidity, predictable returns.
153
  * Mention risks (regulatory, legal, earnings decline) first, then cautiously note positives.
154
  * Downplay speculative or uncertain news.
155
-
156
  If the style is NEUTRAL (Moderate):
157
  * Focus: A balance between growth and safety.
158
  * Highlight: Strategic trade-offs. Analyze how growth initiatives (from news) interact with financial stability (from facts).
159
  * Present risks and opportunities in equal measure.
160
-
161
  If the style is RISKY (Aggressive):
162
  * Focus: High growth potential and maximum returns.
163
  * Highlight: Exciting, forward-looking growth story. Emphasize innovation, expansion, competitive advantages.
164
  * Frame risks as natural volatility on the path to high rewards.
165
  * Place financial facts in the context of supporting aggressive growth.
166
-
167
  OUTPUT REPORT TEMPLATE
168
  Report for: A (investor_style) Investor
169
  Company: (company_name)
170
-
171
  1. Executive Summary:
172
  (Provide a brief, one-paragraph summary that aligns with the investor's style, integrating at least one key metric and one recent news item.)
173
-
174
  2. Key Analysis & Highlights:
175
  (5–7 bullet points. Each bullet must combine a financial metric with a relevant news event, written from the perspective of the given investor style.)
176
-
177
  3. Concluding Remark:
178
  (One or two sentences, neutrally summarizing the company’s current standing for this type of investor.
179
  Do NOT provide direct financial advice or buy/sell recommendations.)
180
-
181
  IMPORTANT:
182
  - Keep the tone professional and concise.
183
  - Reports must be grounded in Facts and News only.
@@ -200,9 +191,6 @@ def generate_llm_report(investor_style, ticker):
200
 
201
  return result
202
 
203
- def reset_search_input():
204
- if "stock_search_input" in st.session_state:
205
- st.session_state.stock_search_input = None
206
 
207
  # 1. 세션 상태(Session State) 초기화
208
  # st.session_state : 스트림릿이 재실행되어도 값을 유지하는 변수
@@ -233,41 +221,40 @@ full_market_df = load_full_df() # (Srisk 모듈용 데이터)
233
  # 3. 입력 섹션 (종목 추가)
234
  st.subheader("1. 보유 종목 추가하기")
235
 
236
- # 컬럼을 나눠서 UI를 깔끔하게 구성
237
- col1, col2 = st.columns([2, 1])
238
-
239
- with col1:
240
- # `selectbox`를 검색 가능한 입력창으로 사용
241
- selected_display = st.selectbox(
242
- "종목 검색 (NASDAQ100 or S&P500 티커 또는 기업명)",
243
- options=TICKER_OPTIONS_LIST,
244
- index=None,
245
- placeholder="티커를 검색하거나 선택하세요 (예: AAPL 또는 Apple)",
246
- key="stock_search_input"
247
- )
248
- with col2:
249
- quantity = st.number_input("보유 수량 (주)", min_value=0.01, step=0.1, format="%.2f")
250
-
251
- # '종목 추가' 버튼
252
- if st.button("➕ 포트폴리오에 추가", use_container_width=True, on_click=reset_search_input):
253
- selected_ticker = None
254
- if selected_display:
255
- selected_ticker = DISPLAY_TO_TICKER_MAP.get(selected_display)
256
- current_price = TICKER_TO_PRICE_MAP.get(selected_ticker)
257
-
258
- if selected_ticker:
259
- st.session_state.portfolio.append({
260
- "ticker": selected_ticker,
261
- "quantity": quantity,
262
- "price": current_price,
263
- "total_value": quantity * current_price
264
- })
265
- st.success(f"{selected_ticker} {quantity}주 (현재가 ${current_price:,.2f})를 포트폴리오에 추가했습니다.")
266
-
267
- st.rerun()
268
 
269
- else:
270
- st.warning("종목, 수량을 모두 올바르게 입력하세요.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  # 4. 포트폴리오 요약 및 보고서 생성 (스케치 레이아웃)
273
  st.subheader("2. 포트폴리오 요약 및 보고서 생성")
@@ -373,7 +360,7 @@ with col_controls:
373
  )
374
 
375
  with col_regen:
376
- if st.button(f"'{new_style}' 스타일로 재생성", use_container_width=True, key="my_regen_button"):
377
  with st.spinner(f"'{new_style}' 스타일로 보고서를 다시 작성 중입니다..."):
378
  regenerated_reports = generate_llm_reports(
379
  st.session_state.portfolio,
 
139
  {news_text}
140
  """
141
  system_prompt = """You are an expert financial analyst. Your mission is to write a concise, objective investment report for a client based on their specific risk profile.
 
142
  ANALYSIS INSTRUCTIONS:
143
  - Use BOTH the provided financial metrics ("Facts") and recent news headlines ("News").
144
  - Always include the metrics listed under `core_metrics` in Facts. These are the most important indicators for the company/sector.
145
  - Each Key Highlight should integrate at least one financial fact and one news item together (not listed separately).
146
  - Do not hallucinate numbers that are not in Facts.
147
  - Adjust the focus and tone strictly based on the investor's style:
 
148
  If the style is SAFE (Conservative):
149
  * Focus: Capital preservation and stable income.
150
  * Highlight: Balance sheet strength, liquidity, predictable returns.
151
  * Mention risks (regulatory, legal, earnings decline) first, then cautiously note positives.
152
  * Downplay speculative or uncertain news.
 
153
  If the style is NEUTRAL (Moderate):
154
  * Focus: A balance between growth and safety.
155
  * Highlight: Strategic trade-offs. Analyze how growth initiatives (from news) interact with financial stability (from facts).
156
  * Present risks and opportunities in equal measure.
 
157
  If the style is RISKY (Aggressive):
158
  * Focus: High growth potential and maximum returns.
159
  * Highlight: Exciting, forward-looking growth story. Emphasize innovation, expansion, competitive advantages.
160
  * Frame risks as natural volatility on the path to high rewards.
161
  * Place financial facts in the context of supporting aggressive growth.
 
162
  OUTPUT REPORT TEMPLATE
163
  Report for: A (investor_style) Investor
164
  Company: (company_name)
 
165
  1. Executive Summary:
166
  (Provide a brief, one-paragraph summary that aligns with the investor's style, integrating at least one key metric and one recent news item.)
 
167
  2. Key Analysis & Highlights:
168
  (5–7 bullet points. Each bullet must combine a financial metric with a relevant news event, written from the perspective of the given investor style.)
 
169
  3. Concluding Remark:
170
  (One or two sentences, neutrally summarizing the company’s current standing for this type of investor.
171
  Do NOT provide direct financial advice or buy/sell recommendations.)
 
172
  IMPORTANT:
173
  - Keep the tone professional and concise.
174
  - Reports must be grounded in Facts and News only.
 
191
 
192
  return result
193
 
 
 
 
194
 
195
  # 1. 세션 상태(Session State) 초기화
196
  # st.session_state : 스트림릿이 재실행되어도 값을 유지하는 변수
 
221
  # 3. 입력 섹션 (종목 추가)
222
  st.subheader("1. 보유 종목 추가하기")
223
 
224
+ with st.form(key='portfolio_add_form', clear_on_submit=True):
225
+ col1, col2 = st.columns([2, 1])
226
+
227
+ with col1:
228
+ # `selectbox`를 검색 가능한 입력창으로 사용
229
+ selected_display = st.selectbox(
230
+ "종목 검색 (NASDAQ100 or S&P500 티커 또는 기업명)",
231
+ options=TICKER_OPTIONS_LIST,
232
+ index=None,
233
+ placeholder="티커를 검색하거나 선택하세요 (예: AAPL 또는 Apple)"
234
+ )
235
+ with col2:
236
+ quantity = st.number_input("보유 수량 (주)", min_value=0.01, step=0.1, format="%.2f")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
+ submitted = st.form_submit_button("➕ 포트폴리오에 추가", use_container_width=True, type="primary")
239
+
240
+ # '종목 추가' 버튼
241
+ if submitted:
242
+ selected_ticker = None
243
+ if selected_display:
244
+ selected_ticker = DISPLAY_TO_TICKER_MAP.get(selected_display)
245
+ current_price = TICKER_TO_PRICE_MAP.get(selected_ticker)
246
+
247
+ if selected_ticker:
248
+ st.session_state.portfolio.append({
249
+ "ticker": selected_ticker,
250
+ "quantity": quantity,
251
+ "price": current_price,
252
+ "total_value": quantity * current_price
253
+ })
254
+ st.success(f"{selected_ticker} {quantity}주 (현재가 ${current_price:,.2f})를 포트폴리오에 추가했습니다.")
255
+ st.rerun()
256
+ else:
257
+ st.warning("종목, 수량을 모두 올바르게 입력하세요.")
258
 
259
  # 4. 포트폴리오 요약 및 보고서 생성 (스케치 레이아웃)
260
  st.subheader("2. 포트폴리오 요약 및 보고서 생성")
 
360
  )
361
 
362
  with col_regen:
363
+ if st.button(f"'{new_style}' 스타일로 재생성", use_container_width=True, "my_regen_button"):
364
  with st.spinner(f"'{new_style}' 스타일로 보고서를 다시 작성 중입니다..."):
365
  regenerated_reports = generate_llm_reports(
366
  st.session_state.portfolio,