harb/onchain/analysis/run-bullbear-sweep.sh

127 lines
5.3 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
set -euo pipefail
# Bull->Bear Parameter Sweep
# Usage: ./analysis/run-bullbear-sweep.sh [--help] [mode]
show_help() {
cat <<'EOF'
Usage: ./analysis/run-bullbear-sweep.sh [--help] [mode]
Run a deterministic bull->bear parameter sweep using BullBearSweep.s.sol.
Each parameter combo runs: 10 buys (bull) -> sell all (bear) -> measure trader PnL.
Modes:
quick 27 combos (~2 min)3 CI x 3 AS x 3 AW x 1 DD
standard 225 combos (~15 min)5 CI x 5 AS x 3 AW x 3 DD (default)
fine 375 combos (~25 min)5 CI x 5 AS x 5 AW x 3 DD
full 1050 combos (~70 min)10 CI x 7 AS x 5 AW x 3 DD (comprehensive 4D)
focused 42 combos (~3 min)1 CI x 7 AS x 6 AW x 1 DD (best region)
Output: analysis/sweep-BULLBEAR-summary.csv
Environment variable overrides (applied after mode defaults):
BULL_BUYS, BUY_SIZE_ETH, LM_FUNDING_ETH, SWEEP_TAG,
CI_VALUES, AS_VALUES, AW_VALUES, DD_VALUES
Examples:
./analysis/run-bullbear-sweep.sh quick
./analysis/run-bullbear-sweep.sh standard
BULL_BUYS=20 ./analysis/run-bullbear-sweep.sh standard
EOF
exit 0
}
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
show_help
fi
cd "$(dirname "$0")/.."
MODE="${1:-standard}"
case "$MODE" in
quick)
echo "=== QUICK MODE: 27 combos ==="
export CI_VALUES="${CI_VALUES:-0,500000000000000000,1000000000000000000}"
export AS_VALUES="${AS_VALUES:-100000000000000000,500000000000000000,1000000000000000000}"
export AW_VALUES="${AW_VALUES:-20,50,80}"
export DD_VALUES="${DD_VALUES:-500000000000000000}"
export BULL_BUYS="${BULL_BUYS:-10}"
export BUY_SIZE_ETH="${BUY_SIZE_ETH:-15}"
;;
standard)
echo "=== STANDARD MODE: 225 combos ==="
export CI_VALUES="${CI_VALUES:-0,300000000000000000,500000000000000000,800000000000000000,1000000000000000000}"
export AS_VALUES="${AS_VALUES:-100000000000000000,300000000000000000,500000000000000000,700000000000000000,1000000000000000000}"
export AW_VALUES="${AW_VALUES:-20,50,80}"
export DD_VALUES="${DD_VALUES:-200000000000000000,500000000000000000,1000000000000000000}"
export BULL_BUYS="${BULL_BUYS:-10}"
export BUY_SIZE_ETH="${BUY_SIZE_ETH:-15}"
;;
fine)
echo "=== FINE MODE: 375 combos ==="
export CI_VALUES="${CI_VALUES:-0,200000000000000000,400000000000000000,600000000000000000,800000000000000000}"
export AS_VALUES="${AS_VALUES:-100000000000000000,200000000000000000,300000000000000000,500000000000000000,1000000000000000000}"
export AW_VALUES="${AW_VALUES:-20,40,60,80,100}"
export DD_VALUES="${DD_VALUES:-200000000000000000,500000000000000000,1000000000000000000}"
export BULL_BUYS="${BULL_BUYS:-10}"
export BUY_SIZE_ETH="${BUY_SIZE_ETH:-15}"
;;
full)
echo "=== FULL MODE: 1050 combos (comprehensive 4D sweep) ==="
# 10 CI values (0-100% in ~10% steps) x 7 AS x 5 AW x 3 DD
# Fine CI resolution to precisely map safe/unsafe boundary
export CI_VALUES="${CI_VALUES:-0,100000000000000000,200000000000000000,300000000000000000,400000000000000000,500000000000000000,600000000000000000,700000000000000000,800000000000000000,1000000000000000000}"
export AS_VALUES="${AS_VALUES:-100000000000000000,200000000000000000,300000000000000000,400000000000000000,500000000000000000,700000000000000000,1000000000000000000}"
export AW_VALUES="${AW_VALUES:-20,40,60,80,100}"
export DD_VALUES="${DD_VALUES:-200000000000000000,500000000000000000,1000000000000000000}"
export BULL_BUYS="${BULL_BUYS:-10}"
export BUY_SIZE_ETH="${BUY_SIZE_ETH:-15}"
;;
focused)
echo "=== FOCUSED MODE: 42 combos (best region) ==="
# Fine-grained sweep around the optimal AS=5-35%, AW=50-100 region
# CI fixed at 50% (confirmed zero effect with ratchet), DD fixed at 50%
export CI_VALUES="${CI_VALUES:-500000000000000000}"
export AS_VALUES="${AS_VALUES:-50000000000000000,100000000000000000,150000000000000000,200000000000000000,250000000000000000,300000000000000000,350000000000000000}"
export AW_VALUES="${AW_VALUES:-50,60,70,80,90,100}"
export DD_VALUES="${DD_VALUES:-500000000000000000}"
export BULL_BUYS="${BULL_BUYS:-10}"
export BUY_SIZE_ETH="${BUY_SIZE_ETH:-15}"
;;
*)
echo "Unknown mode: $MODE"
echo "Use: quick, standard, fine, full, focused (or --help)"
exit 1
;;
esac
export SWEEP_TAG="${SWEEP_TAG:-BULLBEAR}"
export LM_FUNDING_ETH="${LM_FUNDING_ETH:-200}"
echo "Running sweep..."
forge script analysis/BullBearSweep.s.sol --skip-simulation --gas-limit 18446744073709551615 2>&1 | tee /tmp/bullbear-sweep.log
echo ""
echo "=== Results ==="
RESULTS="analysis/sweep-${SWEEP_TAG}-summary.csv"
if [ -f "$RESULTS" ]; then
TOTAL=$(tail -n +2 "$RESULTS" | wc -l)
UNSAFE=$(tail -n +2 "$RESULTS" | awk -F',' '{if ($5+0 > 0) print}' | wc -l || true)
echo "Total combos: $TOTAL"
echo "Unsafe (trader profit): $UNSAFE"
echo ""
echo "Top 10 safest (most trader loss = most LM gain):"
tail -n +2 "$RESULTS" | sort -t',' -k5 -n | head -10
echo ""
echo "Bottom 10 (least trader loss):"
tail -n +2 "$RESULTS" | sort -t',' -k5 -n -r | head -10
echo ""
echo "Lowest drawdown (most stable during bear):"
tail -n +2 "$RESULTS" | sort -t',' -k13 -n | head -10
echo ""
echo "Top 10 by fee revenue (WETH fees total, descending):"
tail -n +2 "$RESULTS" | sort -t',' -k18 -n -r | head -10
fi