File size: 4,463 Bytes
0125724
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""
TradeSense AI — Grounded AI Research Copilot & Evidence Synthesizer
Generates institutional research commentary strictly synthesized from StructuredEvidence payloads.
Zero hallucination / zero financial fabrication guarantee.
"""

from typing import Dict, Any
from backend.app.schemas.contracts import StructuredEvidence, SignalType


class GroundedCopilotEngine:
    """
    Synthesizes a structured, natural-language equity research note strictly from a StructuredEvidence object.
    Never invents unprovided metrics or unsupported price targets.
    """

    @classmethod
    def generate_research_note(cls, evidence: StructuredEvidence) -> str:
        """
        Generates deterministic, evidence-grounded research commentary.
        """
        forecast = evidence.forecast
        backtest = evidence.backtest
        risk = evidence.risk

        # Auto-detect Indian instrument vs US
        from backend.data.providers.yfinance import YFinanceProvider
        is_in = YFinanceProvider.is_indian_symbol(evidence.ticker)
        c = "₹" if is_in else "$"
        
        # Section 1: Executive Stance & Quantitative Signal
        stance_header = f"### 📊 TradeSense Quantitative Research Note: {evidence.ticker} (Horizon: {evidence.horizon_sessions} Sessions)\n\n"
        stance_header += f"**Quantitative Signal**: `{evidence.signal.value}` · **Factor Concurrence**: {evidence.factors_positive}/{evidence.factors_total} Positive Factors\n\n"
        stance_header += f"**Core Assessment**: {evidence.signal_reason}\n\n"

        # Section 2: Probabilistic Forecast Distribution
        fc_text = "#### 🔮 Forecast Distribution & Probability Bounds\n"
        fc_text += f"- **Current Reference Price**: `{c}{forecast.reference_price:,.2f}` (as of {evidence.as_of_session.strftime('%Y-%m-%d')})\n"
        fc_text += f"- **Expected Horizon Value**: `{c}{forecast.expected_price:,.2f}` ({forecast.expected_return_pct:+.2f}%)\n"
        fc_text += f"- **80% Prediction Interval**: `{c}{forecast.interval_80[0]:,.2f}` – `{c}{forecast.interval_80[1]:,.2f}`\n"
        fc_text += f"- **95% Prediction Interval**: `{c}{forecast.interval_95[0]:,.2f}` – `{c}{forecast.interval_95[1]:,.2f}`\n"
        fc_text += f"- **Active Model**: {forecast.active_model_id}\n\n"

        # Section 3: Walk-Forward Out-of-Sample Empirical Evidence
        bt_text = "#### 📈 Walk-Forward Backtesting & Baseline Edge Matrix\n"
        bt_text += f"- **Out-of-Sample RMSE**: `{c}{backtest.oos_rmse:,.2f}` (vs. Naive Baseline RMSE `{c}{backtest.baseline_naive_rmse:,.2f}`)\n"
        bt_text += f"- **Baseline Improvement**: **{backtest.baseline_improvement_rmse_pct:+.1f}%** reduction in forecast error over Naive persistence\n"
        bt_text += f"- **Directional Accuracy**: **{backtest.directional_accuracy_pct:.1f}%** over expanding test windows\n"
        bt_text += f"- **Friction-Adjusted Net Sharpe**: **{backtest.net_sharpe:.2f}** (net of execution friction & statutory drag)\n"
        bt_text += f"- **Empirical 80% Coverage**: {backtest.empirical_coverage_80_pct:.1f}% (Calibration error: {backtest.calibration_error_80_pct:.1f}%)\n\n"

        # Section 4: Quantitative Risk & Geometry
        risk_text = "#### 🛡️ Quantitative Risk & Volatility Sizing\n"
        risk_text += f"- **14-Session ATR**: `{c}{risk.atr_14:,.2f}` ({risk.atr_pct:.2f}% of price) · Regime: {risk.volatility_regime.replace('_', ' ').capitalize()} Volatility\n"
        risk_text += f"- **Key Support / Resistance**: Support at `{c}{risk.support_level:,.2f}` · Resistance at `{c}{risk.resistance_level:,.2f}`\n"
        risk_text += f"- **ATR Suggested Stop-Loss**: `{c}{risk.suggested_stop_loss:,.2f}`\n"
        risk_text += f"- **Suggested Targets**: Target 1 at `{c}{risk.suggested_take_profit_1:,.2f}` (1:2 R:R) · Target 2 at `{c}{risk.suggested_take_profit_2:,.2f}` (1:3 R:R)\n"
        risk_text += f"- **Risk-Reward Score**: **{risk.risk_reward_ratio:.2f}:1**\n\n"

        # Section 5: Cryptographic Lineage & Disclaimer
        disclaimer_text = "---\n"
        disclaimer_text += f"*SHA-256 Forecast Audit Hash*: `{forecast.sha256_audit_hash}`\n\n"
        disclaimer_text += "> **Disclaimer**: TradeSense AI is a quantitative research platform providing algorithmic factor analysis. It does not guarantee market returns or provide individualized investment advice."

        return stance_header + fc_text + bt_text + risk_text + disclaimer_text