# Manual server deployment

## Why the local folder is ~600 MB

| Path | Typical size | Include in deploy zip? |
|---|---:|---|
| `.venv/` | ~450 MB | **No** — recreate on the server |
| `data/features/` | ~60 MB | No for daily ops (research only) |
| `data/raw/` | ~35 MB | No for daily ops (immutable research snapshots) |
| `data/normalized/` + `data/models/` | ~15 MB | **Yes** — required runtime state |
| `src/`, `config/`, `tests/` | ~2 MB | **Yes** |

The packaging script produces a **~20–25 MB** daily-ops archive (profile `daily`) or a **~115 MB** full archive (profile `full`).

## 1. Build the archive (on your Mac)

```bash
cd /path/to/psx-signal-engine
chmod +x scripts/package-for-deploy.sh
./scripts/package-for-deploy.sh daily
```

Output: `dist/psx-signal-engine-daily-YYYYMMDDTHHMMSS.tar.gz`

## 2. Upload and extract (on the server)

```bash
mkdir -p ~/psx-signal-engine
cd ~/psx-signal-engine
tar -xzf /path/to/psx-signal-engine-daily-*.tar.gz
```

## 3. System prerequisites (Linux)

- Python **3.11+** (3.12 recommended)
- Build tools for XGBoost if wheels are unavailable: `build-essential`, `libgomp1`
- Network egress for Yahoo Finance and pyPSX API calls

Ubuntu/Debian example:

```bash
sudo apt update
sudo apt install -y python3 python3-venv python3-pip build-essential libgomp1
```

## 4. Install the application

```bash
cd ~/psx-signal-engine
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e '.[dev]'
psx-signal --help
```

Do **not** copy `.venv` from macOS — Linux needs its own wheels (especially XGBoost, pyarrow, scipy).

## 5. Configure credentials

```bash
cp .env.example .env
$EDITOR .env
```

Required for automated KSE100 benchmark refresh (core pyPSX SDK):

```text
PYPSX_API_KEY_ID=your_key_id
PYPSX_API_SECRET_KEY=your_secret_key
PSX_SIGNAL_CONFIG=config/default.toml
```

Obtain API keys from the pyPSX developer portal. Never commit `.env`.

## 6. Verify install

```bash
source .venv/bin/activate
python -c "import pypsx; print(pypsx.__version__)"   # after pypsx is pinned in pyproject.toml
pytest -q
```

## 7. Daily operation (one command)

Run after the PSX session is final and before the next 09:00 PKT pre-open cutoff:

```bash
source .venv/bin/activate
psx-signal prospective-daily
```

Review:

- `reports/paper/study_v1/daily_report.json`
- `reports/paper/study_v1/daily/YYYY-MM-DD.md`

## 8. Optional cron

```cron
# Weekdays 18:30 PKT (13:30 UTC) — adjust if your provider buffer differs
30 13 * * 1-5 cd /home/USER/psx-signal-engine && . .venv/bin/activate && psx-signal prospective-daily >> logs/prospective-daily.log 2>&1
```

Create `logs/` first: `mkdir -p ~/psx-signal-engine/logs`

## Deploy bundle contents (daily profile)

**Included**

- Application source (`src/`, `tests/`, `config/`, `pyproject.toml`)
- Normalized datasets (`data/normalized/`)
- Frozen model (`data/models/psx_xgb_5d_topn_v1.joblib*`)
- Reference files (`data/reference/`)
- Prospective study state (`reports/paper/study_v1/`)

**Excluded**

- `.venv/` (platform-specific)
- `data/features/` (regenerable research features)
- `data/raw/` (immutable research snapshots)
- Yahoo/pyPSX download caches
- `__pycache__/`, `.pytest_cache/`, `.DS_Store`

## Troubleshooting

| Symptom | Action |
|---|---|
| `PYPSX_CREDENTIALS_REQUIRED` | Set `PYPSX_API_KEY_ID` and `PYPSX_API_SECRET_KEY` in `.env` |
| `WAITING_FOR_BENCHMARK_PROVIDER` | Check pyPSX API status; rerun before pre-open cutoff |
| XGBoost import error on Linux | `sudo apt install libgomp1` or reinstall in a fresh venv |
| Missing model artifact | Ensure `data/models/psx_xgb_5d_topn_v1.joblib` was included in the archive |
