Python tools for screening Canadian (TSX) stocks and running a daily swing-trading “entry pipeline” that tracks candidates across days and emits actionable alerts when setups move through a signal state machine.
This repo contains two primary scripts:
canadian_stock_screener.py— multi-factor momentum screener that ranks a predefined TSX universe and saves a top-N CSV.auto_pipeline.py— consumes daily screener outputs, tracks tickers over time, detects technical entry patterns, and produces alerts + a persistent signal database.
Data source: Yahoo Finance via
yfinance.
.
├── canadian_stock_screener.py
├── auto_pipeline.py
├── config.py
├── requirements.txt
└── data/
└── can_tickers # TSX universe list (one ticker per line)
canadian_stock_screener.py downloads ~2 years of daily data and scores each ticker with a weighted stack (see CONFIG["weights"] in the script):
- Weinstein Stage II alignment
- Relative Strength vs benchmark (
XIU.TO) - MACD momentum
- OBV slope (volume accumulation)
- ADX trend strength
- Volatility-adjusted momentum (VAM)
- 52-week high proximity / breakout pressure
It also applies basic filters such as minimum price and minimum average volume.
- Prints a table to the console.
- Saves the top picks to:
out/screener_outputs/YYYYMMDD_HHMM.csv
python canadian_stock_screener.pyEdit CONFIG inside canadian_stock_screener.py:
top_n(default 10)min_price(default 2.0 CAD)min_avg_volume(default 100,000)weights(factor weighting)lookback_days(default 504 trading days)
Universe list:
data/can_tickers
auto_pipeline.py reads daily screener outputs, tracks tickers across days, detects entry patterns, and alerts on signal state transitions.
Accepted inputs (flexible):
- Any CSV with a
Tickerorsymbolcolumn - Example names (from the script header):
top10_tsx_20260218_1430.csvmy_tickers_2026-02-18.csv
- JSON is also supported for some upstream tools (see
auto_pipeline.pyheader).
The pipeline currently runs three detectors:
- VCP (Volatility Contraction Pattern)
- EMA pullback reclaim (EMA21 and EMA50 variants)
- Base breakout (tight range + volume confirmation)
FORMING → AT_PIVOT → CONFIRMED → ACTIVE / FAILED
- 🔴 URGENT — state jumped to CONFIRMED today (often “enter next session open” style)
- 🟡 WATCH — state reached AT_PIVOT today (often “place buy-stop” / watch volume)
- 🟢 FORMING — setup building, check again
- ⚫ EXPIRED — invalidated/expired
On first run, the pipeline creates:
<base_dir>/
out/
screener_outputs/ # drop daily top-N CSVs here
signal_db/
signal_history.csv # persistent signal state across days (auto-managed)
alerts/
alerts_YYYYMMDD.csv # actionable alerts for each run
report_YYYYMMDD.txt # human-readable daily report
This repository is run as three operational services:
-
main.py- Builds swing universe, runs screener, runs pipeline, and sends report.
- Typical schedule: once daily after market close.
-
virtual_buy.py- Executes virtual buys from the candidate queue and updates funds/positions files.
- Typical schedule: once daily after the pipeline/report step.
-
position_monitor.py- Monitors open positions and can execute virtual sells in pre-close mode.
- Typical schedule:
- Pre-close run for actionable intraday exits.
- Post-close run for informational end-of-day monitoring.
- Python 3.10+ recommended
- Internet access (Yahoo Finance via
yfinance)
python -m venv .venv
# Linux/macOS:
source .venv/bin/activate
# Windows:
# .venv\Scripts\activate
pip install -r requirements.txtyfinancedepends on Yahoo endpoints; intermittent rate limits or missing data can happen.- The screener is designed around TSX tickers and uses
XIU.TOas the benchmark. - The pipeline caps tracked tickers (
--max-tickers, default 40) to avoid excessive API calls.
This repository is for research/education and does not constitute financial advice. Trading involves risk.
- MIT