当前 step 的属性必须设为 optimize=True,非当前 step 必须设为 optimize=False

This commit is contained in:
zhangkun9038@dingtalk.com 2025-10-27 17:45:59 +08:00
parent 4845794584
commit b6b887cc42
4 changed files with 203 additions and 8 deletions

Binary file not shown.

View File

@ -37,7 +37,124 @@ var (
wg sync.WaitGroup
)
// 测试updateParametersInStrategy函数的功能
func testUpdateParametersInStrategy() {
log.Println("========== 开始测试updateParametersInStrategy函数 ==========")
// 创建测试用的属性组特别设置optimize为true
propertyGroups := []model.PropertyGroup{
{
ID: "phase1",
Name: "第一轮优化",
Space: "buy",
Description: "自定义指标参数",
Properties: map[string]model.Property{
"buy_rsi": {
Optimize: true,
Min: 10.0,
Max: 50.0,
Step: 1.0,
Space: "buy",
},
"reduce_coefficient": {
Optimize: true,
Min: 0.1,
Max: 1.0,
Step: 0.01,
Space: "sell",
},
},
},
}
// 创建测试用的策略文件内容
testContent := `from freqtrade.strategy import IStrategy
from freqtrade.optimize.hyperopt import IntParameter, CategoricalParameter, DecimalParameter
import talib.abstract as ta
import numpy as np
# 参数设置
class HyperoptParameters:
# 旧的参数定义
some_old_param = IntParameter(1, 10, default=5, optimize=False)
# 策略类
class FreqaiPrimer(IStrategy):
# 策略配置
minimal_roi = {
"0": 0.10
}
`
// 写入测试文件
testFilePath := "test_strategy.py"
if err := os.WriteFile(testFilePath, []byte(testContent), 0644); err != nil {
log.Fatalf("无法写入测试文件: %v", err)
}
// 读取测试文件内容
testFileContent, err := os.ReadFile(testFilePath)
if err != nil {
log.Fatalf("无法读取测试文件: %v", err)
}
// 测试updateParametersInStrategy函数
updatedContent := updateParametersInStrategy(string(testFileContent), propertyGroups)
// 写入更新后的内容到测试文件进行查看(保留文件以便检查)
outputFilePath := "optimize_test_strategy.py"
if err := os.WriteFile(outputFilePath, []byte(updatedContent), 0644); err != nil {
log.Fatalf("无法写入输出文件: %v", err)
}
// 验证是否正确替换了类
log.Println("验证1: 检查是否包含HyperoptParameters类")
if !strings.Contains(updatedContent, "class HyperoptParameters") {
log.Fatal("❌ 测试失败: 未找到HyperoptParameters类")
}
log.Println("✅ 验证通过: 找到了HyperoptParameters类")
// 验证是否包含新参数
log.Println("验证2: 检查是否包含更新后的buy_rsi参数")
if !strings.Contains(updatedContent, "buy_rsi = IntParameter(10, 50") {
log.Fatal("❌ 测试失败: 未找到更新后的buy_rsi参数")
}
log.Println("✅ 验证通过: 找到了更新后的buy_rsi参数")
// 验证旧参数是否已被移除
log.Println("验证3: 检查旧参数是否已被移除")
if strings.Contains(updatedContent, "some_old_param") {
log.Fatal("❌ 测试失败: 旧参数仍然存在,替换失败")
}
log.Println("✅ 验证通过: 旧参数已被移除")
// 验证optimize状态是否正确设置为True
log.Println("验证4: 检查buy_rsi参数的optimize状态是否为True")
if !strings.Contains(updatedContent, "buy_rsi = IntParameter(10, 50, default=30, optimize=True") {
log.Printf("❌ 测试警告: 未找到optimize=True检查实际值")
// 宽松检查只要包含optimize=True即可
if !strings.Contains(updatedContent, "optimize=True") {
log.Fatal("❌ 测试失败: 参数optimize状态未设置为True")
}
}
log.Println("✅ 验证通过: 参数optimize状态已设置为True")
// 验证reduce_coefficient参数类型是否为DecimalParameter
log.Println("验证5: 检查reduce_coefficient参数是否使用DecimalParameter类型")
if !strings.Contains(updatedContent, "reduce_coefficient = DecimalParameter") {
log.Fatal("❌ 测试失败: reduce_coefficient不是DecimalParameter类型")
}
log.Println("✅ 验证通过: reduce_coefficient参数使用了正确的DecimalParameter类型")
log.Println("========== 测试完成! updateParametersInStrategy函数验证成功 ==========")
log.Printf("更新后的策略文件已保存为: %s\n", outputFilePath)
}
// 程序入口点,确保只定义一次
func main() {
// 添加测试模式标志
testMode := flag.Bool("test-update-params", false, "测试updateParametersInStrategy函数")
log.Println("开始初始化HyperOpt客户端...")
// 解析命令行参数
@ -47,6 +164,12 @@ func main() {
redisDB = *flag.Int("redis-db", config.DefaultRedisConfig().DB, "Redis数据库索引")
flag.Parse()
log.Println(" 命令行参数解析完成")
// 如果是测试模式,运行测试并退出
if *testMode {
testUpdateParametersInStrategy()
return
}
// 获取主机名
log.Println("步骤2: 获取主机名")
@ -880,21 +1003,58 @@ func updateParametersInStrategy(originalContent string, propertyGroups []model.P
paramsClass.WriteString("\n")
paramsClassContent := paramsClass.String()
// 检查是否存在HyperoptParameters类定义
pattern := `class HyperoptParameters[\s\S]*?(?=(?:\n\n|\nclass |$))`
// 检查是否存在HyperoptParameters类定义(不使用前瞻断言)
pattern := `class HyperoptParameters[\s\S]*?`
re := regexp.MustCompile(pattern)
matches := re.FindStringIndex(originalContent)
if len(matches) > 0 {
// 找到现有的HyperoptParameters类精确替换
startIndex := matches[0]
endIndex := matches[1]
log.Printf(" 诊断: 找到HyperoptParameters类将精确替换该类范围从位置 %d 到 %d", startIndex, endIndex)
// 找到了HyperoptParameters类的开始位置需要找到类的结束位置
startPos := matches[1] // 类定义开始的结束位置
indentLevel := 0
endPos := startPos
// 逐行分析查找类的结束
lines := strings.Split(originalContent[startPos:], "\n")
for i, line := range lines {
trimmedLine := strings.TrimSpace(line)
if trimmedLine == "" || strings.HasPrefix(trimmedLine, "#") {
// 空行或注释行,继续
continue
}
// 计算当前行的缩进级别
currentIndent := len(line) - len(strings.TrimLeft(line, " \t"))
// 检查是否是下一个类的开始或其他顶层结构
if strings.HasPrefix(trimmedLine, "class ") || (strings.HasPrefix(trimmedLine, "def ") && currentIndent == 0) {
// 找到下一个类或顶层函数,当前类结束
endPos = startPos
for j := 0; j < i; j++ {
endPos += len(lines[j]) + 1 // +1 for newline
}
break
}
// 记录最大的缩进级别,用于判断类的结束
if currentIndent > 0 {
if indentLevel == 0 || currentIndent < indentLevel {
indentLevel = currentIndent
}
}
}
// 如果没有找到明确的结束位置,默认找到文件末尾
if endPos == startPos {
endPos = len(originalContent)
}
log.Printf(" 诊断: 找到HyperoptParameters类将精确替换该类范围从位置 %d 到 %d", matches[0], endPos)
// 构建更新后的内容
result := originalContent[:startIndex]
result := originalContent[:matches[0]]
result += paramsClassContent
result += originalContent[endIndex:]
result += originalContent[endPos:]
return result
} else {

View File

@ -0,0 +1,19 @@
from freqtrade.strategy import IStrategy
from freqtrade.optimize.hyperopt import IntParameter, CategoricalParameter, DecimalParameter
import talib.abstract as ta
import numpy as np
# 参数设置
# 参数设置
class HyperoptParameters:
# 第一轮优化:
# 自定义指标参数 - 使用Hyperopt可优化参数
buy_rsi = IntParameter(10, 50, default=30, optimize=True, load=True, space='buy')
reduce_coefficient = DecimalParameter(0.10, 1.00, decimals=2, default=0.55, optimize=True, load=True, space='buy')
class FreqaiPrimer(IStrategy):
# 策略配置
minimal_roi = {
"0": 0.10
}

View File

@ -0,0 +1,16 @@
from freqtrade.strategy import IStrategy
from freqtrade.optimize.hyperopt import IntParameter, CategoricalParameter, DecimalParameter
import talib.abstract as ta
import numpy as np
# 参数设置
class HyperoptParameters:
# 旧的参数定义
some_old_param = IntParameter(1, 10, default=5, optimize=False)
# 策略类
class FreqaiPrimer(IStrategy):
# 策略配置
minimal_roi = {
"0": 0.10
}