KKKMatthias commited on
Commit
a750ea9
·
verified ·
1 Parent(s): 3a7b21a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -16
app.py CHANGED
@@ -1,10 +1,11 @@
1
  import os
2
- # 禁用 yfinance 的磁盘缓存,防止在只读环境中报错
3
  os.environ['YF_NOCACHE'] = 'True'
4
 
5
  from fastapi import FastAPI
6
  import yfinance as yf
7
  import math
 
8
  import uvicorn
9
 
10
  app = FastAPI()
@@ -26,23 +27,44 @@ def home():
26
  def get_stock(ticker: str):
27
  try:
28
  stock = yf.Ticker(ticker.upper())
29
- info = stock.info
30
 
31
- # 获取分析师盈利估计详情
32
- # earnings_estimate 通常是一个以时间为行,指标(avg, low, high等)为列的 DataFrame
33
- est = stock.earnings_estimate
34
 
35
- # 默认初始化为 None
 
 
 
 
 
36
  eps_est_current = None
37
  eps_est_next = None
38
 
 
39
  if est is not None and not est.empty:
40
- # yfinance 的索引通常是 '0y' 代表 Current Year, '1y' 代表 Next Year
41
- # 安全地获取 avg 列中的对应值
42
- if '0y' in est.index:
43
- eps_est_current = est.loc['0y', 'avg']
44
- if '1y' in est.index:
45
- eps_est_next = est.loc['1y', 'avg']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  if not info or len(info) < 5:
48
  return {"error": "No data found", "ticker": ticker}
@@ -51,16 +73,17 @@ def get_stock(ticker: str):
51
  "ticker": ticker.upper(),
52
  "pe_static": clean_num(info.get('trailingPE')),
53
  "pe_dynamic": clean_num(info.get('forwardPE')),
54
- # info 里的 trailingEps 是过去一年的实际值
55
- #"eps_trailing": clean_num(info.get('trailingEps')),
56
- # 从 earnings_estimate 中获取的分析师平均预测值
57
  "eps_est_avg_current_year": clean_num(eps_est_current),
58
  "eps_est_avg_next_year": clean_num(eps_est_next),
 
 
 
59
  "source": "hf_space_v1"
60
  }
61
  except Exception as e:
62
  return {"error": str(e)}
63
 
64
  if __name__ == "__main__":
65
- # Hugging Face 会自动分配端口,通常是 7860
66
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import os
2
+ # 禁用 yfinance 的磁盘缓存
3
  os.environ['YF_NOCACHE'] = 'True'
4
 
5
  from fastapi import FastAPI
6
  import yfinance as yf
7
  import math
8
+ import pandas as pd
9
  import uvicorn
10
 
11
  app = FastAPI()
 
27
  def get_stock(ticker: str):
28
  try:
29
  stock = yf.Ticker(ticker.upper())
 
30
 
31
+ # 1. 尝试从 stock.info 获取数据 (这是最快且最稳定的方法)
32
+ # yfinance 的 info 中通常直接包含 forwardEps (下一财年预测)
33
+ info = stock.info
34
 
35
+ # 2. 尝试获取详细的分析师预测表
36
+ try:
37
+ est = stock.earnings_estimate
38
+ except Exception:
39
+ est = None
40
+
41
  eps_est_current = None
42
  eps_est_next = None
43
 
44
+ # --- 修复逻辑开始 ---
45
  if est is not None and not est.empty:
46
+ try:
47
+ # 打印一下索引看看结构 (调试用,生产环境可注释)
48
+ # print(f"Index type: {est.index}")
49
+
50
+ # 方法 A: 使用位置索引 iloc (更通用)
51
+ # 假设数据按时间升序排列,第0行是当前年,第1行是明年
52
+ # 注意:有时 yfinance 返回的顺序可能是反的,或者包含季度数据,
53
+ # 但 earnings_estimate 通常是年度数据且按时间排序。
54
+
55
+ if len(est) > 0:
56
+ eps_est_current = est.iloc[0]['avg'] # 当前财年
57
+ if len(est) > 1:
58
+ eps_est_next = est.iloc[1]['avg'] # 下一财年
59
+
60
+ except Exception as e:
61
+ print(f"Error parsing dataframe: {e}")
62
+ # --- 修复逻辑结束 ---
63
+
64
+ # 3. 如果从表格获取失败,使用 info 中的备用数据
65
+ # forwardEps 通常代表下一财年的预测 EPS
66
+ if eps_est_next is None and info:
67
+ eps_est_next = info.get('forwardEps')
68
 
69
  if not info or len(info) < 5:
70
  return {"error": "No data found", "ticker": ticker}
 
73
  "ticker": ticker.upper(),
74
  "pe_static": clean_num(info.get('trailingPE')),
75
  "pe_dynamic": clean_num(info.get('forwardPE')),
76
+
77
+ # 优先显示从表格获取的数据,如果没有则显示 info 中的数据
 
78
  "eps_est_avg_current_year": clean_num(eps_est_current),
79
  "eps_est_avg_next_year": clean_num(eps_est_next),
80
+
81
+ # 调试信息:告诉你数据来源是 info 还是 table
82
+ "debug_note": "Data from table" if eps_est_current is not None else "Data from info/fallback",
83
  "source": "hf_space_v1"
84
  }
85
  except Exception as e:
86
  return {"error": str(e)}
87
 
88
  if __name__ == "__main__":
 
89
  uvicorn.run(app, host="0.0.0.0", port=7860)