Add SqliteSaver-based checkpointing so crashed analyses resume from the
last successful graph node instead of restarting from scratch.
- checkpointer.py: get_checkpointer(), thread_id(), has/clear_checkpoint()
- --checkpoint flag (default: off for backward compatibility)
- --clear-checkpoints flag to force fresh start
- Per-ticker SQLite DBs for parallel worker safety
- Logs 'Resuming from step N' vs 'Starting fresh'
- Clears checkpoint on successful completion (no stale state)
- Tests: crash resume + different date starts fresh