Explore more topics
Strategy research methods

How a congressional stock disclosure becomes a backtest signal

How NexusTrade turns House and Senate trade reports into dated rows, the PoliticalTrades indicator and copy-trading bots, and how often each updates.

As of 2026-10-13

Jump to a section

TL;DR

Members of Congress report their stock trades on periodic transaction reports. About every 20 hours, NexusTrade downloads new House and Senate reports, reads their transactions into rows, and dates every row by when its report became public: 23:59:59 New York time on the filing date. A backtest can act on a trade from the next trading session, never from the transaction date.

Reports give dollar ranges, so every dollar figure depends on the amount basis you choose. The PoliticalTrades indicator adds up those rows for one stock. Each copy-trading bot weights its stocks by the estimated cost of a member's disclosed purchases that no reported full sale has closed.

How a PDF becomes trade rows

Animation: Nancy Pelosi's text-layer House report 20035143, filed 2026-08-21, is read twice; each of its 7 rows lights up, moves into a table and gets a check mark from both reads. Then Ro Khanna's scanned House report 8217394, filed 2020-07-17, is checked page by page: on page 6 the page-image read lists 90 transactions where the OCR text holds 17 table rows, and on page 7 it lists 74 against 32, so the filing is stamped failed with 0 trades. The 2026-10-13 snapshot lists 1 failed filing out of 10,837.
Pelosi's report 20035143 became 7 rows, and Khanna's scanned report 8217394 failed with 0 trades.
Read the explanation

Extraction runs in the open-source congressional-disclosures package, version 2.2.2 in production. Each kind of filing takes its own path. A filing that cannot be read with confidence is stored as failed and contributes no trades.

Two real reports from Ro Khanna show the failure rule. Report 8217394, filed July 17, 2020, is a scan. On page 6 the page-image read listed 90 transactions where the OCR text held 17 table rows, and on page 7 it listed 74 against 32. The report is stored as failed with 0 rows, and it is the only failed filing among the 10,837 in the October 13, 2026 snapshot.

His report 8218338, filed September 15, 2021, lost rows the same way on pages 12, 18 and 21. The 121 missing trades were added by hand from the page images, and the report is published with 1,308 trades.

A ticker comes from the filing. When a filing prints none, NexusTrade may resolve one from the asset description and records how it was resolved. A row that stays without a ticker, such as Nancy Pelosi's purchase of REOF XXX, LLC, is kept in the tables, and no stock indicator reads it.

  1. Senate electronic reports

    The report's HTML table is parsed directly. No model reads these.

  2. House PDFs with a text layer

    A model reads the PDF's text into a fixed row format twice. The filing is published when two reads agree. When the first two disagree, more reads run, up to five in total, and a later read must match an earlier one.

  3. Scanned House PDFs and Senate paper filings

    Each page is turned upright and OCR'd at two resolutions. One read works from the OCR text and another from the page image alone. Pages where they disagree, or where a date cannot be true, go to a reconciling read. The filing fails when the page-image read lists more transactions on a page than the OCR captured.

  4. Hand readings

    A few filings that no automated read could complete were read or corrected by hand. Each hand reading is bound to the SHA-256 of the exact PDF, so a re-filed document goes back through the automated pipeline.

Where the filings come from

House members file periodic transaction reports with the Clerk of the House. Each run downloads the Clerk's yearly index files for the current and previous year, then fetches every report PDF that is new or due for a retry. Senators file through the Senate's electronic disclosure system (eFD), and each run lists the reports submitted in the last 60 days.

One run processes at most 100 House reports and 200 Senate reports. The rest wait for the next run, and the House backlog is processed oldest first. Every downloaded file is archived with its SHA-256 hash, so each stored row points back to the exact document it was read from.

Each filer is matched to a member of Congress through the public congress-legislators data. The match produces a Bioguide ID, which stays the same across name spellings and across both chambers. The indicator's member filter uses that ID.

The public dataset holds Senate reports filed since July 25, 2012 and House reports filed since January 2, 2014.

Show the table · 2 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

House ClerkYearly index ZIP files for this year and last year, then each new or retry-due report PDFUp to 100
Senate eFDReports submitted in the last 60 days: electronic report pages and the page images of paper filingsUp to 200

These limits come from the daily disclosures job. Coverage dates from the public dataset snapshot generated October 13, 2026.

When a trade becomes usable

Animation: a cursor moves along a July to August 2026 calendar. Nancy Pelosi's spouse bought Bloom Energy (BE) stock on 2026-07-24, reported for $1,000,001 to $5,000,000. The report was filed 2026-08-21, 28 days later; a clock runs through the filing day to 23:59:59 New York time, when the report becomes public. The cursor crosses the weekend and a PoliticalTrades BuyAmount indicator for BE under the LowerBound basis switches from $0 to $1,500,002 for the report's two BE stock purchases on the first trading session after that, 2026-08-24.
The report was public at 23:59:59 New York time on August 21, 2026, so a backtest first acts on August 24, 2026.
Show the table · 7 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

Member and ownerNancy Pelosi, spouseNancy Pelosi, spouse
Transaction date2026-07-242026-09-08
Report filed2026-08-21, House report 200351432026-10-02, House report 20035553
Public from2026-08-21 at 23:59:59 New York time2026-10-02 at 23:59:59 New York time
First session a backtest can actMonday, 2026-08-24Monday, 2026-10-05
Reported amount$1,000,001 to $5,000,000$500,001 to $1,000,000
TickerBENone printed, so no stock indicator reads it

Rows from the public dataset and Nancy Pelosi's member page, read October 13, 2026.

Each row carries two dates that matter. The transaction date is when the trade happened. The availability timestamp is 23:59:59 New York time on the day the report was filed, a conservative time that never comes before the filing. A backtest decision counts a trade only after that timestamp has passed, so the first decision that can use it is the next trading session.

Bloom Energy's purchase below was public 28 days after the trade. A backtest dated by transaction would have bought on July 24, four weeks before the report existed. The lookahead bias guide covers the same rule for company filings.

Amount ranges and the amount basis

Animation: a dot moves across one reported range of $1,000,001 to $5,000,000 and stops at each amount basis, while the BuyAmount for both BE stock purchases in the report reads $1,500,002 under LowerBound, $3,750,001 under Midpoint, $6,000,000 under UpperBound. Then a step chart shows Josh Gottheimer's Applied Materials (AMAT) RemainingBuyAmount under LowerBound: $0 until 2026-09-15, $1,001 after his $1,001 to $15,000 purchase report filed 2026-09-14, and $0 again from 2026-10-08 after a full sale report filed 2026-10-07.
Both BE stock purchases count $3,750,001 at Midpoint, and a full sale closed Gottheimer's AMAT lot on October 8, 2026.
Show the table · 3 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

LowerBound (default)$1,000,001$1,500,002
Midpoint$3,000,000.50$3,750,001
UpperBound$5,000,000$6,000,000

Report 20035143 lists two BE stock purchases: $1,000,001 to $5,000,000 on July 24 and $500,001 to $1,000,000 on July 28, 2026.

Reports give dollar ranges. Each row stores the bounds as amountLow and amountHigh, and the indicator's amount basis chooses which number to use. LowerBound is the default. When a report gives only one bound, both bounds take that value.

NetAmount treats sales conservatively. Under LowerBound it subtracts a sale's upper bound, and under UpperBound it subtracts a sale's lower bound. Midpoint uses midpoints for both purchases and sales.

The PoliticalTrades indicator

PoliticalTrades reads the stored rows for one stock. Its settings are the metric, a trailing window in days, the amount basis, the instrument (Equity by default, Option or All), the chamber (All, House or Senate) and an optional member, given as a Bioguide ID or a name. Windowed metrics count trades that first became public inside the trailing window, using each row's version that is public at the decision.

Josh Gottheimer's Applied Materials shares show RemainingBuyAmount at work. A joint purchase of $1,001 to $15,000, traded August 6, 2026, was filed September 14. A sale of $1,001 to $15,000, not marked partial, was traded September 15 and filed October 7. Under LowerBound his AMAT RemainingBuyAmount was $0 before the purchase report, $1,001 from the session of September 15, and $0 again from the session of October 8.

Show the table · 8 rows, 2 columns
MetricWhat it returns
NetAmountPurchase dollars minus sale dollars in the window, with the conservative sale rule above.
BuyAmount (default)Purchase dollars in the window.
SellAmountSale dollars in the window.
BuyCountThe number of purchases in the window.
SellCountThe number of sales in the window.
DistinctBuyersThe number of different filers with at least one purchase in the window.
Held1 when the latest disclosed purchase or sale leaves the stock open (a purchase or a partial sale), otherwise 0. It reads the full history, ignores the window and cannot be used for options.
RemainingBuyAmountThe purchase amounts of disclosed lots that no matching full sale has closed, across the full history. A partial sale keeps the lot, because the report gives no quantity.

Neither Held nor RemainingBuyAmount establishes a member's actual holdings or share counts.

Amendments and versions

Three tables hold the data. political_filings has one row per report, with its hash, parse method and extraction status. political_trades has one row per transaction printed on a report. political_trade_events has one row per version of a trade.

The same trade can appear on more than one report. Events merge repeated reports of one trade. When an amendment changes a trade's values, the event gains a new version: the old version receives a supersededAt equal to the amendment's availableAt, and the new version is visible from its own availableAt. firstAvailableAt keeps the time the trade was first public.

The indicator reads the version that was public at each decision. A backtest decision before an amendment sees the original values, and a decision after it sees the corrected ones. A correction that became public no later than the version it corrects replaces that version in place, since no reader could have seen the old values. Filings by people who never served in Congress stay in the first two tables and produce no events.

How a copy-trading bot uses it

Animation: the 7 rows of Nancy Pelosi's report 20035143 are checked. Three stock purchases (BE twice, INTC once) get check marks and feed her stocks-only copy-trading bot; three option purchases and one row without a ticker are struck out. At the Midpoint basis BE's RemainingBuyAmount bar grows by $3,750,001 and INTC's by $750,000.50. The condition NewPoliticalDisclosure greater than 0 turns true on 2026-08-24, its DynamicRebalance action fires, and BE's target weight is about 5 times INTC's.
Report 20035143 sets BE's target weight at about 5 times INTC's.
Show the table · 6 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

Starting capital$100,000$100,000
HoldsStocks, from the member's equity rowsStocks, plus at-the-money calls with 300 to 400 days to expiration on underlyings from the member's option rows
RebalancesWhen a new equity disclosure from the member becomes publicWhen a new equity or option disclosure becomes public, and once per trading week
WeightsRemainingBuyAmount, Midpoint basisRemainingBuyAmount, Midpoint basis, with stock and call budgets split by the member's historical purchase mix
Backtest windowThe later of five years ago and the member's first public disclosureThe same window
RankingNot rankedRanked with at least 10 purchases in the window and at least 1,096 days of history, sorted by five-year-equivalent return
Read the explanation

Every member with at least 5 disclosed purchases with a ticker in the last five years gets a stocks-only copy-trading bot with $100,000 of starting capital. Its one strategy has a single condition: NewPoliticalDisclosure for that member's equity rows is greater than 0. That trigger turns on at the first decision after a new qualifying disclosure becomes public, and its action is a DynamicRebalance across all US stocks.

The rebalance keeps every stock whose RemainingBuyAmount for that member, under the Midpoint basis, is above $0, and weights each stock by that amount. The bot has no cap on the number of names and no market-capitalization floor. Its indicator carries a 3,650-day window setting, which RemainingBuyAmount ignores because it reads the full history.

Report 20035143 shows one decision. Its 7 rows included three stock purchases: BE for $1,000,001 to $5,000,000 and for $500,001 to $1,000,000, and INTC for $500,001 to $1,000,000. Three option purchases are left to the stocks-and-calls book, and REOF XXV, LLC had no ticker. At Midpoint, BE gained an estimate of $3,750,001 and INTC $750,000.50. Neither had an earlier open stock lot, so the rule sets BE's target weight at about five times INTC's. In a backtest the trigger fires on Monday, August 24, 2026.

Both books below simulate a rule. They cannot show a member's actual holdings, share counts or returns.

How often each layer updates

Each layer runs on its own schedule, so a new report reaches the bots in steps.

Show the table · 6 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

Members' reportsWithin 30 days of learning of a trade, and no later than 45 days after itSet by the STOCK Act. Late reports still happen.
Filing download and extractionAbout every 20 hoursScheduled 20 hours after the last finished run, with a 26-hour freshness target.
Public Hugging Face snapshotTarget of every 20 hoursPublished only after the lake integrity audit passes.
Live trading enginesEvery 10 minutesEach engine checks the lake for newly published trades.
Copy-bot backtestsAbout every 20 hoursAn alert fires when a bot has no result from the last 48 hours.
Repricing of disclosed purchasesAbout every 20 hoursRuns on days without new filings too, because prices move daily.

Insider Form 4 and 13F differences

Company insiders file SEC Form 4, generally within two business days of a trade, and report exact share counts and prices. NexusTrade ingests Forms 3, 4 and 5 in a separate SEC job. The InsiderTrades indicator counts open-market purchases (code P) and sales (code S) from the moment each filing became public.

Institutional managers file Form 13F each quarter, up to 45 days after the quarter ends. A 13F is a quarterly snapshot of holdings, and trades made between two reports do not appear in it. The InstitutionalHoldings indicator reads the latest disclosed period. The institutional holdings template walks through a real 13F comparison.

Questions

  1. Why does NexusTrade use the filing date instead of the trade date?

    A trade could not be known before its report was public. Dating a trade by its transaction lets a backtest buy days or weeks before the report was public.

  2. Why do Nancy Pelosi's purchase counts differ between pages?

    Her member page counts every purchase event on record: 132 as of October 10, 2026. The rankings count purchases with a ticker that became public inside the five-year backtest window: 53 as of October 13, 2026.

  3. How far back does the data go?

    The public dataset holds Senate reports filed since July 2012 and House reports filed since January 2014.

  4. Can I see which filings failed?

    Yes, political_filings keeps every report with its extractionStatus and failureReason. A failed report has no trade rows.

  5. Do the bots buy a member's actual option contracts?

    No, the rankings book buys its own at-the-money calls on the underlyings named in option disclosures. The live copy-trading bot holds stocks only.

  6. Can I download the data?

    Yes, run npx congressional-disclosures download --sqlite for a ready SQLite database, or download the Parquet files from Hugging Face.

Continue exploring

Discussion

Sign in or create a free account to join the discussion.

No comments yet.