adjust_postion_trade 优化参数和逻辑, 实现加仓间隔密度逐次提高, 加仓幅度放量提高

This commit is contained in:
zhangkun9038@dingtalk.com 2025-09-23 17:51:10 +00:00
parent ade68cdc96
commit 8e654376e4
3 changed files with 164 additions and 20 deletions

View File

@ -15,8 +15,6 @@
"max_open_trades": 5
},
"buy": {
"stake_divisor": 2,
"add_position_callback": 0.053,
"bb_length": 13,
"bb_lower_deviation": 1.04,
"bb_std": 3.0,

View File

@ -103,8 +103,10 @@ class FreqaiPrimer(IStrategy):
h1_max_consecutive_candles = IntParameter(1, 4, default=2, optimize=True, load=True, space='buy')
# 定义可优化参数
max_entry_adjustments = IntParameter(2, 5, default=3, optimize=True, load=True, space='buy') # 最大加仓次数
add_position_callback = DecimalParameter(0.03, 0.06, decimals=3, default=0.047, optimize=True, load=True, space='buy') # 加仓回调百分比
stake_divisor = IntParameter(2, 4, default=2, optimize=False, load=True, space='buy') # 加仓金额分母
add_position_callback = DecimalParameter(0.02, 0.06, decimals=3, default=0.043, optimize=False, load=True, space='buy') # 加仓回调百分比
add_position_growth = DecimalParameter(1.5, 3.0, decimals=2, default=4.5, optimize=False, load=True, space='buy') # 加仓金额增长因子保留2位小数用于hyperopt优化
add_position_multiplier = DecimalParameter(0.2, 10.5, decimals=2, default=0.86, optimize=False, load=True, space='buy') # 加仓间隔系数保留2位小数用于hyperopt优化
stake_divisor = DecimalParameter(2.0, 12.0, decimals=2, default=9.3, optimize=False, load=True, space='buy') # 加仓金额分母小数类型保留2位小数
# 线性ROI参数 - 用于线性函数: y = (a * (x + k)) + t
roi_param_a = DecimalParameter(-0.0002, -0.00005, decimals=5, default=-0.0001, optimize=True, load=True, space='sell') # 系数a
@ -596,7 +598,7 @@ class FreqaiPrimer(IStrategy):
return exit_ratio
def adjust_trade_position(self, trade: 'Trade', current_time, current_rate: float,
def adjust_trade_position(self, trade: 'Trade', current_time, current_rate: float,
current_profit: float, min_stake: float, max_stake: float, **kwargs) -> float:
"""
根据用户要求实现加仓逻辑
@ -605,41 +607,44 @@ class FreqaiPrimer(IStrategy):
"""
# 获取当前交易对
pair = trade.pair
# 获取当前交易的加仓次数
entry_count = len(trade.orders) # 获取所有入场订单数量
# 如果已经达到最大加仓次数,则不再加仓
if entry_count - 1 >= self.max_entry_adjustments.value:
return 0.0
# 获取初始入场价格和当前价格的差值百分比
initial_price = trade.open_rate
if initial_price == 0:
return 0.0
price_diff_pct = (current_rate - initial_price) / initial_price
# 计算加仓次数从1开始计数
adjustment_count = entry_count - 1 # 已加仓次数
# 检查价格回调是否达到加仓间隔
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
current_state = dataframe['market_state'].iloc[-1] if 'market_state' in dataframe.columns else 'neutral'
if price_diff_pct <= -self.add_position_callback.value and current_state not in ['bear', 'weak_bear']:
# 计算当前所需的加仓间隔百分比 = 基础间隔 * (系数 ^ 已加仓次数)
current_callback = self.add_position_callback.value * (self.add_position_multiplier.value ** adjustment_count)
if price_diff_pct <= -current_callback:
# 计算初始入场金额
initial_stake = trade.orders[0].cost # 第一笔订单的成本
# 计算加仓次数从1开始计数
adjustment_count = entry_count - 1 # 已加仓次数
# 计算加仓金额: (initial_stake / stake_divisor) ^ (adjustment_count + 1)
additional_stake = (initial_stake / self.stake_divisor.value) ** (adjustment_count + 1)
additional_stake = (initial_stake / self.stake_divisor.value) * (self.add_position_growth.value ** (adjustment_count + 1))
# 确保加仓金额在允许的范围内
additional_stake = max(min_stake, min(additional_stake, max_stake - trade.stake_amount))
#logger.info(f"[{pair}] 触发加仓: 第{adjustment_count + 1}次加仓, 初始金额{initial_stake:.2f}, \
# 加仓金额{additional_stake:.2f}, 价格差{price_diff_pct:.2%}, 当前利润{current_profit:.2%}")
return additional_stake
# 不符合加仓条件返回0
return 0.0

141
tools/calculate_dca.sh Executable file
View File

@ -0,0 +1,141 @@
#!/bin/bash
# freqai 加仓策略计算器 (DCA Calculator)
# 根据 FreqaiPrimer 策略的5个参数进行计算
# 设置默认值 (与您的 freqaiprimer.py 代码中一致)
MAX_ENTRY_ADJUSTMENTS=4
ADD_POSITION_CALLBACK=0.025
ADD_POSITION_GROWTH=2.97
ADD_POSITION_MULTIPLIER=1.78
STAKE_DIVISOR=4.6
INITIAL_STAKE=75
# 函数:显示使用帮助
usage() {
echo "Usage: $0 [OPTIONS]"
echo "计算FreqaiPrimer策略的加仓计划"
echo ""
echo "选项:"
echo " -h, --help 显示此帮助信息"
echo " -m, --max-adjustments N 最大加仓次数 (默认: $MAX_ENTRY_ADJUSTMENTS)"
echo " -c, --callback FLOAT 基础回调百分比 (默认: $ADD_POSITION_CALLBACK)"
echo " -g, --growth FLOAT 加仓金额增长因子 (默认: $ADD_POSITION_GROWTH)"
echo " -p, --multiplier FLOAT 加仓间隔系数 (默认: $ADD_POSITION_MULTIPLIER)"
echo " -d, --divisor FLOAT 加仓金额分母 (默认: $STAKE_DIVISOR)"
echo " -s, --stake FLOAT 首次入场金额 (默认: $INITIAL_STAKE USDT)"
exit 1
}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
;;
-m|--max-adjustments)
MAX_ENTRY_ADJUSTMENTS="$2"
shift 2
;;
-c|--callback)
ADD_POSITION_CALLBACK="$2"
shift 2
;;
-g|--growth)
ADD_POSITION_GROWTH="$2"
shift 2
;;
-p|--multiplier)
ADD_POSITION_MULTIPLIER="$2"
shift 2
;;
-d|--divisor)
STAKE_DIVISOR="$2"
shift 2
;;
-s|--stake)
INITIAL_STAKE="$2"
shift 2
;;
*)
echo "未知参数: $1"
usage
;;
esac
done
# 检查 bc 是否安装
if ! command -v bc &> /dev/null; then
echo "错误: 计算需要 'bc' 工具,请先安装。"
echo "在 Ubuntu/Debian 上: sudo apt-get install bc"
echo "在 CentOS/RHEL 上: sudo yum install bc"
exit 1
fi
# 计算并输出结果
echo "=================================================="
echo " FreqaiPrimer 加仓策略计算报告"
echo "=================================================="
echo "初始入场金额: ${INITIAL_STAKE} USDT"
echo "最大加仓次数: ${MAX_ENTRY_ADJUSTMENTS}"
echo "基础回调阈值: $(awk "BEGIN {printf \"%.3f\", ${ADD_POSITION_CALLBACK}*100}")%"
echo "增长因子 (G): ${ADD_POSITION_GROWTH}"
echo "间隔系数 (M): ${ADD_POSITION_MULTIPLIER}"
echo "金额分母 (D): ${STAKE_DIVISOR}"
echo "=================================================="
printf "%-8s %-12s %-12s %-12s %-12s\n" "阶段" "累计跌幅" "本次下滑" "加仓金额" "累计投入"
printf "%-8s %-12s %-12s %-12s %-12s\n" "--------" "------------" "------------" "------------" "------------"
# 初始化变量
total_investment=$INITIAL_STAKE
current_callback=$ADD_POSITION_CALLBACK
previous_callback=0
# 循环计算每次加仓
for ((i=0; i<=MAX_ENTRY_ADJUSTMENTS; i++)); do
# 计算当前阶段名称
if [ $i -eq 0 ]; then
stage="首次开仓"
else
stage="${i}次加仓"
fi
# 计算累计跌幅 (从初始价算起)
cumulative_drop=$(echo "$current_callback * 100" | bc -l)
# 计算本次加仓与上一次之间的实际价格下滑
if [ $i -eq 0 ]; then
price_slip="--"
else
actual_slip=$(echo "($current_callback - $previous_callback) * 100" | bc -l)
price_slip=$(printf "%.2f%%" $actual_slip)
fi
# 计算加仓金额
if [ $i -eq 0 ]; then
stake_amount=$INITIAL_STAKE
else
# additional_stake = (initial_stake / stake_divisor) * (add_position_growth) ^ (adjustment_count + 1)
exponent=$((i + 1))
stake_amount=$(echo "scale=2; ($INITIAL_STAKE / $STAKE_DIVISOR) * e(l($ADD_POSITION_GROWTH) * $exponent)" | bc -l)
fi
# 更新累计投入
total_investment=$(echo "scale=2; $total_investment + $stake_amount" | bc -l)
# 格式化输出
printf "%-8s %-12s %-12s %-12s %-12s\n" \
"$stage" \
"$(printf "%.2f%%" $cumulative_drop)" \
"$price_slip" \
"$(printf "%.2f" $stake_amount)" \
"$(printf "%.2f" $total_investment)"
# 为下一次迭代准备
previous_callback=$current_callback
current_callback=$(echo "$current_callback * $ADD_POSITION_MULTIPLIER" | bc -l)
done
echo "=================================================="
echo "总投入资金: ${total_investment} USDT"
echo "=================================================="