| 1 | # 03.3 - Stock Rule Engine V1 |
| 2 | |
| 3 | `STOCK_RULE_ENGINE_V1` is a deterministic, provider-free calculation over durable public-company facts and Research Readiness. It does not read portfolio holdings and it does not invoke NSE, Yahoo, SEC, EODHD, search, MCP, or an LLM. |
| 4 | |
| 5 | ## Aggregation |
| 6 | |
| 7 | The fixed top-level weights are: |
| 8 | |
| 9 | | Area | Weight | |
| 10 | |---|---:| |
| 11 | | VALUATION | 18 | |
| 12 | | FUNDAMENTAL_BUSINESS_QUALITY | 16 | |
| 13 | | GROWTH | 14 | |
| 14 | | BALANCE_SHEET | 9 | |
| 15 | | QUARTERLY_EARNINGS_TREND | 9 | |
| 16 | | ORDER_BOOK_CAPACITY_CATALYSTS | 8 | |
| 17 | | PRICE_TECHNICAL | 7 | |
| 18 | | NEWS_GEOPOLITICAL_EVENTS | 7 | |
| 19 | | SHAREHOLDING | 4 | |
| 20 | | MANAGEMENT_GOVERNANCE | 5 | |
| 21 | | SECTOR_MACRO | 3 | |
| 22 | |
| 23 | The total is exactly 100. Each area is the weighted mean of its available and applicable V1 sub-rules. A missing optional metric is omitted; it is never converted to a zero. Every response reports both the configured sub-rule weight and the applied percentage after normalization over available sub-rules. |
| 24 | |
| 25 | For a scored area `a`: |
| 26 | |
| 27 | ```text |
| 28 | areaScore(a) = sum(metricScore × configuredSubruleWeight) |
| 29 | / sum(configuredSubruleWeight for available applicable metrics) |
| 30 | |
| 31 | weightedContribution(a) = areaScore(a) × topLevelWeight(a) / 100 |
| 32 | |
| 33 | overallScore = sum(areaScore × topLevelWeight) |
| 34 | / sum(topLevelWeight for scorable applicable areas) |
| 35 | ``` |
| 36 | |
| 37 | An unsupported regional area is excluded from the denominator. An unscorable or partial area remains visible, lowers confidence/readiness, and can activate the eligibility gate. Partial analysis is capped at `HOLD`, so omission cannot create a positive decision from incomplete data. |
| 38 | |
| 39 | All interpolation rules below are linear between listed `(input, score)` points and clamp to the endpoint score outside the listed range. |
| 40 | |
| 41 | ## V1 area rules |
| 42 | |
| 43 | ### Valuation (18) |
| 44 | |
| 45 | Available-metric weights are trailing P/E 25, earnings yield 10, forward P/E 15, P/B 18 for financial companies or 8 otherwise, EV/EBITDA 15, PEG 10, and FCF yield 15. |
| 46 | |
| 47 | - Trailing P/E: `(8,92), (15,78), (25,58), (40,32), (60,12)`; positive values only. |
| 48 | - Earnings yield is `100 / trailing P/E`: `(1.5,10), (2.5,30), (4,55), (6.5,78), (10,92)`. |
| 49 | - Forward P/E: `(8,94), (15,80), (25,58), (40,30), (60,10)`. |
| 50 | - Financial-company P/B: `(0.8,94), (1.5,82), (3,60), (5,38), (8,15)`. |
| 51 | - General P/B: `(1,88), (2,76), (4,56), (8,30), (12,12)`. |
| 52 | - Non-financial EV/EBITDA: `(5,94), (8,80), (12,62), (20,35), (30,12)`. |
| 53 | - PEG: `(0.5,90), (1,82), (1.5,65), (2.5,38), (4,15)`. |
| 54 | - FCF yield is `free cash flow / market cap × 100`: `(-5,5), (0,25), (2,48), (5,72), (8,90)`. |
| 55 | |
| 56 | P/B receives financial-sector treatment and EV/EBITDA is omitted for financial companies. Historical or peer valuation is not fabricated when no durable input exists. |
| 57 | |
| 58 | ### Fundamental/business quality (16) |
| 59 | |
| 60 | Available-metric weights are ROE 20, non-financial ROCE 20, operating margin 12, net margin 10, margin stability 12, operating-cash/PAT conversion 16, FCF/PAT quality 10, and profitability consistency 16. |
| 61 | |
| 62 | - Returns and margins: `(0,15), (5,38), (10,58), (18,78), (28,94)` percent. |
| 63 | - Margin stability is the population standard deviation of up to five annual PAT/revenue margins: `(2,92), (5,78), (10,55), (20,25), (35,8)` where lower is better. |
| 64 | - Cash conversion is operating cash flow divided by absolute PAT: `(0,8), (0.5,40), (0.8,65), (1,82), (1.3,94)`. |
| 65 | - FCF quality is FCF divided by absolute PAT: `(-0.5,5), (0,25), (0.5,55), (0.8,75), (1.1,90)`. |
| 66 | - Profitability consistency is the percentage of up to five annual periods with positive PAT. |
| 67 | |
| 68 | ### Growth (14) |
| 69 | |
| 70 | Weights are multi-year revenue CAGR 27, multi-year PAT/EPS CAGR 27, comparable-quarter revenue YoY 15, comparable-quarter earnings YoY 15, recent revenue QoQ 6, and multi-year consistency 10. |
| 71 | |
| 72 | CAGR requires at least three positive annual observations and uses elapsed years. Growth and change scores use `(-30,5), (-10,25), (0,45), (10,65), (20,80), (40,95)` percent. YoY chooses the prior observation 300–430 days earlier that is closest to 365 days. QoQ is deliberately limited to weight 6. Consistency is the percentage of non-declining annual changes across available revenue and earnings history. |
| 73 | |
| 74 | ### Balance sheet (9) |
| 75 | |
| 76 | Non-financial weights are debt/equity 28, net debt/equity 18, EBITDA interest coverage 24, current ratio 15, and annual debt trend 15. |
| 77 | |
| 78 | - Debt/equity percent: `(0,95), (30,85), (60,68), (100,45), (200,18)`. |
| 79 | - Net debt/equity percent: `(-20,98), (0,90), (30,75), (80,48), (150,18)`. |
| 80 | - Interest coverage: `(0.5,5), (1,18), (2,45), (4,70), (8,92)`. |
| 81 | - Current ratio: `(0.5,8), (0.9,35), (1.2,65), (1.8,88), (3,82)`. |
| 82 | - Annual debt change: `(-20,95), (0,78), (10,58), (30,30), (60,8)` percent. |
| 83 | |
| 84 | Banks, NBFCs, insurers, and other financial companies never receive these industrial leverage rules. Their V1 weights are capital adequacy 50, gross NPA 25, and net NPA 25. Capital adequacy uses `(9,20), (12,50), (15,72), (18,90)`; gross and net NPA use `(1,92), (2,78), (4,52), (7,25), (12,8)` where lower is better. If these sector-specific inputs are absent, the area is unscorable rather than bad. |
| 85 | |
| 86 | ### Quarterly earnings trend (9) |
| 87 | |
| 88 | Weights are comparable-quarter revenue YoY 25, PAT YoY 25, EPS YoY 15, revenue QoQ 5, PAT QoQ 5, operating-margin trend 15, and positive-quarter consistency 10. YoY uses the 300–430-day comparable-period rule. Sequential metrics are explicitly low-weight. Margin change scores use `(-8,8), (-3,30), (0,55), (2,75), (5,92)` percentage points. Each metric retains its actual normalized-fact source; qualifying official quarterly filings remain attached separately through area `sourceReferences`. |
| 89 | |
| 90 | ### Order book, capacity, and catalysts (8) |
| 91 | |
| 92 | Only validated real-mode structured events with confidence at least 0.60, reliability A or B, a supported catalyst type, and explicit materiality or an official/regulatory/exchange source are eligible. Documents or keyword matches are not score inputs. Eligible events have equal weight. Absence of order-book evidence does not penalize a business. |
| 93 | |
| 94 | ### Price/technical (7) |
| 95 | |
| 96 | This area reads durable price observations only and requires 50 observations. Weights are price versus the 50-observation median 35, price versus the 150-observation median 35 when available, drawdown from the observation-window peak 20, and observation-window trend 10. The accepted median semantics are explicit; no moving average is substituted. |
| 97 | |
| 98 | Trend points are `(-40,8), (-20,25), (-5,45), (0,55), (10,72), (30,88), (60,78)`. Drawdown points are `(-50,5), (-30,25), (-15,52), (-5,75), (0,90)`. |
| 99 | |
| 100 | ### Current news/geopolitical/events (7) |
| 101 | |
| 102 | Only validated issuer-relevant events whose event/publication age is inclusively between 0 and 30 days are eligible. Events are deduplicated by canonical source URL, normalized title, and event date. A macro/geopolitical event needs both a deterministic sector sensitivity and the same exposure term in the evidence; a general war story is not attached to every company. |
| 103 | |
| 104 | Each eligible event score is: |
| 105 | |
| 106 | ```text |
| 107 | 50 + direction × 50 × severity × probability × duration × pricedInFactor |
| 108 | ``` |
| 109 | |
| 110 | - Direction: strong positive `1`, positive `0.6`, neutral/uncertain `0`, negative `-0.6`, strong negative `-1`. |
| 111 | - Severity: `1` for material contract, cancellation, delay, guidance, regulatory, and management types; otherwise `0.75`; explicit monetary/capacity/percentage materiality adds `0.1`, capped at `1`. |
| 112 | - Probability: event confidence times reliability (`A=1`, `B=.85`, `C=.65`, `D=.4`, `E=.2`). |
| 113 | - Duration: immediate `.75`, short `.85`, medium/long `1`, unknown `.6`. |
| 114 | - V1 has no durable priced-in input, so its factor is the documented neutral `1`; it is never guessed. |
| 115 | |
| 116 | Eligible event scores have equal weight. |
| 117 | |
| 118 | ### Shareholding (4) |
| 119 | |
| 120 | This area applies to India when structured jurisdiction-supported ownership exists. Weights are promoter holding 25, promoter pledge 35, promoter trend 20, FII/FPI trend 10, and DII trend 10. USA/EU absence of NSE-style ownership is `UNSUPPORTED` and excluded. |
| 121 | |
| 122 | Promoter level points are `(0,25), (20,45), (40,65), (55,78), (70,82)`. Pledge points are `(0,95), (5,75), (15,48), (30,20), (50,5)`. Quarterly ownership changes use `(-5,15), (-2,35), (0,55), (2,75), (5,92)` percentage points. |
| 123 | |
| 124 | ### Management/governance (5) |
| 125 | |
| 126 | Validated governance events are not restricted to 30 days. Each unresolved event and promoter-pledge signal has equal weight. Event impact uses the deterministic event formula. Evidence marked rejected, resolved, remediated, cleared, closed, or no-wrongdoing receives the distinct remediation score instead of an unresolved penalty. Source IDs and URLs remain in the breakdown. |
| 127 | |
| 128 | ### Sector/macro (3) |
| 129 | |
| 130 | Weights are canonical-sector basis 20, durable sector performance 45 when available, and each proven-exposure macro event 35. Canonical sector alone is a neutral score of 50. Macro events use the same deterministic event formula and fail closed when exposure cannot be established. |
| 131 | |
| 132 | ## Quality, opportunity, risk, and confidence |
| 133 | |
| 134 | `qualityScore` is the top-level-weight-normalized mean of business quality, growth, balance sheet, quarterly trend, and governance. |
| 135 | |
| 136 | `opportunityScore` is the top-level-weight-normalized mean of valuation, catalysts, technical, current events, and sector/macro. |
| 137 | |
| 138 | `riskScore` is `100 - resilience`, where resilience is the available-metric weighted mean of balance sheet 30, governance 30, quarterly trend 15, current events 15, and business quality 10. Higher risk means worse public-company risk. |
| 139 | |
| 140 | `confidenceScore` never changes the stock score: |
| 141 | |
| 142 | ```text |
| 143 | critical completeness × 40% |
| 144 | + overall completeness × 20% |
| 145 | + mean source authority × 20% |
| 146 | + mean freshness × 20% |
| 147 | - min(30, 15 × conflict count) |
| 148 | ``` |
| 149 | |
| 150 | Source authority points are official/regulatory 100, trusted market data 90, licensed structured 80, approved secondary 65, approved external tool 50, user upload 40, and unverified 20. Freshness points are fresh 100, stale 55, partial 40, conflict/refreshing 20, and missing/failed 0. Unsupported requirements are excluded. Confidence labels are HIGH at 80, MEDIUM at 55, otherwise LOW. |
| 151 | |
| 152 | ## Eligibility and decision gates |
| 153 | |
| 154 | Critical requirements are valuation inputs, business-quality facts, balance-sheet facts, quarterly financials, and latest usable price. |
| 155 | |
| 156 | Full analysis requires at least 80% critical completeness and every mandatory and critical requirement to be `READY_FRESH` or `READY_STALE`. Safe partial analysis requires an explicit `allowPartial=true`, at least 50% critical completeness, at least three usable critical requirements, a usable latest price, and no critical conflict. |
| 157 | |
| 158 | Raw thresholds are: |
| 159 | |
| 160 | | Overall score | Signal | |
| 161 | |---:|---| |
| 162 | | `>= 85` | STRONG_BUY | |
| 163 | | `>= 75` | BUY | |
| 164 | | `>= 65` | ACCUMULATE | |
| 165 | | `>= 50` | HOLD | |
| 166 | | `>= 35` | REDUCE | |
| 167 | | `>= 20` | AVOID | |
| 168 | | `< 20` | EXIT_REVIEW | |
| 169 | |
| 170 | `STRONG_BUY` additionally requires 100% critical completeness, HIGH confidence, and every critical requirement fresh. Any unresolved mandatory conflict caps BUY/STRONG_BUY at HOLD. Partial analysis caps every positive signal at HOLD. Failure of the minimum gate returns `INSUFFICIENT_DATA` and no overall/quality/opportunity/risk score. |
| 171 | |
| 172 | ## Overrides |
| 173 | |
| 174 | Critical overrides require validated, unresolved, real-mode, level-A authoritative evidence with confidence at least 0.75. V1 supports: |
| 175 | |
| 176 | - `CONFIRMED_FRAUD_OR_ACCOUNTING_CRISIS`: explicit confirmed/accounting-fraud evidence with strong-negative impact. |
| 177 | - `CRITICAL_REGULATORY_ACTION`: strong-negative regulatory evidence for license revocation, trading ban, insolvency, criminal enforcement, or suspended operations. |
| 178 | - `SEVERE_UNRESOLVED_GOVERNANCE`: strong-negative auditor resignation/qualification evidence. |
| 179 | - `EXTREME_BALANCE_SHEET_STRESS`: non-financial debt/equity above 300% and interest coverage below 1, with official-tier source facts for every input. |
| 180 | - `BROKEN_INVESTMENT_THESIS`: at least two independent authoritative guidance cuts, order cancellations, or project delays. |
| 181 | |
| 182 | A CRITICAL override forces `EXIT_REVIEW`; a HIGH override forces `AVOID`. Weak generic news cannot activate an override. |
| 183 | |
| 184 | ## API and persistence |
| 185 | |
| 186 | `POST /api/v1/research/analysis/{globalInstrumentId}` accepts `{ "allowPartial": false }`. Identity resolution and all engine reads are provider-free. Find Data remains a separate readiness ensure operation. |
| 187 | |
| 188 | Results are stored globally in `research.global_stock_rule_engine_results`, keyed by global instrument ID, engine version, and SHA-256 input fingerprint. The fingerprint includes its V1 input-contract marker, scoring mode, UTC evaluation date, readiness status and provenance, public profile classification, canonical financial facts and provenance, structured facts, durable prices, events, and shareholding. The evaluation date ensures a cached current-news result expires when evidence crosses the inclusive 30-day boundary. Relevant durable input or source-link changes produce a different fingerprint; no generic score TTL is used. |
| 189 | |
| 190 | Each area returns metric-level provenance and `sourceReferences` copied from the qualifying readiness requirements. This keeps an official filing link, including the NSE quarterly-result URL, traceable from the score breakdown while preserving the actual source attached to each normalized metric. |
| 191 | |
| 192 | The write boundary rejects portfolio IDs, positions, quantities, average cost, cost basis, invested amount, P&L, and allocation anywhere in a result payload. |