hopelessDev commited on
Commit
7d736d7
·
verified ·
1 Parent(s): 1cb61c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -8
app.py CHANGED
@@ -111,9 +111,6 @@ def vector_to_score(vec: np.ndarray) -> float:
111
  # -----------------------------
112
  def get_decay_factor(num_headlines: int, max_headlines: int = MAX_HEADLINES,
113
  min_decay: float = 0.6, max_decay: float = 0.95) -> float:
114
- """
115
- Dynamic decay: more headlines → higher decay → score can approach extremes.
116
- """
117
  ratio = min(num_headlines / max_headlines, 1.0)
118
  return min_decay + ratio * (max_decay - min_decay)
119
 
@@ -127,31 +124,48 @@ class StocksRequest(BaseModel):
127
 
128
  @cached(stock_cache)
129
  def analyze_single_stock(stock: str) -> float | str:
 
130
  headlines = fetch_headlines(stock)
131
  headlines = [h for h in headlines if h and len(h.strip()) > 10]
132
 
133
  if not headlines or len(headlines) < 2:
134
  return "NO_DATA"
135
 
 
136
  vectors = [headline_score_ensemble(h) for h in headlines]
137
  agg = aggregate_headlines_vectors(vectors)
138
  raw_score = vector_to_score(agg)
139
 
140
- # Apply dynamic decay
141
  decay = get_decay_factor(len(headlines))
142
- adjusted_score = 0.5 + decay * (raw_score - 0.5)
143
- return round(adjusted_score, 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  @app.get("/")
146
  def root():
147
- return {"message": "Fin-senti API is running! Use POST /analyze"}
148
 
149
  @app.post("/analyze")
150
  def analyze(req: StocksRequest):
151
  results = {}
152
  for stock in req.stocks:
153
  results[stock] = analyze_single_stock(stock)
154
- return results
155
 
156
  if __name__ == "__main__":
157
  import uvicorn
 
111
  # -----------------------------
112
  def get_decay_factor(num_headlines: int, max_headlines: int = MAX_HEADLINES,
113
  min_decay: float = 0.6, max_decay: float = 0.95) -> float:
 
 
 
114
  ratio = min(num_headlines / max_headlines, 1.0)
115
  return min_decay + ratio * (max_decay - min_decay)
116
 
 
124
 
125
  @cached(stock_cache)
126
  def analyze_single_stock(stock: str) -> float | str:
127
+ # Fetch headlines
128
  headlines = fetch_headlines(stock)
129
  headlines = [h for h in headlines if h and len(h.strip()) > 10]
130
 
131
  if not headlines or len(headlines) < 2:
132
  return "NO_DATA"
133
 
134
+ # Ensemble sentiment
135
  vectors = [headline_score_ensemble(h) for h in headlines]
136
  agg = aggregate_headlines_vectors(vectors)
137
  raw_score = vector_to_score(agg)
138
 
139
+ # Apply decay-weighted hybrid
140
  decay = get_decay_factor(len(headlines))
141
+ hybrid_score = 0.7 * raw_score + 0.3 * (0.5 + decay * (raw_score - 0.5))
142
+
143
+ # Market momentum adjustment (5-day price change)
144
+ try:
145
+ ticker = yf.Ticker(stock)
146
+ hist = ticker.history(period="5d")
147
+ if len(hist) >= 2:
148
+ change = (hist["Close"].iloc[-1] - hist["Close"].iloc[0]) / hist["Close"].iloc[0]
149
+ momentum_correction = np.clip(change * 2, -0.2, 0.2) # ±0.2 max
150
+ final_score = np.clip(hybrid_score + momentum_correction, 0, 1)
151
+ else:
152
+ final_score = hybrid_score
153
+ except Exception as e:
154
+ print(f"[Market momentum error] {e}")
155
+ final_score = hybrid_score
156
+
157
+ return round(final_score, 2)
158
 
159
  @app.get("/")
160
  def root():
161
+ return {"message": "Fin-senti API is live! Use POST /analyze"}
162
 
163
  @app.post("/analyze")
164
  def analyze(req: StocksRequest):
165
  results = {}
166
  for stock in req.stocks:
167
  results[stock] = analyze_single_stock(stock)
168
+ return {"confidence_scores": results}
169
 
170
  if __name__ == "__main__":
171
  import uvicorn