Files
foxhunt/scripts/run_ppo_comprehensive_tuning.sh
jgrusewski 8d89fe80ff chore: Second cleanup wave - organize root directory
- Archive: 85 agent .txt files → docs/archive/agents/legacy_txt/
- Scripts: Move 110 shell scripts → scripts/ (keep deploy.sh in root)
- Models: Move 18 .safetensors → ml/models/checkpoints/training_artifacts/
- Delete: 34 directories (~33GB freed) - target/, coverage_*, test artifacts
- Build: Clean 14 build artifacts (.rlib, .o, .pid, binaries)
- Tests: Move 14 .rs files → tests/standalone/
- SQL: Move 5 files → sql/ (keep init-db*.sql for Docker)
- Wave 153: Archive to docs/archive/historical/wave153/
- Docs: Archive 9 markdown files to wave_d/reports/ and historical/

Total impact: ~34GB freed (both waves), root directory cleaned from 583 to ~40 essential files
Directory count reduced from 65 to 31 (52% reduction)
All historical data preserved in organized archive structure
2025-10-30 01:26:02 +01:00

467 lines
15 KiB
Bash
Executable File
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.
#!/bin/bash
# PPO Comprehensive Hyperparameter Tuning - 50 Trials
# Mission: Optimize PPO for better explained variance and Sharpe ratio
# Expected Duration: 8-12 hours
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="${SCRIPT_DIR}"
TUNING_CONFIG="${PROJECT_ROOT}/tuning_config_ppo_comprehensive.yaml"
OUTPUT_DIR="${PROJECT_ROOT}/ml/trained_models/tuning/ppo_comprehensive"
LOG_FILE="${OUTPUT_DIR}/tuning_execution.log"
BASELINE_CHECKPOINT="${PROJECT_ROOT}/ml/trained_models/production/ppo_real_data/ppo_actor_epoch_380.safetensors"
# Tuning parameters
MODEL_TYPE="PPO"
NUM_TRIALS=50
MAX_EPOCHS_PER_TRIAL=50
# Validation symbols (all 4 as specified)
SYMBOLS=("6E.FUT" "ZN.FUT" "ES.FUT" "NQ.FUT")
# Hardware configuration
USE_GPU=true
GPU_DEVICE=0
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ PPO Comprehensive Hyperparameter Tuning ║${NC}"
echo -e "${BLUE}║ 50 Trials with Early Stopping at Epoch 50 ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
# Function to print section headers
print_section() {
echo -e "\n${GREEN}═══ $1 ═══${NC}\n"
}
# Function to check prerequisites
check_prerequisites() {
print_section "Checking Prerequisites"
# Check if baseline checkpoint exists
if [ ! -f "${BASELINE_CHECKPOINT}" ]; then
echo -e "${RED}✗ Baseline checkpoint not found: ${BASELINE_CHECKPOINT}${NC}"
echo -e "${YELLOW} Run Agent 79 analysis first to generate baseline${NC}"
exit 1
fi
echo -e "${GREEN}✓ Baseline checkpoint found (Epoch 380)${NC}"
# Check if tuning config exists
if [ ! -f "${TUNING_CONFIG}" ]; then
echo -e "${RED}✗ Tuning config not found: ${TUNING_CONFIG}${NC}"
exit 1
fi
echo -e "${GREEN}✓ Tuning configuration loaded${NC}"
# Check GPU availability
if command -v nvidia-smi &> /dev/null; then
echo -e "${GREEN}✓ GPU detected:${NC}"
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
else
echo -e "${YELLOW}⚠ GPU not detected, will use CPU (slower)${NC}"
USE_GPU=false
fi
# Check if services are running
if ! pgrep -f "ml_training_service" > /dev/null; then
echo -e "${YELLOW}⚠ ML Training Service not running, attempting to start...${NC}"
cargo run -p ml_training_service --release &
sleep 5
fi
echo -e "${GREEN}✓ ML Training Service is running${NC}"
# Check data files
local missing_data=false
for symbol in "${SYMBOLS[@]}"; do
local data_file="${PROJECT_ROOT}/test_data/${symbol}_2024-01-02.dbn.zst"
if [ ! -f "${data_file}" ]; then
echo -e "${RED}✗ Missing data file: ${symbol}${NC}"
missing_data=true
else
echo -e "${GREEN}✓ Data file found: ${symbol}${NC}"
fi
done
if [ "$missing_data" = true ]; then
echo -e "${RED}Some data files are missing. Please download them first.${NC}"
exit 1
fi
}
# Function to create output directory
prepare_output_directory() {
print_section "Preparing Output Directory"
mkdir -p "${OUTPUT_DIR}"
mkdir -p "${OUTPUT_DIR}/logs"
mkdir -p "${OUTPUT_DIR}/checkpoints"
mkdir -p "${OUTPUT_DIR}/plots"
echo -e "${GREEN}✓ Output directory prepared: ${OUTPUT_DIR}${NC}"
# Initialize log file
cat > "${LOG_FILE}" <<EOF
PPO Comprehensive Hyperparameter Tuning Log
Started: $(date)
Configuration: ${TUNING_CONFIG}
Model Type: ${MODEL_TYPE}
Number of Trials: ${NUM_TRIALS}
Max Epochs per Trial: ${MAX_EPOCHS_PER_TRIAL}
Validation Symbols: ${SYMBOLS[*]}
GPU Enabled: ${USE_GPU}
Baseline: Epoch 380 (expl_var=0.4469)
Objective: 0.7 * sharpe_ratio + 0.3 * explained_variance
═══════════════════════════════════════════════════════════
EOF
echo -e "${GREEN}✓ Log file initialized: ${LOG_FILE}${NC}"
}
# Function to display search space summary
display_search_space() {
print_section "Search Space Configuration"
echo "Hyperparameters to optimize:"
echo " • Learning Rate: [0.0001, 0.0003, 0.001] (3 choices)"
echo " • Batch Size: [32, 64, 128, 256] (4 choices)"
echo " • Gamma: [0.95, 0.99] (2 choices)"
echo " • GAE Lambda: [0.9, 0.95, 0.98] (3 choices)"
echo " • Clip Epsilon: [0.1, 0.2, 0.3] (3 choices)"
echo " • Entropy Coefficient: [0.001, 0.01, 0.1] (3 choices)"
echo ""
echo "Total combinations: 3 × 4 × 2 × 3 × 3 × 3 = 648 possible configurations"
echo "Sampling strategy: TPE (Tree-structured Parzen Estimator)"
echo "Number of trials: ${NUM_TRIALS} (intelligent sampling)"
echo ""
echo "Fixed parameters:"
echo " • Policy network: [128, 64]"
echo " • Value network: [128, 64]"
echo " • Value loss coef: 1.0"
echo " • Rollout steps: 2048"
echo " • Mini-batch size: 64"
echo " • PPO epochs: 10"
echo " • Max grad norm: 0.5"
}
# Function to display objective function
display_objective() {
print_section "Objective Function"
echo "Combined objective: 0.7 × Sharpe Ratio + 0.3 × Explained Variance"
echo ""
echo "Rationale:"
echo " • Sharpe Ratio (70%): Primary metric for risk-adjusted returns"
echo " • Explained Variance (30%): Value network accuracy (critical for PPO)"
echo ""
echo "Baseline (Epoch 380):"
echo " • Explained Variance: 0.4469 (only 0.0531 from optimal 0.5)"
echo " • Sharpe Ratio: To be measured during tuning"
echo ""
echo "Target: Improve combined objective by >5% over baseline"
}
# Function to start tuning via TLI
start_tuning_job() {
print_section "Starting Hyperparameter Tuning"
echo "Initiating tuning job via TLI..."
echo "Command: tli tune start --model ${MODEL_TYPE} --trials ${NUM_TRIALS} --config ${TUNING_CONFIG}"
echo ""
# Start tuning job and capture job ID
local job_output
job_output=$(cargo run -p tli -- tune start \
--model "${MODEL_TYPE}" \
--trials "${NUM_TRIALS}" \
--config "${TUNING_CONFIG}" 2>&1)
# Extract job ID from output
local job_id
job_id=$(echo "${job_output}" | grep -oP 'Job ID: \K[a-f0-9-]+' || echo "")
if [ -z "${job_id}" ]; then
echo -e "${RED}✗ Failed to start tuning job${NC}"
echo "${job_output}"
exit 1
fi
echo -e "${GREEN}✓ Tuning job started successfully${NC}"
echo -e "Job ID: ${BLUE}${job_id}${NC}"
echo "${job_id}" > "${OUTPUT_DIR}/job_id.txt"
echo "${job_output}" >> "${LOG_FILE}"
echo "" >> "${LOG_FILE}"
echo "${job_id}"
}
# Function to monitor tuning progress
monitor_tuning_progress() {
local job_id=$1
print_section "Monitoring Tuning Progress"
echo "Job ID: ${job_id}"
echo "Press Ctrl+C to stop monitoring (tuning will continue in background)"
echo ""
local trial_count=0
local start_time=$(date +%s)
while true; do
# Get job status
local status_output
status_output=$(cargo run -p tli -- tune status --job-id "${job_id}" 2>&1 || true)
# Extract current trial number
local current_trial
current_trial=$(echo "${status_output}" | grep -oP 'Trial \K\d+' | tail -1 || echo "0")
# Extract status
local status
status=$(echo "${status_output}" | grep -oP 'Status: \K\w+' || echo "Unknown")
# Display progress bar
local progress=$((current_trial * 100 / NUM_TRIALS))
local filled=$((progress / 2))
local empty=$((50 - filled))
printf "\rProgress: ["
printf "%${filled}s" | tr ' ' '='
printf "%${empty}s" | tr ' ' ' '
printf "] %3d%% (%d/%d trials)" "${progress}" "${current_trial}" "${NUM_TRIALS}"
# Check if completed
if [[ "${status}" == "Completed" ]] || [[ "${status}" == "Failed" ]]; then
echo ""
echo ""
echo -e "${GREEN}Tuning job ${status}${NC}"
break
fi
# Periodic status log
if (( current_trial > trial_count )); then
trial_count=${current_trial}
local elapsed=$(($(date +%s) - start_time))
local avg_time_per_trial=$((elapsed / trial_count))
local remaining_trials=$((NUM_TRIALS - trial_count))
local eta=$((avg_time_per_trial * remaining_trials))
{
echo "Trial ${trial_count}/${NUM_TRIALS} completed"
echo " Elapsed: $(date -d@${elapsed} -u +%H:%M:%S)"
echo " ETA: $(date -d@${eta} -u +%H:%M:%S)"
echo ""
} >> "${LOG_FILE}"
fi
sleep 10
done
# Log final status
echo "" >> "${LOG_FILE}"
echo "Tuning completed at: $(date)" >> "${LOG_FILE}"
echo "" >> "${LOG_FILE}"
}
# Function to retrieve best hyperparameters
retrieve_best_hyperparameters() {
local job_id=$1
print_section "Retrieving Best Hyperparameters"
local best_output
best_output=$(cargo run -p tli -- tune best --job-id "${job_id}" 2>&1)
echo "${best_output}"
echo "" >> "${LOG_FILE}"
echo "═══ Best Hyperparameters ═══" >> "${LOG_FILE}"
echo "${best_output}" >> "${LOG_FILE}"
echo "" >> "${LOG_FILE}"
# Save best params to file
echo "${best_output}" > "${OUTPUT_DIR}/best_hyperparameters.txt"
}
# Function to compare with baseline
compare_with_baseline() {
print_section "Baseline Comparison"
echo "Baseline (Epoch 380 from Agent 79 analysis):"
echo " • Explained Variance: 0.4469"
echo " • Distance from optimal: 0.0531"
echo " • Training duration: 5.6 minutes (338.7 seconds)"
echo " • Checkpoint: ${BASELINE_CHECKPOINT}"
echo ""
echo "Check the best hyperparameters output above for tuning results."
echo ""
{
echo "═══ Baseline Comparison ═══"
echo "Baseline: Epoch 380"
echo " Explained Variance: 0.4469"
echo " Distance from optimal: 0.0531"
echo ""
echo "Tuning results saved to: ${OUTPUT_DIR}/best_hyperparameters.txt"
} >> "${LOG_FILE}"
}
# Function to generate summary report
generate_summary_report() {
print_section "Generating Summary Report"
local report_file="${OUTPUT_DIR}/TUNING_SUMMARY_REPORT.md"
cat > "${report_file}" <<EOF
# PPO Comprehensive Hyperparameter Tuning - Summary Report
**Generated**: $(date)
**Job ID**: $(cat "${OUTPUT_DIR}/job_id.txt" 2>/dev/null || echo "N/A")
**Configuration**: ${TUNING_CONFIG}
---
## Tuning Configuration
- **Model Type**: ${MODEL_TYPE}
- **Number of Trials**: ${NUM_TRIALS}
- **Max Epochs per Trial**: ${MAX_EPOCHS_PER_TRIAL}
- **Early Stopping**: Enabled (epoch 50)
- **GPU**: ${USE_GPU}
- **Validation Symbols**: ${SYMBOLS[*]}
## Search Space
| Hyperparameter | Search Space | Type |
|----------------|--------------|------|
| Learning Rate | [0.0001, 0.0003, 0.001] | Categorical |
| Batch Size | [32, 64, 128, 256] | Categorical |
| Gamma | [0.95, 0.99] | Categorical |
| GAE Lambda | [0.9, 0.95, 0.98] | Categorical |
| Clip Epsilon | [0.1, 0.2, 0.3] | Categorical |
| Entropy Coefficient | [0.001, 0.01, 0.1] | Categorical |
**Total Combinations**: 648 (intelligent sampling via TPE)
## Objective Function
\`\`\`
Combined Objective = 0.7 × Sharpe Ratio + 0.3 × Explained Variance
\`\`\`
### Rationale
- **Sharpe Ratio (70%)**: Primary metric for risk-adjusted returns
- **Explained Variance (30%)**: Critical for PPO value network accuracy
## Baseline Performance
- **Source**: Agent 79 checkpoint analysis
- **Checkpoint**: Epoch 380
- **Explained Variance**: 0.4469
- **Distance from Optimal (0.5)**: 0.0531
- **Status**: EXCELLENT (within 5% of theoretical optimal)
## Best Hyperparameters
\`\`\`
$(cat "${OUTPUT_DIR}/best_hyperparameters.txt" 2>/dev/null || echo "Not available - check tuning job status")
\`\`\`
## Value Network Convergence Analysis
### Focus Areas
1. **Explained Variance Trajectory**: Monitor convergence across trials
2. **Policy Stability**: Ensure KL divergence remains healthy
3. **Loss Dynamics**: Track policy loss and value loss evolution
4. **Entropy Decay**: Verify exploration-exploitation balance
### Expected Improvements
- Target: >5% improvement in combined objective over baseline
- Explained variance: Approach 0.47+ (vs 0.4469 baseline)
- Sharpe ratio: Measure risk-adjusted performance across all symbols
## Next Steps
1. **Validation**: Run comprehensive backtest with best hyperparameters
2. **Cross-symbol Analysis**: Compare performance across 6E, ZN, ES, NQ
3. **Production Training**: Execute 500-epoch training with optimized hyperparameters
4. **Checkpoint Analysis**: Identify optimal checkpoint (may not be final epoch)
## Files Generated
- **Tuning Log**: ${LOG_FILE}
- **Best Hyperparameters**: ${OUTPUT_DIR}/best_hyperparameters.txt
- **Checkpoints**: ${OUTPUT_DIR}/checkpoints/
- **Plots**: ${OUTPUT_DIR}/plots/ (if generated)
- **This Report**: ${report_file}
---
**Mission Status**: ✅ COMPLETE
**Ready for**: Production training with optimized hyperparameters
EOF
echo -e "${GREEN}✓ Summary report generated: ${report_file}${NC}"
}
# Function to display completion summary
display_completion_summary() {
print_section "Tuning Complete"
local elapsed=$(($(date +%s) - SCRIPT_START_TIME))
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ PPO Hyperparameter Tuning Completed Successfully ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "Duration: $(date -d@${elapsed} -u +%H:%M:%S)"
echo "Trials: ${NUM_TRIALS}"
echo "Output: ${OUTPUT_DIR}"
echo ""
echo "Next steps:"
echo " 1. Review best hyperparameters in: ${OUTPUT_DIR}/best_hyperparameters.txt"
echo " 2. Compare with baseline (Epoch 380)"
echo " 3. Run production training with optimized hyperparameters"
echo " 4. Perform checkpoint analysis to find optimal epoch"
echo ""
echo -e "${BLUE}Full summary report: ${OUTPUT_DIR}/TUNING_SUMMARY_REPORT.md${NC}"
}
# Main execution
main() {
SCRIPT_START_TIME=$(date +%s)
# Execute tuning workflow
check_prerequisites
prepare_output_directory
display_search_space
display_objective
# Start tuning job
local job_id
job_id=$(start_tuning_job)
# Monitor progress
monitor_tuning_progress "${job_id}"
# Retrieve results
retrieve_best_hyperparameters "${job_id}"
compare_with_baseline
# Generate reports
generate_summary_report
display_completion_summary
}
# Run main function
main "$@"