Investment restriction
Permitted and prohibited investments
Permitted and prohibited investments define what a portfolio may hold: a permitted list names the allowed universe, a prohibited list names what is excluded. Acclimetry tests either form: in prohibited mode any listed holding is a breach, and in permitted mode any holding outside the list is. The result names the offending holdings and their weight.
instrument_listPermitted / prohibited list
How policies word it
Most written policies carry a section headed ‘Permissible investments’, ‘Eligible instruments’ or ‘Kinds of investments to be held’. Many add an ‘expressly prohibited’ list, such as margin purchases, unregistered stock or direct derivatives.
Trustees of UK occupational pension schemes must invest predominantly in assets admitted to trading on regulated markets. They may use derivatives only to reduce risk or for efficient portfolio management.
The two forms fail differently. A permitted list fails closed: anything new is outside it until added. A prohibited list fails open: anything not named is allowed.
- Permissible investments: listed equities, investment-grade bonds, regulated collective investment schemes and cash deposits.
- The following are expressly prohibited: commodities, unlisted securities and structured products.
- No direct investment in cryptocurrencies.
- The manager may not invest in securities denominated in currencies other than sterling, US dollars or euros.
- No holdings in issuers domiciled in the countries listed in Schedule 2.
How it is measured
A holding can be listed by instrument id, issuer id, class name or identifier (ISIN, CUSIP, SEDOL or FIGI). It can also be listed by listing country, currency, counterparty, issuer domicile or a governed field value written CODE=value, such as SECTOR=Tobacco. Country matching is case-insensitive.
Prohibited mode breaches on any listed holding; permitted mode breaches on any holding outside the allowed universe. The result names the offending positions and reports their combined weight of portfolio value. A portfolio with no offending holding is compliant at zero.
When it is breached and what follows
A prohibited holding is usually an active breach: someone bought it. It can also arise passively, when a list update, a reclassification or a corporate action brings an existing holding within the list. The result is the same either way, and the case opens at once.
What follows is set by the policy: divest, or record a time-bound waiver naming the holding. Before a purchase, Trade Impact can check the proposed order against the list.
Data the check reads
- Market value of every position
- The fields the list matches on: instrument and issuer ids, class, identifiers, listing country, currency, counterparty or issuer domicile
- Governed custom fields for CODE=value matches, such as a sector field
- The mode (permitted or prohibited) and the list entries
Rule parameters
Prohibited mode breaches on any listed holding; permitted mode breaches on any holding outside the allowed universe. A holding is listed by instrument, issuer, class, identifier, listing country, currency, counterparty, issuer domicile or a governed field value (CODE=value).
| Parameter | In the platform | Options and help |
|---|---|---|
| mode | Mode | prohibited (Prohibited — breach on any listed holding) · permitted (Permitted — breach on any holding outside the list) |
| assetKeys | Asset ids | |
| issuerKeys | Issuer ids | |
| classNames | Class names | |
| identifiers | Instrument identifiers (ISIN, CUSIP, SEDOL, FIGI) | |
| countries | Countries | |
| currencies | Currencies | |
| counterpartyKeys | Counterparty ids (or group keys) | |
| issuerCountries | Issuer countries (domicile) | |
| fieldMatches | Governed field values (CODE=value) |
Parameter names, methodology text and result-code meanings are shown exactly as the platform states them.
Worked examples, run by the engine
A book holding nothing on the prohibited list is compliant at zero offending weight
Rule template:instrument_list mode: prohibitedassetKeys: BANNED
| Holding | Market value |
|---|---|
| A | 600 |
| B | 400 |
| Group | Status | Value | Bounds | Headroom to the hard bound | Code |
|---|---|---|---|---|---|
| Prohibited holdings | Compliant | 0% | – | – | NO_PROHIBITED_HOLDINGS |
NO_PROHIBITED_HOLDINGS: Returned by the engine; the registry’s reason-code dictionary has no entry for it.
These are the product's own test cases for this template, evaluated by the Acclimetry rule engine (backend commit 8197063). The build fails if any result changes.
A prohibited country matches case-insensitively, and the 300 listed holding of a 1,000 book breaches at 30% offending weight
Rule template:instrument_list mode: prohibitedcountries: ru
| Holding | Country | Market value |
|---|---|---|
| RU1 | RU | 300 |
| GB1 | GB | 700 |
| Group | Status | Value | Bounds | Headroom to the hard bound | Code |
|---|---|---|---|---|---|
| Prohibited holdings | Breach | 30% | – | – | PROHIBITED_HOLDING_PRESENT |
PROHIBITED_HOLDING_PRESENT: Returned by the engine; the registry’s reason-code dictionary has no entry for it.
Largest contributors: Prohibited holdings → RU1 30%
These are the product's own test cases for this template, evaluated by the Acclimetry rule engine (backend commit 8197063). The build fails if any result changes.
In permitted mode a 250 holding outside the allowed classes breaches at 25% of the 1,000 book
Rule template:instrument_list mode: permittedclassNames: Stocks
| Holding | Class | Market value |
|---|---|---|
| EQ | Stocks | 750 |
| BTC | Crypto | 250 |
| Group | Status | Value | Bounds | Headroom to the hard bound | Code |
|---|---|---|---|---|---|
| Eligibility | Breach | 25% | – | – | HOLDING_OUTSIDE_PERMITTED_UNIVERSE |
HOLDING_OUTSIDE_PERMITTED_UNIVERSE: Returned by the engine; the registry’s reason-code dictionary has no entry for it.
Largest contributors: Eligibility → BTC 25%
These are the product's own test cases for this template, evaluated by the Acclimetry rule engine (backend commit 8197063). The build fails if any result changes.
In permitted mode, a structured note worth 3% of the portfolio sits outside the allowed classes, so the rule breaches and names it.
Rule template:instrument_list mode: permittedclassNames: Listed equities, Government bonds, Cash
| Holding | Class | Market value |
|---|---|---|
| UK listed equities | Listed equities | 620,000 |
| UK Treasury 2032 | Government bonds | 300,000 |
| Sterling deposit | Cash | 50,000 |
| Structured note 2028 | Structured notes | 30,000 |
| Group | Status | Value | Bounds | Headroom to the hard bound | Code |
|---|---|---|---|---|---|
| Eligibility | Breach | 3% | – | – | HOLDING_OUTSIDE_PERMITTED_UNIVERSE |
HOLDING_OUTSIDE_PERMITTED_UNIVERSE: Returned by the engine; the registry’s reason-code dictionary has no entry for it.
Largest contributors: Eligibility → Structured note 2028 3%
Computed at build time by the Acclimetry rule engine (backend commit 8197063); the same code runs in the product.
Interpretation traps
Permitted lists fail closed
In permitted mode, a new asset type is a breach until the list changes. That is the intended reading of ‘only the following’, but every new class then needs an approved new rule version.
Match on stable keys
Names change; identifiers and governed fields change less. Prefer ISINs, issuer ids or a governed field over free-text class names, and keep the classification current.
Funds hide holdings
The list tests the positions the portfolio holds. A fund that owns a prohibited security is not caught unless the fund itself matches; look-through applies to exposure limits, not to this list.
Allowances are caps
Some policies allow a small amount, such as ‘unlisted securities up to 5%’. That is a weight cap, not a list: an asset allocation range with a maximum on the class tests it.
Result codes this check can return
| Code | State | Meaning | What to do |
|---|---|---|---|
| NO_PROHIBITED_HOLDINGS ✓ | Compliant | Returned by the engine; the registry’s reason-code dictionary has no entry for it. | – |
| HOLDING_OUTSIDE_PERMITTED_UNIVERSE ✓ | Breach | Returned by the engine; the registry’s reason-code dictionary has no entry for it. | – |
| PROHIBITED_HOLDING_PRESENT ✓ | Breach | Returned by the engine; the registry’s reason-code dictionary has no entry for it. | – |
| EMPTY_PORTFOLIO | Not applicable | The portfolio held no positions at the evaluation moment. | – |
| NOT_IN_SCOPE | Not applicable | This rule version does not apply to this portfolio — the portfolio is outside the version's stated scope. Recorded so that "considered and out of scope" can be told from "never run". | – |
| AGGREGATE_MEMBER_NOT_ACCEPTED | Not evaluated: data quality | A portfolio in the measured set has no authoritative snapshot, so the set-level number cannot be stated. | Accept the named portfolios' snapshots. A partial set produces no aggregate. |
| SNAPSHOT_NOT_ACCEPTED | Not evaluated: data quality | The portfolio's newest snapshot awaits data-quality review; only accepted data may produce an authoritative result. | Accept, override or reject the snapshot on Data & Quality. |
| SNAPSHOT_REJECTED | Not evaluated: data quality | The portfolio's newest snapshot was rejected, so there is no authoritative data to measure. | Load a corrected file. |
| STALE_POSITIONS | Not evaluated: data quality | The newest snapshot is older than the organisation's staleness threshold. | Load current positions, or revisit the threshold on Data & Quality ▸ Policy. |
| STALE_PRICES | Not evaluated: data quality | A holding had no price on the position file and its approved price was older than the organisation's price-staleness threshold, so it was left unvalued. | Load a current price for the holding, price it on the position file, or revisit the threshold on Data & Quality ▸ Policy. |
| AWAITING_EXTERNAL_DATA | Pending external data | An approved input is late but still inside the organisation's grace window. This is not a pass and not an exception. | None yet. If the delivery does not arrive, this becomes a data-quality exception. |
| METHOD_NOT_SUPPORTED | Not evaluated: unsupported | The rule version asks for a measurement method this engine does not implement. Declared rather than approximated. | Choose a supported methodology, or treat this limit as a manual obligation until the method ships. |
| EVALUATOR_ERROR | Not evaluated: system error | The evaluator raised an error. Surfaced as a visible result rather than as silence. | Report it. A system error is never a pass and never a compliant reading. |
✓ seen in the worked examples. The rest come from the platform registry’s own scan of the template source.
Regulatory analogues
- Statement of investment principles: regulated markets and derivatives (OPS Investment Regs 2005 reg 4)
- NURS 20% in non-eligible securities (COLL 5.6.5R)
- UK UCITS 10% limit on crypto ETNs (COLL 5.2.11R)
Acclimetry evaluates whether any holding matches a prohibited list, or falls outside a permitted one, and reports the offending weight. Matches use instrument, issuer, class, identifier, country, currency, counterparty, domicile or governed field values. It does not maintain sanctions lists, share lists across organisations, look through funds, or decide legal eligibility.
The free Limit Checker runs this same template in your browser against a CSV of holdings. Nothing is uploaded.
Questions
How is this different from an exclusion screen?
This list matches the holdings you name. The exclusion screen applies ESG, ethical or sanctions exclusions from an approved data source and discloses the weight it could not screen.
Does a 0.1% prohibited holding still breach?
Yes. Any listed holding breaches in prohibited mode, whatever its weight. The result reports the weight so the case can size the remedy.
Sources
- Occupational Pension Schemes (Investment) Regulations 2005, reg 4 · OGL v3.0 · Read on12 October 2026
- FCA Handbook, COLL 5.6 (non-UCITS retail schemes), read 12 October 2026; pending FCA API snapshot · © FCA, OGL v3.0 · Read on12 October 2026
- FCA Handbook, COLL 5.2 (UK UCITS schemes), read 12 October 2026; pending FCA API snapshot · © FCA, OGL v3.0 · Read on12 October 2026