SEC Form 4 Insider-Filing AgentΒΆ
This example analyzes public SEC Form 4 filings. It does not use material
non-public information. Records first become visible at the SEC
acceptance/publication time (normalized as published_at), never merely
on their earlier transaction date.
The parser preserves transaction codes, direct versus indirect ownership, derivative status, amendments, quantities, prices, and computed values. The default strategy considers only open-market transactions; grants, gifts, option exercises, derivatives, and amendments must not be treated as ordinary open-market buying or selling.
form4_researcher builds the evidence packet without trading permission.
trading_risk_manager independently verifies account state and price and is
the only agent allowed to submit an order.
The live source is the SEC Form 4 Atom feed at
https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=4&output=atom.
The strategy may act only on entries whose published time is already visible
at the backtest clock. A January 23, 2026 clock fetched 40 current entries
and hid all 40 as future. A live feed item such as Mark W. Webb, accession
0001193125-26-397981, is the kind of row live mode can see when it is still
in the latest feed.
This example does not ship sample trades. Pass official EDGAR filings in
transactions or a JSON file of those filings in transactions_path.
Running the module with neither argument stops instead of inventing trades.
A backtest on this page is real only after those filings and market prices
are supplied.
1"""SEC Form 4 public-insider-filings strategy.
2
3Python creates the agents and runs them. It does not download the feed or place orders.
4The research agent fetches the public Atom feed. The trading agent places the orders.
5"""
6
7from lumibot.example_strategies.agent_cycle import add_agent, run_cycle, trader_prompt
8from lumibot.strategies import Strategy
9
10_FEED_URL = "https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=4&output=atom"
11
12
13class AISECInsiderFilingsStrategy(Strategy):
14 parameters = {
15 "feed_url": _FEED_URL,
16 }
17
18 def initialize(self):
19 self.sleeptime = "1D"
20 add_agent(
21 self,
22 "insider_trade_researcher",
23 (
24 "Use rss_fetch on the supplied SEC Form 4 feed. Ignore any entry whose published time "
25 "is after as_of. Ignore grants, gifts, option exercises, automatic plans, and amendments. "
26 "Keep open-market purchases and sales only. Report the ticker, the side, and the published time. "
27 "Do not submit orders."
28 ),
29 allow_trading=False,
30 )
31 add_agent(
32 self,
33 "bull",
34 "Argue for copying the open-market insider buys. Do not submit orders.",
35 allow_trading=False,
36 )
37 add_agent(
38 self,
39 "bear",
40 "Argue the risks: grants, amendments, thin names, and sales. Do not submit orders.",
41 allow_trading=False,
42 )
43 add_agent(
44 self,
45 "interpreter",
46 "Read both cases. Assign account weights for the open-market tickers only. Do not submit orders.",
47 allow_trading=False,
48 )
49 add_agent(
50 self,
51 "trading_risk_manager",
52 trader_prompt(
53 book_rule=(
54 "Trade only exact tickers from open-market Form 4 rows already public on as_of. "
55 "Never short. Never treat a grant, gift, or option exercise as an open-market purchase."
56 ),
57 exit_rule=(
58 "Sell a name with the order tool when a later visible filing is a sale. "
59 "Otherwise stay invested, with cash near 0% to 5%."
60 ),
61 ),
62 allow_trading=True,
63 )
64
65 def on_trading_iteration(self):
66 as_of = self.get_datetime()
67 context = {
68 "as_of": as_of.isoformat(),
69 "feed_url": self.parameters["feed_url"],
70 "clock_rule": "Ignore any feed entry published after as_of.",
71 "risk_policy": {
72 "cash_target": "0% to 5%",
73 "sizing": "scale the open-market filings to account value",
74 "never_short": True,
75 },
76 }
77 run_cycle(
78 self,
79 context,
80 researcher="insider_trade_researcher",
81 bull="bull",
82 bear="bear",
83 interpreter="interpreter",
84 trader="trading_risk_manager",
85 research_task="Fetch the Form 4 feed and report only open-market rows already public on as_of.",
86 bull_task="Make the bull case for the open-market buys.",
87 bear_task="Make the bear case against copying the filings.",
88 interpret_task="Assign account weights for the open-market tickers.",
89 trade_task="Scale the visible open-market book to this account. Sell names the filings sold.",
90 )