Files
python_charts/AGENTS.md
T
thePR0M3TH3AN e5b1d091c5 Enhance documentation and scripts for handling UNRATE null values
- Add policy for managing NaN values in UNRATE series to AGENTS.md.
- Update README.md with new chart script details and usage instructions.
- Modify `lagged_oil_unrate_chart_styled.py` to implement clamping to last valid index for UNRATE data.
- Introduce new script `bitcoin_m2_chart.py` for Bitcoin vs. global M2 overlay chart.
- Ensure all scripts maintain data integrity by avoiding estimates for current month.
2025-05-31 09:59:33 -04:00

133 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md — Guidance for OpenAI Codex
## Execution Commands
- **Always** invoke Python scripts via the startup wrapper, which installs dependencies globally and then runs your code under the system Python:
```bash
./startup.sh --offset <months> --end <YYYY-MM-DD> --extend-years <N>
````
* **Never** call `refresh_data.py` from within a Task Command. This environment has **no internet access**, so attempts to fetch external data will fail. Data in `data/fred.db` must already be present.
## Policy for Handling UNRATE Null Values
When generating the UNRATE vs. Oil chart, the UNRATE series may include a `NaN` for the most recent month if that month’s data has not yet been published. To prevent the script from raising a `ValueError: UNRATE contains null values`, follow this policy:
1. **Clamp to Last Valid Index**
* After loading `unrate` and `oil` with `fetch_series(...)`, immediately determine the last non-NaN date in the `unrate` DataFrame using:
```python
last_date = unrate.last_valid_index()
```
* Truncate both `unrate` and `oil` so that any trailing `NaN` row in `unrate` (and corresponding index in `oil`) is removed:
```python
unrate = unrate.loc[:last_date]
oil = oil.loc[:last_date]
```
* Only after this truncation should you call `validate_series(unrate, oil)`. This ensures that neither DataFrame contains nulls and that they share a valid overlapping date range.
2. **Rationale**
* Doing a forward-fill or dropping all NaNs could inadvertently hide missing data or distort recent observations. Clamping to the last officially published month preserves data purity.
* By slicing both series at `last_valid_index()`, you ensure that the chart is plotted only with officially released data and no “estimate” for the current month.
3. **Implementation in `lagged_oil_unrate_chart_styled.py`**
* Right after `unrate, oil = fetch_series(start_dt, end_dt, args.db)`, insert:
```python
last_date = unrate.last_valid_index()
unrate = unrate.loc[:last_date]
oil = oil.loc[:last_date]
```
* Then proceed to `validate_series(unrate, oil)` and the usual plotting logic.
## Project Overview
This repository, **python\_charts**, provides a framework for fetching economic time series from FRED, storing them locally, and producing custom matplotlib charts with configurable parameters. The core components are:
* **`startup.sh`**: Single‐entrypoint script to install dependencies globally, ensure local data is present, and run specified commands under system Python.
* **`Makefile`**: Convenient high‐level targets (`install`, `data`, `plot`, `plot‐custom`, `test`, `clean`) that funnel through `startup.sh` for reproducible builds.
* **`scripts/refresh_data.py`**: Downloads UNRATE and DCOILWTICO series into `data/fred.db`—**only run in an internet-connected environment**, not in Codex/CI.
* **`scripts/lagged_oil_unrate_chart_styled.py`**: Generates the lagged oil vs. unemployment chart with fixed axes styling and log scale.
* **`scripts/bitcoin_m2_chart.py`**: Produces a Bitcoin vs. global M2 overlay chart with adjustable day offset.
* **`scripts/custom_chart.py`**: Plots arbitrary FRED series stored in `data/fred.db`.
Future extensions will add additional custom chart scripts under `scripts/`, all driven by the same bootstrapping and command conventions.
## Usage Conventions
### Primary Commands
* **Bootstrap & default plot**:
```bash
./startup.sh
```
Installs/upgrades dependencies globally and runs the default lagged‐oil chart with an 18‐month offset.
* **Custom plot**:
```bash
./startup.sh --offset 12 --end 2025-05-31 --extend-years 5
```
* **Data refresh (offline environments)**:
* **Do not** run `refresh_data.py` in Codex/CI — data must already be in `data/fred.db`.
* To update data in an internet‐connected shell, run:
```bash
python scripts/refresh_data.py
```
* **Run tests**:
```bash
./startup.sh pytest -q
```
### Argument Rules
* If the first token starts with `--`, it’s forwarded to the default chart script.
* If the first token names a `.py` script, it’s executed via `python <script>`.
* Otherwise, commands are executed directly (e.g., `pytest`, `flake8`).
## Coding Standards
* **Python**: Target version ≥ 3.8. Use type hints for all function signatures. Follow PEP8 with Black formatting.
* **Bash**: `startup.sh` uses `set -euo pipefail`.
* **Makefile**: Use tab‐indented commands. All targets should funnel through `startup.sh`.
## Testing & Validation
* **Automated tests**: Add pytest modules under `tests/` following the pattern `test_*.py`.
* **Data mocking**: For new chart scripts, mock FRED downloads via monkeypatching `pandas_datareader.data.DataReader`.
* **Figure tests**: `tests/test_plot.py` ensures `plot_lagged` returns a figure with two axes and at least one line.
## Extending with New Charts
1. **Create** `scripts/custom_chart.py`.
2. **Implement** a `main()` with `argparse` for `--start`, `--end`, `--offset`, etc.
3. **Invoke** via:
```bash
./startup.sh python scripts/custom_chart.py --your-args
```
4. **Optionally** add a Makefile target if desired.
## CI / Codex Integration
* **Setup Script** →
```bash
chmod +x startup.sh && ./startup.sh
```
* **Task Command** →
```bash
./startup.sh --offset 18
```