Nancy Pelosi Copy Trading Bot¶
Most Pelosi copy bots only buy her stocks. But much of her trading is call options: in her January 23, 2026 report alone she bought call options on Alphabet, Amazon, Apple and Nvidia that expire in January 2027 (House Clerk report). This bot copies those too: it holds her stocks, plus calls on the same stocks with the same expiration dates, sized to your account.
Only want her stocks? Use the Nancy Pelosi Stock Trading Bot.
How it works¶
Research agent goes to the House Clerk website (disclosures-clerk.house.gov) and opens the yearly list of filings. It finds Pelosi’s newest yearly report, which lists every stock and call option she owned on December 31, and every trade report filed since.
The research agent works out what she owns today: every stock, and every call option with its number of contracts, strike price and expiration date. It skips options that have already expired and only uses reports filed before today.
Portfolio agent sizes everything to your account. By default 20% goes to her calls and the rest to her stocks, in her proportions. Her calls cost $9,000 to $18,000 a contract, more than a normal account can spread around, so the bot uses her exact strike when it fits and otherwise the nearest cheaper strike with the same expiration date.
Trading agent buys and sells the stocks and calls in the plan, and checks that every order filled.
The bot checks once a day, but it only trades when she files a new report, so it does not trade every day.
Want a different member of Congress? Change last_name from "Pelosi" to any House member’s last name.
Run it on BotSpot¶
Run this bot on BotSpot without installing anything. BotSpot runs LumiBot in the cloud, backtests it, and connects it to your broker.
The code¶
The whole bot is one short file. The three prompts are the strategy. The research agent uses LumiBot’s built-in web tools, which read ZIP files, PDFs, spreadsheets and web pages from any website.
"""Nancy Pelosi Copy Trading Bot.
Copies Nancy Pelosi's stocks and her call options (same stock, same expiration),
sized to your account. A research agent reads her House Clerk reports, a
portfolio agent sizes each holding, and a trading agent rebalances when she files
a new report. "options_share" sets the share of the account in calls.
"""
from lumibot.strategies import Strategy
HOUSE = "https://disclosures-clerk.house.gov/public_disc"
class NancyPelosiCopyTradingBot(Strategy):
parameters = {"last_name": "Pelosi", "options_share": 0.2}
def initialize(self):
self.sleeptime = "1D"
self.agents.create(
name="researcher",
allow_trading=False,
allow_network=True,
system_prompt=(
"You find out which stocks and call options a member of Congress owns today, from the House Clerk "
f"website. Each year's list of filings is a ZIP file such as {HOUSE}/financial-pdfs/2026FD.ZIP "
"(change 2026 to the year). Each row is one filing with its filing date. FilingType O is a yearly "
"report of everything the member owned on December 31 of that Year; P is a trade report. Yearly "
f"reports are at {HOUSE}/financial-pdfs/YEAR/DOCID.pdf and trade reports at "
f"{HOUSE}/ptr-pdfs/YEAR/DOCID.pdf. Every day, first check the lists for this year and the two years "
"before, using only filings dated before today. Start your answer with \"Newest filing:\" and the "
"date and DocID of the member's own newest filing, yearly or trade report (other people's filings "
"do not count). If your notes start with that same newest filing, reply only NOTHING NEW. Otherwise "
"start from the newest yearly report and apply every trade dated after the December 31 it covers; "
"ignore earlier trades, because the yearly report already includes them. Shares bought, including "
"shares from exercised call options, add to a stock. A sale removes a stock only when the report "
"says all shares or the entire position were sold; \"Sold 10,000 shares\" alone is a partial sale, so "
"keep the stock. Partnership units with a ticker, such as AB, count as stocks. List every stock the "
"member still owns with a dollar range: the yearly report's range, or the trade amount for a stock "
"bought since. List every call option she still owns with the number of contracts, strike price, "
"expiration date, and dollar range. Leave out expired options, real estate, private companies, "
"funds, and bonds. Do not trade."
),
)
self.agents.create(
name="portfolio",
allow_trading=False,
system_prompt=(
"You scale a member's holdings to our account. Put options_share of the account into her call "
"options and the rest into her stocks. Use the middle of each dollar range as a holding's value. "
"Stocks: each stock gets its value divided by the total value of her stocks. Calls: split the "
"options money across her calls in proportion to their values. For each call use the same stock and "
"the same expiration date. Use her strike if one contract fits that call's money; if not, use the "
"nearest higher strike where one contract fits, and buy as many contracts as fit. If no strike "
"fits, give that money to her other calls. Do the math with a calculator, not in your head. Return "
"one line per holding: the stock and its target percent, or the exact call (strike and expiration) "
"and its number of contracts. Do not trade."
),
)
self.agents.create(
name="trader",
allow_trading=True,
system_prompt=(
"You move the account to the targets in the plan: shares for stocks, and the exact call options in "
"the plan (its strike price, expiration date, and number of contracts). Sell every holding that is "
"not in the plan and buy every holding in the plan you do not own yet. Only change a holding you "
"already own when it is more than 2 percentage points away from its target, so the account does not "
"trade every day. If you already hold a call on the same stock and expiration as a planned call, "
"keep it instead of switching strikes. Sell before you buy, never short, never sell options you do "
"not own, and never spend more cash than you have. Check that every order filled."
),
)
def on_trading_iteration(self):
facts = {"last_name": self.parameters["last_name"]}
research = self.agents["researcher"].run(task_prompt="What does the member own today?", context=facts)
answer = research.summary or ""
# Rebalance only when her newest filing changes, never on a re-read of the same filings.
newest = "".join(ch for ch in answer.split("DocID", 1)[-1][:20] if ch.isdigit()) if "DocID" in answer else ""
if (newest and newest == self.vars.get("newest_filing")) or (not newest and "NOTHING NEW" in answer):
return
plan = self.agents["portfolio"].run(
task_prompt="Set the targets.",
context={"holdings": research.summary, "options_share": self.parameters["options_share"]},
)
self.agents["trader"].run(task_prompt="Rebalance to the plan.", context={"plan": plan.summary})
if newest:
self.vars.set("newest_filing", newest)
if __name__ == "__main__":
from lumibot.credentials import IS_BACKTESTING
if IS_BACKTESTING:
from lumibot.backtesting import AlpacaBacktesting
NancyPelosiCopyTradingBot.backtest(AlpacaBacktesting)
else:
NancyPelosiCopyTradingBot().run_live()
Run it yourself¶
pip install lumibot
python -m lumibot.example_strategies.ai_nancy_pelosi_copy_trading_bot
Put these in your .env file: OPENAI_API_KEY, and your broker keys (for example ALPACA_API_KEY, ALPACA_API_SECRET, and ALPACA_IS_PAPER=true for paper trading). Your broker account needs options trading turned on. With IS_BACKTESTING=false the bot trades. With IS_BACKTESTING=true it backtests on Alpaca’s price history instead, which has options from February 2024; set BACKTESTING_START and BACKTESTING_END to pick the dates, and start with a week or two, because every AI call costs a little.
Good to know¶
Change
options_shareto put more or less of your account into calls. Set it to0to copy only her stocks.A cheaper strike is a bigger bet on the stock going up than her strike: it is cheaper because it pays off only above a higher price.
Call options can lose all their value by the expiration date.
Members of Congress can take up to 45 days to report a trade, so the bot always buys late, often at a different price than she paid.
Reports show dollar ranges, such as $1,000,001 to $5,000,000. The bot uses the middle of each range.
The yearly report comes out in May and shows what she owned on December 31. Until the new one is filed, the bot starts from the year before and adds every trade since.
In a backtest the website also shows reports from after the test date. The research agent reads the date on each report and skips any report filed after the test day.
Pelosi said on November 6, 2025 that she will not run for re-election in 2026 (NBC News). Her reports stop after she leaves office, so change
last_nameto keep the bot trading.The House website says its reports may not be used for most commercial purposes (5 U.S.C. 13107). Check that your use is allowed.
See AI Trading Bot Examples for more AI trading bots and Backtest, paper, or live: choose the runner for backtest and live runs.