Congressional Trading Dataset
Access stock trading activity from both chambers of the US Congress. Track purchases and sales disclosed by House Representatives and Senators under the STOCK Act, collected directly from the official disclosure systems and updated daily.
What’s Included
Section titled “What’s Included”The Congressional Trading dataset provides:
- Politician Name: Name of the House or Senate member
- Chamber: Whether the trade was filed by a House Representative or a Senator
- Transaction Type: Purchase or Sale
- Amount Range: Transaction size bracket, normalized to the statutory STOCK Act brackets — the string as originally filed is preserved in
amountRaw, and rows whose amount could not be safely normalized are flagged viaamountFlag - Beneficial Owner: Whose account traded (
owner) — the member’s own (SELF), spouse (SP), dependent child (DC), or joint (JT) - Transaction Date: When the trade occurred
- Dual Dating: Both the transaction date and the public disclosure date (
disclosureDate) — the disclosure date marks when the trade became public, making it the correct point-in-time anchor for backtesting - Historical Data: 10+ years of history (filings since 2016), 100,000+ ticker-matched transactions
Coverage
Section titled “Coverage”| Chamber | Source | Update Frequency |
|---|---|---|
| House | House Clerk financial disclosures (Periodic Transaction Reports) | Daily |
| Senate | Senate eFD system (Periodic Transaction Reports) | Daily |
Filings are collected directly from the official House and Senate disclosure systems — not resold third-party feeds — with the original filings archived for provenance. Coverage includes all 535 sitting members of both chambers, plus covered filings by former members, and spans US-listed stocks and ETFs with 10+ years of history (filings since 2016) available for backtesting.
Disclosure timing: the STOCK Act requires members of Congress to disclose trades within 45 days of the transaction. New filings appear in the dataset the day they are collected, but the reporting lag is inherent to the disclosure regime — factor it into any signal research. Members occasionally disclose trades late, so transaction dates older than the filing window do appear.
Every trade carries both dates, so you can measure that lag directly rather than assuming it: date is when the member traded, disclosureDate is when the filing became public. Any backtest should enter on disclosureDate — entering on date assumes knowledge that was not available at the time and will overstate returns. Disclosure dates were backfilled across the full history, so nulls are rare — but the field is still nullable, so guard for missing values in point-in-time work.
Beneficial Owner
Section titled “Beneficial Owner”Each trade identifies whose account traded via the owner field:
| Value | Meaning |
|---|---|
SELF |
The member’s own account |
SP |
Spouse |
DC |
Dependent child |
JT |
Joint account |
| Account code | A member-specific account identifier as filed |
UNKNOWN |
Senate filing left the owner column blank |
House filings that leave the owner column blank report SELF, per the House PTR-form instructions. This lets you separate trades a member made directly from spousal or family-account activity — a distinction that matters when weighting trades by how informed they are likely to be.
Amount Ranges
Section titled “Amount Ranges”Congressional disclosures report amounts in ranges:
| Range | Minimum | Maximum |
|---|---|---|
| $1,001 - $15,000 | $1,001 | $15,000 |
| $15,001 - $50,000 | $15,001 | $50,000 |
| $50,001 - $100,000 | $50,001 | $100,000 |
| $100,001 - $250,000 | $100,001 | $250,000 |
| $250,001 - $500,000 | $250,001 | $500,000 |
| $500,001 - $1,000,000 | $500,001 | $1,000,000 |
| $1,000,001 - $5,000,000 | $1,000,001 | $5,000,000 |
| Over $5,000,000 | $5,000,001 | N/A |
The amount field is normalized to these statutory brackets whenever the filed string is an unambiguous formatting variant of one; when a value is rewritten, the string as originally filed is preserved in amountRaw. Exact values (e.g., "$360.00") and open-ended filing categories (e.g., "Over $1,000,000") are kept as filed. A filing whose amount could not be read at all reports amount as "Unknown" with amountFlag set to review; a filing with two defensible readings is flagged ambiguous and kept as filed. Clean rows — the overwhelming majority — carry null in both fields.
Quick Start
Section titled “Quick Start”House and Senate trades are served by separate endpoints with an identical schema:
from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
house_df = fb.house_trades.ticker("NVDA", as_dataframe=True)senate_df = fb.senate_trades.ticker("NVDA", as_dataframe=True)print(house_df)print(senate_df)import requests
API_KEY = "YOUR_API_KEY"BASE_URL = "https://api.finbrain.tech/v2"
for chamber in ["house", "senate"]: response = requests.get( f"{BASE_URL}/congress/{chamber}/NVDA", headers={"Authorization": f"Bearer {API_KEY}"} )
data = response.json() for trade in data["data"]["trades"]: print(f"{trade['date']}: {trade['politician']} ({chamber}) - " f"{trade['transactionType']} {trade['amount']}")For complete code examples in Python, JavaScript, C++, Rust, and cURL, see the API Reference.
Visualization
Section titled “Visualization”Plot congressional trades on a price chart with the built-in SDK charts. You must supply your own price data:
from finbrain import FinBrainClientimport yfinance as yf
fb = FinBrainClient(api_key="YOUR_API_KEY")
# Provide your own price dataprice_df = yf.download("NVDA", start="2024-01-01", end="2025-01-01")
# One-line interactive charts with buy/sell markers on pricefb.plot.house_trades("NVDA", price_df)fb.plot.senate_trades("NVDA", price_df)

Use Cases
Section titled “Use Cases”Congressional Trade Alert System
Section titled “Congressional Trade Alert System”Build alerts for significant congressional purchases across both chambers:
from finbrain import FinBrainClientimport pandas as pd
fb = FinBrainClient(api_key="YOUR_API_KEY")
LARGE_TRADES = [ "$500,001 - $1,000,000", "$1,000,001 - $5,000,000", "Over $5,000,000"]
def get_congress_trades(symbol): """Combine House and Senate trades for a symbol""" frames = [] for chamber, api in [("house", fb.house_trades), ("senate", fb.senate_trades)]: try: df = api.ticker(symbol, as_dataframe=True) df["chamber"] = chamber frames.append(df) except Exception: continue return pd.concat(frames) if frames else pd.DataFrame()
def scan_large_congressional_trades(symbols): """Find stocks with large congressional purchases""" results = []
for symbol in symbols: df = get_congress_trades(symbol) if df.empty: continue
large_purchases = df[ (df["transactionType"] == "Purchase") & (df["amount"].isin(LARGE_TRADES)) ]
if not large_purchases.empty: results.append({ "symbol": symbol, "trades": large_purchases })
return results
# Scan popular stockssymbols = ["NVDA", "AAPL", "MSFT", "GOOGL", "AMZN", "META", "TSLA"]alerts = scan_large_congressional_trades(symbols)
for alert in alerts: print(f"\n{alert['symbol']}:") for _, trade in alert['trades'].iterrows(): print(f" {trade['politician']} ({trade['chamber']}): {trade['amount']}")Follow Specific Politicians
Section titled “Follow Specific Politicians”Track trading activity of specific members of Congress:
from finbrain import FinBrainClientimport pandas as pd
fb = FinBrainClient(api_key="YOUR_API_KEY")
def get_politician_trades(politician_name, symbols): """Get all trades by a specific member across both chambers""" all_trades = []
for symbol in symbols: for api in [fb.house_trades, fb.senate_trades]: try: df = api.ticker(symbol, as_dataframe=True) mask = df["politician"].str.lower().str.contains(politician_name.lower()) matched = df[mask].copy() matched["symbol"] = symbol all_trades.append(matched) except Exception: continue
return pd.concat(all_trades) if all_trades else pd.DataFrame()
# Track a specific politician's tradestrades = get_politician_trades( "Pelosi", ["NVDA", "AAPL", "MSFT", "GOOGL", "AMZN", "CRM", "RBLX"])
for date, row in trades.iterrows(): print(f"{date}: {row['symbol']} - {row['transactionType']} {row['amount']}")Cluster Buying Signal
Section titled “Cluster Buying Signal”Find stocks where multiple members of Congress are buying:
from finbrain import FinBrainClientimport pandas as pd
fb = FinBrainClient(api_key="YOUR_API_KEY")
def find_cluster_buying(symbol, min_buyers=3): """Find if multiple members of Congress are buying a stock""" frames = [] for api in [fb.house_trades, fb.senate_trades]: try: frames.append(api.ticker(symbol, as_dataframe=True)) except Exception: continue
if not frames: return None
df = pd.concat(frames) purchases = df[df["transactionType"] == "Purchase"]
# Count unique members making purchases buyers = purchases["politician"].unique()
if len(buyers) >= min_buyers: return { "symbol": symbol, "unique_buyers": len(buyers), "total_purchases": len(purchases), "politicians": list(buyers) }
return None
# Check multiple symbolsfor symbol in ["NVDA", "AAPL", "MSFT", "GOOGL", "META"]: result = find_cluster_buying(symbol) if result: print(f"{symbol}: {result['unique_buyers']} unique buyers")Related Resources
Section titled “Related Resources”- Congressional Trading API Reference - Endpoint details, parameters, and response schema
- Insider Transactions - Corporate insider trades
- Corporate Lobbying - Lobbying disclosure filings
