A stock insider cluster-buying strategy using public Form 4 timestamps
An insider cluster buying backtest starts with reviewed purchase events, not a count of every Form 4 row carrying the letter P. Define which securities, transaction types and independent people qualify, freeze when the information became publicly usable, and only then schedule a stock order. A transaction date tells you when someone traded; it does not tell you when an outside investor could have acted on the disclosure.
This guide builds one synthetic cluster and a complete cash account. It requires externally reviewed canonical event records. CoTrading’s Form 4 collection, amendment reconciliation, insider identity resolution and live execution capabilities remain planned or unverified. No actual insider portfolio or historical return series was obtained for this example.
Turn the disclosure into an auditable input
The SEC Form 4 and its instructions separate non-derivative and derivative securities into Tables I and II. The transaction-code instructions include both open-market and private purchases under P, and cover non-derivative or derivative securities. Therefore P alone cannot establish a public-market purchase of common stock. An automated filter that treats it that way changes the research population before any trading calculation begins.
Our narrower editorial rule requires Table I, common shares, an acquisition marked A in the acquired/disposed field, transaction code P, positive finite shares and price, and an independently reviewed confirmation of an open-market purchase. The acquisition field A is different from transaction code A, which the example excludes. It also excludes exercise code M and tax or exercise-price payment code F. Footnotes and security descriptions need review; an unknown confirmation stays ineligible rather than becoming a convenient yes.
Each row includes issuer, canonical event identifier, independent-person group, transaction date, first usable public timestamp and a canonical-review flag. Separate reporting entities representing the same beneficial person must not manufacture a two-person cluster. The supplied group is an externally resolved input, not a name-matching algorithm. Preserve the filing accession, footnote evidence and review version alongside a real dataset so another researcher can reproduce the classification.
An identical canonical event repeated twice is ignored. Conflicting versions of the same issuer and event identifier raise an error and require upstream resolution. This demonstration does not claim to reconcile every Form 4 amendment automatically. A replacement row that silently overwrites the earlier public information can leak a later correction into an earlier investment decision.
Define a ten-day information window
Sort records by public availability, issuer and event identifier. For the issuer currently being evaluated, collect qualified events whose availability lies within the inclusive preceding 240 elapsed hours (ten 24-hour days). Count unique independent-person groups, not filings, rows or transactions. Emit a trigger only when the issuer moves from fewer than two qualifying groups to at least two. Remaining above the threshold does not emit another trigger on every new row.
This is a disclosure-availability window. It is deliberately different from grouping purchases by transaction date. The latter could be a valid separate specification, but it still must not permit trading before the disclosures are usable. The choice belongs in the research contract because delayed reporting can create very different clusters under the two definitions.
The synthetic issuer ALFA has E1 from group P1 publicly usable on January 5, 2026 at 16:30 Eastern, a duplicate E1, and E2 from the same P1 on January 6. These still represent one independent buyer. E3 from P2 on January 7 is a private purchase and does not qualify. E4 from P2 on January 8 at 16:30 is a reviewed open-market common-share acquisition. Only then does the cluster appear, with groups P1 and P2 and qualifying events E1, E2 and E4.
The private-purchase control is a different failure mechanism from duplicate reporting: one concerns transaction eligibility and the other event identity. Additional controls reject a derivative-table purchase, grant, exercise, payment code and an unresolved footnote. A P2 event for another issuer cannot complete ALFA’s cluster. Moving P2’s qualifying disclosure to January 25 lets the earlier P1 disclosures expire, so there is no cluster at that point.
Order instants, not timestamp strings
Parse every availability value as an aware datetime and convert it to UTC before sorting or testing the window. A missing timezone raises timezone_required; the script does not guess the computer’s local zone or attach UTC without evidence. The Python datetime documentation distinguishes aware instants from ambiguous naive values. Original timestamp spelling remains in the trigger for provenance, while available_utc identifies its normalized instant.
The mixed-offset control gives P1 January 5 at 22:00 UTC and P2 January 5 at 17:30 with offset minus five hours, which is 22:30 UTC. It must form one cluster at the later instant. Lexical ISO-string sorting would process P2 first and can miss the transition. Reversing inputs and expressing both rows in equivalent UTC must preserve groups, event identifiers and normalized trigger time. Simultaneous instants use issuer and event identifier as deterministic tie keys.
The ten-day window here means exactly 240 elapsed hours, with both endpoints included, rather than a count of local date labels across daylight-saving changes. A P1 observation at January 5, 22:00 UTC still qualifies for P2 exactly January 15, 22:00 UTC; one microsecond later it has expired. This policy is separate from the twenty-exchange-session holding period. Source timestamps still need correct historical offsets supplied upstream.
Map the trigger to actual sessions
The cluster is known after the January 8 close. The next provided regular opening is January 9 at 09:30 Eastern. Use actual exchange sessions, including the absence of January 19 in this window, rather than adding twenty weekdays. The NYSE hours and calendars provide the regular-session and holiday reference used to freeze this short session list.
The holding convention is twenty opening-to-opening intervals: entry at list index 4 and exit at index 24. That maps January 9 to February 9. It does not mean selling on the twentieth row when the entry row is counted as day one. Both timestamps are asserted so an off-by-one change cannot preserve the narrative while changing the trade.
For a longer study, freeze a complete exchange calendar and explain early closes, suspensions and missing execution bars. This fixture supplies usable openings for the two orders. It does not turn an absent bar into a fill, predict an opening auction price from a disclosure or establish a broker’s acceptance of the order.
Close the account, including the losing outcome
Start with 1,000 currency units and no shares. At the January 9 opening buy forty ALFA shares at 10 and charge one unit. Cash becomes 599, holdings forty and cumulative fees one. The purchase is affordable without borrowing. At the February 9 opening sell all forty at 9.5 and charge another unit. The account receives 379 and finishes with cash 978, no shares and fees two.
The bridge is 1,000 minus 401 plus 379 equals 978. The price component is forty times negative 0.5, or negative twenty; fees subtract another two. A valid cluster therefore produces a losing synthetic trade. Neither eligibility nor the frequency of insider buying establishes that the subsequent price will rise. Do not relabel this mechanism check as evidence of predictive skill or a historical strategy return.
The example asserts exact buy and sell records, entry cash, exit cash, fee total and flat holdings. It also reverses the event input order and requires the same canonical trigger, preventing ingestion order from changing information time. A production portfolio would additionally need position sizing across simultaneous issuers, concentration limits, blocked-sale behavior and a consistent valuation policy. Those choices should be explicit additions, not assumptions hidden behind this one-stock account.
Run and inspect the evidence
Download the complete example. Run python R591.py with Python 3.12 or newer. The script uses only the standard library, synthetic reviewed events and synthetic prices. It does not contact the SEC, scrape filings or call a trading service. The printed trigger includes the contributing events and independent groups, followed by the order timestamps and final account.
Review the exclusion controls before changing the threshold. If a reader changes private-purchase confirmation to true, E3 can make the cluster appear earlier; that is a changed input classification, not improved execution. If two P1 transactions are counted as two people, the first cluster moves earlier for the wrong reason. If calendar days are used for the holding exit, the account no longer follows the declared twenty-session contract.
For real-data work, archive each original filing, its first usable timestamp, identity-group mapping and amendment decision. Reconcile issuer corporate actions and stock identifiers separately from person identities. Then replay a frozen event prefix and verify that later filings cannot alter its earlier triggers. These records make the result reviewable even when a later correction changes what is believed to be true about the underlying purchase.
Preserve the event-to-account audit chain
A review export should distinguish transaction date, first usable disclosure time, issuer-level cluster transition and actual opening execution. E1 and E2 contribute two events but only one person group; E4 adds the second group, and its after-close disclosure pushes entry to January 9. The account then exits twenty intervals later even if more qualifying purchases arrive. Each link has a different identifier and failure reason. Keeping them separate prevents a correct event count from being mistaken for a correct trade date or a completed profitable account.
The expiry test also covers a gap with no intervening disclosure: P1 appears January 5, P2 January 8 and P1 again January 17. Before the last event, the earlier P1 has expired while P2 remains. The new P1 therefore creates a second cluster transition. Recompute the prior window at the current event time; caching only the last event’s active flag would miss that re-entry.
FAQ
Does code P prove an open-market common-stock purchase?
No. This strategy additionally requires reviewed security, table and open-market conditions. Unknown classifications are excluded, and those external review decisions must be preserved.
Is 978 a historical result for an insider strategy?
No. It is the final cash of one synthetic losing trade, with two explicitly charged fees. Historical performance requires a separately sourced, point-in-time event archive and a broader portfolio simulation.