emmanuelakbi commited on
Commit
0d2f0f9
Β·
1 Parent(s): 1e840aa

fix(signals): clean structured reasoning on synthesized fallback

Browse files
Files changed (1) hide show
  1. crew/crew.py +39 -6
crew/crew.py CHANGED
@@ -528,12 +528,45 @@ class FinAgentCrew:
528
  50 + min(25, round(abs(pct_change) * 5))
529
  )
530
 
531
- # Preserve the agents' narrative so the user still sees the
532
- # reasoning β€” just trimmed so the UI card stays readable.
533
- narrative = raw_output.strip()
534
- if len(narrative) > 800:
535
- narrative = narrative[:800] + "..."
536
- reasoning = {"Synthesized": narrative} if narrative else None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
537
 
538
  return TradingSignal(
539
  ticker=ticker,
 
528
  50 + min(25, round(abs(pct_change) * 5))
529
  )
530
 
531
+ # Clean, structured reasoning β€” the fallback path runs precisely
532
+ # when the LLM's final output is unparseable (often because Qwen
533
+ # dumped raw <think>…</think> reasoning instead of the required
534
+ # structured format). Dropping that noise onto the UI card would
535
+ # look unprofessional, so we synthesise a concise four-line
536
+ # rationale from the live data we already have.
537
+ if action == Action.BUY:
538
+ rationale = (
539
+ f"Price up {pct_change:+.2f}% vs previous close "
540
+ f"β€” short-term momentum favours a long entry."
541
+ )
542
+ elif action == Action.SELL:
543
+ rationale = (
544
+ f"Price down {pct_change:+.2f}% vs previous close "
545
+ f"β€” short-term momentum favours a short entry."
546
+ )
547
+ else:
548
+ rationale = (
549
+ f"Price flat ({pct_change:+.2f}% vs previous close) "
550
+ f"β€” no directional conviction; HOLD and wait for a cleaner setup."
551
+ )
552
+
553
+ stop_pct_shown = abs(stop - entry) / entry * 100
554
+ target_pct_shown = abs(target - entry) / entry * 100
555
+ risk_note = (
556
+ f"Bands sized to your {self._preferences.risk_tolerance} / "
557
+ f"{self._preferences.trading_style} profile: "
558
+ f"stop β‰ˆ {stop_pct_shown:.1f}% / target β‰ˆ {target_pct_shown:.1f}%."
559
+ )
560
+
561
+ reasoning = {
562
+ "Market": rationale,
563
+ "Fundamental": "Deterministic fallback β€” LLM output was unparseable.",
564
+ "Technical": (
565
+ "Entry anchored to live yfinance quote; stop/target derived "
566
+ "from the preference-aware default band."
567
+ ),
568
+ "Risk": risk_note,
569
+ }
570
 
571
  return TradingSignal(
572
  ticker=ticker,