DEV Community

SmartMoneyData
SmartMoneyData

Posted on

Track Insider Buying and Selling with SEC Form 4 Data in Python

When a CEO buys their own company's stock on the open market, they are putting personal money behind a view only they can really hold. Insider buying is one of the most studied signals in finance, and the raw data is free: every officer, director and 10% owner has to file a Form 4 with the SEC within two business days of a trade.

The catch is the format. Form 4s are XML documents scattered across EDGAR, mixed with option grants, tax withholdings and gifts that are not real buying or selling. This tutorial turns them into a clean table of trades you can actually use.

What you will build

  • A script that pulls recent insider purchases and sales for any tickers
  • A filter that keeps only real open-market trades and drops pre-planned 10b5-1 sales
  • A "cluster buying" check: several insiders buying the same stock at once
  • A Google Sheets or Slack feed of new trades

The data source

We will use the Insider Trading API, which reads Form 4 filings straight from SEC EDGAR, typically minutes after they are published. Each row is one transaction:

Field Meaning
ticker, issuerName the company
insiderName, insiderRole who traded, e.g. "Chief Financial Officer"
transactionCode, transactionType P = open-market purchase, S = open-market sale, and others
shares, pricePerShare, valueUsd size of the trade
holdingChangePct how much of their stake they bought or sold
is10b5_1Plan true if the trade was pre-scheduled under a 10b5-1 plan
filingUrl link to the original filing

It costs $3 per 1,000 transactions, and transactions filtered out are free.

Step 1: Setup

pip install apify-client pandas
export APIFY_TOKEN="your-token-here"   # from Apify Console → Settings → API & Integrations
Enter fullscreen mode Exit fullscreen mode

Step 2: Pull insider trades for a watchlist

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("smartmoney-data/sec-insider-trades-tracker").call(
    run_input={
        "tickers": ["AAPL", "NVDA", "TSLA", "JPM"],
        "lookbackDays": 90,
        "transactionCodes": ["P", "S"],   # open-market buys and sells only
    }
)
trades = list(client.dataset(run["defaultDatasetId"]).iterate_items())

for t in trades[:10]:
    print(t["ticker"], t["insiderName"], t["insiderRole"], t["transactionType"], t["valueUsd"])
Enter fullscreen mode Exit fullscreen mode

Leave tickers empty to get the most recent Form 4s across the whole market instead.

Step 3: Separate signal from noise

Most insider selling is routine: executives sell on a pre-set schedule (10b5-1 plans) to diversify or pay taxes. Purchases are rarer and more informative. Two filters do most of the work:

import pandas as pd

df = pd.DataFrame(trades)
buys = df[(df.transactionCode == "P") & (df.valueUsd >= 100_000)]
discretionary_sales = df[(df.transactionCode == "S") & (~df.is10b5_1Plan)]

print(buys[["ticker", "insiderName", "insiderRole", "valueUsd", "transactionDate"]])
Enter fullscreen mode Exit fullscreen mode

Step 4: Find cluster buying

One insider buying can be noise. Three insiders buying the same stock in the same few weeks is much harder to dismiss:

clusters = (buys.groupby("ticker")
                .agg(insiders=("insiderName", "nunique"),
                     total_usd=("valueUsd", "sum"),
                     last_buy=("transactionDate", "max"))
                .query("insiders >= 2")
                .sort_values(["insiders", "total_usd"], ascending=False))
print(clusters)
Enter fullscreen mode Exit fullscreen mode

Step 5: Send it somewhere useful

  • Google Sheets / Slack / email: schedule the actor in Apify Console and add an integration.
  • Only new trades: Smart Money Alerts remembers what it already sent.
  • A combined score: Smart Money Confluence blends insider trades with activist 13D stakes, Form 144 planned sales and Congress trades into one score per ticker.

Bonus: see sales before they happen

Insiders who own restricted stock must file a Form 144 when they plan to sell, often before the Form 4 shows up. The Form 144 API returns those notices the day they are filed.

Use it from an AI assistant

https://mcp.apify.com/?tools=smartmoney-data/sec-insider-trades-tracker
Enter fullscreen mode Exit fullscreen mode

Add it as a remote MCP server in Claude, ChatGPT or Cursor, then ask: "Which insiders bought more than $500k of their own company's stock this week?"

FAQ

How fast does a trade appear? Insiders have two business days to file; the actor reads EDGAR directly, so a filing is available minutes after the SEC publishes it.

What do the transaction codes mean? P is an open-market purchase and S an open-market sale. A (grants), F (tax withholding) and M (option exercises) are usually compensation, not conviction, which is why the default keeps only P and S.

Is this legal to use? Yes. Form 4 filings are public SEC records.


Data is for informational purposes only and is not investment advice.

Top comments (0)