Every congressional copy-trading backtest I get sent has the same bug, and it is always the same one. The person filtered their equities data by the date the member of Congress made the trade, then simulated buying at that day's price. The equity curve looks incredible. It should. They gave the strategy a look at information that did not exist yet. On the day a senator bought a stock, you had no way of knowing they had done it. You found out weeks later when the filing hit. Backtesting on the trade date is not a copy-trading strategy, it is a time machine, and the moment you fix the date the whole thing usually deflates.
So the entire exercise really comes down to getting the event timeline right and then being honest about everything that happens after. The mechanism is not complicated once you see it, but almost nobody wires it correctly the first time.
The timeline you actually trade on
There are two dates on every congressional trade, and they are not the same date. There is the transaction date, which is when the member bought or sold. Then there is the disclosure date, which is when the filing became public. Under the disclosure rules that govern these filings, members have a reporting window measured in weeks, not days, and in practice a lot of filings land near the far end of that window. The gap between the two dates is frequently a month or more.
You can only act on the disclosure date. That is the first moment the information exists for you. So the rule is simple to state and easy to get wrong in code. Your entry price is the price on the disclosure date, or realistically the next trading session after it, not the price on the day the trade was executed. If your backtest reads the transaction date and looks up a price there, you have baked in lookahead bias, and every number downstream is fiction.
A cleaner way to think about it: build your event stream keyed entirely on disclosure timestamps, and treat the transaction date as metadata you are allowed to display but never to trade on. If a date touches your fill logic, it has to be the disclosure date. Do that one thing and you have already fixed the failure that breaks most of the published backtests floating around.
Amount ranges and amended filings
The filings do not report exact dollar amounts. They report ranges, things like a wide band between two round numbers, and the bands get very wide at the top end. This matters more than it looks, because if you are position-sizing proportionally to the member's trade, you are sizing off a number you do not actually have. A trade reported in a band could be near the floor or near the ceiling, and you cannot tell.
My rule of thumb is to not pretend you have precision you do not have. Either size every copied trade equally and ignore the reported amount entirely, or size off the low end of the band so you undersell the position rather than overstate it. What you should never do is grab the midpoint of the range, treat it as a real dollar figure, and report a dollar-weighted return to three decimal places. That return is an artifact of an assumption, not a measurement.
Amended filings are the other quiet trap. Members refile. A trade shows up, and later a correction changes the amount, the date, the ticker, or occasionally deletes the whole thing. If your backtest ingests filings once and never reconciles amendments, you can end up trading on a version of history that was later corrected. Worse, if you pull the amended data today and backtest against it, you are again using information that did not exist at the original disclosure date. The honest approach is to trade on what was knowable at each disclosure date and let amendments enter the timeline only when they were actually filed, as their own later events.
Survivorship hiding in the member list
Here is the one that sneaks past careful people. If you build your list of members to copy by taking the roster of current representatives and senators, then pulling their entire trade histories, you have introduced survivorship bias through the back door. You are only copying the people who are still in office. Members who left, lost, retired, or were removed drop out of your universe, and there is no reason to assume their trading was representative of the ones who stayed.
The fix is to reconstruct the eligible member list as it stood at each point in the backtest. On any given date, you should only be copying trades from members who were in office and disclosing on that date, using the roster as it existed then, not the roster as it exists now. It is more work and it will lower your numbers, which is exactly why it is worth doing.
Execution assumptions that do not flatter you
Once the timeline is right, the last place a backtest lies to you is the fill. A few things I always force into the model:
- Enter at the next session's open after disclosure, not the disclosure day's close. You did not see the filing the instant it posted, and you were not first in line.
- Apply slippage and a spread, especially for the smaller and less liquid names that show up in these filings more than you would expect. Frictionless fills are a fantasy.
- Decide your exit rule in advance and apply it mechanically. Copying the entry is easy. The filings also disclose sales, but those disclosures lag too, so you learn the member exited weeks after they did. If your strategy holds until the disclosed sale, you are again trading on delayed information, and you should model the exit on the sale's disclosure date, not its transaction date.
- Account for the cash you are not deploying. Signals arrive lumpy and infrequent. A backtest that assumes you are always fully invested overstates returns against a benchmark you were never actually matching.
A quick sanity check I run on any of these: take the same strategy and deliberately rebuild it on transaction dates instead of disclosure dates. The transaction-date version should look dramatically better. If it does not, something is wrong with your disclosure-date wiring, because the lookahead version is supposed to cheat. That gap between the two curves is roughly the size of the edge you would have given yourself for free, and it is a good gut check on whether your pipeline is honest.
None of this guarantees the strategy works. Plenty of these copy approaches, once you enter on disclosure dates with realistic fills and an honest member universe, turn out to be mediocre or worse. That is the point. A backtest that will not flatter itself is the only kind worth trusting, and if the edge survives disclosure-date entry, wide amount bands, amendment reconciliation, survivorship correction, and real friction, then you might have something. We built the disclosure feeds inside Blockcircle partly because sourcing clean, correctly-dated filings was the annoying half of the work, but you can assemble the same discipline from public filings if you are patient about the timestamps. Get the dates right first. Everything else is downstream of that.