diff --git a/launchd/ai.tradingagent.caffeinate.plist b/launchd/ai.tradingagent.caffeinate.plist
new file mode 100644
index 0000000..de1bf6e
--- /dev/null
+++ b/launchd/ai.tradingagent.caffeinate.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ Label
+ ai.tradingagent.caffeinate
+
+ ProgramArguments
+
+ /usr/bin/caffeinate
+ -is
+ -t
+ 33000
+
+ StartCalendarInterval
+
+ Hour23
+ Minute56
+
+ StandardOutPath
+ /Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_caffeinate.log
+ StandardErrorPath
+ /Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_caffeinate.log
+
+
diff --git a/launchd/ai.tradingagent.market_open.plist b/launchd/ai.tradingagent.market_open.plist
new file mode 100644
index 0000000..9b5e194
--- /dev/null
+++ b/launchd/ai.tradingagent.market_open.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ Label
+ ai.tradingagent.market_open
+ ProgramArguments
+
+ /Users/aryan/Documents/GitHub/trading-agent/scripts/execute.sh
+
+
+ StartCalendarInterval
+
+ Hour8
+ Minute30
+
+ StandardOutPath
+ /Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_execution.log
+ StandardErrorPath
+ /Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_execution.log
+
+
diff --git a/launchd/ai.tradingagent.nightly.plist b/launchd/ai.tradingagent.nightly.plist
new file mode 100644
index 0000000..63f6afb
--- /dev/null
+++ b/launchd/ai.tradingagent.nightly.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ Label
+ ai.tradingagent.nightly
+ ProgramArguments
+
+ /Users/aryan/Documents/GitHub/trading-agent/scripts/nightly.sh
+
+
+ StartCalendarInterval
+
+ Hour0
+ Minute0
+
+ StandardOutPath
+ /Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_nightly.log
+ StandardErrorPath
+ /Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_nightly.log
+
+
diff --git a/scripts/execute.sh b/scripts/execute.sh
new file mode 100755
index 0000000..e293a69
--- /dev/null
+++ b/scripts/execute.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# launchd wrapper for the market-open execution (08:30 CT = 09:30 ET). Gated on Alpaca's clock.
+cd /Users/aryan/Documents/GitHub/trading-agent
+export PATH="/opt/homebrew/bin:$PATH"
+mkdir -p state/logs
+exec uv run python -m execution.run_market_open >> state/logs/launchd_execution.log 2>&1
diff --git a/scripts/install_launchd.sh b/scripts/install_launchd.sh
new file mode 100755
index 0000000..68a9766
--- /dev/null
+++ b/scripts/install_launchd.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+# Install the launchd jobs (caffeinate, nightly research, market-open execution).
+set -euo pipefail
+PROJ="/Users/aryan/Documents/GitHub/trading-agent"
+LA="$HOME/Library/LaunchAgents"
+mkdir -p "$LA" "$PROJ/state/logs"
+chmod +x "$PROJ/scripts/nightly.sh" "$PROJ/scripts/execute.sh"
+
+for p in caffeinate nightly market_open; do
+ cp "$PROJ/launchd/ai.tradingagent.$p.plist" "$LA/"
+ launchctl unload "$LA/ai.tradingagent.$p.plist" 2>/dev/null || true
+ launchctl load "$LA/ai.tradingagent.$p.plist"
+ echo "loaded ai.tradingagent.$p"
+done
+
+cat <<'EOF'
+
+── ONE-TIME MANUAL STEP (needs sudo) ─────────────────────────────
+Wake the Mac nightly at 23:55 CT so the 00:00 job can fire:
+
+ sudo pmset repeat wakeorpoweron MTWRFSU 23:55:00
+
+── REQUIREMENTS for overnight runs ───────────────────────────────
+ • plugged into AC power
+ • lid OPEN (caffeinate can't beat clamshell sleep on a laptop)
+ • logged in (lock screen is fine; logged out = jobs won't run)
+ • oMLX running with a model available (it auto-starts on login)
+ • .env populated with Alpaca paper + Finnhub keys
+──────────────────────────────────────────────────────────────────
+EOF
diff --git a/scripts/nightly.sh b/scripts/nightly.sh
new file mode 100755
index 0000000..5cea4d2
--- /dev/null
+++ b/scripts/nightly.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# launchd wrapper for the nightly research run (00:00 CT).
+cd /Users/aryan/Documents/GitHub/trading-agent
+export PATH="/opt/homebrew/bin:$PATH"
+mkdir -p state/logs
+exec uv run python -m orchestration.run_nightly >> state/logs/launchd_nightly.log 2>&1
diff --git a/scripts/run_dashboard.sh b/scripts/run_dashboard.sh
new file mode 100755
index 0000000..38c4f78
--- /dev/null
+++ b/scripts/run_dashboard.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+# Launch the local dashboard: uv run streamlit run web/dashboard.py
+set -euo pipefail
+cd "$(dirname "$0")/.."
+exec uv run streamlit run web/dashboard.py "$@"
diff --git a/scripts/uninstall_launchd.sh b/scripts/uninstall_launchd.sh
new file mode 100755
index 0000000..747edea
--- /dev/null
+++ b/scripts/uninstall_launchd.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+# Remove the launchd jobs and print how to clear the wake schedule.
+set -euo pipefail
+LA="$HOME/Library/LaunchAgents"
+for p in caffeinate nightly market_open; do
+ launchctl unload "$LA/ai.tradingagent.$p.plist" 2>/dev/null || true
+ rm -f "$LA/ai.tradingagent.$p.plist"
+ echo "removed ai.tradingagent.$p"
+done
+echo
+echo "Also clear the nightly wake schedule (needs sudo):"
+echo " sudo pmset repeat cancel"