EU Insider Trading Scanner (AFM Directors' Dealings) avatar

EU Insider Trading Scanner (AFM Directors' Dealings)

Pricing

from $10.00 / 1,000 transaction scrapeds

Go to Apify Store
EU Insider Trading Scanner (AFM Directors' Dealings)

EU Insider Trading Scanner (AFM Directors' Dealings)

Read managers' transactions (MAR Art. 19) from the Dutch AFM register, convert values to EUR, and score open-market buys with a documented 0-100 heuristic and cluster detection. Covers AFM-supervised issuers only. Not investment advice.

Pricing

from $10.00 / 1,000 transaction scrapeds

Rating

0.0

(0)

Developer

goober

goober

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Share

EU Directors' Dealings API: insider buys and sells from the AFM register, scored 0-100

Get recent insider trades (managers' transactions under EU MAR Article 19) as clean JSON: issuer, ISIN, person and role, buy or sell, price, quantity, value in EUR and a link to the official record. It is for investors, analysts and developers who want a directors' dealings feed without reading registers by hand. Open-market buys also get a documented conviction score with cluster detection.

Coverage: Netherlands only (AFM register). Germany, France and Belgium are not covered, see the table below. The register includes foreign companies listed in Amsterdam, but it is not all EU insider trades.

Not investment advice. The score is a heuristic computed from public filings. It is not a recommendation to buy or sell anything and says nothing about future returns.

Why use this Actor

  • Official source: the public AFM register of MAR Article 19 notifications, no scraping of third-party sites.
  • Every row is normalised (buy / sell / other) and flagged as open-market or not, with the reason.
  • Values converted to EUR with ECB reference rates of the transaction date.
  • Conviction score 0-100 for open-market buys, with the points per component in the output.
  • Plain HTTP, no proxies, no browser. One request per second to the AFM, so it is polite and cheap.

Quick start

Click Start with the prefilled input:

{ "lookbackDays": 14, "maxItems": 5, "transactionTypes": ["buy"] }

After about 2 minutes you get up to 5 open-market buys from the last 14 days, each with value in EUR, role, conviction score and sourceUrl.

Input

FieldDefaultMeaning
lookbackDays30 (prefill 14)Only transactions dated within this many days before today
maxItems100 (prefill 5)Hard cap on output rows; each row is billed
openMarketOnlytrueSkip grants, share plans, exercises, swaps, dividends, gifts, transfers, bonds
transactionTypesbuy, sell (prefill buy)Any of buy, sell, other
minConvictionScore0Keep only open-market buys with at least this score
minValueEur0Minimum trade value in EUR
clusterWindowDays14Window (+/- days) for cluster detection
issuerContains, isinsemptyOptional issuer/ISIN filters; blank entries are ignored
maxNotifications1500Safety cap on pages read
requestDelaySecs1Delay between requests (minimum 1)

What you get

Real item from a live run (input: lookbackDays 30, maxItems 5, buys only, minValueEur 5000). More samples are in sample_run/.

{
"id": "202609245F7409F8-223C-41D0-8368-4CA34634D263-0",
"country": "NL",
"regulator": "AFM",
"issuer": "Shell Plc",
"issuerLei": "21380068P1DRHMJ8KU70",
"isin": "GB00BP6MXD84",
"person": "Sawan W.",
"personRole": "Chief Executive Officer",
"roleCategory": "ceo",
"transactionType": "buy",
"registerTransactionType": "Koop",
"registerTransactionCategory": "Verwerving",
"instrument": "Gewoon aandeel",
"instrumentClass": "equity",
"isOpenMarket": true,
"nonMarketReason": null,
"price": 42.21,
"currency": "EUR",
"quantity": 2211.85,
"valueEur": 93362.19,
"fxRateEur": 1.0,
"fxRateDate": null,
"transactionDate": "2026-09-24",
"notificationDate": null,
"venue": "EURONEXT - EURONEXT AMSTERDAM",
"partOfOptionProgram": false,
"convictionScore": 79,
"convictionBreakdown": { "role": 25, "size": 14, "relativeSize": 10, "cluster": 30, "venuePenalty": 0 },
"clusterInsiderCount": 8,
"clusterWindowDays": 14,
"sourceUrl": "https://www.afm.nl/en/sector/registers/meldingenregisters/transacties-leidinggevenden-mar19-/details?id=202609245F7409F8-223C-41D0-8368-4CA34634D263",
"scrapedAt": "2026-10-18T22:20:13Z"
}

Field notes:

  • registerTransactionType, registerTransactionCategory and instrument are the register's original (Dutch) words; transactionType, instrumentClass and roleCategory are the normalised versions.
  • notificationDate is always null: the AFM register publishes only the transaction date. scrapedAt tells you when the row was read.
  • valueEur is price x quantity converted at the ECB reference rate (fxRateEur = currency units per EUR, fxRateDate = rate date). It is null for bonds (prices are quoted in percent of nominal), for currencies the ECB does not publish, and when price or quantity is missing. Pence quotes (GBX) are converted to pounds.
  • Unknown values stay null; nothing is guessed.

Open-market definition

A row is isOpenMarket: true only if all of these hold: the register's transaction type is a plain purchase (Koop) or sale (Verkoop); the instrument is plain equity (shares, share classes, depositary receipts); it is not flagged as part of a stock-option programme; and price and quantity are positive. Everything else (Dividend, Schenking/gift, Uitoefening of options, Omwisseling of instruments, Overdracht, Uitlenen, conditional awards, restricted/performance share rights, bonds, purchases made by an AIF manager) is isOpenMarket: false with the reason in nonMarketReason. The register's Koop label is used as reported; some small Koop rows are in practice automatic plan or dividend-reinvestment purchases (see limits).

Conviction score (0-100, open-market buys only)

ComponentMaxRule
Role25CEO or CFO 25, chair 20, other executive 15, board member 12, other 8, unknown 5, closely associated person 6 (role read from the free-text position)
Size25Log scale of the trade value in EUR: EUR 5,000 gives 0, EUR 1,000,000 or more gives 25
Size relative to the person's prior buys20Value vs the median of that person's earlier open-market buys in the data window: 3x or more 20, 1.5x 15, 0.75x 10, lower 5; no earlier buy seen gives a neutral 10
Cluster30Other insiders of the same issuer with an open-market buy within +/- clusterWindowDays: 1 other 15, 2 others 24, 3 or more 30. Only buys worth at least EUR 5,000 count, on both sides
OTC penalty-10Trade reported with venue OTC (may be a negotiated or private deal)

The total is clamped to 0-100, and the per-component points are in convictionBreakdown. "Prior buys" and clusters only see data inside the walked window (lookback plus the cluster window), not the whole history of a person.

Pricing

Pay per event: one transaction-scraped event per transaction row written to the dataset, USD 10.00 per 1,000 transactions (USD 0.01 each).

  • Not charged: rows removed by your filters, non-market rows when openMarketOnly is on, empty rows, and rows that could not be read.
  • maxItems caps the rows and therefore the cost of a run. The run also stops when your maximum cost per run is reached.
  • Example: maxItems 100 with enough matching trades costs at most USD 1.00.

Runtime is dominated by the polite 1 request per second: roughly 100 notifications take about 2 minutes, and one notification holds about 1.5 transaction rows on average.

Use with AI agents (MCP, Claude, Cursor, n8n, Make)

AI agents can call this Actor through the Apify MCP server. Add it to your MCP client config (sign in with OAuth in the browser on first use):

{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=goobertje/eu-insider-trading-scanner" } } }

Example prompts and the input each one maps to:

  1. "Show me open-market insider buys at AFM-registered companies from the last 7 days." { "lookbackDays": 7, "maxItems": 50, "transactionTypes": ["buy"] }
  2. "Which insider buys over 50,000 euro have a conviction score of at least 60 this month?" { "lookbackDays": 30, "transactionTypes": ["buy"], "minValueEur": 50000, "minConvictionScore": 60, "maxItems": 50 }
  3. "Any insider trades at Unilever or Shell in the last 30 days, buys and sells?" { "lookbackDays": 30, "issuerContains": ["unilever", "shell"], "transactionTypes": ["buy", "sell"], "maxItems": 100 }

In n8n, Make or Zapier use the Apify node or module, pick this Actor and paste the same JSON.

Use cases

  • Screen for clusters of open-market buys by several insiders of one issuer.
  • Daily or weekly directors' dealings feed for a watchlist (issuerContains, isins).
  • Compare insider buying and selling by role or issuer over time for research.
  • Add a "recent insider activity" field to a stock screener or newsletter.

FAQ

Where does the data come from and is it allowed? From the public AFM register of managers' transactions (MAR Article 19) and ECB reference rates. The AFM allows reuse with the AFM named as source. Details under Legal.

How fresh is it? As fresh as the register, usually within days of the trade. Late or corrected notifications can change later.

How much does a typical run cost? The prefilled run (5 rows) costs at most USD 0.05. 1,000 rows cost USD 10.

What if the AFM blocks me or changes its pages? On repeated HTTP 403/429 the run stops, logs an error and delivers the rows already read; the status message starts with PARTIAL. If the page layout changes, rows may be missing and the status message says so.

Can I schedule it or get only new items? You can schedule it in Apify. There is no built-in "only new" mode; use the stable id field to skip rows you already stored.

What is not included? Other countries, the notification or publication date (the register does not give it), intraday timestamps, and any investment recommendation.

Coverage

CountrySourceStatus
NetherlandsAFM register "Managers' transactions MAR 19"Supported, tested live
Germany (BaFin)portal.mvp.bafin.deNot built: its robots.txt is Disallow: / for all agents
France (AMF / BDIF)bdif.amf-france.orgNot built: the open API only returns document metadata, the transaction details are inside PDFs (no PDF parsing here)
Belgium (FSMA)fsma.beNot built: no machine-readable PDMR export was verified, robots.txt asks for a 30 s crawl delay

The AFM register lists notifications for issuers supervised by the AFM. Many large foreign issuers (for example Shell, Coca-Cola Europacific, Unilever, STMicroelectronics) also appear there because they are listed in Amsterdam.

Limits and honest caveats

  • Only the Netherlands (AFM) is covered, see the coverage table.
  • Data freshness is that of the AFM register (usually within days of the trade). Late or corrected notifications can change after you scraped them.
  • Fractional quantities, tiny values and many insiders buying the same amount on the same day often mean automatic plan or dividend-reinvestment purchases, not discretionary conviction. The EUR 5,000 floor for cluster counting reduces but does not remove this. Check the source filing.
  • Register values are entered by the notifying companies and can contain mistakes (for example inconsistent prices inside one notification). They are passed through as published.
  • The run reads one page per notification, so very large lookbacks (hundreds of days) take a long time; use maxNotifications and lookbackDays to bound it.
  • If the AFM site answers with HTTP 403/429 repeatedly, the run stops, logs an error and delivers (and bills) the rows already read; the status message then starts with PARTIAL. Any page that cannot be read mid-walk (not found, redirected off-site, unparsable) also ends the walk with a PARTIAL status message and a log line. It never tries to bypass blocking.
  • People are matched by name only, per issuer (the register has no person ID). Two different people with the same name at one issuer are treated as one, and a person spelled differently across filings is treated as two. Closely associated persons are scored but never count as an independent insider in a cluster. Duplicate or corrected notifications of the same trade (same issuer, person, ISIN, date, price, quantity, type) are output once.
  • The register is ordered by publication, not transaction date, so the walk stops only after 10 consecutive notifications older than the lookback plus cluster window plus a 14-day margin. The lookback date uses the Europe/Amsterdam calendar day.
  • Rows with no ISIN, no instrument, and neither price nor quantity are dropped and never billed.

Data comes from the public register that the AFM publishes under MAR Article 19 and from the ECB euro foreign exchange reference rates. The AFM website states that its information may be copied or distributed only with explicit acknowledgement of the AFM as the source: source: Autoriteit Financiele Markten (AFM), afm.nl. Every item carries the sourceUrl of the official record. The Actor applies the AFM robots.txt rules checked on 2026-10-19 (Disallow: /sitecore only), identifies itself in the User-Agent, waits at least one second between requests and does not use proxies, browsers or any evasion. You are responsible for using the data in line with applicable law (including data protection law for the personal names in the register) and the AFM terms.

This Actor is not affiliated with, endorsed by or sponsored by the AFM, the ECB or any issuer. Nothing here is investment advice.

Found a problem or want a field added? Open an issue on the Actor page.