ποΈ Congress Lobbying Γ Stock Trades Overlap
Pricing
from $0.50 / actor start
ποΈ Congress Lobbying Γ Stock Trades Overlap
Cross-references US federal lobbying filings (LDA) with Congressional stock trades (STOCK Act PTRs). One auditable record per member/quarter/sector overlap β trades, lobbying filings, committee links, disclosure lag. Every row traceable to filing IDs. Pairs with our Congress Trade Trackers.
Pricing
from $0.50 / actor start
Rating
0.0
(0)
Developer
Fatih Δ°lhan
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Congress Lobbying Γ Trades Overlap
Cross-reference US federal lobbying disclosures with Congressional stock trading disclosures β one auditable record per overlap.
This actor joins two public disclosure systems that don't share keys: quarterly lobbying filings under the Lobbying Disclosure Act (LDA) and member stock transactions disclosed under the STOCK Act (PTR filings). It surfaces same-quarter co-occurrence: a member traded in sector X during a quarter in which sector X was the subject of lobbying activity β and, where the member sits on a committee with jurisdiction over that sector, it says so.
Every output row is traceable to specific filing IDs and source URLs. This is a records product: it reports what the filings say, in a form you can archive, query, and verify. It does not score, rank, or interpret.
An overlap is not a finding of wrongdoing. Members of Congress trade securities and industries lobby Congress; both are legal, disclosed, and continuous. Co-occurrence within a quarter is a factual observation about two public datasets, nothing more. This actor makes no claim of causation and emits no trade recommendations.
Part of a set:
- House Trading Pipeline β House Clerk PTRs, feeds this actor's House trades.
- Senate Trading Pipeline β Senate eFD PTRs, feeds this actor's Senate trades.
Source: github.com/seralifatih/congress-trading-pipeline/tree/master/lobbying-overlap
What it produces
One record per (member, quarter, sector) overlap β not one per trade, not one per filing. Each record bundles the full evidence on both sides:
{"member_bioguide_id": "A000379","member_name": "Mark Alford","chamber": "house","party": "R","state": "MO","quarter": "2026-Q1","sector": "defense","mapping_rule_id": "tk:LMT->defense","mapping_confidence": "high","overlap_type": "committee_match","disclosure_lag_days": 30,"trades": [{"ptr_filing_id": "4d6016b4...","ptr_url": "https://disclosures-clerk.house.gov/...","ticker": "LMT","transaction_type": "purchase","amount_range": "$1,001 - $15,000","transaction_date": "2026-01-05","disclosure_date": "2026-02-04","filing_type": "original"}],"lobbying": [{"lda_filing_uuid": "7866327b-c892-4430-b9f0-1f0f679c58c6","lda_url": "https://lda.gov/api/v1/filings/7866327b-.../","registrant": "Example Government Affairs LLC","client": "Example Defense Corp","issue_codes": ["DEF", "BUD"],"amount_reported": 240000.0,"amount_outlier": false}],"sector_lobbying_filing_count": 38,"committees": [{"committee_id": "HSAS","committee_name": "House Committee on Armed Services","jurisdiction_tags": ["defense", "aerospace"],"is_subcommittee": false,"role": "Member"}]}
| Field | Type | Notes |
|---|---|---|
member_bioguide_id | string | Bioguide ID from unitedstates/congress-legislators |
member_name | string | Current official full name |
chamber | 'house' | 'senate' | |
party | 'D' | 'R' | 'I' | |
state | string | Two-letter USPS code |
quarter | string | YYYY-QN, derived from trade date |
sector | string | Crosswalk sector vocabulary, e.g. defense, healthcare |
mapping_rule_id | string | Which crosswalk rule fired, e.g. tk:LMT->defense β always traceable |
mapping_confidence | 'high' | 'medium' | Confidence of the strongest rule that produced this record. low-confidence records are excluded from the dataset entirely β see "Low-confidence mappings are excluded" below |
overlap_type | 'committee_match' | 'sector_match_only' | See below |
disclosure_lag_days | integer | null | Days from the earliest trade's transaction date to its disclosure date. null when that trade is an amendment β see "Amendments and disclosure_lag_days" below |
trades[] | array | Every trade by this member in this sector/quarter, each traceable to a PTR filing. Each item includes filing_type ('original' | 'amendment' | null, same vocabulary as the Senate/House pipelines) |
lobbying[] | array | Lobbying filings for this sector/quarter β sector-wide, not specific to this trade (see "sector_lobbying_filing_count, not lobbying_filing_count" below), capped to the largest by reported amount. Each item includes amount_outlier |
sector_lobbying_filing_count | integer | Uncapped total matching filings β if greater than lobbying.length, the list was truncated |
committees[] | array | Committee assignments that produced a committee_match; empty for sector_match_only |
overlap_type
committee_matchβ the member sits on at least one committee whose jurisdiction covers the overlap sector. The matched committee assignments are included as evidence.sector_match_onlyβ the sector overlap exists, but no committee link does.
LDA filings disclose which chamber or agency was lobbied, not which committee β so committee matching is resolved through sector jurisdiction, and the record shows exactly which committee and which jurisdiction tag produced the match.
Amendments and disclosure_lag_days
Every trade in trades[] carries filing_type ('original' | 'amendment' | null) straight through from the Senate/House pipeline row it came from β same vocabulary those actors use, sourced from each filing's own label, never inferred from duplication.
An amendment can be filed long after the original PTR for reasons that have nothing to do with disclosure timeliness β most commonly, correcting an amount range or asset description. If disclosure_lag_days were computed from an amendment's dates, a routine correction filed 200 days after the original trade would read as a 200-day disclosure-lag violation, when the original filing may have been timely and only the correction was late. That is not a finding this actor is in a position to make, so it doesn't.
The rule: disclosure_lag_days is null whenever the record's earliest trade has filing_type: "amendment". It is only ever a number when that trade is "original" or unlabeled (null β the source didn't say, which carries no particular suspicion). Consumers computing average or worst-case disclosure lag should filter to non-null values, not treat null as zero.
Low-confidence mappings are excluded
The crosswalk's GICS-sector fallback (used when a ticker has no explicit override) is graded high / medium / low per rule, and low-confidence rules are wrong often enough to be noise rather than signal β e.g. AT&T mapping to media_entertainment, or Mastercard mapping to technology, purely because of their broad GICS sector classification. Records whose strongest matching rule is low confidence are excluded from the dataset by default; the count excluded is reported in RUN_SUMMARY.low_confidence_excluded so the exclusion is visible, never silent.
sector_lobbying_filing_count, not lobbying_filing_count
lobbying[] and its count are sector-and-quarter-wide, not specific to the member's trade or the counterparties on the other side of it. A member who traded a defense stock will see every lobbying filing tagged to the defense sector that quarter β which can include registrants and clients with no connection to that trade at all (one real PLTR overlap record's lobbying[] included Drexel University, the Qatar embassy, and California water agencies, all legitimately lobbying on defense-adjacent issue codes that quarter). The field is named sector_lobbying_filing_count specifically so it can't be misread as "filings related to this trade."
LDA amount outliers
A small number of LDA filings report implausibly large amount_reported values for a single LD-2 β most likely data-entry errors upstream (one observed filing reports $20,000,000 with a registrant/client string containing "STATE OF LOC NATION"). These are never dropped or silently zeroed: any lobbying[] item with amount_reported >= $10,000,000 carries amount_outlier: true, and the count seen in a run is reported in RUN_SUMMARY.lda_amount_outliers. A downstream consumer summing amount_reported for a spend total should filter out amount_outlier: true rows first.
How it works
Parallel fetch Adapt Join (pure) Outputββββββββββββββββββββββ ββββββββββββββββ βββββββββββββββββ βββββββββββββββββ congress-legislatorsβ β Name β member β β trades Γ β β Dataset ββ House/Senate trade ββββββββββΆβ resolution βββββΆβ filings on βββΆβ + RUN_SUMMARYββ actors (Apify API) β β Ticker/issue β β (quarter, β β (KV store) ββ LDA quarterly filingsβ β code mapping β β sector) β β βββββββββββββββββββββββ ββββββββββββββββ βββββββββββββββββ ββββββββββββββββ
1. Parallel fetch. Reads the latest successful dataset of the House and/or Senate trading pipeline actors via the Apify API, fetches lobbying filings for the requested quarters from the Senate LDA REST API, and loads the member/committee roster from unitedstates/congress-legislators (cached 30 days).
2. Adapt. House and Senate trade actors emit different field names β the adapter normalizes both into one Trade shape and resolves filer display names to bioguide IDs (exact match, then a first+last fallback that tolerates nicknames and middle names). Unresolved names are reported, never dropped.
3. Crosswalk. Every trade ticker and every LDA issue code is mapped onto a shared sector vocabulary via data/crosswalk.yaml (ticker overrides, then a GICS-sector fallback for issue codes). Committee jurisdictions come from data/committee_jurisdictions.yaml. Every mapping carries a confidence grade and a rule_id that names exactly which row fired.
4. Join (pure). Trades and lobbying filings are grouped by (member, quarter, sector). A record is emitted only when a member traded in a sector that had at least one lobbying filing that same quarter, and only when the group's strongest crosswalk rule is high or medium confidence β low-confidence groups are excluded (see "Low-confidence mappings are excluded" above). Committee assignments are checked against the sector to decide committee_match vs sector_match_only. disclosure_lag_days is computed from the earliest trade in the group, and nulled if that trade is an amendment (see "Amendments and disclosure_lag_days" above).
5. Output. Records land in the default Apify dataset. Every run β including zero-overlap runs β also writes a RUN_SUMMARY to the key-value store: quarters covered, members scanned, overlap counts by type, low-confidence records excluded, LDA amount outliers flagged, and every unmapped issue code / ticker / committee / member name, so nothing is silently dropped.
All HTTP calls retry with exponential backoff; the LDA fetcher additionally paces requests against LDA's shared rate limit and honors Retry-After.
The crosswalk is yours to audit
There is no official mapping between LDA issue codes, stock tickers, and committee jurisdictions. Every product in this space invents one β most keep it hidden. This one ships in the open, in the repo, as hand-editable YAML:
data/crosswalk.yamlβ all 79 official LDA general issue codes β sectors, plus ticker β sector rules (explicit per-ticker overrides and a GICS-sector fallback)data/committee_jurisdictions.yamlβ every current House, Senate, and joint committee β jurisdiction sectors
Every mapping row carries a confidence grade (high / medium / low), and every output record names the exact rule that fired (mapping_rule_id). If you disagree with a mapping, you can see it, trace it, and change it β the run summary also lists every issue code, ticker, and committee the crosswalk could not resolve.
Environment variables
| Variable | Required | Description |
|---|---|---|
LDA_API_KEY | No | Senate LDA API key. Falls back to the lda_api_key actor input, then anonymous access (heavily rate-limited). Register a free key at lda.gov for reliable multi-quarter runs. Never logged β only whether a key was used. |
APIFY_TOKEN | Yes (standalone only) | Needed to read the House/Senate trading pipeline actors' datasets via the Apify API when running outside the Apify platform. Not required when running as an actor on Apify β the platform provides dataset access natively. |
Copy .env.example locally if you add one for your own runs; none is checked in because both variables are optional or platform-provided. Never commit real key values.
Input
| Field | Type | Default | Description |
|---|---|---|---|
quarters | array | last completed quarter | Quarters to cover, e.g. ["2026-Q1"] |
chambers | array | ["house", "senate"] | Which chambers to scan |
overlap_types | array | both | Filter to committee_match and/or sector_match_only |
lda_api_key | secret | β | Optional. The actor ships with a shared key sufficient for typical runs. Provide your own free key from lda.gov for heavy multi-quarter backfills or guaranteed throughput. |
max_concurrency | integer | 5 | Outbound API concurrency (clamped to 10 server-side) |
max_filings_per_record | integer | 100 | Cap on the lobbying evidence list per record; sector_lobbying_filing_count always shows the uncapped total |
lda_max_pages | integer | β | Debug cap for cheap test runs |
How to use
Apify Console (no code): open the actor, pick your quarters, run. Results land in the dataset; export as JSON, CSV, or Excel.
API:
curl -X POST "https://api.apify.com/v2/acts/seralifatih~congress-lobbying-trades-overlap/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"quarters": ["2026-Q1"], "chambers": ["house", "senate"]}'
Scheduled: lobbying data is quarterly by law. A quarterly schedule a few weeks after each LDA filing deadline (Jan 20, Apr 20, Jul 20, Oct 20) keeps a complete archive with four runs a year.
Self-hosting
git clone https://github.com/seralifatih/congress-trading-pipelinecd congress-trading-pipeline/lobbying-overlappip install -r requirements.txtexport APIFY_TOKEN=your_token # needed to read the House/Senate actors' datasetsexport LDA_API_KEY=your_key # optional, avoids anonymous rate limitspython -m src
Run the join logic standalone against local JSON dumps (no tokens needed) via the source modules directly, e.g. python -m src.sources.ptr --file house_items.json --out mapped.json or python -m src.sources.lda 2026-Q1 --out q.json.
Project layout
src/βββ main.py Actor entry point β fetch β adapt β join β dataset + RUN_SUMMARYβββ models.py Pydantic v2 output schema, strict validationβββ crosswalk.py Crosswalk loader/resolver β issue codes, tickers, committees β sectorsβββ overlap.py Pure join logic: trades Γ filings Γ committees β OverlapRecordβββ sources/βββ lda.py Senate LDA REST API client β paced, retried, rate-limit awareβββ legislators.py Member/committee roster from unitedstates/congress-legislatorsβββ ptr.py Adapter over the House/Senate trading pipeline actors' datasetsdata/βββ crosswalk.yaml LDA issue codes + tickers β sectors, hand-editedβββ committee_jurisdictions.yaml Committees β jurisdiction sectors, hand-editedtests/ pytest suite mirroring src/
Data sources
| Source | What it provides |
|---|---|
Senate LDA REST API (lda.gov) | Quarterly lobbying filings: registrant, client, issue codes, reported amounts |
| House / Senate trading pipeline actors | Member stock transactions from PTR filings |
unitedstates/congress-legislators | Member roster and committee membership (cached, refreshed monthly) |
All sources are official or community-maintained public records. This actor does not scrape third-party aggregators.
Limitations
- Federal only. State-level lobbying is out of scope.
- Quarterly granularity β that is the resolution the LDA imposes; nothing here is or can be real-time.
- Sector mapping is inherently judgment-laden. The crosswalk exposes every judgment it makes (
mapping_rule_id,confidence) so you can audit or override them, but no mapping of tickers and issue codes to sectors is beyond argument. - Trades without a listed ticker (real estate, private funds, bonds) are excluded and counted in the run summary.
Disclaimer
This actor republishes and cross-references public disclosure records. An overlap record documents that two disclosed activities occurred in the same quarter and sector β it is not evidence of impropriety by any person, and must not be presented as such. Nothing in this actor's output is investment, legal, or any other kind of advice.
License
MIT. Use the actor or the source however you want.