AlanRex commited on
Commit
40923c7
·
verified ·
1 Parent(s): 6d14018

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -48
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # HUGING_FACE_V2.1.3.py (整合 Bert_predict 版本)
2
 
3
  # 系統套件
4
  import os
@@ -477,61 +477,53 @@ def update_volume_chart(selected_stock, period):
477
  fig.update_layout(title=f'{stock_name} 成交量', xaxis_title='日期', yaxis_title='成交量', height=300)
478
  return fig
479
 
480
- # 更新產業分析圖表 (修改版本 - 自動抓取波動標的)
481
  @app.callback(
482
  dash.dependencies.Output('industry-analysis', 'figure'),
483
- [dash.dependencies.Input('stock-dropdown', 'value')] # 這個輸入參數在您原程式碼中,但新邏輯中用不到
484
  )
485
  def update_industry_analysis(selected_stock):
486
- # 1. 獲取所有股票的近3個月歷史數據,並計算波動性
487
- all_stocks_volatility = []
488
- # 這裡的 TAIWAN_STOCKS.values() 包含了您所有的股票代碼
489
- for symbol in TAIWAN_STOCKS.values():
490
- # 這裡獲取3個月的數據來計算波動性,確保數據量足夠
491
- data = get_stock_data(symbol, '3mo')
492
- if not data.empty and len(data) >= 60: # 確保至少有3個月左右的交易日數據 (約60天)
493
- # 計算收盤價的標準差,標準差越大,代表波動性越高
494
- volatility = data['Close'].std()
495
- stock_name = [name for name, symbol_code in TAIWAN_STOCKS.items() if symbol_code == symbol][0]
496
- all_stocks_volatility.append({'股票': stock_name, '代碼': symbol, '波動性': volatility})
497
-
498
- # 如果沒有任何股票數據,則直接返回空圖表
499
- if not all_stocks_volatility:
500
- fig = go.Figure().add_annotation(text="無法獲取任何股票數據", showarrow=False)
501
- fig.update_layout(title="產業表現分析")
502
- return fig
503
-
504
- # 2. 根據波動性從高到低排序,並選出前10名
505
- df_volatility = pd.DataFrame(all_stocks_volatility).sort_values(by='波動性', ascending=False)
506
- top_10_volatile_stocks = df_volatility.head(10)['代碼'].tolist()
507
-
508
- # 3. 針對這前10名股票,重新獲取1個月的數據來計算月報酬率
509
- industry_data = []
510
- for symbol in top_10_volatile_stocks:
511
  data = get_stock_data(symbol, '1mo')
512
- if not data.empty and len(data) > 1: # 確保有足夠的數據來計算報酬率
513
- stock_name = [name for name, symbol_code in TAIWAN_STOCKS.items() if symbol_code == symbol][0]
514
- # 計算月報酬率
515
  return_pct = ((data['Close'].iloc[-1] - data['Close'].iloc[0]) / data['Close'].iloc[0]) * 100
516
- industry_data.append({'股票': stock_name, '代碼': symbol, '月報酬率(%)': return_pct, '產業': INDUSTRY_MAPPING.get(symbol, '其他')})
517
-
518
- # 如果篩選後沒有任何數據,也返回空圖表
519
- if not industry_data:
520
- fig = go.Figure().add_annotation(text="無法計算波動較大股票的月報酬率", showarrow=False)
521
- fig.update_layout(title="產業表現分析")
 
 
 
 
522
  return fig
523
-
524
- # 4. 繪製圓餅圖
525
- df_industry = pd.DataFrame(industry_data)
526
- fig = px.pie(df_industry,
527
- values='月報酬率(%)',
528
- names='股票',
529
- title='月波動較大股票之報酬率比較',
530
- color_discrete_sequence=px.colors.qualitative.Set3)
531
-
532
- fig.update_layout(height=400)
533
-
 
 
 
 
 
 
 
 
 
 
534
  return fig
 
535
 
536
  # 更新景氣燈號圖表
537
  @app.callback(
 
1
+ # HUGING_FACE_V3.1.2.py (整合 Bert_predict 版本)
2
 
3
  # 系統套件
4
  import os
 
477
  fig.update_layout(title=f'{stock_name} 成交量', xaxis_title='日期', yaxis_title='成交量', height=300)
478
  return fig
479
 
480
+ # ========================= MODIFIED SECTION START =========================
481
  @app.callback(
482
  dash.dependencies.Output('industry-analysis', 'figure'),
483
+ [dash.dependencies.Input('stock-dropdown', 'value')] # Callback can be triggered by any change, e.g., the main stock selection
484
  )
485
  def update_industry_analysis(selected_stock):
486
+ performance_data = []
487
+ # 1. Iterate through ALL stocks to calculate their performance
488
+ for name, symbol in TAIWAN_STOCKS.items():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  data = get_stock_data(symbol, '1mo')
490
+ if not data.empty and len(data) > 1:
491
+ # Calculate 1-month return percentage
 
492
  return_pct = ((data['Close'].iloc[-1] - data['Close'].iloc[0]) / data['Close'].iloc[0]) * 100
493
+ performance_data.append({
494
+ '股票': name,
495
+ '代碼': symbol,
496
+ '月報酬率(%)': return_pct,
497
+ '絕對波動': abs(return_pct) # Use absolute value for sorting
498
+ })
499
+
500
+ if not performance_data:
501
+ fig = go.Figure().add_annotation(text="無法計算產業資料", showarrow=False)
502
+ fig.update_layout(title="近一月市場波動最大標的", height=400)
503
  return fig
504
+
505
+ # 2. Sort by the absolute fluctuation and take the top 10
506
+ df_performance = pd.DataFrame(performance_data)
507
+ df_top_movers = df_performance.sort_values(by='絕對波動', ascending=False).head(10)
508
+
509
+ # 3. Create the pie chart with the top 10 movers
510
+ # We use the absolute value for the pie chart size to represent volatility,
511
+ # but the hover data will show the actual (positive/negative) return.
512
+ fig = px.pie(
513
+ df_top_movers,
514
+ values='絕對波動',
515
+ names='股票',
516
+ title='近一月市場波動最大 Top 10 標的',
517
+ hover_data={'月報酬率(%)': ':.2f'} # Show the actual return on hover
518
+ )
519
+ fig.update_traces(
520
+ textposition='inside',
521
+ textinfo='percent+label',
522
+ hovertemplate="<b>%{label}</b><br>月報酬率: %{customdata[0]:.2f}%<extra></extra>"
523
+ )
524
+ fig.update_layout(height=400, showlegend=False)
525
  return fig
526
+ # ========================== MODIFIED SECTION END ==========================
527
 
528
  # 更新景氣燈號圖表
529
  @app.callback(