./cover_params.sh 把hyperopt优化后的参数覆盖到策略文件中

This commit is contained in:
zhangkun9038@dingtalk.com 2025-10-19 19:18:34 +00:00
parent fed42d9d39
commit 6ce623824c
2 changed files with 377 additions and 18 deletions

View File

@ -81,39 +81,39 @@ class FreqaiPrimer(IStrategy):
timeframe = "3m" # 主时间框架为 3 分钟
can_short = False # 禁用做空
# 这两个就不优化了, 参数太多了
h1_max_consecutive_candles = IntParameter(1, 4, default=2, optimize=False, load=True, space='buy')
h1_max_consecutive_candles = IntParameter(1, 4, default=3, optimize=False, load=True, space='buy')
h1_max_candles = IntParameter(100, 300, default=200, optimize=False, load=True, space='buy')
# 第一步 buy 空间优化参数 7个:
# --- 趋势与信号生成 ---
bb_length = IntParameter(10, 30, default=20, optimize=True, load=True, space='buy')
bb_std = DecimalParameter(1.5, 3.0, decimals=1, default=2.0, optimize=True, load=True, space='buy')
rsi_length = IntParameter(7, 21, default=14, optimize=True, load=True, space='buy')
bb_length = IntParameter(10, 30, default=14, optimize=True, load=True, space='buy')
bb_std = DecimalParameter(1.5, 3.0, decimals=1, default=3, optimize=True, load=True, space='buy')
rsi_length = IntParameter(7, 21, default=16, optimize=True, load=True, space='buy')
# 入场条件阈值
bb_lower_deviation = DecimalParameter(1.01, 1.05, decimals=2, default=1.03, optimize=True, load=True, space='buy')
bb_lower_deviation = DecimalParameter(1.01, 1.05, decimals=2, default=1.05, optimize=True, load=True, space='buy')
rsi_oversold = IntParameter(30, 50, default=42, optimize=True, load=True, space='buy')
volume_multiplier = DecimalParameter(1.2, 2.0, decimals=1, default=1.5, optimize=True, load=True, space='buy')
bb_width_threshold = DecimalParameter(0.01, 0.03, decimals=3, default=0.02, optimize=True, load=True, space='buy')
volume_multiplier = DecimalParameter(1.2, 2.0, decimals=1, default=1.6, optimize=True, load=True, space='buy')
bb_width_threshold = DecimalParameter(0.01, 0.03, decimals=3, default=0.012, optimize=True, load=True, space='buy')
# 剧烈拉升检测参数 - 使用Hyperopt可优化参数
h1_rapid_rise_threshold = DecimalParameter(0.05, 0.15, decimals=3, default=0.11, optimize=True, load=True, space='buy')
h1_rapid_rise_threshold = DecimalParameter(0.05, 0.15, decimals=3, default=0.065, optimize=True, load=True, space='buy')
# 第二步 buy 空间优化参数 7个:
# --- 资金管理与加仓 ---
add_position_callback = DecimalParameter(0.03, 0.06, decimals=3, default=0.053, optimize=False, load=True, space='buy')
stake_divisor = DecimalParameter(2, 4, decimals=3, default=2.867, optimize=False, load=True, space='buy')
step_coefficient = DecimalParameter(0.5, 1.5, decimals=2, default=0.92, optimize=False, load=True, space='buy')
max_entry_adjustments = IntParameter(2, 5, default=3, optimize=False, load=True, space='buy') # 可暂时关闭
add_position_callback = DecimalParameter(0.03, 0.06, decimals=3, default=0.028, optimize=False, load=True, space='buy')
stake_divisor = DecimalParameter(2, 4, decimals=3, default=2.793, optimize=False, load=True, space='buy')
step_coefficient = DecimalParameter(0.5, 1.5, decimals=2, default=1.45, optimize=False, load=True, space='buy')
max_entry_adjustments = IntParameter(2, 5, default=2, optimize=False, load=True, space='buy') # 可暂时关闭
# 市场状态相关(辅助决策)
min_condition_count = IntParameter(2, 4, default=3, optimize=False, load=True, space='buy')
stochrsi_neutral_threshold = IntParameter(20, 30, default=20, optimize=False, load=True, space='buy') # 固定为20
stochrsi_bull_threshold = IntParameter(30, 40, default=35, optimize=False, load=True, space='buy')
rsi_bull_threshold = IntParameter(45, 55, default=50, optimize=False, load=True, space='buy') # 固定为50
min_condition_count = IntParameter(2, 4, default=2, optimize=False, load=True, space='buy')
stochrsi_neutral_threshold = IntParameter(20, 30, default=29, optimize=False, load=True, space='buy') # 固定为20
stochrsi_bull_threshold = IntParameter(30, 40, default=36, optimize=False, load=True, space='buy')
rsi_bull_threshold = IntParameter(45, 55, default=54, optimize=False, load=True, space='buy') # 固定为50
# 第三步, 优化sell空间
exit_bb_upper_deviation = DecimalParameter(0.98, 1.02, decimals=2, default=1.0, optimize=True, load=True, space='sell')
exit_volume_multiplier = DecimalParameter(1.5, 3.0, decimals=1, default=2.0, optimize=True, load=True, space='sell')
exit_bb_upper_deviation = DecimalParameter(0.98, 1.02, decimals=2, default=0.99, optimize=True, load=True, space='sell')
exit_volume_multiplier = DecimalParameter(1.5, 3.0, decimals=1, default=1.7, optimize=True, load=True, space='sell')
rsi_overbought = IntParameter(57, 59, default=58, optimize=True, load=True, space='sell')
# -------------------------- 简化后的减仓Hyperopt参数仅3个对齐加仓 --------------------------
reduce_profit_base = DecimalParameter(0.05, 0.12, default=0.075, space='sell', optimize=True) # 减仓基础盈利阈值触发门槛默认7.5%

359
tools/cover_params.sh Executable file
View File

@ -0,0 +1,359 @@
#!/bin/bash
# 通用工具脚本 v1.0.0
# 功能:提供参数处理、配置管理、分级日志等通用功能
# 全局变量
SCRIPT_NAME="$(basename "$0")"
SCRIPT_VERSION="v1.0.0"
CONFIG_LOADED=false
# 默认配置
DEFAULT_CONFIG_FILE="/Users/zhangkun/myTestFreqAI/freqtrade/templates/freqaiprimer.json"
DEFAULT_LOG_LEVEL="info"
# 配置变量(可通过参数或.env文件覆盖
CONFIG_FILE="${CONFIG_FILE:-$DEFAULT_CONFIG_FILE}"
LOG_LEVEL="${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}"
VERBOSE=false
DRY_RUN=false
# 获取当前日期时间
get_timestamp() {
date "+%Y-%m-%d %H:%M:%S"
}
# 获取日志级别对应的数值
# 0: debug, 1: info, 2: warn, 3: error
log_level_to_num() {
case "$1" in
debug) echo 0 ;;
info) echo 1 ;;
warn) echo 2 ;;
error) echo 3 ;;
*) echo 1 ;;
esac
}
# 获取日志级别对应的颜色
log_level_to_color() {
case "$1" in
debug) echo "\033[0;36m" ;;
info) echo "\033[0;32m" ;;
warn) echo "\033[0;33m" ;;
error) echo "\033[0;31m" ;;
*) echo "\033[0m" ;;
esac
}
# 日志函数
log() {
local level=$1
local message=$2
local current_level_num=$(log_level_to_num "$LOG_LEVEL")
local message_level_num=$(log_level_to_num "$level")
# 只输出大于等于当前日志级别的消息
if [ "$message_level_num" -ge "$current_level_num" ]; then
local color=$(log_level_to_color "$level")
local reset="\033[0m"
local timestamp=$(get_timestamp)
echo -e "$color[$timestamp] [$level] $message$reset"
fi
}
# 显示错误消息并退出
error_exit() {
log "error" "$1"
exit 1
}
# 加载环境变量
load_env() {
if [ -f ".env" ]; then
log "info" "加载环境变量文件: .env"
# 安全加载环境变量
set -a
source .env
set +a
# 检查是否有.env中设置的CONFIG_FILE
if [ ! -z "$CONFIG_FILE" ] && [ "$CONFIG_FILE" != "$DEFAULT_CONFIG_FILE" ]; then
# 如果是相对路径,则将其转换为绝对路径(相对于脚本所在目录)
if [[ ! "$CONFIG_FILE" = /* ]]; then
# 检查是否需要添加../freqtrade/templates/前缀
if [ ! -f "$CONFIG_FILE" ] && [ "$CONFIG_FILE" = "freqaiprimer.json" ]; then
CONFIG_FILE="/Users/zhangkun/myTestFreqAI/freqtrade/templates/freqaiprimer.json"
log "debug" "自动修正配置文件路径为: $CONFIG_FILE"
fi
fi
fi
# 确保配置变量使用默认值(如果环境变量未设置)
LOG_LEVEL="${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}"
return 0
else
log "warn" "环境变量文件 .env 不存在"
return 1
fi
}
# 函数: 获取配置文件的绝对路径
get_absolute_path() {
local path=$1
# 如果是相对路径,则转换为绝对路径
if [[ ! "$path" = /* ]]; then
# 获取脚本所在目录的绝对路径
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "$script_dir/$path"
else
echo "$path"
fi
}
# 函数: 加载配置文件
load_config() {
local config_file=$1
# 直接使用传入的路径(已经是绝对路径)
if [ ! -f "$config_file" ]; then
log "warn" "配置文件 $config_file 不存在,将使用默认配置"
return 1
fi
log "info" "加载配置文件: $config_file"
# 检查是否有 jq 工具可用
if command -v jq &> /dev/null; then
# 使用 jq 解析 JSON 配置文件
CONFIG_LOADED=true
log "debug" "使用 jq 解析配置文件"
# 这里可以根据需要添加具体的配置解析逻辑
else
log "warn" "未找到 jq 工具,无法解析 JSON 配置文件"
fi
}
# 显示帮助信息
show_help() {
cat << EOF
$SCRIPT_NAME $SCRIPT_VERSION
用法: $SCRIPT_NAME [选项]
选项:
-h, --help 显示此帮助信息
-v, --version 显示脚本版本
-c, --config <文件路径> 指定配置文件路径(默认: $DEFAULT_CONFIG_FILE
-l, --log-level <级别> 设置日志级别 (debug, info, warn, error),默认: info
--verbose 启用详细输出模式
--dry-run 试运行模式,不执行实际操作
--custom-param <值> 自定义参数
示例:
$SCRIPT_NAME --help
$SCRIPT_NAME --config custom.json --log-level debug
$SCRIPT_NAME --dry-run --verbose
EOF
}
# 解析命令行参数
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-v|--version)
echo "$SCRIPT_NAME $SCRIPT_VERSION"
exit 0
;;
-c|--config)
CONFIG_FILE="$2"
shift 2
;;
-l|--log-level)
LOG_LEVEL="$2"
shift 2
;;
--verbose)
VERBOSE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
--custom-param)
CUSTOM_PARAM="$2"
shift 2
;;
*)
error_exit "未知参数: $1"
;;
esac
done
}
# 函数将JSON配置覆盖到Python文件中的hyperopt参数
override_hyperopt_params() {
local json_file=$1
local py_file=$2
local dry_run=$3
log "info" "开始从 $json_file 覆盖参数到 $py_file"
# 检查jq工具是否可用
if ! command -v jq &> /dev/null; then
log "error" "未找到 jq 工具,无法解析 JSON 配置文件"
return 1
fi
# 检查Python文件是否存在
if [ ! -f "$py_file" ]; then
log "error" "Python 文件 $py_file 不存在"
return 1
fi
# 获取脚本所在目录
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 确保路径正确
if [[ ! "$json_file" = /* ]]; then
json_file="$script_dir/$json_file"
fi
if [[ ! "$py_file" = /* ]]; then
py_file="$script_dir/$py_file"
fi
log "debug" "使用JSON文件: $json_file"
log "debug" "目标Python文件: $py_file"
# 创建临时文件用于记录修改
local changes_log=$(mktemp)
# 解析所有一级参数类别buy, sell, stoploss等
local param_categories=$(jq -r '.params | keys[]' "$json_file")
for category in $param_categories; do
log "debug" "处理参数类别: $category"
# 获取该类别下的所有参数
local params=$(jq -r ".params.$category | keys[]" "$json_file")
for param in $params; do
# 获取参数值
local value=$(jq -r ".params.$category.$param" "$json_file")
# 特殊处理字符串值,添加引号
if [[ "$value" =~ ^[a-zA-Z]+$ ]] && [[ ! "$value" == "true" ]] && [[ ! "$value" == "false" ]]; then
value="\"$value\""
fi
log "debug" " 处理参数: $param = $value"
# 构建sed命令来替换Python文件中的默认值
if [ "$dry_run" = true ]; then
# 试运行模式:显示将要进行的修改
log "info" "[DRY RUN] 将替换参数 $param 的默认值为 $value"
# 检查该参数是否存在于文件中
if grep -q "$param.*default=" "$py_file"; then
echo "$param: $value" >> "$changes_log"
else
log "warn" " 参数 $param$py_file 中未找到"
fi
else
# 实际运行模式:执行替换
if grep -q "$param.*default=" "$py_file"; then
# 使用sed替换默认值保留其他属性完全兼容macOS
# 创建临时文件保存替换结果
local temp_file=$(mktemp)
sed "s/\($param.*default=\)[^,}]*/\\1$value/" "$py_file" > "$temp_file"
# 将临时文件内容复制回原文件
mv "$temp_file" "$py_file"
log "info" " 已更新参数 $param 的默认值为 $value"
echo "$param: $value" >> "$changes_log"
else
log "warn" " 参数 $param$py_file 中未找到"
fi
fi
done
done
# 显示修改摘要
local change_count=$(wc -l < "$changes_log")
log "info" "参数更新完成,共修改 $change_count 个参数"
if [ "$VERBOSE" = true ] && [ -s "$changes_log" ]; then
log "info" "修改的参数列表:"
cat "$changes_log" | while read line; do
log "info" " $line"
done
fi
# 清理临时文件
rm -f "$changes_log"
return 0
}
# 核心任务执行函数
execute_core_task() {
log "info" "开始执行核心任务"
# 默认的JSON和Python文件路径
local default_json_file="../freqtrade/templates/freqaiprimer.json"
local default_py_file="../freqtrade/templates/freqaiprimer.py"
# 如果通过--custom-param指定了特殊操作处理它
if [ "$CUSTOM_PARAM" = "update_params" ]; then
log "info" "执行参数更新操作"
override_hyperopt_params "$default_json_file" "$default_py_file" "$DRY_RUN"
else
# 常规模式:从配置文件读取参数
if [ "$DRY_RUN" = true ]; then
log "info" "[DRY RUN] 模拟执行核心任务"
# 试运行时也执行参数更新的试运行
override_hyperopt_params "$default_json_file" "$default_py_file" "true"
else
log "info" "执行参数更新任务"
override_hyperopt_params "$default_json_file" "$default_py_file" "false"
fi
fi
# 显示当前配置信息(如果启用了详细模式)
if [ "$VERBOSE" = true ]; then
log "debug" "当前配置信息:"
log "debug" " 配置文件: $CONFIG_FILE"
log "debug" " 日志级别: $LOG_LEVEL"
log "debug" " 详细模式: $VERBOSE"
log "debug" " 试运行模式: $DRY_RUN"
if [ -n "$CUSTOM_PARAM" ]; then
log "debug" " 自定义参数: $CUSTOM_PARAM"
fi
fi
log "info" "核心任务执行完成"
}
# 主函数
main() {
# 加载环境变量
load_env
# 解析命令行参数(命令行参数优先级高于环境变量)
parse_args "$@"
# 加载配置文件
load_config "$CONFIG_FILE"
# 执行核心任务
execute_core_task
log "info" "脚本执行完成"
}
# 入口点
main "$@"