05 — Shariah Compliance Engine¶
1. Position of this component¶
Compliance is the highest-priority constraint in the system and the only one with veto power over every other consideration. It is implemented as a deterministic gate that runs first, not as an agent whose opinion is weighed against financial attractiveness.
Three consequences follow, and they shape components far from this document:
- The gate runs before any analysis budget is spent (04 §8).
- Missing inputs produce
UNCERTAIN, which excludes the candidate. The engine fails closed — there is no path where absent data yields a pass. - Whole product capabilities are removed rather than disabled: short selling, margin, interest on cash, and conventional derivatives are not features that are switched off. They are absent from the domain model.
2. Limits of this system¶
This must be stated plainly, and the application states it at the point of use, not only here.
- This engine mechanically applies published screening methodologies. It is a research and screening tool.
- It is not a fatwa and does not constitute a religious ruling. Scholars differ on methodology, thresholds, denominators, and the treatment of specific business activities.
- Threshold values and rule details in the shipped rule packs are drawn from published descriptions of the respective methodologies. They must be verified against the current official standard text, and a user following a particular standard should confirm the configuration matches their scholar's or board's guidance.
- Classification of business activity from filings is model-assisted and can be wrong, particularly for conglomerates, holding companies, and firms with revenue segments that are disclosed coarsely.
- Where the engine is uncertain, it says so rather than choosing.
UNCERTAINis a first-class verdict, not an error state.
The design intent is that the user can audit the reasoning, not that they should defer to it.
3. Verdict model¶
class ShariahVerdict(BaseModel):
instrument_id: UUID
rule_pack: str # "aaoifi_ss21" | "djim" | "msci_islamic" | "ftse" | "custom:<id>"
rule_pack_version: str
status: Literal["COMPLIANT", "NON_COMPLIANT", "UNCERTAIN"]
business_activity: ActivityScreenResult
financial_ratios: list[RatioResult]
impure_income: ImpureIncomeResult
failing_criteria: list[str] # empty iff COMPLIANT
uncertainty_causes: list[str] # missing/stale inputs, ambiguous classification
confidence: float # classification confidence, NOT permission to proceed
purification_rate: Decimal | None # proportion of dividends to purify
as_of: datetime
inputs: list[FeatureRef] # every value used, with as-of dates and source docs
explanation: str # plain language, generated from the above
confidence describes how sure the engine is of its classification, and never softens the verdict. A NON_COMPLIANT at 0.6 confidence still blocks; it simply also flags itself for review.
4. Screen 1 — business activity¶
Revenue-segment classification against the rule pack's prohibited and restricted categories.
Typically prohibited primary activities across mainstream methodologies: conventional banking and lending; conventional insurance; alcohol production and distribution; tobacco; pork-related products; gambling, casinos, and betting; adult entertainment; and — varying by standard — conventional entertainment/media, hotels with material non-compliant revenue, and weapons manufacture.
Classification pipeline:
- Structured first. GICS/SIC/NAICS codes and XBRL revenue-segment disclosures give a machine-readable starting point for the majority of the universe.
- Document evidence second. Business description (10-K Item 1) and segment reporting are retrieved and read by the classifier for revenue attribution the codes do not capture — a retailer's alcohol shelf share, a conglomerate's finance arm.
- Model classification third, only for what remains ambiguous, emitting per-category revenue share with a citation for each attribution.
- User overrides last. The user may pin a classification, with the override recorded, dated, and shown on every future verdict for that instrument. Their standard, their call — but never silently.
Revenue tolerance. Most methodologies permit incidental non-compliant revenue below a threshold, commonly 5% of total revenue. Above the threshold, the instrument fails regardless of financial ratios.
Sector classification is a known weak point for holding companies and conglomerates. The engine responds by lowering classification confidence and, past a threshold, returning UNCERTAIN with the specific segment that could not be attributed — rather than guessing in either direction.
5. Screen 2: financial ratios¶
Methodologies differ on three axes: which ratios, what threshold, and — most consequentially — what denominator. Market-capitalisation denominators move with price, so an instrument can pass and fail on price action alone; total-asset denominators are stable but less responsive. The engine treats all three axes as configuration.
Rule packs are declarative, versioned files:
id: aaoifi_ss21
version: "2024.1"
label: "AAOIFI Shari'ah Standard No. 21 (as commonly implemented)"
source_note: >
Thresholds reflect widely published implementations of AAOIFI SS 21.
Verify against the current official standard text before relying on them.
impure_income:
numerator: non_permissible_revenue
denominator: total_revenue
max: 0.05
ratios:
- id: debt_screen
label: "Interest-bearing debt"
numerator: interest_bearing_debt
denominator: market_cap # some implementations use total_assets
max: 0.30
- id: liquidity_screen
label: "Cash and interest-bearing securities"
numerator: cash_plus_interest_bearing_securities
denominator: market_cap
max: 0.30
on_missing_input: UNCERTAIN # never PASS
Shipped rule packs — each with the same caveat that thresholds must be verified against the official current text of the standard:
| Pack | Denominator convention | Typical screens |
|---|---|---|
aaoifi_ss21 |
Market capitalisation | Debt ≤ 30%; cash + interest-bearing securities ≤ 30%; non-permissible income ≤ 5% |
djim |
Trailing 24-month average market cap | Debt, cash + interest-bearing securities, and accounts receivable each < 33%; impure income ≤ 5% |
msci_islamic |
Total assets | Debt, cash + interest-bearing securities, and receivables each < 33.33%; impure revenue ≤ 5% |
ftse_shariah |
Total assets | Debt < 33%; cash + interest-bearing items < 33%; receivables + cash < 50%; impure income ≤ 5% |
custom |
User-defined | Any combination, with the user's own thresholds and notes |
The custom pack matters more than it appears. Users follow different scholars; a system that hard-codes one methodology and calls it "halal" is making a religious claim it has no standing to make. Making the standard explicit and swappable is the honest design.
Trailing-average denominators (as DJIM uses) require price history and are recomputed daily; when insufficient history exists — a recent IPO, for instance — the pack's on_missing_input policy applies, which is UNCERTAIN.
Ratio drift monitoring. Because market-cap denominators move continuously, an instrument can drift toward a threshold without any new filing. The engine tracks distance-to-threshold and raises a COMPLIANCE_AT_RISK event at a configurable buffer (default 10% relative), so a held position that is about to fail is flagged before it does, not after.
6. Screen 3 — impure income and purification¶
Even a compliant instrument may generate a small share of non-permissible income, typically interest on corporate cash. Most methodologies require the corresponding proportion of dividends received to be purified — given away, without the intent of reward, and not counted as personal gain.
purification_rate = non_permissible_income / total_income (per fiscal period)
purification_amount = dividend_received × purification_rate
The engine:
- computes the rate per instrument per period from filed statements, with sources cited;
- accrues a purification liability on every simulated dividend in the paper account, so the practice is established from day one;
- reports portfolio-level purification owed, per period and cumulative, on the Performance screen;
- shows performance net of purification as the headline figure, because a return figure that includes money the user intends to give away overstates what they actually earned.
Variation is expected here — some scholars compute purification on income, others on dividend, some per-share — so the numerator/denominator basis is part of the rule pack, not hard-coded.
7. Instrument eligibility¶
Beyond issuer screening, whole instrument classes are excluded by the compliance model. These are architectural, not configurable:
| Excluded | Reason |
|---|---|
| Short selling | Selling what one does not own |
| Margin and leverage | Interest-bearing borrowing |
| Conventional bonds, T-bills, money market funds | Interest instruments |
| Conventional options, futures, CFDs, swaps | Excessive uncertainty (gharar) and speculation (maysir) under mainstream rulings |
| Interest on idle cash | Riba. The paper broker accrues 0% on cash balances; if a live broker later pays interest, it is routed entirely to purification |
Permitted, subject to screening: listed equities, Shariah-screened ETFs (screened at the fund level via holdings look-through where data permits, otherwise flagged UNCERTAIN), sukuk (Phase 4 — requires structure-level review, not just issuer screening), and physical commodity exposure such as allocated gold and silver, with the constraint that mainstream rulings require immediate possession-equivalent settlement, which rules out most conventional commodity derivatives.
Deferred: cryptocurrency. Scholarly opinion is genuinely divided and depends on the specific asset's structure and use. Rather than shipping a guess, it is out of scope until a dedicated rule pack with clear provenance can be written.
8. Recomputation and lifecycle¶
A verdict is not permanent. It is recomputed:
- On new filings — a 10-Q changes debt and cash immediately.
- Daily for any pack using a price-based denominator.
- On rule pack change — including a user editing thresholds, which triggers full-universe and full-portfolio re-evaluation.
- On corporate action — mergers and spinoffs can change the business entirely.
When a held position becomes non-compliant, the system does not force a sale. It raises a high-priority alert with the specific failing criterion, the magnitude of the breach, and guidance that mainstream practice is typically to exit within a grace period and purify gains attributable to the non-compliant period. The action is the user's; the information and the calculation are the system's job.
Every verdict transition is recorded, so an instrument's compliance history is itself queryable — which is useful both for the user and for the backtest engine, which must screen using the verdict as it stood at the historical date, never today's. Backtesting a "halal strategy" against today's compliance list is a look-ahead error that would flatter results substantially.
9. Explanation output¶
Every verdict renders to a structure the app displays directly:
NVDA — Compliant (AAOIFI SS 21, evaluated 2026-08-03)
Business activity — pass. Semiconductor design and manufacture. No revenue attributed to prohibited categories. Source: FY2025 10-K, Item 1, filed 2026-02-26.
Interest-bearing debt — pass. $9.7B ÷ $2,940B market cap = 0.33% (limit 30%). Source: 10-Q Q1 FY2026, filed 2026-05-28.
Cash and interest-bearing securities — pass. $38.4B ÷ $2,940B = 1.31% (limit 30%). Same source.
Non-permissible income — pass. Interest income $1.1B ÷ total income $92.3B = 1.19% (limit 5%).
Purification: 1.19% of dividends received.
This is a mechanical application of a published methodology, not a religious ruling. Figures above link to their source filings.
Numbers above are illustrative of the format, not current data. Every figure in a real verdict is a tappable link to the filing and the exact line item, and the entire block is reproducible from the stored inputs list.
10. Validation¶
The compliance engine is the component most in need of external validation, because it is the one whose errors matter most.
- Constituency agreement. Run each rule pack against a labelled universe drawn from published index constituents on historical dates; target ≥ 98% agreement, with every disagreement individually investigated and documented. Disagreements are informative — they usually reveal a denominator or timing convention that the published description understates.
- Golden set regression. A hand-checked set of instruments spanning easy passes, clear fails, and known-hard cases (conglomerates, REITs, holding companies, recent IPOs) runs on every change to rules or feature definitions.
- Point-in-time replay. Historical verdicts recompute identically from the stored inputs — this is the same harness described in 03 §4.
- Property tests. Invariants: missing input never yields
COMPLIANT; tightening any threshold never converts a fail into a pass; verdicts are deterministic given identical inputs and pack version. - Human review. The intent is that a qualified reviewer can examine the rule packs and a sample of verdicts. The engine's job is to make that review possible by showing every input, threshold, and step.