Ranking Stocks by Reported Insider Buying and Selling
Summary
This example outlines a long-only stock allocation approach based on recent reported insider activity. A research agent reviews SEC filings for executives' open-market purchases and sales, excluding awards, gifts, and option exercises. It reports amounts and traders for a watchlist; a separate trading-enabled agent then tilts account holdings toward stocks with more insider buying and away from those with selling. The example instructs the trading agent to hold every watchlist stock and never short.
The document gives an implementation outline, not empirical evidence that insider activity predicts returns. It specifies a recent filing window and daily strategy iterations, but provides no backtest results, transaction-cost analysis, position limits, or rules for resolving conflicting signals. The research and trading roles are separated, yet the allocation strength is left to the agent's interpretation. Filing dates, reporting delays, data quality, and portfolio risk controls would matter in practical evaluation.
Key ideas
- The proposed signal compares executives' open-market purchases and sales.
- The research process excludes awards, gifts, and option exercises from the trade tally.
- A research agent summarizes insider activity while a separate agent adjusts the portfolio.
- The example holds the watchlist long-only and does not specify quantitative position weights.
- No performance or transaction-cost evidence is supplied.
Tags
Full text
# ai_insider_trading_bot.py
```py
"""Insider Trading Bot.
Buys more of the stocks whose CEOs and directors are buying their own company's
shares, and less of the stocks they are selling. A research agent reads the
insider trade reports executives file with the SEC. A trading agent then moves
the account toward the stocks insiders are buying.
"""
from lumibot.strategies import Strategy
class InsiderTradingBot(Strategy):
parameters = {"watchlist": ["AAPL", "MSFT", "JPM", "BAC", "XOM", "CVX", "PFE", "INTC", "F", "KO"]}
def initialize(self):
self.sleeptime = "1D"
self.agents.create(
name="researcher",
allow_trading=False,
system_prompt=(
"For each stock in the watchlist, look up the insider trades its executives reported to the "
"SEC in the last 30 days. Count only real buys and sells on the open market, not stock "
"awards, gifts, or option exercises. Report the dollars bought and sold for each stock and "
"who traded. Do not trade."
),
)
self.agents.create(
name="trader",
allow_trading=True,
system_prompt=(
"Hold every stock in the watchlist. Put more money in the stocks insiders are buying and less "
"in the stocks they are selling. Never short."
),
)
def on_trading_iteration(self):
facts = {"watchlist": self.parameters["watchlist"]}
research = self.agents["researcher"].run(task_prompt="Find this month's insider buys and sells.", context=facts)
self.agents["trader"].run(
task_prompt="Lean the account toward insider buying.", context={**facts, "research": research.summary}
)
if __name__ == "__main__":
from lumibot.credentials import IS_BACKTESTING
if IS_BACKTESTING:
from lumibot.backtesting import YahooDataBacktesting
InsiderTradingBot.backtest(YahooDataBacktesting)
else:
InsiderTradingBot().run_live()
```Shown in full with attribution under the source's licence. Licence: GPL-3.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.