Loading...
Loading...
Set up automated trading strategies — DCA, limit orders, and stop losses — by composing mp CLI commands with OS scheduling (cron/launchd).
npx skill4agent add moonpay/skills moonpay-trading-automationmpmp user retrievemp token balance list --wallet <name> --chain <chain>mpwhich mpjqwhich jq~/.config/moonpay/scripts/~/.config/moonpay/logs/trading.log#!/bin/bash
set -euo pipefail
MP="$(which mp)" # absolute path for cron/launchd
LOG="$HOME/.config/moonpay/logs/trading.log"
mkdir -p "$(dirname "$LOG")"
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" >> "$LOG"; }
# --- Config (agent fills these in) ---
WALLET="main"
CHAIN="solana"
FROM_TOKEN="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" # USDC
TO_TOKEN="So11111111111111111111111111111111111111111" # SOL
AMOUNT=5
# --- Execute ---
log "SWAP: $AMOUNT $FROM_TOKEN -> $TO_TOKEN on $CHAIN"
RESULT=$("$MP" -f compact token swap \
--wallet "$WALLET" --chain "$CHAIN" \
--from-token "$FROM_TOKEN" --from-amount "$AMOUNT" \
--to-token "$TO_TOKEN" 2>&1) || {
log "FAILED: $RESULT"
exit 1
}
log "OK: $RESULT"mp -f compactjq$(which mp)MPmpmp token search~/.config/moonpay/scripts/dca-sol.sh# Buy $5 of SOL daily at 9am UTC — moonpay:dca-sol
0 9 * * * ~/.config/moonpay/scripts/dca-sol.sh(crontab -l 2>/dev/null; echo '0 9 * * * ~/.config/moonpay/scripts/dca-sol.sh # moonpay:dca-sol') | crontab -0 * * * *0 */4 * * *0 9 * * *0 9 * * 1~/Library/LaunchAgents/com.moonpay.dca-sol.plist<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.moonpay.dca-sol</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/USERNAME/.config/moonpay/scripts/dca-sol.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardErrorPath</key>
<string>/Users/USERNAME/.config/moonpay/logs/dca-sol.err</string>
</dict>
</plist>launchctl load ~/Library/LaunchAgents/com.moonpay.dca-sol.plist~/Users/USERNAME/...echo $HOME~/.config/moonpay/scripts/limit-buy-sol.sh#!/bin/bash
set -euo pipefail
MP="$(which mp)"
LOG="$HOME/.config/moonpay/logs/trading.log"
mkdir -p "$(dirname "$LOG")"
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" >> "$LOG"; }
# --- Config ---
WALLET="main"
CHAIN="solana"
TOKEN="So11111111111111111111111111111111111111111"
BUY_WITH="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" # USDC
BUY_AMOUNT=50
TARGET_PRICE=80
SCRIPT_NAME="limit-buy-sol"
# --- Check price ---
PRICE=$("$MP" -f compact token retrieve --token "$TOKEN" --chain "$CHAIN" | jq -r '.marketData.price')
if [ -z "$PRICE" ] || [ "$PRICE" = "null" ]; then
log "LIMIT $SCRIPT_NAME: price fetch failed, skipping"
exit 0
fi
# --- Compare ---
if (( $(echo "$PRICE < $TARGET_PRICE" | bc -l) )); then
log "LIMIT $SCRIPT_NAME: price $PRICE < $TARGET_PRICE — executing buy"
RESULT=$("$MP" -f compact token swap \
--wallet "$WALLET" --chain "$CHAIN" \
--from-token "$BUY_WITH" --from-amount "$BUY_AMOUNT" \
--to-token "$TOKEN" 2>&1) || {
log "LIMIT $SCRIPT_NAME FAILED: $RESULT"
exit 1
}
log "LIMIT $SCRIPT_NAME OK: bought at $PRICE — $RESULT"
# Self-disable after fill
if [[ "$OSTYPE" == "darwin"* ]]; then
launchctl unload "$HOME/Library/LaunchAgents/com.moonpay.${SCRIPT_NAME}.plist" 2>/dev/null || true
else
crontab -l | grep -v "$SCRIPT_NAME" | crontab -
fi
log "LIMIT $SCRIPT_NAME: disabled after fill"
else
log "LIMIT $SCRIPT_NAME: price $PRICE >= $TARGET_PRICE — waiting"
fi*/5 * * * * ~/.config/moonpay/scripts/limit-buy-sol.sh # moonpay:limit-buy-sol<key>StartInterval</key><integer>300</integer>StartCalendarInterval# --- Config ---
SELL_TOKEN="So11111111111111111111111111111111111111111" # SOL
TO_TOKEN="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" # USDC
TRIGGER_PRICE=70
SCRIPT_NAME="stop-loss-sol"
# --- Check price ---
PRICE=$("$MP" -f compact token retrieve --token "$SELL_TOKEN" --chain "$CHAIN" | jq -r '.marketData.price')
if (( $(echo "$PRICE < $TRIGGER_PRICE" | bc -l) )); then
# Get current balance to sell all
BALANCE=$("$MP" -f compact token balance list --wallet "$WALLET" --chain "$CHAIN" \
| jq -r --arg addr "$SELL_TOKEN" '.items[] | select(.address == $addr) | .balance.amount')
if [ -n "$BALANCE" ] && (( $(echo "$BALANCE > 0" | bc -l) )); then
log "STOP-LOSS $SCRIPT_NAME: price $PRICE < $TRIGGER_PRICE — selling $BALANCE"
RESULT=$("$MP" -f compact token swap \
--wallet "$WALLET" --chain "$CHAIN" \
--from-token "$SELL_TOKEN" --from-amount "$BALANCE" \
--to-token "$TO_TOKEN" 2>&1) || {
log "STOP-LOSS $SCRIPT_NAME FAILED: $RESULT"
exit 1
}
log "STOP-LOSS $SCRIPT_NAME OK: sold at $PRICE — $RESULT"
# Self-disable (same pattern as limit order)
fi
fi# macOS
launchctl list | grep moonpay
# Linux
crontab -l | grep moonpay# macOS
launchctl unload ~/Library/LaunchAgents/com.moonpay.dca-sol.plist
rm ~/Library/LaunchAgents/com.moonpay.dca-sol.plist
# Linux
crontab -l | grep -v "moonpay:dca-sol" | crontab -tail -50 ~/.config/moonpay/logs/trading.loglaunchctl unload ~/Library/LaunchAgents/com.moonpay.dca-sol.plist # pause
launchctl load ~/Library/LaunchAgents/com.moonpay.dca-sol.plist # resumeif [[ "$OSTYPE" == "darwin"* ]]; then
# macOS: use launchd (fires even if machine was asleep)
else
# Linux: use crontab
fitail -20 ~/.config/moonpay/logs/trading.logmpmp token retrievebc -lbcawk "BEGIN {exit !($PRICE < $TARGET)}"# moonpay:{name}