hyperopt 需要携带两个日期参数,类似: '2025-06-02 08:00' '2025-06-04 08:00'

This commit is contained in:
zhangkun9038@dingtalk.com 2025-08-08 21:53:23 +08:00
parent 3a04501be6
commit da6d3fe292

View File

@ -4,10 +4,10 @@
if [ ! -f ".env" ]; then
echo "⚠️ 本地缺少 .env 文件,请创建并配置。示例内容如下:"
echo ""
echo "STRATEGY_NAME=FreqaiPrimer"
echo "CONFIG_FILE=FreqaiPrimer.json"
echo "TEST_BRANCH=freqaiprimer-deviation-test"
echo "DRYRUN_BRANCH=freqaiprimer-deviation-dryrun"
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
@ -15,101 +15,258 @@ fi
# 加载 .env 文件中的变量
export $(grep -v '^#' .env | xargs)
# 设置默认值
STRATEGY_NAME=${STRATEGY_NAME:-FreqaiPrimer}
CONFIG_FILE=${CONFIG_FILE:-FreqaiPrimer.json}
PARAMS_NAME=$(echo "$STRATEGY_NAME" | tr '[:upper:]' '[:lower:]')
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"
# Parse command line arguments
START_DATE=${1:-$(date -d "2 days ago" +"%Y%m%d")}
END_DATE=${2:-$(date -d "tomorrow" +"%Y%m%d")}
# Parse command line arguments
START_DATE_RAW=${1:-$(date -d "2 days ago" +"%Y-%m-%d %H:%M:%S")}
END_DATE_RAW=${2:-$(date -d "tomorrow" +"%Y-%m-%d %H:%M:%S")}
# Parse command line arguments
START_DATE_RAW=${1:-$(date -d "2 days ago" +"%Y-%m-%d 00:00")}
END_DATE_RAW=${2:-$(date -d "today" +"%Y-%m-%d 00:00")}
# Function to extract the value of a parameter
get_param_value() {
local param="$1"
shift
local args=("$@")
local i=0
# Convert raw date strings to timestamps
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" "$@")
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"
else
echo "Warning: Third parameter '$THIRD_PARAM' is neither a URL nor a pair"
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
START_DATE=$(date -d "${START_DATE_RAW} 00:00:00" +"%s")
# 兼容旧格式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} 00:00:00" +"%s")
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
echo "Start timestamp: $START_TIMESTAMP"
echo "End timestamp: $END_TIMESTAMP"
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/*
#docker-compose -f docker-compose_backtest.yml run --rm freqtrade >output.log 2>&1
echo "docker-compose run --rm freqtrade hyperopt \
hyperopt_config="${STRATEGY_NAME%.py}.json"
echo "docker-compose run --rm freqtrade backtesting $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 \
--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 \
--strategy $STRATEGY_NAME \
--timerange $START_DATE-$END_DATE \
--fee 0.0008 \
--breakdown day \
--cache none >output.log"
docker-compose run --rm freqtrade backtesting $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 \
--strategy-path /freqtrade/templates \
--timerange ${START_DATE}-${END_DATE} \
-e 100 \
-j 4 \
--hyperopt-loss SharpeHyperOptLoss \
--spaces buy sell trailing \
--fee 0.0016
--strategy $STRATEGY_NAME \
--timerange $START_DATE-$END_DATE \
--fee 0.0008 \
--breakdown day \
--cache none >output.log 2>&1
#>output.log 2>&1
#sed -i 's/\x1B\[[0-9;]*m//g' output.log
sed -i 's/\x1B\[[0-9;]*m//g' output.log
#python3 tools/filter.py
rm ./result/*.json -fr
rm ./result/*.py -fr
mv ./user_data/backtest_results/* ./result/
# rm ./result/*.json -fr
# rm ./result/*.py -fr
# mv ./user_data/backtest_results/* ./result/
#
# cd ./result
# # 查找当前目录下的所有 zip 文件
# zip_files=(*.zip)
#
# # 检查是否只有一个 zip 文件
# if [ ${#zip_files[@]} -eq 1 ]; then
# # 解压缩该 zip 文件到当前目录
# unzip "${zip_files[0]}"
# rm *.zip
# rm *.feather
# else
# echo "当前目录下没有 zip 文件或者有多个 zip 文件,无法操作。"
# fi
#
# cd -
# sed -i 's/\x1B\[[0-9;]*m//g' output.log
# #python3 ../filter.py
# cp output.log result/ -f
# cd tools/
# python tradestocsv.py
# python analytic.py >../result/analytic.log
# cd ../
cd ./result
# 查找当前目录下的所有 zip 文件
zip_files=(*.zip)
# 检查是否只有一个 zip 文件
if [ ${#zip_files[@]} -eq 1 ]; then
# 解压缩该 zip 文件到当前目录
unzip "${zip_files[0]}"
rm *.zip
rm *.feather
else
echo "当前目录下没有 zip 文件或者有多个 zip 文件,无法操作。"
fi
cd -
sed -i 's/\x1B\[[0-9;]*m//g' output.log
cp output.log result/ -f
cd tools/
python tradestocsv.py
python analytic.py >../result/analytic.log
cd ../