a
This commit is contained in:
parent
ec5cb088a9
commit
ff3775eada
|
|
@ -109,20 +109,23 @@ class ConfigManager:
|
|||
"""获取交易配置字典(兼容原有config.py的TRADING_CONFIG)"""
|
||||
return {
|
||||
# 仓位控制
|
||||
'MAX_POSITION_PERCENT': self.get('MAX_POSITION_PERCENT', 0.05),
|
||||
'MAX_TOTAL_POSITION_PERCENT': self.get('MAX_TOTAL_POSITION_PERCENT', 0.30),
|
||||
'MIN_POSITION_PERCENT': self.get('MIN_POSITION_PERCENT', 0.01),
|
||||
'MIN_MARGIN_USDT': self.get('MIN_MARGIN_USDT', 0.5), # 最小保证金要求(USDT)
|
||||
'MAX_POSITION_PERCENT': self.get('MAX_POSITION_PERCENT', 0.08), # 提高单笔仓位到8%
|
||||
'MAX_TOTAL_POSITION_PERCENT': self.get('MAX_TOTAL_POSITION_PERCENT', 0.40), # 提高总仓位到40%
|
||||
'MIN_POSITION_PERCENT': self.get('MIN_POSITION_PERCENT', 0.02), # 提高最小仓位到2%
|
||||
'MIN_MARGIN_USDT': self.get('MIN_MARGIN_USDT', 5.0), # 提高最小保证金到5美元
|
||||
|
||||
# 涨跌幅阈值
|
||||
'MIN_CHANGE_PERCENT': self.get('MIN_CHANGE_PERCENT', 2.0),
|
||||
'TOP_N_SYMBOLS': self.get('TOP_N_SYMBOLS', 10),
|
||||
|
||||
# 风险控制
|
||||
'STOP_LOSS_PERCENT': self.get('STOP_LOSS_PERCENT', 0.10), # 默认10%(更宽松,避免被小幅波动触发)
|
||||
'TAKE_PROFIT_PERCENT': self.get('TAKE_PROFIT_PERCENT', 0.20), # 默认20%(提高盈亏比)
|
||||
'STOP_LOSS_PERCENT': self.get('STOP_LOSS_PERCENT', 0.10), # 默认10%
|
||||
'TAKE_PROFIT_PERCENT': self.get('TAKE_PROFIT_PERCENT', 0.30), # 默认30%(盈亏比3:1)
|
||||
'MIN_STOP_LOSS_PRICE_PCT': self.get('MIN_STOP_LOSS_PRICE_PCT', 0.02), # 默认2%
|
||||
'MIN_TAKE_PROFIT_PRICE_PCT': self.get('MIN_TAKE_PROFIT_PRICE_PCT', 0.03), # 默认3%
|
||||
'USE_ATR_STOP_LOSS': self.get('USE_ATR_STOP_LOSS', True), # 是否使用ATR动态止损
|
||||
'ATR_STOP_LOSS_MULTIPLIER': self.get('ATR_STOP_LOSS_MULTIPLIER', 1.8), # ATR止损倍数
|
||||
'ATR_TAKE_PROFIT_MULTIPLIER': self.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0), # ATR止盈倍数
|
||||
|
||||
# 市场扫描(1小时主周期)
|
||||
'SCAN_INTERVAL': self.get('SCAN_INTERVAL', 3600), # 1小时
|
||||
|
|
@ -141,10 +144,10 @@ class ConfigManager:
|
|||
'MIN_SIGNAL_STRENGTH': self.get('MIN_SIGNAL_STRENGTH', 5),
|
||||
'LEVERAGE': self.get('LEVERAGE', 10),
|
||||
'USE_DYNAMIC_LEVERAGE': self.get('USE_DYNAMIC_LEVERAGE', True),
|
||||
'MAX_LEVERAGE': self.get('MAX_LEVERAGE', 20),
|
||||
'MAX_LEVERAGE': self.get('MAX_LEVERAGE', 15), # 降低到15,更保守,配合更大的保证金
|
||||
'USE_TRAILING_STOP': self.get('USE_TRAILING_STOP', True),
|
||||
'TRAILING_STOP_ACTIVATION': self.get('TRAILING_STOP_ACTIVATION', 0.05), # 默认5%(避免过早触发)
|
||||
'TRAILING_STOP_PROTECT': self.get('TRAILING_STOP_PROTECT', 0.03), # 默认3%(更合理)
|
||||
'TRAILING_STOP_ACTIVATION': self.get('TRAILING_STOP_ACTIVATION', 0.10), # 默认10%(给趋势更多空间)
|
||||
'TRAILING_STOP_PROTECT': self.get('TRAILING_STOP_PROTECT', 0.05), # 默认5%(保护更多利润)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,10 +130,10 @@ CREATE TABLE IF NOT EXISTS `trade_recommendations` (
|
|||
-- 初始化默认配置
|
||||
INSERT INTO `trading_config` (`config_key`, `config_value`, `config_type`, `category`, `description`) VALUES
|
||||
-- 仓位控制
|
||||
('MAX_POSITION_PERCENT', '0.05', 'number', 'position', '单笔最大仓位:账户余额的5%'),
|
||||
('MAX_TOTAL_POSITION_PERCENT', '0.30', 'number', 'position', '总仓位上限:账户余额的30%'),
|
||||
('MIN_POSITION_PERCENT', '0.01', 'number', 'position', '单笔最小仓位:账户余额的1%'),
|
||||
('MIN_MARGIN_USDT', '0.5', 'number', 'position', '最小保证金要求:0.5 USDT(避免手续费侵蚀收益)'),
|
||||
('MAX_POSITION_PERCENT', '0.08', 'number', 'position', '单笔最大仓位:账户余额的8%(提高收益)'),
|
||||
('MAX_TOTAL_POSITION_PERCENT', '0.40', 'number', 'position', '总仓位上限:账户余额的40%(允许更多持仓)'),
|
||||
('MIN_POSITION_PERCENT', '0.02', 'number', 'position', '单笔最小仓位:账户余额的2%(避免过小仓位)'),
|
||||
('MIN_MARGIN_USDT', '5.0', 'number', 'position', '最小保证金要求:5 USDT(提高收益)'),
|
||||
|
||||
-- 涨跌幅阈值
|
||||
('MIN_CHANGE_PERCENT', '2.0', 'number', 'scan', '最小涨跌幅阈值:2%'),
|
||||
|
|
@ -141,10 +141,13 @@ INSERT INTO `trading_config` (`config_key`, `config_value`, `config_type`, `cate
|
|||
('MAX_SCAN_SYMBOLS', '500', 'number', 'scan', '扫描的最大交易对数量(0表示扫描所有,建议100-500)'),
|
||||
|
||||
-- 风险控制
|
||||
('STOP_LOSS_PERCENT', '0.10', 'number', 'risk', '止损:10%(相对于保证金,更宽松避免被小幅波动触发)'),
|
||||
('TAKE_PROFIT_PERCENT', '0.20', 'number', 'risk', '止盈:20%(相对于保证金,提高盈亏比)'),
|
||||
('STOP_LOSS_PERCENT', '0.10', 'number', 'risk', '止损:10%(相对于保证金)'),
|
||||
('TAKE_PROFIT_PERCENT', '0.30', 'number', 'risk', '止盈:30%(相对于保证金,盈亏比3:1)'),
|
||||
('MIN_STOP_LOSS_PRICE_PCT', '0.02', 'number', 'risk', '最小止损价格变动:2%(防止止损过紧)'),
|
||||
('MIN_TAKE_PROFIT_PRICE_PCT', '0.03', 'number', 'risk', '最小止盈价格变动:3%(防止止盈过紧)'),
|
||||
('USE_ATR_STOP_LOSS', 'true', 'boolean', 'risk', '是否使用ATR动态止损(优先于固定百分比)'),
|
||||
('ATR_STOP_LOSS_MULTIPLIER', '1.8', 'number', 'risk', 'ATR止损倍数(1.5-2倍ATR,默认1.8)'),
|
||||
('ATR_TAKE_PROFIT_MULTIPLIER', '3.0', 'number', 'risk', 'ATR止盈倍数(3倍ATR,对应3:1盈亏比)'),
|
||||
|
||||
-- 市场扫描(1小时主周期)
|
||||
('SCAN_INTERVAL', '3600', 'number', 'scan', '扫描间隔:1小时(秒)'),
|
||||
|
|
@ -161,10 +164,10 @@ INSERT INTO `trading_config` (`config_key`, `config_value`, `config_type`, `cate
|
|||
('MIN_SIGNAL_STRENGTH', '7', 'number', 'strategy', '最小信号强度(0-10),已提升至7以提高入场质量'),
|
||||
('LEVERAGE', '10', 'number', 'strategy', '基础杠杆倍数'),
|
||||
('USE_DYNAMIC_LEVERAGE', 'true', 'boolean', 'strategy', '是否启用动态杠杆(根据信号强度调整杠杆倍数)'),
|
||||
('MAX_LEVERAGE', '20', 'number', 'strategy', '最大杠杆倍数(动态杠杆上限)'),
|
||||
('MAX_LEVERAGE', '15', 'number', 'strategy', '最大杠杆倍数(动态杠杆上限,降低到15更保守)'),
|
||||
('USE_TRAILING_STOP', 'true', 'boolean', 'strategy', '是否使用移动止损'),
|
||||
('TRAILING_STOP_ACTIVATION', '0.05', 'number', 'strategy', '移动止损激活阈值(盈利5%后激活,避免过早触发)'),
|
||||
('TRAILING_STOP_PROTECT', '0.03', 'number', 'strategy', '移动止损保护利润(保护3%利润,更合理)'),
|
||||
('TRAILING_STOP_ACTIVATION', '0.10', 'number', 'strategy', '移动止损激活阈值(盈利10%后激活,给趋势更多空间)'),
|
||||
('TRAILING_STOP_PROTECT', '0.05', 'number', 'strategy', '移动止损保护利润(保护5%利润,更合理)'),
|
||||
|
||||
-- 持仓同步
|
||||
('POSITION_SYNC_INTERVAL', '300', 'number', 'scan', '持仓状态同步间隔(秒),默认5分钟,用于同步币安实际持仓与数据库状态'),
|
||||
|
|
|
|||
|
|
@ -161,17 +161,20 @@ def _get_trading_config():
|
|||
return _config_manager.get_trading_config()
|
||||
# 回退到默认配置
|
||||
return {
|
||||
'MAX_POSITION_PERCENT': 0.05,
|
||||
'MAX_TOTAL_POSITION_PERCENT': 0.30,
|
||||
'MIN_POSITION_PERCENT': 0.01,
|
||||
'MIN_MARGIN_USDT': 0.5, # 最小保证金要求(USDT),如果保证金小于此值,自动调整到0.5U保证金
|
||||
'MAX_POSITION_PERCENT': 0.08, # 提高单笔仓位到8%(原来5%),增加收益
|
||||
'MAX_TOTAL_POSITION_PERCENT': 0.40, # 提高总仓位到40%(原来30%),允许更多持仓
|
||||
'MIN_POSITION_PERCENT': 0.02, # 提高最小仓位到2%(原来1%),避免过小仓位
|
||||
'MIN_MARGIN_USDT': 5.0, # 提高最小保证金到5美元(原来0.5U),确保收益可观
|
||||
'MIN_CHANGE_PERCENT': 0.5, # 降低到0.5%以获取更多推荐(推荐系统可以更宽松)
|
||||
'TOP_N_SYMBOLS': 50, # 每次扫描后处理的交易对数量(增加到50以获取更多推荐)
|
||||
'MAX_SCAN_SYMBOLS': 500, # 扫描的最大交易对数量(0表示扫描所有)
|
||||
'STOP_LOSS_PERCENT': 0.10, # 止损百分比(相对于保证金),默认10%(更宽松,避免被小幅波动触发)
|
||||
'TAKE_PROFIT_PERCENT': 0.20, # 止盈百分比(相对于保证金),默认20%(提高盈亏比)
|
||||
'STOP_LOSS_PERCENT': 0.10, # 止损百分比(相对于保证金),默认10%
|
||||
'TAKE_PROFIT_PERCENT': 0.30, # 止盈百分比(相对于保证金),默认30%(盈亏比3:1)
|
||||
'MIN_STOP_LOSS_PRICE_PCT': 0.02, # 最小止损价格变动百分比(如0.02表示2%),防止止损过紧,默认2%
|
||||
'MIN_TAKE_PROFIT_PRICE_PCT': 0.03, # 最小止盈价格变动百分比(如0.03表示3%),防止止盈过紧,默认3%
|
||||
'USE_ATR_STOP_LOSS': True, # 是否使用ATR动态止损(优先于固定百分比)
|
||||
'ATR_STOP_LOSS_MULTIPLIER': 1.8, # ATR止损倍数(1.5-2倍ATR,默认1.8)
|
||||
'ATR_TAKE_PROFIT_MULTIPLIER': 3.0, # ATR止盈倍数(3倍ATR,对应3:1盈亏比)
|
||||
'SCAN_INTERVAL': 3600,
|
||||
'KLINE_INTERVAL': '1h',
|
||||
'PRIMARY_INTERVAL': '1h',
|
||||
|
|
@ -182,10 +185,10 @@ def _get_trading_config():
|
|||
'MIN_SIGNAL_STRENGTH': 7, # 提高至7,只交易高质量信号(简化策略后)
|
||||
'LEVERAGE': 10, # 基础杠杆倍数
|
||||
'USE_DYNAMIC_LEVERAGE': True, # 是否启用动态杠杆(根据信号强度调整)
|
||||
'MAX_LEVERAGE': 20, # 最大杠杆倍数(动态杠杆上限)
|
||||
'MAX_LEVERAGE': 15, # 最大杠杆倍数(降低到15,更保守,配合更大的保证金)
|
||||
'USE_TRAILING_STOP': True,
|
||||
'TRAILING_STOP_ACTIVATION': 0.05, # 移动止损激活从1%改为5%(避免过早触发)
|
||||
'TRAILING_STOP_PROTECT': 0.03, # 保护利润从1%提高到3%(更合理)
|
||||
'TRAILING_STOP_ACTIVATION': 0.10, # 移动止损激活提高到10%(盈利10%后激活,给趋势更多空间)
|
||||
'TRAILING_STOP_PROTECT': 0.05, # 保护利润提高到5%(保护5%利润,更合理)
|
||||
'POSITION_SYNC_INTERVAL': 300, # 持仓状态同步间隔(秒),默认5分钟
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ class PositionManager:
|
|||
atr=atr
|
||||
)
|
||||
|
||||
<<<<<<< Current (Your changes)
|
||||
# 计算止盈(基于保证金)
|
||||
# 优先使用配置的止盈百分比,如果没有配置则使用止损的2倍
|
||||
take_profit_pct_margin = self.risk_manager.config.get('TAKE_PROFIT_PERCENT', 0.15)
|
||||
|
|
@ -172,6 +173,18 @@ class PositionManager:
|
|||
take_profit_price = self.risk_manager.get_take_profit_price(
|
||||
entry_price, side, quantity, leverage,
|
||||
take_profit_pct=take_profit_pct_margin
|
||||
=======
|
||||
# 计算止盈(基于保证金,支持ATR动态止盈)
|
||||
# 优先使用配置的止盈百分比,如果没有配置则使用止损的3倍(盈亏比3:1)
|
||||
take_profit_pct_margin = self.risk_manager.config.get('TAKE_PROFIT_PERCENT', 0.30)
|
||||
# 如果配置中没有设置止盈,则使用止损的3倍作为默认(盈亏比3:1)
|
||||
if take_profit_pct_margin is None or take_profit_pct_margin == 0:
|
||||
take_profit_pct_margin = stop_loss_pct_margin * 3.0
|
||||
take_profit_price = self.risk_manager.get_take_profit_price(
|
||||
entry_price, side, quantity, leverage,
|
||||
take_profit_pct=take_profit_pct_margin,
|
||||
atr=atr # 传递ATR用于动态止盈
|
||||
>>>>>>> Incoming (Background Agent changes)
|
||||
)
|
||||
|
||||
# 下单
|
||||
|
|
|
|||
|
|
@ -426,6 +426,28 @@ class RiskManager:
|
|||
position_value = entry_price * quantity
|
||||
margin = position_value / leverage if leverage > 0 else position_value
|
||||
|
||||
# 优先使用ATR动态止损(如果启用且ATR可用)
|
||||
use_atr_stop = self.config.get('USE_ATR_STOP_LOSS', True)
|
||||
atr_multiplier = self.config.get('ATR_STOP_LOSS_MULTIPLIER', 1.8)
|
||||
|
||||
if use_atr_stop and atr is not None and atr > 0:
|
||||
# 基于ATR的动态止损
|
||||
atr_stop_distance = atr * atr_multiplier
|
||||
|
||||
if side == 'BUY': # 做多,止损价低于入场价
|
||||
stop_loss_price_atr = entry_price - atr_stop_distance
|
||||
else: # 做空,止损价高于入场价
|
||||
stop_loss_price_atr = entry_price + atr_stop_distance
|
||||
|
||||
logger.info(
|
||||
f"ATR动态止损计算 ({side}): ATR={atr:.4f}, 倍数={atr_multiplier}, "
|
||||
f"止损距离={atr_stop_distance:.4f}, ATR止损价={stop_loss_price_atr:.4f}"
|
||||
)
|
||||
else:
|
||||
stop_loss_price_atr = None
|
||||
if use_atr_stop and (atr is None or atr <= 0):
|
||||
logger.debug(f"ATR不可用,使用固定百分比止损")
|
||||
|
||||
# 获取止损百分比(相对于保证金)
|
||||
stop_loss_percent = stop_loss_pct or self.config['STOP_LOSS_PERCENT']
|
||||
|
||||
|
|
@ -449,23 +471,27 @@ class RiskManager:
|
|||
stop_loss_price_price = entry_price * (1 - min_price_change_pct)
|
||||
else:
|
||||
stop_loss_price_price = entry_price * (1 + min_price_change_pct)
|
||||
else:
|
||||
stop_loss_price_price = None
|
||||
|
||||
# 取更宽松的止损价(对做多取更大的值,对做空取更小的值)
|
||||
# 选择最终的止损价:优先ATR,其次保证金,最后价格百分比(取更宽松的)
|
||||
candidate_prices = []
|
||||
if stop_loss_price_atr is not None:
|
||||
candidate_prices.append(('ATR', stop_loss_price_atr))
|
||||
candidate_prices.append(('保证金', stop_loss_price_margin))
|
||||
if stop_loss_price_price is not None:
|
||||
candidate_prices.append(('价格百分比', stop_loss_price_price))
|
||||
|
||||
# 对做多取最大的值(最宽松),对做空取最小的值(最宽松)
|
||||
if side == 'BUY':
|
||||
stop_loss_price = max(stop_loss_price_margin, stop_loss_price_price)
|
||||
stop_loss_price = max(p[1] for p in candidate_prices)
|
||||
selected_method = [p[0] for p in candidate_prices if p[1] == stop_loss_price][0]
|
||||
else:
|
||||
stop_loss_price = min(stop_loss_price_margin, stop_loss_price_price)
|
||||
stop_loss_price = min(p[1] for p in candidate_prices)
|
||||
selected_method = [p[0] for p in candidate_prices if p[1] == stop_loss_price][0]
|
||||
|
||||
logger.info(
|
||||
f"止损计算 ({side}): 基于保证金={stop_loss_price_margin:.4f}, "
|
||||
f"基于价格={stop_loss_price_price:.4f}, "
|
||||
f"最终止损={stop_loss_price:.4f} (取更宽松)"
|
||||
)
|
||||
else:
|
||||
# 没有配置最小价格变动,直接使用基于保证金的止损价
|
||||
stop_loss_price = stop_loss_price_margin
|
||||
|
||||
# 如果提供了技术分析数据,可以调整止损价(但不能超过基于保证金的止损范围)
|
||||
# 如果提供了技术分析数据,计算技术止损(允许更紧的止损,但需要在保证金止损范围内)
|
||||
technical_stop = None
|
||||
if klines and len(klines) >= 10:
|
||||
# 计算支撑/阻力位
|
||||
low_prices = [float(k[3]) for k in klines[-20:]] # 最近20根K线的最低价
|
||||
|
|
@ -483,22 +509,14 @@ class RiskManager:
|
|||
bollinger_stop = bollinger['lower'] * 0.995 # 布林带下轨下方0.5%
|
||||
technical_stop = max(technical_stop, bollinger_stop)
|
||||
|
||||
# 使用技术止损,但不能超过基于保证金的止损范围(允许更紧的止损)
|
||||
# 如果技术止损更紧(价格更低),使用技术止损;否则使用基于保证金的止损
|
||||
if technical_stop < stop_loss_price:
|
||||
# 技术止损更紧,使用技术止损
|
||||
logger.info(
|
||||
f"动态止损计算 (BUY): 使用技术止损 {technical_stop:.4f} "
|
||||
f"(基于保证金的止损: {stop_loss_price:.4f}, 止损金额: {stop_loss_amount:.2f} USDT)"
|
||||
# 技术止损更紧,但需要确保在保证金止损范围内(不能超过保证金止损)
|
||||
if technical_stop < stop_loss_price and technical_stop >= stop_loss_price_margin:
|
||||
# 技术止损在合理范围内,可以考虑使用
|
||||
candidate_prices.append(('技术分析', technical_stop))
|
||||
logger.debug(
|
||||
f"技术止损 (BUY): {technical_stop:.4f} "
|
||||
f"(在保证金止损范围内)"
|
||||
)
|
||||
return technical_stop
|
||||
else:
|
||||
logger.info(
|
||||
f"动态止损计算 (BUY): 使用基于保证金的止损 {stop_loss_price:.4f} "
|
||||
f"(技术止损: {technical_stop:.4f}, 止损金额: {stop_loss_amount:.2f} USDT, "
|
||||
f"止损比例: {stop_loss_percent*100:.1f}% of margin)"
|
||||
)
|
||||
return stop_loss_price
|
||||
else: # 做空,止损放在阻力位上方
|
||||
# 找到近期波段高点
|
||||
recent_high = max(high_prices)
|
||||
|
|
@ -511,31 +529,32 @@ class RiskManager:
|
|||
bollinger_stop = bollinger['upper'] * 1.005 # 布林带上轨上方0.5%
|
||||
technical_stop = min(technical_stop, bollinger_stop)
|
||||
|
||||
# 使用技术止损,但不能超过基于保证金的止损范围(允许更紧的止损)
|
||||
# 如果技术止损更紧(价格更高),使用技术止损;否则使用基于保证金的止损
|
||||
if technical_stop > stop_loss_price:
|
||||
# 技术止损更紧,使用技术止损
|
||||
logger.info(
|
||||
f"动态止损计算 (SELL): 使用技术止损 {technical_stop:.4f} "
|
||||
f"(基于保证金的止损: {stop_loss_price:.4f}, 止损金额: {stop_loss_amount:.2f} USDT)"
|
||||
# 技术止损更紧,但需要确保在保证金止损范围内(不能超过保证金止损)
|
||||
if technical_stop > stop_loss_price and technical_stop <= stop_loss_price_margin:
|
||||
# 技术止损在合理范围内,可以考虑使用
|
||||
candidate_prices.append(('技术分析', technical_stop))
|
||||
logger.debug(
|
||||
f"技术止损 (SELL): {technical_stop:.4f} "
|
||||
f"(在保证金止损范围内)"
|
||||
)
|
||||
return technical_stop
|
||||
else:
|
||||
logger.info(
|
||||
f"动态止损计算 (SELL): 使用基于保证金的止损 {stop_loss_price:.4f} "
|
||||
f"(技术止损: {technical_stop:.4f}, 止损金额: {stop_loss_amount:.2f} USDT, "
|
||||
f"止损比例: {stop_loss_percent*100:.1f}% of margin)"
|
||||
)
|
||||
return stop_loss_price
|
||||
|
||||
# 没有技术分析数据,直接使用基于保证金的止损
|
||||
# 重新选择最终的止损价(包括技术止损)
|
||||
if side == 'BUY':
|
||||
final_stop_loss = max(p[1] for p in candidate_prices)
|
||||
selected_method = [p[0] for p in candidate_prices if p[1] == final_stop_loss][0]
|
||||
else:
|
||||
final_stop_loss = min(p[1] for p in candidate_prices)
|
||||
selected_method = [p[0] for p in candidate_prices if p[1] == final_stop_loss][0]
|
||||
|
||||
logger.info(
|
||||
f"止损计算 ({side}): 入场价={entry_price:.4f}, 数量={quantity:.4f}, "
|
||||
f"杠杆={leverage}x, 保证金={margin:.4f} USDT, "
|
||||
f"止损金额={stop_loss_amount:.4f} USDT ({stop_loss_percent*100:.1f}% of margin), "
|
||||
f"止损价={stop_loss_price:.4f}"
|
||||
f"最终止损 ({side}): {final_stop_loss:.4f} (使用{selected_method}), "
|
||||
+ (f"ATR={stop_loss_price_atr:.4f}, " if stop_loss_price_atr else "")
|
||||
+ f"保证金={stop_loss_price_margin:.4f}, "
|
||||
+ (f"价格={stop_loss_price_price:.4f}, " if stop_loss_price_price else "")
|
||||
+ (f"技术={technical_stop:.4f}, " if technical_stop else "")
|
||||
+ f"止损金额={stop_loss_amount:.2f} USDT ({stop_loss_percent*100:.1f}% of margin)"
|
||||
)
|
||||
return stop_loss_price
|
||||
return final_stop_loss
|
||||
|
||||
def get_take_profit_price(
|
||||
self,
|
||||
|
|
@ -543,10 +562,11 @@ class RiskManager:
|
|||
side: str,
|
||||
quantity: float,
|
||||
leverage: int,
|
||||
take_profit_pct: Optional[float] = None
|
||||
take_profit_pct: Optional[float] = None,
|
||||
atr: Optional[float] = None
|
||||
) -> float:
|
||||
"""
|
||||
计算止盈价格(基于保证金的盈亏金额)
|
||||
计算止盈价格(基于保证金的盈亏金额,支持ATR动态止盈)
|
||||
|
||||
Args:
|
||||
entry_price: 入场价格
|
||||
|
|
@ -554,6 +574,7 @@ class RiskManager:
|
|||
quantity: 持仓数量
|
||||
leverage: 杠杆倍数
|
||||
take_profit_pct: 止盈百分比(相对于保证金),如果为None则使用配置值
|
||||
atr: 平均真实波幅,用于计算动态止盈(可选)
|
||||
|
||||
Returns:
|
||||
止盈价格
|
||||
|
|
@ -562,6 +583,28 @@ class RiskManager:
|
|||
position_value = entry_price * quantity
|
||||
margin = position_value / leverage if leverage > 0 else position_value
|
||||
|
||||
# 优先使用ATR动态止盈(如果启用且ATR可用)
|
||||
use_atr_stop = self.config.get('USE_ATR_STOP_LOSS', True)
|
||||
atr_tp_multiplier = self.config.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0)
|
||||
|
||||
if use_atr_stop and atr is not None and atr > 0:
|
||||
# 基于ATR的动态止盈(对应3:1盈亏比)
|
||||
atr_tp_distance = atr * atr_tp_multiplier
|
||||
|
||||
if side == 'BUY': # 做多,止盈价高于入场价
|
||||
take_profit_price_atr = entry_price + atr_tp_distance
|
||||
else: # 做空,止盈价低于入场价
|
||||
take_profit_price_atr = entry_price - atr_tp_distance
|
||||
|
||||
logger.info(
|
||||
f"ATR动态止盈计算 ({side}): ATR={atr:.4f}, 倍数={atr_tp_multiplier}, "
|
||||
f"止盈距离={atr_tp_distance:.4f}, ATR止盈价={take_profit_price_atr:.4f}"
|
||||
)
|
||||
else:
|
||||
take_profit_price_atr = None
|
||||
if use_atr_stop and (atr is None or atr <= 0):
|
||||
logger.debug(f"ATR不可用,使用固定百分比止盈")
|
||||
|
||||
# 获取止盈百分比(相对于保证金)
|
||||
take_profit_percent = take_profit_pct or self.config['TAKE_PROFIT_PERCENT']
|
||||
|
||||
|
|
@ -585,27 +628,32 @@ class RiskManager:
|
|||
take_profit_price_price = entry_price * (1 + min_price_change_pct)
|
||||
else:
|
||||
take_profit_price_price = entry_price * (1 - min_price_change_pct)
|
||||
else:
|
||||
take_profit_price_price = None
|
||||
|
||||
# 取更宽松的止盈价(对做多取更大的值,对做空取更小的值)
|
||||
# 选择最终的止盈价:优先ATR,其次保证金,最后价格百分比(取更宽松的)
|
||||
candidate_prices = []
|
||||
if take_profit_price_atr is not None:
|
||||
candidate_prices.append(('ATR', take_profit_price_atr))
|
||||
candidate_prices.append(('保证金', take_profit_price_margin))
|
||||
if take_profit_price_price is not None:
|
||||
candidate_prices.append(('价格百分比', take_profit_price_price))
|
||||
|
||||
# 对做多取最大的值(更宽松),对做空取最小的值(更宽松)
|
||||
if side == 'BUY':
|
||||
take_profit_price = max(take_profit_price_margin, take_profit_price_price)
|
||||
take_profit_price = max(p[1] for p in candidate_prices)
|
||||
selected_method = [p[0] for p in candidate_prices if p[1] == take_profit_price][0]
|
||||
else:
|
||||
take_profit_price = min(take_profit_price_margin, take_profit_price_price)
|
||||
take_profit_price = min(p[1] for p in candidate_prices)
|
||||
selected_method = [p[0] for p in candidate_prices if p[1] == take_profit_price][0]
|
||||
|
||||
logger.info(
|
||||
f"止盈计算 ({side}): 基于保证金={take_profit_price_margin:.4f}, "
|
||||
f"基于价格={take_profit_price_price:.4f}, "
|
||||
f"最终止盈={take_profit_price:.4f} (取更宽松)"
|
||||
)
|
||||
else:
|
||||
# 没有配置最小价格变动,直接使用基于保证金的止盈价
|
||||
take_profit_price = take_profit_price_margin
|
||||
|
||||
logger.info(
|
||||
f"止盈计算 ({side}): 入场价={entry_price:.4f}, 数量={quantity:.4f}, "
|
||||
f"杠杆={leverage}x, 保证金={margin:.4f} USDT, "
|
||||
f"止盈金额={take_profit_amount:.4f} USDT ({take_profit_percent*100:.1f}% of margin), "
|
||||
f"止盈价={take_profit_price:.4f}"
|
||||
f"止盈计算 ({side}): "
|
||||
+ (f"ATR={take_profit_price_atr:.4f}, " if take_profit_price_atr else "")
|
||||
+ f"基于保证金={take_profit_price_margin:.4f}, "
|
||||
+ (f"基于价格={take_profit_price_price:.4f}, " if take_profit_price_price else "")
|
||||
+ f"最终止盈={take_profit_price:.4f} (使用{selected_method}, 取更宽松), "
|
||||
+ f"止盈金额={take_profit_amount:.4f} USDT ({take_profit_percent*100:.1f}% of margin)"
|
||||
)
|
||||
return take_profit_price
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user