Skip to main content

insidertracker

A Python wrapper for OpenInsider.com that scrapes SEC Form 4 insider trading data and caches it locally in DuckDB.

Installation

pip install insidertracker

Quick Start

from insidertracker import InsiderTracker

tracker = InsiderTracker()

# Insider trades for one or more tickers
df = tracker.ticker.get_insider_trades("AAPL")
df = tracker.ticker.get_insider_trades(["AAPL", "TSLA", "NVDA"])

# Latest cluster buys (multiple insiders buying the same stock)
df = tracker.cluster_buys.get_cluster_buys()

# CEO/CFO purchases over $25k (high-signal)
df = tracker.ceo_cfo_purchases_25k.get_ceo_cfo_purchases_25k()

Endpoints

Attribute Method Source Page
ticker get_insider_trades(ticker) Screener filtered by ticker
ticker get_insider_sales(ticker) Same, filtered to sales only
cluster_buys get_cluster_buys() /latest-cluster-buys
insider_purchases get_insider_purchases() /insider-purchases
insider_sales get_insider_sales() /insider-sales
insider_purchases_25k get_insider_purchases_25k() /latest-insider-purchases-25k
ceo_cfo_purchases_25k get_ceo_cfo_purchases_25k() /latest-ceo-cfo-purchases-25k
ceo_cfo_sales_100k get_ceo_cfo_sales_100k() /latest-ceo-cfo-sales-100k
top_officer_purchases_week get_top_officer_purchases_week() /top-officer-purchases-of-the-week
screener get(**kwargs) /screener with full filter support

All methods return a Polars DataFrame.

Common Parameters

All endpoint methods accept these optional parameters:

Parameter Type Description
stale_threshold timedelta How old cached data can be before re-fetching
force_update bool Bypass cache and always re-fetch
min_date datetime Only return rows with filing_date after this date
max_date datetime Only return rows with filing_date before this date
import datetime as dt

df = tracker.cluster_buys.get_cluster_buys(
    stale_threshold=dt.timedelta(days=1),
    force_update=False,
    min_date=dt.datetime(2025, 1, 1, tzinfo=dt.timezone.utc),
    max_date=dt.datetime(2025, 12, 31, tzinfo=dt.timezone.utc),
)

Screener

The screener module exposes the full OpenInsider screener with 30+ filter parameters:

df = tracker.screener.get(
    ticker="AAPL",
    transaction_value_min_usd_thousands=100,
    filing_date_within_days=30,
    page_size=200,
)

Data Schema

Ticker / Latest Purchase & Sale endpoints

Column Type Description
filing_date TIMESTAMPTZ SEC filing timestamp
trade_date DATE Date the trade occurred
ticker VARCHAR Stock symbol
company_name VARCHAR Company name
insider_name VARCHAR Name of the insider
title VARCHAR Insider's role (CEO, CFO, Dir, etc.)
trade_type VARCHAR e.g. S - Sale, P - Purchase
price DOUBLE Trade price per share
quantity DOUBLE Number of shares traded
owned DOUBLE Shares owned after trade
ownership_change DOUBLE Fractional change in ownership (e.g. -0.20)
value DOUBLE Total value of trade in USD

Cluster Buys

Same as above, with insider_name and title replaced by:

Column Type Description
industry VARCHAR Industry classification
num_insiders VARCHAR Number of insiders who bought

Database

Data is cached in a local DuckDB database. The path is resolved in this order:

  1. INSIDERTRACKER_DB environment variable
  2. database key in the config file
  3. Default: ~/.config/insidertracker/insidertracker.db (Linux), ~/Library/Application Support/insidertracker/insidertracker.db (macOS), %APPDATA%\insidertracker\insidertracker.db (Windows)

To use a custom path:

export INSIDERTRACKER_DB=/path/to/my.db

Or create a config file at the platform default config path:

{
  "database": "/path/to/my.db"
}

Individual Classes

You can import and use each module independently without going through InsiderTracker:

from insidertracker import CeoCfoPurchases25k

ceo = CeoCfoPurchases25k()
df = ceo.get_ceo_cfo_purchases_25k(force_update=True)

Metadata

Release files for insidertracker 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for insidertracker 0.1.2
File Size Uploaded
insidertracker-0.1.2.tar.gz 8.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for insidertracker 0.1.2
File Interpreter ABI Platform
insidertracker-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 24.5 kB

Release files / insidertracker-0.1.2.tar.gz

Download URL insidertracker-0.1.2.tar.gz
Size 8.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7d05a1877cbbf5506d69918f9bc0daa0384ca1c917f99ef8a1e19290c9a0f4e9
BLAKE2b-256 checksum
How to use checksums
10b242836abd16b9dcfe14fdd8d9291dfbd7b5d969bd95093fa605589b3d24af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release files / insidertracker-0.1.2-py3-none-any.whl

Download URL insidertracker-0.1.2-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e8fda6f89fbc263406196150eec75ce41b565af5c85069ed88da15f30b7306e
BLAKE2b-256 checksum
How to use checksums
134f2170e5cb6b91b2975ebcbdeec7f42abae7b3d0535c9186f0757d4210f8b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page