Chapter 18 Exercises: MiFID II, MiFIR, and Best Execution Compliance

Instructions: Complete all five exercises. Exercises 1-3 are quantitative and analytical; Exercise 4 is a Python coding exercise extending the BestExecutionAnalyzer class; Exercise 5 is a research and comparative analysis exercise on the UK Wholesale Markets Review.


Exercise 1: Best Execution Analysis Calculation

Context: You are a compliance analyst at Meridian Capital, a UK broker-dealer. On 14 March 2024, the firm executed the following orders in ISIN GB00B1FBQ344 (a fictional mid-cap UK equity) on behalf of an institutional asset manager.

Order details:

Order ID Side Quantity Order Type Order Received
ORD-0341 Buy 75,000 Market 09:32:15
ORD-0342 Sell 40,000 Market 11:15:42
ORD-0343 Buy 120,000 Market 14:02:09

Execution records:

Execution ID Order ID Executed Price (p) Executed Qty Venue Execution Time
EX-001 ORD-0341 318.50 30,000 XLON 09:32:20
EX-002 ORD-0341 318.65 30,000 XLON 09:32:24
EX-003 ORD-0341 318.80 15,000 BATE 09:32:31
EX-004 ORD-0342 319.40 20,000 XLON 11:15:47
EX-005 ORD-0342 319.25 20,000 XLON 11:15:53
EX-006 ORD-0343 317.90 50,000 XLON 14:02:16
EX-007 ORD-0343 318.10 50,000 BATE 14:02:22
EX-008 ORD-0343 318.40 20,000 AQUI 14:02:35

Benchmark data:

Order ID Arrival Mid-Price (p) Market VWAP for period (p)
ORD-0341 318.20 318.55
ORD-0342 319.60 319.35
ORD-0343 317.50 317.95

Tasks:

1a. For each order, calculate the volume-weighted average execution price (VWAP) achieved by the firm. Show your workings.

1b. For each order, calculate the arrival price slippage in basis points. Use the formula:

For buy orders: slippage_bps = ((firm_vwap - arrival_mid) / arrival_mid) × 10,000 For sell orders: slippage_bps = ((arrival_mid - firm_vwap) / arrival_mid) × 10,000

A positive value represents a cost to the client.

1c. For each order, calculate the VWAP slippage against the market VWAP in basis points. Use the same sign convention (positive = cost to client).

1d. Assess the execution quality for each order: - ORD-0341 was a standard institutional buy. The firm's internal tolerance band is ±15 bps. Does ORD-0341 breach this band? - ORD-0342 was executed partly at 319.40p and partly at 319.25p. The arrival mid was 319.60p. Without performing the exact calculation, explain qualitatively why the sell-side slippage calculation is sign-inverted relative to the buy-side. - ORD-0343 was a large order (120,000 shares). The instrument's average daily volume (ADV) is approximately 600,000 shares. What additional best execution factor, beyond price, should the compliance team assess for this order and why?

1e. Prepare a one-paragraph compliance note that the head of best execution would use to sign off on the day's execution quality. Address all three orders and note any exceptions requiring further review.


Exercise 2: Transaction Reporting Field Completion

Context: Priya Nair is advising a new buy-side client — Cairngorm Capital Management — on their MiFID II transaction reporting obligations. Cairngorm is a UK-authorised investment manager (FCA-regulated) with LEI 213800DTXKZPPPEWKE96. On 15 March 2024, Cairngorm purchased 50,000 shares of a German company (ISIN DE000A1EWWW0, admitted to trading on Xetra, MIC code XETR) for a client pension fund. The order was executed on Xetra. The executed price was EUR 87.45 per share. The investment decision was made by a portfolio manager (a natural person, UK national, passport number: P12345678). The execution was carried out via a TWAP algorithm integrated into Cairngorm's execution management system.

The trading venue assigned TVTIC: XETR20240315000142689.

Tasks:

2a. Complete the following subset of the 65-field MiFIR transaction report template for this transaction. Where a field value depends on facts not provided, explain what information would be needed.

Field No. Field Name Your Answer
1 Reporting Firm LEI
26 Algorithmic Trading Indicator
27 Algo Decision-Making Indicator
28 Algo Execution Indicator
29 Trading Capacity
41 Instrument ISIN
42 Venue MIC
43 TVTIC
46 Price
50 Quantity

2b. For Field 3 (Investment Decision Maker), the portfolio manager is a natural person with a UK passport. The MiFIR reporting guidelines require natural persons to be identified using a concatenated code comprising: {NATIONALITY}{ID_TYPE}{ID_NUMBER}. Using the information provided, construct this identifier.

2c. Cairngorm's compliance officer proposes to submit this report without completing Fields 27 and 28, on the basis that "a human approved the trade before the TWAP algo ran." Explain whether this argument is correct under the MiFID II definition of algorithmic trading and ESMA's reporting guidelines. What is the risk if Fields 27 and 28 are left blank when the algorithmic trading indicator (Field 26) is "Y"?

2d. Three months after implementation, Cairngorm's ARM reports a 2.3% rejection rate for transaction reports, predominantly driven by "LEI validation failures" on Field 7 (Buyer ID). Priya investigates and finds that several of Cairngorm's sub-fund entities do not have valid LEIs registered in GLEIF. Describe: (a) the regulatory consequence of executing transactions for clients without valid LEIs; (b) the practical steps Cairngorm should take to remediate this issue; (c) how Cairngorm should handle the historical reports filed with missing or incorrect buyer LEIs.


Exercise 3: Systematic Internaliser Determination Methodology

Context: Verdant Bank, a UK challenger bank and investment firm (CCO: Maya Osei), has recently expanded its equity trading operations. The compliance team needs to determine whether Verdant Bank meets the SI thresholds for three UK equity instruments in which it has been active.

Data (three-month period ending 31 December 2023):

Instrument ISIN Total EU-Wide Trading Volume (shares) Verdant Bank OTC Internal Executions (shares) Verdant Bank Total Trading (shares)
GB00BH4HKS39 45,000,000 380,000 2,200,000
GB00BJQSQH41 12,000,000 95,000 580,000
GB00B1YW4409 800,000,000 2,500,000 18,000,000

The two SI determination tests under MiFID II are:

  • Frequency/Systematicity Test: OTC internal executions > 1% of total EU-wide trading in the instrument
  • Size Test: OTC internal executions > 15% of total EU trading by the firm in that instrument

A firm is an SI if either test is met.

Tasks:

3a. For each instrument, apply both tests and determine whether Verdant Bank meets the SI thresholds. Show your calculations.

3b. For the instrument(s) where Verdant Bank is determined to be an SI, explain what regulatory obligations arise: - Must Verdant Bank publish pre-trade quotes? Under what conditions? - Are the quotes required to be firm? - What is the "standard market size" concept and why does it matter?

3c. Maya Osei is concerned that being classified as an SI in one instrument will increase compliance costs significantly. She proposes reducing Verdant Bank's OTC internal executions in that instrument to just below the 15% size test threshold, while keeping the frequency/systematicity test result unchanged. Evaluate this proposal: (a) would reducing OTC internal executions below 15% of total firm trading avoid SI classification? (b) what operational and regulatory risks does this proposal introduce?

3d. Post-Brexit, the FCA indicated in the Wholesale Markets Review that it would consider reforming the SI determination methodology to make it more proportionate for smaller firms. Identify two specific criticisms of the current binary threshold approach and explain how a proportionality-based alternative might work in practice.


Exercise 4: Python Coding Exercise — Extending BestExecutionAnalyzer

Context: The BestExecutionAnalyzer class in Chapter 18 implements core best execution metrics. Your task is to extend it with three additional methods that are commonly required for MiFID II compliance evidence packages.

Setup: Use the data structures from Chapter 18:

from dataclasses import dataclass
from datetime import datetime
from typing import Optional
import pandas as pd
import numpy as np

@dataclass
class ClientOrder:
    order_id: str
    instrument_isin: str
    side: str
    quantity: float
    order_type: str
    limit_price: Optional[float]
    received_time: datetime
    client_id: str

@dataclass
class Execution:
    execution_id: str
    order_id: str
    executed_price: float
    executed_quantity: float
    venue: str
    execution_time: datetime

Task 4a: Implement flag_exceptions method

Add a method flag_exceptions(report: pd.DataFrame, slippage_threshold_bps: float, fill_rate_threshold: float) -> pd.DataFrame that takes the output of generate_execution_quality_report, applies two exception criteria, and returns only the rows where one or more criteria are breached:

  • Slippage exception: Arrival slippage exceeds slippage_threshold_bps (absolute value) in either direction
  • Fill rate exception: Fill rate is below fill_rate_threshold

The returned DataFrame should include an additional column exception_reasons that is a list of strings describing which criteria were breached for each row.

Task 4b: Implement monthly_venue_ranking method

Add a method monthly_venue_ranking(executions: list[Execution], month: int, year: int) -> pd.DataFrame that filters executions to those occurring in the specified month and year, then produces a venue ranking DataFrame with: - venue: venue name - total_quantity: total executed quantity - total_notional: total executed notional value - avg_price: volume-weighted average price - trade_count: number of individual execution records - pct_of_total_quantity: percentage of total executed quantity at that venue

Sort by pct_of_total_quantity descending. This output supports RTS 28 annual reporting (top-five venue identification).

Task 4c: Implement implementation_shortfall_time_series method

Add a method implementation_shortfall_time_series(orders: list[ClientOrder], executions: list[Execution], benchmarks: dict, freq: str = 'W') -> pd.DataFrame that computes average arrival price slippage aggregated by time period (freq parameter uses pandas frequency strings: 'D' for daily, 'W' for weekly, 'ME' for month-end). This supports trend analysis — detecting whether execution quality is improving or deteriorating over time.

The output DataFrame should be indexed by the period and include: - avg_slippage_bps: mean arrival slippage for the period - median_slippage_bps: median arrival slippage - order_count: number of orders in the period - avg_fill_rate: mean fill rate

Task 4d: Write a test harness

Using the test data below, instantiate your extended BestExecutionAnalyzer, call all three new methods, and print the results.

# Test data — use this to validate your implementation
test_orders = [
    ClientOrder("O-001", "GB00B1FBQ344", "buy",  80_000, "market", None,
                datetime(2024, 1, 10, 9, 31, 0), "CLI-001"),
    ClientOrder("O-002", "GB00B1FBQ344", "sell", 30_000, "market", None,
                datetime(2024, 1, 15, 11, 0, 0), "CLI-002"),
    ClientOrder("O-003", "GB00BJQSQH41", "buy",  50_000, "market", None,
                datetime(2024, 2, 5, 14, 0, 0), "CLI-001"),
    ClientOrder("O-004", "GB00BJQSQH41", "buy", 200_000, "market", None,
                datetime(2024, 2, 20, 9, 35, 0), "CLI-003"),
]

test_executions = [
    Execution("E-001", "O-001", 318.80, 80_000, "XLON", datetime(2024, 1, 10, 9, 31, 8)),
    Execution("E-002", "O-002", 319.10, 30_000, "XLON", datetime(2024, 1, 15, 11, 0, 6)),
    Execution("E-003", "O-003", 445.20, 30_000, "XLON", datetime(2024, 2, 5, 14, 0, 10)),
    Execution("E-004", "O-003", 445.50, 20_000, "BATE", datetime(2024, 2, 5, 14, 0, 18)),
    Execution("E-005", "O-004", 444.80, 100_000, "XLON", datetime(2024, 2, 20, 9, 35, 12)),
    # Note: O-004 is only 50% filled — tests fill_rate exception
]

test_benchmarks = {
    "O-001": {"arrival_price": 318.40, "market_vwap": 318.60},
    "O-002": {"arrival_price": 319.30, "market_vwap": 319.20},
    "O-003": {"arrival_price": 444.80, "market_vwap": 445.10},
    "O-004": {"arrival_price": 444.50, "market_vwap": 444.70},
}

Guidance notes: - For flag_exceptions, the exception_reasons column should contain a Python list of strings (e.g., ["slippage_exceeded", "fill_rate_below_threshold"]) - For monthly_venue_ranking, filter executions by execution_time.month and execution_time.year - For implementation_shortfall_time_series, use pd.Grouper with the freq parameter on a DatetimeIndex built from order.received_time


Exercise 5: Research Exercise — UK Wholesale Markets Review Outcomes

Context: The FCA's Wholesale Markets Review (WMR), culminating in Policy Statement PS22/2 (March 2022) and the subsequent Financial Services and Markets Act 2023, represents the most significant departure from inherited EU MiFID II in UK capital markets regulation since Brexit.

Task 5a: Primary source research

Access the FCA's Policy Statement PS22/2 (available at fca.org.uk). Identify and summarise four specific regulatory changes made to the UK's MiFID II framework. For each change, note: - The EU MiFID II rule that was modified - The specific change made in the UK - The FCA's stated rationale for diverging from the EU approach

Task 5b: Comparative analysis — SI regime

The EU and UK have diverged in their approach to the SI determination methodology. Drawing on PS22/2 and FCA discussion papers, compare:

(a) The EU MiFID II SI determination methodology (frequency/systematicity test and size test thresholds as set out in EU RTS 14)

(b) The UK's current approach and any proposed reforms signalled in the WMR

(c) The arguments for and against applying a single, uniform threshold set to all investment firms regardless of size — as opposed to a proportionality-based approach that calibrates thresholds to firm size or activity

Task 5c: Industry perspective

Access at least one of the following industry consultation responses to the FCA's WMR and summarise the key concerns raised about the transaction reporting and best execution framework: - AFME (Association for Financial Markets in Europe) response to CP21/9 - Investment Association response to CP21/9 - FIX Trading Community response

If these documents are not publicly accessible, use the FCA's summary of consultation responses published in PS22/2.

Task 5d: Practitioner reflection

Maya Osei at Verdant Bank operates under UK MiFID II and processes both UK and some EU-linked transactions. Write a 200-word compliance brief for Maya's board, explaining: (a) the two most commercially significant UK-EU divergences that affect Verdant Bank's trading operations; (b) what ongoing monitoring Verdant Bank should conduct to track further UK regulatory divergence; and (c) whether Maya should recommend dual-tracking both the EU and UK frameworks or developing fully separate compliance programmes.


Suggested Solutions and Marking Guidance

Exercise 1 Solutions

1a. Volume-weighted average execution prices:

ORD-0341 (Buy, 75,000 shares):

Total value = (318.50 × 30,000) + (318.65 × 30,000) + (318.80 × 15,000)
            = 9,555,000 + 9,559,500 + 4,782,000
            = 23,896,500p
Total qty   = 75,000
Firm VWAP   = 23,896,500 / 75,000 = 318.620p

ORD-0342 (Sell, 40,000 shares):

Total value = (319.40 × 20,000) + (319.25 × 20,000)
            = 6,388,000 + 6,385,000
            = 12,773,000p
Total qty   = 40,000
Firm VWAP   = 12,773,000 / 40,000 = 319.325p

ORD-0343 (Buy, 120,000 shares):

Total value = (317.90 × 50,000) + (318.10 × 50,000) + (318.40 × 20,000)
            = 15,895,000 + 15,905,000 + 6,368,000
            = 38,168,000p
Total qty   = 120,000
Firm VWAP   = 38,168,000 / 120,000 = 318.067p

1b. Arrival price slippage:

ORD-0341 (Buy): ((318.620 - 318.20) / 318.20) × 10,000 = (0.420/318.20) × 10,000 = **+13.2 bps** ORD-0342 (Sell): ((319.60 - 319.325) / 319.60) × 10,000 = (0.275/319.60) × 10,000 = **+8.6 bps** ORD-0343 (Buy): ((318.067 - 317.50) / 317.50) × 10,000 = (0.567/317.50) × 10,000 = **+17.9 bps**

1c. VWAP slippage:

ORD-0341 (Buy): ((318.620 - 318.55) / 318.55) × 10,000 = **+2.2 bps** (firm slightly above market VWAP) ORD-0342 (Sell): ((319.35 - 319.325) / 319.35) × 10,000 = **+0.8 bps** (firm slightly below market VWAP — small cost) ORD-0343 (Buy): ((318.067 - 317.95) / 317.95) × 10,000 = **+3.7 bps** (firm slightly above market VWAP)

1d assessment notes: - ORD-0341: 13.2 bps arrival slippage. Within the ±15 bps tolerance band — no exception. - ORD-0342: For a sell order, the client wants as high a price as possible; executing below the arrival mid is a cost. The sign inversion reflects that a lower execution price vs. mid is adverse for the seller, just as a higher execution price vs. mid is adverse for the buyer. Both represent "slipping away from the arrival mid." - ORD-0343: 17.9 bps arrival slippage exceeds the 15 bps tolerance band — triggers exception review. The order represents 20% of ADV (120,000 / 600,000 = 20%), meaning size and market impact are the key additional best execution factors. The multi-venue routing across XLON, BATE, and AQUI should be assessed for whether the routing strategy minimised market impact.

Exercise 3 Solutions

3a. SI Determination:

GB00BH4HKS39: - Frequency test: 380,000 / 45,000,000 = 0.844% → Below 1% threshold. FAIL. - Size test: 380,000 / 2,200,000 = 17.3% → Exceeds 15% threshold. PASS. - Result: Verdant Bank IS an SI in GB00BH4HKS39 (size test met).

GB00BJQSQH41: - Frequency test: 95,000 / 12,000,000 = 0.792% → Below 1%. FAIL. - Size test: 95,000 / 580,000 = 16.4% → Exceeds 15%. PASS. - Result: Verdant Bank IS an SI in GB00BJQSQH41 (size test met).

GB00B1YW4409: - Frequency test: 2,500,000 / 800,000,000 = 0.313% → Below 1%. FAIL. - Size test: 2,500,000 / 18,000,000 = 13.9% → Below 15%. FAIL. - Result: Verdant Bank is NOT an SI in GB00B1YW4409.


End of Chapter 18 Exercises