hyperopt mardingale
This commit is contained in:
parent
5490d392c5
commit
6dc6cade30
@ -8,6 +8,9 @@ import datetime
|
||||
import pandas as pd
|
||||
import math
|
||||
|
||||
# 设置pandas选项以解决FutureWarning警告
|
||||
pd.set_option('future.no_silent_downcasting', True)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MartinGale(IStrategy):
|
||||
@ -79,21 +82,21 @@ class MartinGale(IStrategy):
|
||||
timeframe = "3m" # 主时间框架为 3 分钟
|
||||
can_short = False # 禁用做空
|
||||
|
||||
# 自定义指标参数 - 使用Hyperopt可优化参数
|
||||
# 自定义指标参数 - 设置为可通过Hyperopt优化
|
||||
# 从OKX App中获取的参数
|
||||
rsi_length = IntParameter(7, 21, default=14, optimize=False, load=True, space='buy') # RSI周期为14
|
||||
rsi_oversold = IntParameter(20, 40, default=30, optimize=False, load=True, space='buy') # RSI触发阈值为30
|
||||
rsi_length = IntParameter(7, 21, default=14, optimize=True, load=True, space='buy') # RSI周期为14,可优化范围7-21
|
||||
rsi_oversold = IntParameter(20, 40, default=30, optimize=True, load=True, space='buy') # RSI触发阈值为30,可优化范围20-40
|
||||
|
||||
# 马丁格尔策略参数 - 基于OKX App界面设置
|
||||
max_entry_adjustments = IntParameter(5, 15, default=10, optimize=False, load=True, space='buy') # 最大加仓次数10次
|
||||
add_position_callback = DecimalParameter(0.005, 0.015, decimals=3, default=0.0066, optimize=False, load=True, space='buy') # 跌幅加仓阈值0.66%
|
||||
max_entry_adjustments = IntParameter(5, 15, default=10, optimize=True, load=True, space='buy') # 最大加仓次数10次,可优化范围5-15
|
||||
add_position_callback = DecimalParameter(0.005, 0.015, decimals=3, default=0.0066, optimize=True, load=True, space='buy') # 跌幅加仓阈值0.66%,可优化范围0.5%-1.5%
|
||||
|
||||
# 马丁格尔加仓比例参数
|
||||
step_coefficient = DecimalParameter(1.0, 1.1, decimals=2, default=1.05, optimize=False, load=True, space='buy') # 加仓比例1.05倍
|
||||
stake_divisor = DecimalParameter(0.9, 1.1, decimals=2, default=1.0, optimize=False, load=True, space='buy') # 初始比例
|
||||
step_coefficient = DecimalParameter(1.0, 1.1, decimals=2, default=1.05, optimize=True, load=True, space='buy') # 加仓比例1.05倍,可优化范围1.0-1.1
|
||||
stake_divisor = DecimalParameter(0.9, 1.1, decimals=2, default=1.0, optimize=True, load=True, space='buy') # 初始比例,可优化范围0.9-1.1
|
||||
|
||||
# 止盈目标参数 - 对应OKX App中的单周期止盈目标2.50%
|
||||
take_profit_target = DecimalParameter(0.02, 0.03, decimals=3, default=0.025, optimize=False, load=True, space='sell')
|
||||
take_profit_target = DecimalParameter(0.02, 0.03, decimals=3, default=0.025, optimize=True, load=True, space='sell') # 止盈目标2.5%,可优化范围2.0%-3.0%
|
||||
|
||||
def informative_pairs(self):
|
||||
"""定义辅助时间框架"""
|
||||
@ -156,10 +159,12 @@ class MartinGale(IStrategy):
|
||||
df_1h['rsi_1h'] = ta.rsi(df_1h['close'], length=rsi_length_value)
|
||||
df_1h['ema_50_1h'] = ta.ema(df_1h['close'], length=50) # 1h 50周期EMA
|
||||
df_1h['ema_200_1h'] = ta.ema(df_1h['close'], length=200) # 1h 200周期EMA
|
||||
df_1h['trend_1h'] = df_1h['close'] > df_1h['ema_50_1h'] # 1h上涨趋势
|
||||
|
||||
# 将1h数据重新索引到主时间框架(3m),并填充缺失值
|
||||
df_1h = df_1h.set_index('date').reindex(dataframe['date']).ffill().bfill().reset_index()
|
||||
|
||||
# 计算1h上涨趋势,确保不包含None值
|
||||
df_1h['trend_1h'] = df_1h['close'] > df_1h['ema_50_1h'] # 1h上涨趋势
|
||||
df_1h = df_1h.rename(columns={'index': 'date'})
|
||||
df_1h = df_1h[['date', 'rsi_1h', 'trend_1h', 'ema_50_1h', 'ema_200_1h']].ffill()
|
||||
|
||||
|
||||
@ -13,20 +13,21 @@ if [ ! -f ".env" ]; then
|
||||
fi
|
||||
|
||||
# 加载 .env 文件中的变量
|
||||
export $(grep -v '^#' .env | xargs)
|
||||
if [ -f .env ]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
fi
|
||||
# 设置默认值
|
||||
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"
|
||||
TEST_BRANCH=${TEST_BRANCH:-develop}
|
||||
|
||||
# Function to extract the value of a parameter
|
||||
get_param_value() {
|
||||
local param="$1"
|
||||
shift
|
||||
local args=("$@")
|
||||
local args=($@)
|
||||
local i=0
|
||||
|
||||
while [ $i -lt ${#args[@]} ]; do
|
||||
@ -58,6 +59,7 @@ for arg in "$@"; do
|
||||
HAS_NAMED_PARAMS=true
|
||||
break
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Initialize variables
|
||||
@ -78,6 +80,7 @@ if [ "$HAS_NAMED_PARAMS" = true ]; then
|
||||
if [ -z "$STRATEGY_ARG" ]; then
|
||||
STRATEGY_ARG=$(get_param_value "-t" "$@")
|
||||
fi
|
||||
CONFIG_ARG=$(get_param_value "--config" "$@")
|
||||
else
|
||||
# Use positional parameter parsing
|
||||
if [ $# -gt 0 ]; then
|
||||
@ -92,18 +95,25 @@ else
|
||||
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\"
|
||||
# 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
|
||||
elif [[ "$THIRD_PARAM" == *.py ]] || [[ "$THIRD_PARAM" != -* ]]; 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
|
||||
if [ $# -gt 3 ]; then
|
||||
FOURTH_PARAM="$4"
|
||||
if [[ "$FOURTH_PARAM" == *.json ]]; then
|
||||
CONFIG_ARG="$FOURTH_PARAM"
|
||||
echo "Detected config parameter: $CONFIG_ARG"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set default values if parameters not provided
|
||||
@ -129,52 +139,120 @@ 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")
|
||||
|
||||
# 使用 --pairs 参数提供的交易对
|
||||
PAIRS_FLAG="--pairs $PAIRS_ARG"
|
||||
echo "Using pairs from --pairs parameter: $PAIRS_ARG"
|
||||
echo "Number of pairs: $(echo "$PAIRS_ARG" | wc -w)"
|
||||
# 使用默认的交易对列表
|
||||
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"
|
||||
# 检查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 '')")
|
||||
|
||||
# 如果命令行提供了策略参数,覆盖 .env 文件中的设置
|
||||
if [ -n "$STRATEGY_ARG" ]; then
|
||||
STRATEGY_NAME="$STRATEGY_ARG"
|
||||
echo "Overriding strategy from command line: $STRATEGY_NAME"
|
||||
# 如果解析成功且有交易对
|
||||
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"
|
||||
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 "No pairs parameter provided, using default pairs: $DEFAULT_PAIRS"
|
||||
fi
|
||||
|
||||
# 如果命令行提供了策略参数,覆盖.env文件设置
|
||||
if [ -n "$STRATEGY_ARG" ]; then
|
||||
# 策略类名保持不变(如MyStrategy),但文件名使用小写
|
||||
STRATEGY_CLASS_NAME="$STRATEGY_ARG"
|
||||
STRATEGY_FILE_NAME="$(echo "$STRATEGY_ARG" | tr '[:upper:]' '[:lower:]').py"
|
||||
STRATEGY_NAME="$STRATEGY_FILE_NAME"
|
||||
echo "Overriding strategy with command line parameter: $STRATEGY_CLASS_NAME"
|
||||
echo "Strategy class name: $STRATEGY_CLASS_NAME"
|
||||
echo "Strategy file name: $STRATEGY_FILE_NAME"
|
||||
|
||||
# 自动匹配策略对应的配置文件(使用小写)
|
||||
STRATEGY_CONFIG_LOWER="$(echo "$STRATEGY_ARG" | tr '[:upper:]' '[:lower:]').json"
|
||||
|
||||
echo "Checking auto-matched config file: freqtrade/templates/$STRATEGY_CONFIG_LOWER"
|
||||
|
||||
# 检查小写配置文件
|
||||
if [ -f "../freqtrade/templates/$STRATEGY_CONFIG_LOWER" ]; then
|
||||
CONFIG_FILE="$STRATEGY_CONFIG_LOWER"
|
||||
echo "Auto-matched config file for strategy: $CONFIG_FILE"
|
||||
else
|
||||
echo "Warning: Auto-matched config file '$STRATEGY_CONFIG_LOWER' not found in templates directory"
|
||||
echo "Available config files in templates directory:"
|
||||
ls ../freqtrade/templates/*.json 2>/dev/null | sed 's|.*/||' || echo "No JSON config files found"
|
||||
echo "Using current config: $CONFIG_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 如果命令行提供了配置参数,覆盖.env文件设置
|
||||
if [ -n "$CONFIG_ARG" ]; then
|
||||
CONFIG_FILE="$CONFIG_ARG"
|
||||
echo "Overriding config with command line parameter: $CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# 检查指定的配置文件是否存在,如果不存在则使用默认配置
|
||||
echo "Checking config file: freqtrade/templates/$CONFIG_FILE"
|
||||
if [ ! -f "../freqtrade/templates/$CONFIG_FILE" ]; then
|
||||
echo "Warning: Config file freqtrade/templates/$CONFIG_FILE not found, using default configuration"
|
||||
CONFIG_FILE="basic.json"
|
||||
else
|
||||
echo "Config file found: freqtrade/templates/$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# 在参数处理完成后输出最终使用的值
|
||||
echo "Using strategy: $STRATEGY_NAME"
|
||||
echo "Using config: $CONFIG_FILE"
|
||||
echo "Using testBranch: $TEST_BRANCH"
|
||||
|
||||
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/*
|
||||
rm -f 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 \
|
||||
--strategy $STRATEGY_CLASS_NAME \
|
||||
--config /freqtrade/config_examples/$CONFIG_FILE \
|
||||
--config /freqtrade/templates/${PARAMS_NAME}.json \
|
||||
--enable-protections \
|
||||
@ -185,4 +263,48 @@ docker-compose run --rm freqtrade hyperopt $PAIRS_FLAG \
|
||||
-j 20 \
|
||||
--hyperopt-loss SharpeHyperOptLossDaily \
|
||||
--spaces sell \
|
||||
--fee 0.001
|
||||
--fee 0.001"
|
||||
|
||||
docker-compose run --rm freqtrade hyperopt $PAIRS_FLAG \
|
||||
--logfile /freqtrade/user_data/logs/freqtrade.log \
|
||||
--freqaimodel LightGBMRegressorMultiTarget \
|
||||
--strategy $STRATEGY_CLASS_NAME \
|
||||
--config /freqtrade/config_examples/$CONFIG_FILE \
|
||||
--config /freqtrade/templates/${PARAMS_NAME}.json \
|
||||
--enable-protections \
|
||||
--strategy-path /freqtrade/templates \
|
||||
--timerange ${START_DATE}-${END_DATE} \
|
||||
--random-state 19 \
|
||||
-e 2500 \
|
||||
-j 20 \
|
||||
--hyperopt-loss SharpeHyperOptLossDaily \
|
||||
--spaces sell \
|
||||
--fee 0.001 >output.log 2>&1
|
||||
|
||||
sed -i 's/\x1B\[[0-9;]*m//g' output.log
|
||||
|
||||
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
|
||||
cp output.log result/ -f
|
||||
cd tools/
|
||||
python tradestocsv.py
|
||||
python analytic.py >../result/analytic.log
|
||||
cd ../
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user