myTestFreqAI/tools/hyperopt.sh
2025-10-14 00:32:28 +08:00

266 lines
8.9 KiB
Bash
Executable File
Raw Permalink 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
# 检查 .env 文件
if [ ! -f ".env" ]; then
echo "⚠️ 本地缺少 .env 文件,请创建并配置。示例内容如下:"
echo ""
echo "STRATEGY_NAME=TheForceV7"
echo "CONFIG_FILE=basic.json"
echo "TEST_BRANCH=theforce-noai-test"
echo "DRYRUN_BRANCH=theforce-noai-dryrun"
echo ""
exit 1
fi
# 加载 .env 文件中的变量
export $(grep -v '^#' .env | xargs)
# 设置默认值
STRATEGY_NAME=${STRATEGY_NAME:-TheForceV7}
CONFIG_FILE=${CONFIG_FILE:-basic.json}
echo "Using strategy: $STRATEGY_NAME"
echo "Using config: $CONFIG_FILE"
echo "Using testBranch: $TEST_BRANCH"
# Function to extract the value of a parameter
get_param_value() {
local param="$1"
shift
local args=("$@")
local i=0
while [ $i -lt ${#args[@]} ]; do
case "${args[$i]}" in
$param=*)
echo "${args[$i]#*=}"
return 0
;;
$param)
# Check if the next argument exists and does not start with a dash
if [ $((i + 1)) -lt ${#args[@]} ] && [[ "${args[$((i + 1))]}" != -* ]]; then
echo "${args[$((i + 1))]}"
return 0
else
echo "Error: Missing value for parameter $param" >&2
exit 1
fi
;;
esac
i=$((i + 1))
done
return 0
}
# Check if we have named parameters
HAS_NAMED_PARAMS=false
for arg in "$@"; do
if [[ "$arg" == --* ]]; then
HAS_NAMED_PARAMS=true
break
fi
done
# Initialize variables
START_DATE_RAW=""
END_DATE_RAW=""
PAIRS_ARG=""
PAIR_REMOTE_LIST_URL=""
# Parse parameters based on whether we have named parameters
if [ "$HAS_NAMED_PARAMS" = true ]; then
# Use named parameter parsing
START_DATE_RAW=$(get_param_value "--start-date" "$@")
END_DATE_RAW=$(get_param_value "--end-date" "$@")
PAIRS_ARG=$(get_param_value "--pairs" "$@")
PAIR_REMOTE_LIST_URL=$(get_param_value "--pairRemoteList" "$@")
STRATEGY_ARG=$(get_param_value "--strategy" "$@")
# 支持 -t 作为 --strategy 的简化参数
if [ -z "$STRATEGY_ARG" ]; then
STRATEGY_ARG=$(get_param_value "-t" "$@")
fi
else
# Use positional parameter parsing
if [ $# -gt 0 ]; then
START_DATE_RAW="$1"
fi
if [ $# -gt 1 ]; then
END_DATE_RAW="$2"
fi
if [ $# -gt 2 ]; then
THIRD_PARAM="$3"
# Check if it's a URL
if [[ "$THIRD_PARAM" == http://* ]] || [[ "$THIRD_PARAM" == https://* ]]; then
PAIR_REMOTE_LIST_URL="$THIRD_PARAM"
echo "Detected URL parameter: $PAIR_REMOTE_LIST_URL"
# Check if it's a pair like "*/USDT"
elif [[ "$THIRD_PARAM" == */USDT ]] || [[ "$THIRD_PARAM" == */BUSD ]] || [[ "$THIRD_PARAM" == */USDC ]]; then
PAIRS_ARG="$THIRD_PARAM"
echo "Detected pair parameter: $PAIRS_ARG"
# Check if it's a strategy name
elif [[ "$THIRD_PARAM" =~ ^[a-zA-Z0-9]+$ ]]; then
STRATEGY_ARG="$THIRD_PARAM"
echo "Detected strategy parameter: $STRATEGY_ARG"
else
echo "Warning: Third parameter '$THIRD_PARAM' is neither a URL nor a pair nor a strategy"
fi
fi
fi
# Set default values if parameters not provided
if [ -z "$START_DATE_RAW" ]; then
START_DATE_RAW=$(date -d "2 days ago" +"%Y-%m-%d %H:%M:%S")
fi
if [ -z "$END_DATE_RAW" ]; then
END_DATE_RAW=$(date -d "tomorrow" +"%Y-%m-%d %H:%M:%S")
fi
# Parse dates
if [[ "$START_DATE_RAW" == *" "* ]]; then
START_DATE=$(date -d "$START_DATE_RAW" +"%s")
else
# 兼容旧格式20250616 -> 转换为 2025-06-16 00:00:00 再转为时间戳
START_DATE=$(date -d "${START_DATE_RAW:0:4}-${START_DATE_RAW:4:2}-${START_DATE_RAW:6:2} 00:00:00" +"%s")
fi
if [[ "$END_DATE_RAW" == *" "* ]]; then
END_DATE=$(date -d "$END_DATE_RAW" +"%s")
else
END_DATE=$(date -d "${END_DATE_RAW:0:4}-${END_DATE_RAW:4:2}-${END_DATE_RAW:6:2} 00:00:00" +"%s")
fi
# Format end_date for URL parameter (YYYY-MM-DD format)
END_DATE_FORMATTED=$(date -d "@$END_DATE" "+%Y-%m-%d")
# 处理交易对参数:优先级为 --pairRemoteList > --pairs > 默认值
if [ -n "$PAIR_REMOTE_LIST_URL" ]; then
# 从远程API获取交易对列表
echo "Fetching pairs from remote URL: $PAIR_REMOTE_LIST_URL"
pairs_json=$(curl -s "$PAIR_REMOTE_LIST_URL")
# 检查API响应是否成功
if [[ $? -ne 0 || -z "$pairs_json" ]]; then
echo "Error: Failed to fetch pairs from remote URL, using --pairs parameter or default"
if [ -n "$PAIRS_ARG" ]; then
PAIRS_FLAG="--pairs $PAIRS_ARG"
echo "Using pairs from --pairs parameter: $PAIRS_ARG"
else
# 使用默认的交易对列表
DEFAULT_PAIRS="BTC/USDT TON/USDT DOT/USDT XRP/USDT OKB/USDT SOL/USDT DOGE/USDT WCT/USDT TRUMP/USDT SUI/USDT PEPE/USDT TRB/USDT MASK/USDT UNI/USDT KAITO/USDT"
PAIRS_FLAG="--pairs $DEFAULT_PAIRS"
echo "Using default pairs: $DEFAULT_PAIRS"
fi
else
# 解析JSON并提取交易对将连字符替换为斜杠
remote_pairs=$(echo "$pairs_json" | python3 -c "
import sys, json
data = json.load(sys.stdin)
pairs = [pair.replace('-', '/') for pair in data.get('pairlist', [])]
print(' '.join(pairs) if pairs else '')
")
# 如果解析成功且有交易对
if [[ -n "$remote_pairs" ]]; then
PAIRS_FLAG="--pairs $remote_pairs"
echo "Successfully fetched $(echo "$remote_pairs" | wc -w) pairs from remote URL"
echo "Pairs: $remote_pairs"
else
echo "Error: Failed to parse or empty pairlist from remote URL, using --pairs parameter or default"
if [ -n "$PAIRS_ARG" ]; then
PAIRS_FLAG="--pairs $PAIRS_ARG"
echo "Using pairs from --pairs parameter: $PAIRS_ARG"
else
# 使用默认的交易对列表
DEFAULT_PAIRS="BTC/USDT TON/USDT DOT/USDT XRP/USDT OKB/USDT SOL/USDT DOGE/USDT WCT/USDT TRUMP/USDT SUI/USDT PEPE/USDT TRB/USDT MASK/USDT UNI/USDT KAITO/USDT"
PAIRS_FLAG="--pairs $DEFAULT_PAIRS"
echo "Using default pairs: $DEFAULT_PAIRS"
fi
fi
fi
elif [ -n "$PAIRS_ARG" ]; then
# 使用 --pairs 参数提供的交易对
PAIRS_FLAG="--pairs $PAIRS_ARG"
echo "Using pairs from --pairs parameter: $PAIRS_ARG"
echo "Number of pairs: $(echo "$PAIRS_ARG" | wc -w)"
else
# 优先从指定URL获取交易对列表
echo "Fetching pairs from primary URL with date parameter..."
PRIMARY_URL="http://pairlist.xl.home/api/pairlist?mute=true&count=30&date=${END_DATE_FORMATTED}"
echo "Requesting: $PRIMARY_URL"
pairs_json=$(curl -s "$PRIMARY_URL")
# 检查API响应是否成功
if [[ $? -ne 0 || -z "$pairs_json" ]]; then
echo "Error: Failed to fetch pairs from primary URL, using default pairs"
# 使用默认的交易对列表
DEFAULT_PAIRS="BTC/USDT TON/USDT DOT/USDT XRP/USDT OKB/USDT SOL/USDT DOGE/USDT WCT/USDT TRUMP/USDT SUI/USDT PEPE/USDT TRB/USDT MASK/USDT UNI/USDT KAITO/USDT"
PAIRS_FLAG="--pairs $DEFAULT_PAIRS"
echo "Using default pairs: $DEFAULT_PAIRS"
else
# 解析JSON并提取交易对将连字符替换为斜杠
remote_pairs=$(echo "$pairs_json" | python3 -c "
import sys, json
data = json.load(sys.stdin)
pairs = [pair.replace('-', '/') for pair in data.get('pairlist', [])]
print(' '.join(pairs) if pairs else '')
")
# 如果解析成功且有交易对
if [[ -n "$remote_pairs" ]]; then
PAIRS_FLAG="--pairs $remote_pairs"
echo "Successfully fetched $(echo "$remote_pairs" | wc -w) pairs from primary URL"
echo "Pairs: $remote_pairs"
else
echo "Error: Failed to parse or empty pairlist from primary URL, using default pairs"
# 使用默认的交易对列表
DEFAULT_PAIRS="BTC/USDT TON/USDT DOT/USDT XRP/USDT OKB/USDT SOL/USDT DOGE/USDT WCT/USDT TRUMP/USDT SUI/USDT PEPE/USDT TRB/USDT MASK/USDT UNI/USDT KAITO/USDT"
PAIRS_FLAG="--pairs $DEFAULT_PAIRS"
echo "Using default pairs: $DEFAULT_PAIRS"
fi
fi
fi
# 如果命令行提供了策略参数,覆盖 .env 文件中的设置
if [ -n "$STRATEGY_ARG" ]; then
STRATEGY_NAME="$STRATEGY_ARG"
echo "Overriding strategy from command line: $STRATEGY_NAME"
fi
cd ../
source .venv/bin/activate
rm -rf user_data/models/*
rm -rf ./freqtrade/user_data/data/backtest_results/*
rm -fr ./user_data/dryrun_results/*
rm result/*
PARAMS_NAME=freqaiprimer
hyperopt_config="${STRATEGY_NAME%.py}.json"
echo "docker-compose run --rm freqtrade hyperopt $PAIRS_FLAG \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--freqaimodel LightGBMRegressorMultiTarget \
--strategy $STRATEGY_NAME \
--config /freqtrade/config_examples/$CONFIG_FILE \
--config /freqtrade/templates/${PARAMS_NAME}.json \
--enable-protections \
--strategy-path /freqtrade/templates \
--timerange ${START_DATE}-${END_DATE} \
-e 100 \
-j 4 \
--hyperopt-loss ShortTradeDurHyperOptLoss \
--spaces buy sell trailing \
--fee 0.0016"
docker-compose run --rm freqtrade hyperopt $PAIRS_FLAG \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--freqaimodel LightGBMRegressorMultiTarget \
--strategy $STRATEGY_NAME \
--config /freqtrade/config_examples/$CONFIG_FILE \
--config /freqtrade/templates/${PARAMS_NAME}.json \
--enable-protections \
--strategy-path /freqtrade/templates \
--timerange ${START_DATE}-${END_DATE} \
-e 500 \
-j 4 \
--hyperopt-loss SharpeHyperOptLossDaily \
--spaces buy sell \
--fee 0.0016