This repository contains a collection of CLI tools that ingest market data, compute technical signals, and generate text reports against a MySQL database. Each tool shares a common YAML configuration, so you can manage credentials and connection details in one place.
- Python 3.9+
- Docker (for running MySQL via
docker-compose.yml) - Polygon.io API key (for price ingestion)
- Python dependencies from
requirements.txt
-
Install dependencies
pip install -r requirements.txt
-
Configure MySQL
docker-compose up -d mysql
-
Set up configuration
Copy
config.yaml(or create your own) and adjust the credentials if needed. Environment variables (MYSQL_HOST,MYSQL_USER, etc.) override values in the file. -
Polygon API key
export POLYGON_API_KEY=your_api_key
All tools accept --config to point to an alternate YAML file:
python3 src/prices.py --config /path/to/config.yamlIf omitted, config.yaml in the repository root is used.
Loads company metadata (symbol, name, sector, industry, market cap) from CSVs in data/ into the companies table.
python3 src/import_to_mysql.py \
--data-dir data \
--chunk-size 500Expectations:
- Input files:
*.csvwith headers mapping tosymbol,company,sector,industry,market cap, etc. - The script upserts rows so reruns refresh the latest values.
Fetches OHLC aggregates from Polygon for every company symbol and stores them in the prices table. The script resumes from the last stored date per symbol, or uses the provided start date.
python3 src/prices.py \
--start-date 2024-01-01 \
--end-date 2024-01-31 \
--lookback-days 60 \
--sleep 0.25Flags worth noting:
--adjusted/--rawtoggles adjusted pricing.--timespanand--multipliercontrol the aggregation window (default: daily candles).--sleepadds delay between API calls to avoid rate limits.
Ensure POLYGON_API_KEY is set before running.
Calculates moving-average crossovers and price-vs-SMA cross events, persisting them into sma_events. On each run it only evaluates new data since the latest stored event per symbol.
python3 src/sma_events.py \
--short-window 50 \
--long-window 200 \
--chunk-size 500Stored event types include:
golden_crossanddeath_crossprice_cross_short_up/downprice_cross_long_up/down
The report generator (below) filters to golden_cross and death_cross.
Produces a text summary under data/report_YYYYMMDD.txt with:
- Top gainers above a configurable percentage
- Same-day
golden_crossanddeath_crossevents - Sector and industry leaders (average % change and top performer)
- Volume spikes (≥ 3× rolling average)
python3 src/generate_report.py \
--report-date 2024-02-15 \
--gain-threshold 12 \
--volume-window 30 \
--output-dir data/reports- Import or refresh the
companiestable (src/import_to_mysql.py). - Ingest latest prices after market close (
src/prices.py). - Update SMA and price crossover events (
src/sma_events.py). - Generate the daily report (
src/generate_report.py).
Automate these steps via cron or a scheduler, passing --config as needed.
- Missing config: ensure
config.yamlexists or pass--config path. - Access denied: double-check database credentials and Docker MySQL logs.
- Polygon errors: confirm network access and API key validity.
- Sandbox compile failures: when developing in restricted environments, run
python3 -m compilealllocally to validate syntax.
The shared helpers in src/db.py centralize configuration and SQLAlchemy setup. Reuse them in new scripts to keep configuration consistent. Example:
from db import load_database_config_from_args, create_engine_from_config
config = load_database_config_from_args(args)
engine = create_engine_from_config(config)Contributions that add new analytics, improve reporting, or expand automation are welcome.