Event-Driven Stock Strategy Backtester
A learning and research project for testing a rules-based stock strategy built around public U.S. congressional stock disclosures. The focus is not just on generating signals, but on modelling what would actually have been knowable and tradable at each point in time.
Research / educational project only. No live trading or investment advice.
What it is
The project started as a way to investigate whether clusters of public congressional stock transactions could be turned into a testable, repeatable strategy. It has grown into a chronological portfolio simulator with explicit entry, exit, position-sizing and cash-management rules.
Signal window
Transactions are grouped into time-bounded clusters rather than treated as isolated events.
Distinct members
A qualifying signal requires activity from at least three different members.
Base holding period
Positions are scheduled for exit on the first valid trading session on or after the target date.
How it works
The backtester is deliberately chronological. The signal logic and portfolio engine are separated so that the model can distinguish between when information becomes available and when a trade can actually be executed.
Prepare and validate input data
The project is being built around public disclosure events, market prices and trading-session data. Inputs are cleaned and checked before they are allowed to affect the strategy logic.
Build signals from disclosed activity
The signal detector looks for defined combinations of member activity in the same ticker while respecting the strategy's timing rules.
Convert signals into executable events
Entries are scheduled for the next valid trading-session open rather than assumed to happen instantly when a signal is detected.
Process the portfolio chronologically
Cash, open positions, closed positions and trade events are updated in time order, with whole-share handling and explicit capital constraints.
Record portfolio history
Daily snapshots can be used to analyse equity, drawdown, capital utilisation, realised/unrealised P&L and other portfolio-level metrics.
Current strategy rules
The rules are intentionally explicit so that changes can be tested one at a time instead of being hidden inside discretionary decisions.
Signal quality
Same ticker, at least three distinct members, bipartisan participation and activity across both chambers within a 30-day transaction window.
Entry timing
A qualifying signal triggers one entry attempt at the next valid trading-session open. The backtester does not silently retry failed entries.
Position sizing
Allocation is tied to signal quality using defined sizing bands, with a portfolio-level cap per ticker and whole-share execution.
Holding and exits
The base holding period is 180 calendar days, with exit on the first valid session on or after the target date.
Chronology first
The project is designed to avoid look-ahead bias: the backtester should never use information before it would have been available in the real world. That constraint influences the way disclosures, signals, trading sessions and portfolio events are processed.
Inside the code
This code view is adapted directly from a development excerpt of the chronological portfolio test. It is one of the pieces that helped move the project away from separate buy/sell phases and toward processing portfolio events in time order, so cash and open positions reflect what would actually have been available at each point in time.
print()
print("CHRONOLOGICAL PORTFOLIO TEST")
test_cash = starting_cash
open_positions = {}
for event in portfolio_events:
position_id = event["position_id"]
if event["event"] == "buy":
position = positions[position_id - 1]
cost = position["shares"] * event["price"]
if cost > test_cash:
raise ValueError(f"Not enough cash for position {position_id}")
test_cash -= cost
open_positions[position_id] = position
print(
event["date"].date(),
"BUY",
event["ticker"],
"position",
position_id,
"cash:",
test_cash
)
elif event["event"] == "sell":
if position_id not in open_positions:
raise ValueError(f"Position {position_id} is not open")
position = open_positions[position_id]
2026-05-21 BUY PANW position 1 cash: 95187.5
2026-06-11 BUY NVDA position 2 cash: 90217.5
2026-08-26 BUY PANW position 3 cash: 85341.5
The project has continued to grow around this test with entry candidates, planned buy/sell events, position IDs, cash reuse after exits and portfolio-accounting logic. The output above comes from a development test used to verify chronology and state handling; it is not a historical performance result. The code window is intentionally an excerpt rather than a full source dump.
What I am learning
Python is a tool for the project rather than the end goal. The bigger challenge is learning to turn an idea into a system whose logic can be inspected, tested and improved without losing track of how the pieces fit together.
Python
Data processing, functions, state management, debugging and building larger pieces of logic incrementally.
Git
Keeping changes traceable and making it easier to experiment without losing working versions of the project.
VS Code
Developing, navigating and testing the project in a real code editor rather than treating code as isolated snippets.
AI-assisted learning
I use AI to explain unfamiliar concepts, review and debug code, challenge assumptions and accelerate iteration. I still work through changes incrementally so I can understand what the code is doing and why.
System design & testing
The project forces me to think about chronology, state, edge cases, data quality, reproducibility and whether a result reflects the intended rules rather than an implementation mistake.
Current status
The project is actively being developed. The current milestone is completing and validating the end-to-end pipeline for the first full real-data portfolio backtest. Until that validation is finished, I intentionally avoid presenting performance statistics and focus instead on making the chronology, portfolio accounting and assumptions easy to inspect and verify.
About me
Hi, I'm Sverker Dilts Lindblom. This is a relatively new personal project that grew out of two things I enjoy: markets and learning how technical systems work by building them myself.
I started the project in late August 2026. During its first week and a half I worked on it across several focused sessions, going from setting up and learning the workflow around Python, Git and VS Code to building and testing core pieces of the backtester, including signal rules, chronological trade events, position tracking and cash handling.
What I enjoy most is the learning process: breaking an unfamiliar problem into smaller parts, understanding why the code behaves the way it does, and then improving the system one step at a time. The project has become a practical way for me to learn quickly without treating the code as a black box.