This commit is contained in:
薇薇安 2026-01-14 09:34:06 +08:00
parent 5b9a8fd917
commit 685e12220d
2 changed files with 79 additions and 24 deletions

View File

@ -371,20 +371,40 @@ const ConfigItem = ({ label, config, onUpdate, disabled }) => {
// //
const getConfigDetail = (key) => { const getConfigDetail = (key) => {
const details = { const details = {
'SCAN_INTERVAL': '扫描间隔。值越小扫描越频繁能更快捕捉波动但资源消耗增加。建议300-3600秒', //
'MIN_CHANGE_PERCENT': '最小涨跌幅阈值(%。值越小捕捉机会越多但可能包含噪音。建议1.0%-3.0%', 'SCAN_INTERVAL': '扫描间隔。系统每隔多长时间扫描一次市场寻找交易机会。值越小扫描越频繁能更快捕捉波动但会增加API请求和系统负载。建议保守策略3600秒(1小时)平衡策略600秒(10分钟)激进策略300秒(5分钟)。晚间波动大时可降低到300-600秒。',
'MIN_SIGNAL_STRENGTH': '最小信号强度0-10。值越小交易机会越多但信号质量可能下降。建议3-7', 'MIN_CHANGE_PERCENT': '最小涨跌幅阈值(%。只有24小时涨跌幅达到此值的交易对才会被考虑交易。值越小捕捉机会越多但可能包含噪音和假信号。值越大只捕捉大幅波动信号质量更高但机会更少。建议保守策略2.0-3.0%平衡策略1.5-2.0%激进策略1.0-1.5%。',
'TOP_N_SYMBOLS': '每次处理的交易对数量。值越大机会越多但计算量增加。建议10-20', 'MIN_SIGNAL_STRENGTH': '最小信号强度0-10。技术指标综合评分只有达到此强度的信号才会执行交易。值越小交易机会越多但信号质量可能下降胜率降低。值越大只执行高质量信号胜率更高但机会更少。建议保守策略5-7平衡策略4-5激进策略3-4。',
'MIN_VOLATILITY': '最小波动率小数。值越小允许更多交易对。建议0.015-0.025', 'TOP_N_SYMBOLS': '每次扫描后处理的交易对数量。从符合条件的交易对中选择涨跌幅最大的前N个进行详细分析。值越大机会越多但计算量增加API请求增多。建议保守策略8-10个平衡策略12-15个激进策略15-20个。',
'MIN_VOLUME_24H': '最小24小时成交量USDT。过滤流动性差的交易对。建议≥500万', 'MIN_VOLATILITY': '最小波动率小数形式如0.02表示2%。过滤掉波动率低于此值的交易对确保只交易有足够波动的币种。值越小允许更多交易对但可能包含波动不足的币种。值越大只交易高波动币种但可能错过一些机会。建议0.015-0.0251.5%-2.5%)。',
'PRIMARY_INTERVAL': '主周期。用于计算技术指标。周期越短反应越快。建议15m-1h', 'MIN_VOLUME_24H': '最小24小时成交量USDT。过滤掉24小时交易量低于此值的交易对确保只交易流动性好的币种避免滑点和流动性风险。建议≥500万USDT主流币种可设置1000万以上。',
'ENTRY_INTERVAL': '入场周期。用于确定入场时机。建议5m-15m', 'KLINE_INTERVAL': 'K线数据周期。获取K线数据的基础周期影响技术指标的计算粒度。周期越短反应越快但可能包含更多噪音。周期越长信号更平滑但反应较慢。建议5m-1h通常与PRIMARY_INTERVAL保持一致。',
'MAX_POSITION_PERCENT': '单笔最大仓位(账户余额%。值越大单笔金额越大。建议3%-10%', 'PRIMARY_INTERVAL': '主周期。策略分析的主要时间周期用于计算技术指标RSI、MACD、布林带等。决定策略主要关注的市场趋势级别。周期越短反应越快周期越长趋势更明确。建议保守策略4h-1d平衡策略1h-4h激进策略15m-1h。',
'MAX_TOTAL_POSITION_PERCENT': '总仓位上限(账户余额%。值越大可同时持有更多仓位。建议20%-50%', 'CONFIRM_INTERVAL': '确认周期。用于确认交易信号的更长时间周期增加信号的可靠性减少假信号。通常比主周期更长。建议保守策略1d平衡策略4h-1d激进策略1h-4h。',
'STOP_LOSS_PERCENT': '止损百分比。值越小止损更严格。建议2%-5%', 'ENTRY_INTERVAL': '入场周期。用于精确入场的短时间周期优化入场点提高单笔交易的盈亏比。通常比主周期更短。建议保守策略1h平衡策略15m-30m激进策略5m-15m。',
'TAKE_PROFIT_PERCENT': '止盈百分比。值越大目标利润更高。建议3%-8%'
//
'MAX_POSITION_PERCENT': '单笔最大仓位账户余额的百分比如0.05表示5%。单笔交易允许的最大仓位大小。值越大单笔金额越大潜在收益和风险都增加。注意币安要求最小名义价值5 USDT如果账户余额较小系统会自动调整。建议保守策略3-5%平衡策略5-7%激进策略7-10%。',
'MAX_TOTAL_POSITION_PERCENT': '总仓位上限账户余额的百分比如0.30表示30%。所有持仓的总价值不能超过账户余额的百分比防止过度交易和风险集中。值越大可以同时持有更多仓位但风险集中度增加。建议保守策略20-30%平衡策略30-40%激进策略40-50%。',
'MIN_POSITION_PERCENT': '单笔最小仓位账户余额的百分比如0.01表示1%。单笔交易允许的最小仓位大小避免交易过小的仓位减少手续费影响。建议1-2%。',
//
'STOP_LOSS_PERCENT': '止损百分比如0.03表示3%。当亏损达到此百分比时自动平仓止损限制单笔交易的最大亏损。值越小止损更严格单笔损失更小但可能被正常波动触发。值越大允许更大的回撤但单笔损失可能较大。建议保守策略3-5%平衡策略2-3%激进策略2-3%。注意止损应该小于止盈建议盈亏比至少1:1.5。',
'TAKE_PROFIT_PERCENT': '止盈百分比如0.05表示5%。当盈利达到此百分比时自动平仓止盈锁定利润。值越大目标利润更高但可能错过及时止盈的机会持仓时间更长。值越小能更快锁定利润但可能错过更大的趋势。建议保守策略5-8%平衡策略5-6%激进策略3-5%。注意应该大于止损建议盈亏比至少1:1.5。',
//
'LEVERAGE': '交易杠杆倍数。放大资金利用率同时放大收益和风险。杠杆越高相同仓位下需要的保证金越少但风险越大。建议保守策略5-10倍平衡策略10倍激进策略10-15倍。注意高杠杆会增加爆仓风险请谨慎使用。',
'USE_TRAILING_STOP': '是否启用移动止损true/false。启用后当盈利达到激活阈值时止损会自动跟踪价格保护利润。适合趋势行情可以捕捉更大的利润空间。建议平衡和激进策略启用保守策略可关闭。',
'TRAILING_STOP_ACTIVATION': '移动止损激活阈值百分比如0.01表示1%。当盈利达到此百分比时移动止损开始跟踪价格将止损移至成本价保本。值越小激活越早更早保护利润但可能过早退出。值越大激活越晚给价格更多波动空间。建议1-2%。',
'TRAILING_STOP_PROTECT': '移动止损保护利润百分比如0.01表示1%。当价格从最高点回撤达到此百分比时触发止损平仓锁定利润。值越小保护更严格能锁定更多利润但可能过早退出。值越大允许更大回撤可能捕捉更大趋势但利润可能回吐。建议1-2%。',
'USE_UNICORN_WEBSOCKET': '是否使用高性能Unicorn WebSocket APItrue/false。启用后使用unicorn-binance-websocket-api获取实时数据效率更高减少API请求频率限制。建议启用true。',
// API
'BINANCE_API_KEY': '币安API密钥。用于访问币安账户的凭证需要启用"合约交易"权限。请妥善保管,不要泄露。',
'BINANCE_API_SECRET': '币安API密钥。与API Key配对使用用于签名验证。请妥善保管不要泄露。',
'USE_TESTNET': '是否使用币安测试网true/false。true表示使用测试网模拟交易无真实资金false表示使用生产网真实交易。建议测试时使用true正式交易使用false。'
} }
return details[key] || '暂无详细说明' return details[key] || '暂无详细说明,请参考配置说明文档'
} }
export default ConfigPanel export default ConfigPanel

View File

@ -12,7 +12,11 @@ except ImportError:
from risk_manager import RiskManager from risk_manager import RiskManager
import config import config
logger = logging.getLogger(__name__)
# 尝试导入数据库模型(如果可用) # 尝试导入数据库模型(如果可用)
DB_AVAILABLE = False
Trade = None
try: try:
import sys import sys
from pathlib import Path from pathlib import Path
@ -22,12 +26,18 @@ try:
sys.path.insert(0, str(backend_path)) sys.path.insert(0, str(backend_path))
from database.models import Trade from database.models import Trade
DB_AVAILABLE = True DB_AVAILABLE = True
logger.info("✓ 数据库模型导入成功,交易记录将保存到数据库")
else: else:
logger.warning("⚠ backend目录不存在无法使用数据库功能")
DB_AVAILABLE = False DB_AVAILABLE = False
except Exception: except ImportError as e:
logger.warning(f"⚠ 无法导入数据库模型: {e}")
logger.warning(" 交易记录将不会保存到数据库")
DB_AVAILABLE = False
except Exception as e:
logger.warning(f"⚠ 数据库初始化失败: {e}")
logger.warning(" 交易记录将不会保存到数据库")
DB_AVAILABLE = False DB_AVAILABLE = False
logger = logging.getLogger(__name__)
class PositionManager: class PositionManager:
@ -133,8 +143,9 @@ class PositionManager:
if order: if order:
# 记录到数据库 # 记录到数据库
trade_id = None trade_id = None
if DB_AVAILABLE: if DB_AVAILABLE and Trade:
try: try:
logger.info(f"正在保存 {symbol} 交易记录到数据库...")
trade_id = Trade.create( trade_id = Trade.create(
symbol=symbol, symbol=symbol,
side=side, side=side,
@ -143,9 +154,16 @@ class PositionManager:
leverage=leverage, leverage=leverage,
entry_reason=entry_reason entry_reason=entry_reason
) )
logger.info(f"{symbol} 交易记录已保存到数据库 (ID: {trade_id})") logger.info(f"{symbol} 交易记录已保存到数据库 (ID: {trade_id})")
except Exception as e: except Exception as e:
logger.warning(f"保存交易记录到数据库失败: {e}") logger.error(f"❌ 保存交易记录到数据库失败: {e}")
logger.error(f" 错误类型: {type(e).__name__}")
import traceback
logger.error(f" 错误详情:\n{traceback.format_exc()}")
elif not DB_AVAILABLE:
logger.debug(f"数据库不可用,跳过保存 {symbol} 交易记录")
elif not Trade:
logger.warning(f"Trade模型未导入无法保存 {symbol} 交易记录")
# 记录持仓信息(包含动态止损止盈) # 记录持仓信息(包含动态止损止盈)
position_info = { position_info = {
@ -217,19 +235,27 @@ class PositionManager:
) )
if order: if order:
# 获取平仓价格
ticker = await self.client.get_ticker_24h(symbol)
if not ticker:
logger.warning(f"无法获取 {symbol} 价格,使用订单价格")
exit_price = float(order.get('avgPrice', 0)) or float(order.get('price', 0))
else:
exit_price = ticker['price']
# 更新数据库记录 # 更新数据库记录
if DB_AVAILABLE and symbol in self.active_positions: if DB_AVAILABLE and Trade and symbol in self.active_positions:
position_info = self.active_positions[symbol] position_info = self.active_positions[symbol]
trade_id = position_info.get('tradeId') trade_id = position_info.get('tradeId')
if trade_id: if trade_id:
try: try:
logger.info(f"正在更新 {symbol} 平仓记录到数据库 (ID: {trade_id})...")
# 计算盈亏 # 计算盈亏
entry_price = position_info['entryPrice'] entry_price = position_info['entryPrice']
exit_price = ticker['price'] if 'ticker' in locals() else current_price
if position_info['side'] == 'BUY': if position_info['side'] == 'BUY':
pnl = (exit_price - entry_price) * quantity pnl = (exit_price - entry_price) * quantity
pnl_percent = ((exit_price - entry_price) / entry_price) * 100 pnl_percent = ((exit_price - entry_price) / entry_price) * 100
else: else: # SELL
pnl = (entry_price - exit_price) * quantity pnl = (entry_price - exit_price) * quantity
pnl_percent = ((entry_price - exit_price) / entry_price) * 100 pnl_percent = ((entry_price - exit_price) / entry_price) * 100
@ -240,9 +266,18 @@ class PositionManager:
pnl=pnl, pnl=pnl,
pnl_percent=pnl_percent pnl_percent=pnl_percent
) )
logger.info(f"{symbol} 平仓记录已更新到数据库") logger.info(f"{symbol} 平仓记录已更新到数据库 (盈亏: {pnl:.2f} USDT, {pnl_percent:.2f}%)")
except Exception as e: except Exception as e:
logger.warning(f"更新平仓记录到数据库失败: {e}") logger.error(f"❌ 更新平仓记录到数据库失败: {e}")
logger.error(f" 错误类型: {type(e).__name__}")
import traceback
logger.error(f" 错误详情:\n{traceback.format_exc()}")
else:
logger.warning(f"{symbol} 没有关联的数据库交易ID无法更新平仓记录")
elif not DB_AVAILABLE:
logger.debug(f"数据库不可用,跳过更新 {symbol} 平仓记录")
elif not Trade:
logger.warning(f"Trade模型未导入无法更新 {symbol} 平仓记录")
# 移除持仓记录 # 移除持仓记录
if symbol in self.active_positions: if symbol in self.active_positions: