a
This commit is contained in:
parent
3dc037599b
commit
c778afdcb6
|
|
@ -75,23 +75,56 @@ async def check_config_feasibility():
|
||||||
required_position_value = min_margin_usdt * leverage
|
required_position_value = min_margin_usdt * leverage
|
||||||
required_position_percent = required_position_value / available_balance if available_balance > 0 else 0
|
required_position_percent = required_position_value / available_balance if available_balance > 0 else 0
|
||||||
|
|
||||||
# 检查是否可行
|
# 计算使用最小仓位百分比时,实际能得到的保证金
|
||||||
is_feasible = required_position_percent <= max_position_percent
|
min_position_value = available_balance * min_position_percent
|
||||||
|
actual_min_margin = min_position_value / leverage if leverage > 0 else min_position_value
|
||||||
|
|
||||||
|
# 检查是否可行:
|
||||||
|
# 1. 需要的仓位百分比不能超过最大允许的仓位百分比
|
||||||
|
# 2. 使用最小仓位百分比时,实际保证金必须 >= 最小保证金要求
|
||||||
|
is_feasible = (required_position_percent <= max_position_percent) and (actual_min_margin >= min_margin_usdt)
|
||||||
|
|
||||||
suggestions = []
|
suggestions = []
|
||||||
|
|
||||||
if not is_feasible:
|
if not is_feasible:
|
||||||
# 不可行,给出建议
|
# 不可行,给出建议
|
||||||
# 方案1:降低最小保证金
|
# 判断是哪个条件不满足
|
||||||
suggested_min_margin = (available_balance * max_position_percent) / leverage
|
if required_position_percent > max_position_percent:
|
||||||
suggestions.append({
|
# 条件1不满足:需要的仓位百分比超过最大允许
|
||||||
"type": "reduce_min_margin",
|
# 方案1:降低最小保证金
|
||||||
"title": "降低最小保证金",
|
suggested_min_margin = (available_balance * max_position_percent) / leverage
|
||||||
"description": f"将 MIN_MARGIN_USDT 调整为 {suggested_min_margin:.2f} USDT(当前: {min_margin_usdt:.2f} USDT)",
|
suggestions.append({
|
||||||
"config_key": "MIN_MARGIN_USDT",
|
"type": "reduce_min_margin",
|
||||||
"suggested_value": round(suggested_min_margin, 2),
|
"title": "降低最小保证金",
|
||||||
"reason": f"当前配置需要 {required_position_percent*100:.1f}% 的仓位价值,但最大允许 {max_position_percent*100:.1f}%"
|
"description": f"将 MIN_MARGIN_USDT 调整为 {suggested_min_margin:.2f} USDT(当前: {min_margin_usdt:.2f} USDT)",
|
||||||
})
|
"config_key": "MIN_MARGIN_USDT",
|
||||||
|
"suggested_value": round(suggested_min_margin, 2),
|
||||||
|
"reason": f"当前配置需要 {required_position_percent*100:.1f}% 的仓位价值,但最大允许 {max_position_percent*100:.1f}%"
|
||||||
|
})
|
||||||
|
|
||||||
|
if actual_min_margin < min_margin_usdt:
|
||||||
|
# 条件2不满足:使用最小仓位时,实际保证金不足
|
||||||
|
# 方案1:降低最小保证金到实际能支持的值
|
||||||
|
suggestions.append({
|
||||||
|
"type": "reduce_min_margin_to_supported",
|
||||||
|
"title": "降低最小保证金到可支持值",
|
||||||
|
"description": f"将 MIN_MARGIN_USDT 调整为 {actual_min_margin:.2f} USDT(当前: {min_margin_usdt:.2f} USDT,实际只支持 {actual_min_margin:.2f} USDT)",
|
||||||
|
"config_key": "MIN_MARGIN_USDT",
|
||||||
|
"suggested_value": round(actual_min_margin, 2),
|
||||||
|
"reason": f"当前账户余额和配置下,使用最小仓位 {min_position_percent*100:.1f}% 时,实际保证金只有 {actual_min_margin:.2f} USDT,无法满足 {min_margin_usdt:.2f} USDT 的要求"
|
||||||
|
})
|
||||||
|
|
||||||
|
# 方案2:提高最小仓位百分比
|
||||||
|
required_min_position_percent = (min_margin_usdt * leverage) / available_balance if available_balance > 0 else 0
|
||||||
|
if required_min_position_percent <= max_position_percent:
|
||||||
|
suggestions.append({
|
||||||
|
"type": "increase_min_position",
|
||||||
|
"title": "提高最小仓位百分比",
|
||||||
|
"description": f"将 MIN_POSITION_PERCENT 调整为 {required_min_position_percent*100:.2f}%(当前: {min_position_percent*100:.1f}%)",
|
||||||
|
"config_key": "MIN_POSITION_PERCENT",
|
||||||
|
"suggested_value": round(required_min_position_percent, 4),
|
||||||
|
"reason": f"需要至少 {required_min_position_percent*100:.2f}% 的仓位才能满足 {min_margin_usdt:.2f} USDT 的保证金要求"
|
||||||
|
})
|
||||||
|
|
||||||
# 方案2:增加账户余额
|
# 方案2:增加账户余额
|
||||||
required_balance = required_position_value / max_position_percent
|
required_balance = required_position_value / max_position_percent
|
||||||
|
|
@ -141,7 +174,10 @@ async def check_config_feasibility():
|
||||||
"calculated_values": {
|
"calculated_values": {
|
||||||
"required_position_value": required_position_value,
|
"required_position_value": required_position_value,
|
||||||
"required_position_percent": required_position_percent * 100,
|
"required_position_percent": required_position_percent * 100,
|
||||||
"max_allowed_position_percent": max_position_percent * 100
|
"max_allowed_position_percent": max_position_percent * 100,
|
||||||
|
"min_position_value": min_position_value,
|
||||||
|
"actual_min_margin": actual_min_margin,
|
||||||
|
"min_position_percent": min_position_percent * 100
|
||||||
},
|
},
|
||||||
"suggestions": suggestions
|
"suggestions": suggestions
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -301,10 +301,19 @@ const ConfigPanel = () => {
|
||||||
最小保证金: <strong>{feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2) || 'N/A'}</strong> USDT
|
最小保证金: <strong>{feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2) || 'N/A'}</strong> USDT
|
||||||
</p>
|
</p>
|
||||||
{!feasibilityCheck.feasible && (
|
{!feasibilityCheck.feasible && (
|
||||||
<p className="warning-text">
|
<div className="warning-text">
|
||||||
需要仓位价值: <strong>{feasibilityCheck.calculated_values?.required_position_percent?.toFixed(1)}%</strong> |
|
<p>
|
||||||
最大允许: <strong>{feasibilityCheck.calculated_values?.max_allowed_position_percent?.toFixed(1)}%</strong>
|
需要仓位价值: <strong>{feasibilityCheck.calculated_values?.required_position_percent?.toFixed(1)}%</strong> |
|
||||||
</p>
|
最大允许: <strong>{feasibilityCheck.calculated_values?.max_allowed_position_percent?.toFixed(1)}%</strong>
|
||||||
|
</p>
|
||||||
|
{feasibilityCheck.calculated_values?.actual_min_margin !== undefined && (
|
||||||
|
<p>
|
||||||
|
实际支持保证金: <strong>{feasibilityCheck.calculated_values.actual_min_margin.toFixed(2)} USDT</strong>
|
||||||
|
(使用最小仓位 {feasibilityCheck.calculated_values.min_position_percent?.toFixed(1)}%) |
|
||||||
|
要求: <strong>{feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2)} USDT</strong>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{feasibilityCheck.suggestions && feasibilityCheck.suggestions.length > 0 && (
|
{feasibilityCheck.suggestions && feasibilityCheck.suggestions.length > 0 && (
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ class RiskManager:
|
||||||
client: 币安客户端
|
client: 币安客户端
|
||||||
"""
|
"""
|
||||||
self.client = client
|
self.client = client
|
||||||
self.config = config.TRADING_CONFIG
|
# 不保存引用,每次都从 config.TRADING_CONFIG 读取最新配置
|
||||||
|
# self.config = config.TRADING_CONFIG # 移除,避免使用旧配置
|
||||||
|
|
||||||
async def check_position_size(self, symbol: str, quantity: float) -> bool:
|
async def check_position_size(self, symbol: str, quantity: float) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
@ -57,11 +58,11 @@ class RiskManager:
|
||||||
current_price = ticker['price']
|
current_price = ticker['price']
|
||||||
position_value = quantity * current_price
|
position_value = quantity * current_price
|
||||||
|
|
||||||
# 检查单笔仓位是否超过最大限制
|
# 检查单笔仓位是否超过最大限制(每次都从最新配置读取)
|
||||||
max_position_value = available_balance * self.config['MAX_POSITION_PERCENT']
|
max_position_value = available_balance * config.TRADING_CONFIG['MAX_POSITION_PERCENT']
|
||||||
min_position_value = available_balance * self.config['MIN_POSITION_PERCENT']
|
min_position_value = available_balance * config.TRADING_CONFIG['MIN_POSITION_PERCENT']
|
||||||
max_position_pct = self.config['MAX_POSITION_PERCENT'] * 100
|
max_position_pct = config.TRADING_CONFIG['MAX_POSITION_PERCENT'] * 100
|
||||||
min_position_pct = self.config['MIN_POSITION_PERCENT'] * 100
|
min_position_pct = config.TRADING_CONFIG['MIN_POSITION_PERCENT'] * 100
|
||||||
|
|
||||||
logger.info(f" 数量: {quantity:.4f}")
|
logger.info(f" 数量: {quantity:.4f}")
|
||||||
logger.info(f" 价格: {current_price:.4f} USDT")
|
logger.info(f" 价格: {current_price:.4f} USDT")
|
||||||
|
|
@ -150,8 +151,8 @@ class RiskManager:
|
||||||
logger.warning("账户总余额为0,无法开仓")
|
logger.warning("账户总余额为0,无法开仓")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
max_total_position = total_balance * self.config['MAX_TOTAL_POSITION_PERCENT']
|
max_total_position = total_balance * config.TRADING_CONFIG['MAX_TOTAL_POSITION_PERCENT']
|
||||||
max_total_position_pct = self.config['MAX_TOTAL_POSITION_PERCENT'] * 100
|
max_total_position_pct = config.TRADING_CONFIG['MAX_TOTAL_POSITION_PERCENT'] * 100
|
||||||
|
|
||||||
# 详细日志
|
# 详细日志
|
||||||
logger.info("=" * 60)
|
logger.info("=" * 60)
|
||||||
|
|
@ -243,9 +244,9 @@ class RiskManager:
|
||||||
logger.info(f" 当前价格: {current_price:.4f} USDT")
|
logger.info(f" 当前价格: {current_price:.4f} USDT")
|
||||||
|
|
||||||
# 根据涨跌幅调整仓位大小(涨跌幅越大,仓位可以适当增加)
|
# 根据涨跌幅调整仓位大小(涨跌幅越大,仓位可以适当增加)
|
||||||
base_position_percent = self.config['MAX_POSITION_PERCENT']
|
base_position_percent = config.TRADING_CONFIG['MAX_POSITION_PERCENT']
|
||||||
max_position_percent = self.config['MAX_POSITION_PERCENT']
|
max_position_percent = config.TRADING_CONFIG['MAX_POSITION_PERCENT']
|
||||||
min_position_percent = self.config['MIN_POSITION_PERCENT']
|
min_position_percent = config.TRADING_CONFIG['MIN_POSITION_PERCENT']
|
||||||
|
|
||||||
# 涨跌幅超过5%时,可以适当增加仓位(但不超过1.5倍)
|
# 涨跌幅超过5%时,可以适当增加仓位(但不超过1.5倍)
|
||||||
if abs(change_percent) > 5:
|
if abs(change_percent) > 5:
|
||||||
|
|
@ -303,9 +304,9 @@ class RiskManager:
|
||||||
position_value = required_quantity * current_price
|
position_value = required_quantity * current_price
|
||||||
|
|
||||||
# 检查最小保证金要求(如果保证金小于此值,自动调整到0.5U保证金)
|
# 检查最小保证金要求(如果保证金小于此值,自动调整到0.5U保证金)
|
||||||
min_margin_usdt = self.config.get('MIN_MARGIN_USDT', 0.5) # 默认0.5 USDT
|
min_margin_usdt = config.TRADING_CONFIG.get('MIN_MARGIN_USDT', 0.5) # 默认0.5 USDT
|
||||||
# 使用传入的实际杠杆,如果没有传入则使用配置的基础杠杆
|
# 使用传入的实际杠杆,如果没有传入则使用配置的基础杠杆
|
||||||
actual_leverage = leverage if leverage is not None else self.config.get('LEVERAGE', 10)
|
actual_leverage = leverage if leverage is not None else config.TRADING_CONFIG.get('LEVERAGE', 10)
|
||||||
|
|
||||||
# 计算实际需要的保证金 = 仓位价值 / 杠杆
|
# 计算实际需要的保证金 = 仓位价值 / 杠杆
|
||||||
required_margin = position_value / actual_leverage
|
required_margin = position_value / actual_leverage
|
||||||
|
|
@ -378,7 +379,7 @@ class RiskManager:
|
||||||
是否应该交易
|
是否应该交易
|
||||||
"""
|
"""
|
||||||
# 检查最小涨跌幅阈值
|
# 检查最小涨跌幅阈值
|
||||||
if abs(change_percent) < self.config['MIN_CHANGE_PERCENT']:
|
if abs(change_percent) < config.TRADING_CONFIG['MIN_CHANGE_PERCENT']:
|
||||||
logger.debug(f"{symbol} 涨跌幅 {change_percent:.2f}% 小于阈值")
|
logger.debug(f"{symbol} 涨跌幅 {change_percent:.2f}% 小于阈值")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -427,8 +428,8 @@ class RiskManager:
|
||||||
margin = position_value / leverage if leverage > 0 else position_value
|
margin = position_value / leverage if leverage > 0 else position_value
|
||||||
|
|
||||||
# 优先使用ATR动态止损(如果启用且ATR可用)
|
# 优先使用ATR动态止损(如果启用且ATR可用)
|
||||||
use_atr_stop = self.config.get('USE_ATR_STOP_LOSS', True)
|
use_atr_stop = config.TRADING_CONFIG.get('USE_ATR_STOP_LOSS', True)
|
||||||
atr_multiplier = self.config.get('ATR_STOP_LOSS_MULTIPLIER', 1.8)
|
atr_multiplier = config.TRADING_CONFIG.get('ATR_STOP_LOSS_MULTIPLIER', 1.8)
|
||||||
|
|
||||||
if use_atr_stop and atr is not None and atr > 0:
|
if use_atr_stop and atr is not None and atr > 0:
|
||||||
# 基于ATR的动态止损
|
# 基于ATR的动态止损
|
||||||
|
|
@ -449,7 +450,7 @@ class RiskManager:
|
||||||
logger.debug(f"ATR不可用,使用固定百分比止损")
|
logger.debug(f"ATR不可用,使用固定百分比止损")
|
||||||
|
|
||||||
# 获取止损百分比(相对于保证金)
|
# 获取止损百分比(相对于保证金)
|
||||||
stop_loss_percent = stop_loss_pct or self.config['STOP_LOSS_PERCENT']
|
stop_loss_percent = stop_loss_pct or config.TRADING_CONFIG['STOP_LOSS_PERCENT']
|
||||||
|
|
||||||
# 计算止损金额(相对于保证金)
|
# 计算止损金额(相对于保证金)
|
||||||
stop_loss_amount = margin * stop_loss_percent
|
stop_loss_amount = margin * stop_loss_percent
|
||||||
|
|
@ -464,7 +465,7 @@ class RiskManager:
|
||||||
|
|
||||||
# 同时计算基于价格百分比的止损价(作为最小值保护)
|
# 同时计算基于价格百分比的止损价(作为最小值保护)
|
||||||
# 获取最小价格变动百分比(如果配置了)
|
# 获取最小价格变动百分比(如果配置了)
|
||||||
min_price_change_pct = self.config.get('MIN_STOP_LOSS_PRICE_PCT', None)
|
min_price_change_pct = config.TRADING_CONFIG.get('MIN_STOP_LOSS_PRICE_PCT', None)
|
||||||
if min_price_change_pct is not None:
|
if min_price_change_pct is not None:
|
||||||
# 基于价格百分比的止损价
|
# 基于价格百分比的止损价
|
||||||
if side == 'BUY':
|
if side == 'BUY':
|
||||||
|
|
@ -584,8 +585,8 @@ class RiskManager:
|
||||||
margin = position_value / leverage if leverage > 0 else position_value
|
margin = position_value / leverage if leverage > 0 else position_value
|
||||||
|
|
||||||
# 优先使用ATR动态止盈(如果启用且ATR可用)
|
# 优先使用ATR动态止盈(如果启用且ATR可用)
|
||||||
use_atr_stop = self.config.get('USE_ATR_STOP_LOSS', True)
|
use_atr_stop = config.TRADING_CONFIG.get('USE_ATR_STOP_LOSS', True)
|
||||||
atr_tp_multiplier = self.config.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0)
|
atr_tp_multiplier = config.TRADING_CONFIG.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0)
|
||||||
|
|
||||||
if use_atr_stop and atr is not None and atr > 0:
|
if use_atr_stop and atr is not None and atr > 0:
|
||||||
# 基于ATR的动态止盈(对应3:1盈亏比)
|
# 基于ATR的动态止盈(对应3:1盈亏比)
|
||||||
|
|
@ -606,7 +607,7 @@ class RiskManager:
|
||||||
logger.debug(f"ATR不可用,使用固定百分比止盈")
|
logger.debug(f"ATR不可用,使用固定百分比止盈")
|
||||||
|
|
||||||
# 获取止盈百分比(相对于保证金)
|
# 获取止盈百分比(相对于保证金)
|
||||||
take_profit_percent = take_profit_pct or self.config['TAKE_PROFIT_PERCENT']
|
take_profit_percent = take_profit_pct or config.TRADING_CONFIG['TAKE_PROFIT_PERCENT']
|
||||||
|
|
||||||
# 计算止盈金额(相对于保证金)
|
# 计算止盈金额(相对于保证金)
|
||||||
take_profit_amount = margin * take_profit_percent
|
take_profit_amount = margin * take_profit_percent
|
||||||
|
|
@ -621,7 +622,7 @@ class RiskManager:
|
||||||
|
|
||||||
# 同时计算基于价格百分比的止盈价(作为最小值保护)
|
# 同时计算基于价格百分比的止盈价(作为最小值保护)
|
||||||
# 获取最小价格变动百分比(如果配置了)
|
# 获取最小价格变动百分比(如果配置了)
|
||||||
min_price_change_pct = self.config.get('MIN_TAKE_PROFIT_PRICE_PCT', None)
|
min_price_change_pct = config.TRADING_CONFIG.get('MIN_TAKE_PROFIT_PRICE_PCT', None)
|
||||||
if min_price_change_pct is not None:
|
if min_price_change_pct is not None:
|
||||||
# 基于价格百分比的止盈价
|
# 基于价格百分比的止盈价
|
||||||
if side == 'BUY':
|
if side == 'BUY':
|
||||||
|
|
@ -671,10 +672,10 @@ class RiskManager:
|
||||||
杠杆倍数
|
杠杆倍数
|
||||||
"""
|
"""
|
||||||
# 获取配置参数
|
# 获取配置参数
|
||||||
use_dynamic_leverage = self.config.get('USE_DYNAMIC_LEVERAGE', True)
|
use_dynamic_leverage = config.TRADING_CONFIG.get('USE_DYNAMIC_LEVERAGE', True)
|
||||||
base_leverage = self.config.get('LEVERAGE', 10)
|
base_leverage = config.TRADING_CONFIG.get('LEVERAGE', 10)
|
||||||
max_leverage = self.config.get('MAX_LEVERAGE', 20)
|
max_leverage = config.TRADING_CONFIG.get('MAX_LEVERAGE', 20)
|
||||||
min_signal_strength = self.config.get('MIN_SIGNAL_STRENGTH', 7)
|
min_signal_strength = config.TRADING_CONFIG.get('MIN_SIGNAL_STRENGTH', 7)
|
||||||
|
|
||||||
# 如果未启用动态杠杆,返回基础杠杆
|
# 如果未启用动态杠杆,返回基础杠杆
|
||||||
if not use_dynamic_leverage:
|
if not use_dynamic_leverage:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user