# Repository Context

Generated on: 2025-05-30

## Directory Tree (Whitelist Only)

```
.
    ├── scripts/
        ├── lagged_oil_unrate_chart_styled.py
        ├── pyproject.toml
    ├── README.md
    ├── requirements.txt
```

## Important Files

## python_charts/README.md
```markdown
# Lagged Oil vs. Unemployment Charting

This repository provides two Python scripts to fetch the latest US Unemployment Rate (UNRATE) and WTI crude oil price (DCOILWTICO) from FRED, apply a configurable lag or lead to the oil series, and generate polished dual‑axis charts.

## Files

* **`lagged_oil_unrate_chart.py`**
  A lightweight script that:

  1. Downloads monthly UNRATE and averages daily WTI to monthly.
  2. Shifts the oil series by `N` months (default = 18).
  3. Plots both series on a dual‑axis Matplotlib chart.

* **`lagged_oil_unrate_chart_styled.py`**
  A more polished version that adds:

  * Title, subtitle, footnote with date range and source.
  * Clean dual‑axis styling with percentage and dollar‑format ticks.
  * Customizable date range and extended x‑axis (e.g., 1973–2028).
  * CLI flags for offset, start/end dates, and axis extension.

* **`requirements.txt`**
  Lists all Python dependencies for both scripts.

## Prerequisites

* Python 3.7 or later
* Internet connection (to fetch data from FRED)

## Setup

Clone or download this repository:

```bash
git clone https://your-repo-url.git
cd your-repo-folder
```

### Create a Virtual Environment & Install Dependencies

#### On Linux / macOS

```bash
# 1. Create a venv
python3 -m venv venv

# 2. Activate it
source venv/bin/activate

# 3. Upgrade pip and install requirements
pip install --upgrade pip
pip install -r requirements.txt
```

#### On Windows (PowerShell)

```powershell
# 1. Create a venv
python -m venv venv

# 2. Activate it
venv\Scripts\Activate.ps1

# 3. Upgrade pip and install requirements
python -m pip install --upgrade pip
pip install -r requirements.txt
```

> **Note:** If you get execution policy errors on Windows, you may need to run:
>
> ```powershell
> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
> ```

## Usage

Once the virtual environment is active and dependencies are installed, run either script from the project root.

### 1. Basic Lag Script

```bash
# Default: oil lags unemployment by 18 months (~1.5 years)
python lagged_oil_unrate_chart.py

# Other offsets (in months)
python lagged_oil_unrate_chart.py --offset 6    # 6‑month lag
python lagged_oil_unrate_chart.py --offset -12  # 12‑month lead
```

### 2. Styled & Configurable Chart

```bash
python lagged_oil_unrate_chart_styled.py \
    --offset 18 \
    --start 1973-01-01 \
    --end 2025-05-31 \
    --extend-years 3
```

| Flag               | Description                                                    |
| ------------------ | -------------------------------------------------------------- |
| `--offset N`       | Lag (positive) or lead (negative) in months (default = 18)     |
| `--start DATE`     | Series start date (`YYYY-MM-DD`, default = `1973-01-01`)       |
| `--end DATE`       | Series end date (`YYYY-MM-DD`, default = today)                |
| `--extend-years M` | How many years beyond `end` to extend the x‑axis (default = 3) |

## Customization

* **Normalization**: Insert a normalization step (e.g., percent change from a base date).
* **Export**: Modify the script to save figures with `plt.savefig('chart.png', dpi=300)`.
* **Statistics**: Add `ta.correl()` or use Pandas to compute rolling correlations.

## Troubleshooting

* **"ModuleNotFoundError"**: Ensure your venv is activated, then reinstall dependencies.
* **SSL/DataReader errors**: Upgrade `pandas_datareader` or switch to an alternate data source.

## License

This project is released under the MIT License.

```

## python_charts/requirements.txt
```
pandas>=1.5.0
pandas_datareader>=0.10.0    # good
matplotlib>=3.5.0
lxml>=4.6.0
python-dateutil>=2.8.1

```

## scripts/pyproject.toml
```
# pyproject.toml

[project]
name = "lagged-oil-unrate"
version = "0.1.0"
description = "Plot UNRATE vs WTI oil price with adjustable lag"
authors = ["Your Name <you@example.com>"]
dependencies = [
  "pandas>=1.3.0",
  "pandas_datareader>=0.10.0",
  "matplotlib>=3.4.0",
  "python-dateutil>=2.8.0",
  "lxml>=4.6.0"
]

```

## scripts/lagged_oil_unrate_chart_styled.py
```python
#!/usr/bin/env python3
"""
lagged_oil_unrate_chart_styled.py
---------------------------------
Fetch and plot UNRATE vs. WTI oil price with a configurable lag,
date range, and polished dual-axis styling.

Usage:
    python lagged_oil_unrate_chart_styled.py \
        --offset 18 \
        --start 1973-01-01 \
        --end 2025-05-31 \
        --extend-years 3

Dependencies:
    pip install pandas pandas_datareader matplotlib python-dateutil
"""
import argparse
from datetime import datetime
from dateutil.relativedelta import relativedelta

import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
import pandas_datareader.data as web


def fetch_series(start, end):
    # FRED series
    unrate = web.DataReader("UNRATE", "fred", start, end)
    oil   = web.DataReader("DCOILWTICO", "fred", start, end)

    # Resample WTI to month-end average
    oil_monthly = oil.resample("M").mean()
    # Ensure UNRATE is at month-end timestamps, too
    unrate.index = unrate.index.to_period("M").to_timestamp("M")
    return unrate, oil_monthly


def plot_lagged(
    unrate: pd.DataFrame,
    oil: pd.DataFrame,
    offset_months: int,
    start_date: datetime,
    end_date: datetime,
    extend_years: int
):
    # Shift oil by offset: positive = lag; negative = lead
    oil_shifted = oil.shift(offset_months)

    # Build figure
    fig, ax1 = plt.subplots(figsize=(14, 7))
    plt.title("Unemployment Rate and US Oil Price", fontsize=20, weight="bold")
    plt.suptitle(
        "Civilian Unemployment Rate and WTI Crude Oil Price",
        fontsize=14,
        y=0.93
    )

    # Plot UNRATE on left axis
    ax1.plot(unrate.index, unrate["UNRATE"], 
             label="UNRATE (LHS)", linewidth=2.5, color="#1f77b4")
    ax1.set_ylabel("Unemployment rate (%)", fontsize=12)
    ax1.set_ylim(0, unrate["UNRATE"].max() * 1.1)
    ax1.yaxis.set_major_formatter("{x:.0f}%")
    ax1.grid(axis="y", linestyle="--", alpha=0.4)

    # Plot shifted oil on right axis
    ax2 = ax1.twinx()
    ax2.plot(oil_shifted.index, oil_shifted["DCOILWTICO"],
             label="USOIL (RHS)", linewidth=2, linestyle="-", alpha=0.8, color="#FF9900")
    ax2.set_ylabel("Oil price (USD)", fontsize=12)
    ax2.set_ylim(0, oil_shifted["DCOILWTICO"].max() * 1.1)
    ax2.yaxis.set_major_formatter("${x:,.0f}")

    # X-axis formatting
    ax1.set_xlim(start_date, end_date + relativedelta(years=extend_years))
    ax1.xaxis.set_major_locator(mdates.YearLocator(base=5))
    ax1.xaxis.set_minor_locator(mdates.YearLocator(1))
    ax1.xaxis.set_major_formatter(mdates.DateFormatter("%Y"))
    plt.setp(ax1.get_xticklabels(), rotation=0, fontsize=11)

    # Combine legends
    lines, labels = ax1.get_legend_handles_labels()
    l2, l2l = ax2.get_legend_handles_labels()
    ax1.legend(lines + l2, labels + l2l, loc="upper left", frameon=False, fontsize=12)

    # Footnotes
    foot = (
        f"Dates: {start_date.strftime('%Y')} through {unrate.index[-1].strftime('%d %b %Y')}.\n"
        "Source: FRED, pandas_datareader."
    )
    plt.annotate(
        foot,
        (0,0), (0, -40), 
        xycoords="axes fraction", textcoords="offset points",
        va="top", fontsize=10, color="gray"
    )

    fig.tight_layout(rect=[0, 0.03, 1, 0.95])
    plt.show()


if __name__ == "__main__":
    p = argparse.ArgumentParser()
    p.add_argument("-o", "--offset", type=int, default=18,
                   help="lag in months (positive=lag, negative=lead)")
    p.add_argument("--start", type=str, default="1973-01-01",
                   help="series start date (YYYY-MM-DD)")
    p.add_argument("--end", type=str, default=datetime.today().strftime("%Y-%m-%d"),
                   help="series end date (YYYY-MM-DD)")
    p.add_argument("--extend-years", type=int, default=3,
                   help="how many years beyond end_date to show on the x-axis")
    args = p.parse_args()

    start_dt = datetime.fromisoformat(args.start)
    end_dt   = datetime.fromisoformat(args.end)

    unrate, oil = fetch_series(start_dt, end_dt)
    plot_lagged(unrate, oil, args.offset, start_dt, end_dt, args.extend_years)

```

