File size: 3,069 Bytes
d4f8959 | 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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | from backend.recommendations import evaluate_recommendation, recommend_from_red_flags
class FakeGraph:
def __init__(self, data):
self._data = data
def get_company_metrics(self, company):
return self._data.get(company, {})
FAKE_DATA = {
# clean bank, zero flags -> BUY
"ICICI Bank": {
"2023": {"deposits": {"value": 1_000_000_00_00_000, "confidence": "high"}},
"2024": {
"profit_after_tax": {"value": 400_000_00_00_000, "confidence": "high"},
"deposits": {"value": 1_050_000_00_00_000, "confidence": "high"},
"gross_npa_pct": 1.1, "net_npa_pct": 0.3,
"casa_ratio": 42.0, "capital_adequacy": 17.0,
},
},
# one severe flag only (negative net income) -> AVOID even though
# aggregate score is under the AVOID threshold
"Infosys": {
"2023": {"revenue": {"value": 1_500_000_000_000, "confidence": "high"}},
"2024": {
"revenue": {"value": 1_490_000_000_000, "confidence": "high"},
"net_income": {"value": -50_000_000, "confidence": "high"},
"attrition": 18.0,
},
},
# only low-severity CASA flag -> HOLD
"AxisBank": {
"2023": {"deposits": {"value": 900_000_00_00_000, "confidence": "high"}},
"2024": {
"profit_after_tax": {"value": 200_000_00_00_000, "confidence": "high"},
"deposits": {"value": 920_000_00_00_000, "confidence": "high"},
"gross_npa_pct": 2.0, "net_npa_pct": 0.8,
"casa_ratio": 25.0, "capital_adequacy": 16.0,
},
},
"SunPharma": {
"2024": {
"revenue": {"value": 500_000_000_000, "confidence": "high"},
"r_and_d": {"value": 30_000_000_000, "confidence": "high"},
"net_income": {"value": 60_000_000_000, "confidence": "high"},
},
},
}
def _rec(company, year, sector):
return evaluate_recommendation(FakeGraph(FAKE_DATA), company, year, sector=sector)
def test_clean_company_is_buy():
assert _rec("ICICI Bank", "2024", "BANK")["recommendation"] == "BUY"
def test_single_severe_flag_forces_avoid():
result = _rec("Infosys", "2024", "IT")
assert result["recommendation"] == "AVOID"
assert "high-severity" in result["reason"]
def test_minor_flags_only_is_hold():
assert _rec("AxisBank", "2024", "BANK")["recommendation"] == "HOLD"
def test_unsupported_sector_is_skip():
result = _rec("SunPharma", "2024", "PHARMA")
assert result["recommendation"] == "SKIP"
def test_missing_company_is_skip_with_reason():
result = _rec("NoSuchCompany", "2024", "BANK")
assert result["recommendation"] == "SKIP"
assert result["reason"]
def test_low_confidence_forces_skip():
payload = {
"company": "X", "year": "2024", "sector": "BANK",
"flags_triggered": [
{"flag": "LOW_CASA", "message": "m", "confidence": "low"}
],
"risk_score": 10,
"confidence": "low",
}
assert recommend_from_red_flags(payload)["recommendation"] == "SKIP"
|