a
This commit is contained in:
parent
6ddcbde645
commit
0570ff6823
|
|
@ -124,10 +124,6 @@ class ConfigManager:
|
||||||
'MIN_STOP_LOSS_PRICE_PCT': self.get('MIN_STOP_LOSS_PRICE_PCT', 0.02), # 默认2%
|
'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%
|
'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动态止损
|
'USE_ATR_STOP_LOSS': self.get('USE_ATR_STOP_LOSS', True), # 是否使用ATR动态止损
|
||||||
<<<<<<< Current (Your changes)
|
|
||||||
'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止盈倍数
|
|
||||||
=======
|
|
||||||
'ATR_STOP_LOSS_MULTIPLIER': self.get('ATR_STOP_LOSS_MULTIPLIER', 1.8), # ATR止损倍数(1.5-2倍)
|
'ATR_STOP_LOSS_MULTIPLIER': self.get('ATR_STOP_LOSS_MULTIPLIER', 1.8), # ATR止损倍数(1.5-2倍)
|
||||||
'ATR_TAKE_PROFIT_MULTIPLIER': self.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0), # ATR止盈倍数(3倍ATR)
|
'ATR_TAKE_PROFIT_MULTIPLIER': self.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0), # ATR止盈倍数(3倍ATR)
|
||||||
'RISK_REWARD_RATIO': self.get('RISK_REWARD_RATIO', 3.0), # 盈亏比(止损距离的倍数)
|
'RISK_REWARD_RATIO': self.get('RISK_REWARD_RATIO', 3.0), # 盈亏比(止损距离的倍数)
|
||||||
|
|
@ -135,7 +131,6 @@ class ConfigManager:
|
||||||
'USE_DYNAMIC_ATR_MULTIPLIER': self.get('USE_DYNAMIC_ATR_MULTIPLIER', False), # 是否根据波动率动态调整ATR倍数
|
'USE_DYNAMIC_ATR_MULTIPLIER': self.get('USE_DYNAMIC_ATR_MULTIPLIER', False), # 是否根据波动率动态调整ATR倍数
|
||||||
'ATR_MULTIPLIER_MIN': self.get('ATR_MULTIPLIER_MIN', 1.5), # 动态ATR倍数最小值
|
'ATR_MULTIPLIER_MIN': self.get('ATR_MULTIPLIER_MIN', 1.5), # 动态ATR倍数最小值
|
||||||
'ATR_MULTIPLIER_MAX': self.get('ATR_MULTIPLIER_MAX', 2.5), # 动态ATR倍数最大值
|
'ATR_MULTIPLIER_MAX': self.get('ATR_MULTIPLIER_MAX', 2.5), # 动态ATR倍数最大值
|
||||||
>>>>>>> Incoming (Background Agent changes)
|
|
||||||
|
|
||||||
# 市场扫描(1小时主周期)
|
# 市场扫描(1小时主周期)
|
||||||
'SCAN_INTERVAL': self.get('SCAN_INTERVAL', 3600), # 1小时
|
'SCAN_INTERVAL': self.get('SCAN_INTERVAL', 3600), # 1小时
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,44 @@ logger = logging.getLogger(__name__)
|
||||||
class BinanceClient:
|
class BinanceClient:
|
||||||
"""币安客户端封装类"""
|
"""币安客户端封装类"""
|
||||||
|
|
||||||
def __init__(self, api_key: str = None, api_secret: str = None, testnet: bool = False):
|
def __init__(self, api_key: str = None, api_secret: str = None, testnet: bool = None):
|
||||||
"""
|
"""
|
||||||
初始化币安客户端
|
初始化币安客户端
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
api_key: API密钥
|
api_key: API密钥(如果为None,从config读取)
|
||||||
api_secret: API密钥
|
api_secret: API密钥(如果为None,从config读取)
|
||||||
testnet: 是否使用测试网
|
testnet: 是否使用测试网(如果为None,从config读取)
|
||||||
"""
|
"""
|
||||||
self.api_key = api_key or config.BINANCE_API_KEY
|
# 如果未提供参数,从config读取(确保使用最新值)
|
||||||
self.api_secret = api_secret or config.BINANCE_API_SECRET
|
if api_key is None:
|
||||||
self.testnet = testnet or config.USE_TESTNET
|
# 尝试从配置管理器直接获取
|
||||||
|
if config._config_manager:
|
||||||
|
try:
|
||||||
|
api_key = config._config_manager.get('BINANCE_API_KEY')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# 如果还是None,使用config模块的值
|
||||||
|
if not api_key:
|
||||||
|
api_key = config.BINANCE_API_KEY
|
||||||
|
|
||||||
|
if api_secret is None:
|
||||||
|
# 尝试从配置管理器直接获取
|
||||||
|
if config._config_manager:
|
||||||
|
try:
|
||||||
|
api_secret = config._config_manager.get('BINANCE_API_SECRET')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# 如果还是None,使用config模块的值
|
||||||
|
if not api_secret:
|
||||||
|
api_secret = config.BINANCE_API_SECRET
|
||||||
|
|
||||||
|
if testnet is None:
|
||||||
|
testnet = config.USE_TESTNET
|
||||||
|
|
||||||
|
self.api_key = api_key
|
||||||
|
self.api_secret = api_secret
|
||||||
|
self.testnet = testnet
|
||||||
self.client: Optional[AsyncClient] = None
|
self.client: Optional[AsyncClient] = None
|
||||||
self.socket_manager: Optional[BinanceSocketManager] = None
|
self.socket_manager: Optional[BinanceSocketManager] = None
|
||||||
self._symbol_info_cache: Dict[str, Dict] = {} # 缓存交易对信息
|
self._symbol_info_cache: Dict[str, Dict] = {} # 缓存交易对信息
|
||||||
|
|
@ -41,8 +67,10 @@ class BinanceClient:
|
||||||
self._price_cache: Dict[str, Dict] = {} # WebSocket价格缓存 {symbol: {price, volume, changePercent, timestamp}}
|
self._price_cache: Dict[str, Dict] = {} # WebSocket价格缓存 {symbol: {price, volume, changePercent, timestamp}}
|
||||||
self._price_cache_ttl = 60 # 价格缓存有效期(秒)
|
self._price_cache_ttl = 60 # 价格缓存有效期(秒)
|
||||||
|
|
||||||
|
# 隐藏敏感信息,只显示前4位和后4位
|
||||||
logger.info(f"初始化币安客户端: {self.api_key}, {self.api_secret}, {self.testnet}")
|
api_key_display = f"{self.api_key[:4]}...{self.api_key[-4:]}" if self.api_key and len(self.api_key) > 8 else self.api_key
|
||||||
|
api_secret_display = f"{self.api_secret[:4]}...{self.api_secret[-4:]}" if self.api_secret and len(self.api_secret) > 8 else self.api_secret
|
||||||
|
logger.info(f"初始化币安客户端: {api_key_display}, {api_secret_display}, {self.testnet}")
|
||||||
|
|
||||||
|
|
||||||
# 初始化 Redis 缓存
|
# 初始化 Redis 缓存
|
||||||
|
|
|
||||||
|
|
@ -140,10 +140,16 @@ def _get_config_value(key, default=None):
|
||||||
"""获取配置值(支持动态重载)"""
|
"""获取配置值(支持动态重载)"""
|
||||||
if _config_manager:
|
if _config_manager:
|
||||||
try:
|
try:
|
||||||
_config_manager.reload() # 每次获取配置时重新加载
|
# 不每次都reload,避免性能问题,只在需要时reload
|
||||||
value = _config_manager.get(key, default)
|
value = _config_manager.get(key)
|
||||||
# 如果从数据库获取到值,直接返回(即使是空字符串也返回)
|
# 如果从数据库获取到值,直接返回(排除None和空字符串,除非是敏感配置)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
# 对于API密钥,即使是空字符串也返回(表示数据库中有配置但值为空)
|
||||||
|
if key in ['BINANCE_API_KEY', 'BINANCE_API_SECRET']:
|
||||||
|
return value if value else default
|
||||||
|
# 对于其他配置,空字符串视为无效,返回default
|
||||||
|
if value == '':
|
||||||
|
return default
|
||||||
return value
|
return value
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -151,8 +157,12 @@ def _get_config_value(key, default=None):
|
||||||
logger.debug(f"从配置管理器获取{key}失败: {e},尝试环境变量")
|
logger.debug(f"从配置管理器获取{key}失败: {e},尝试环境变量")
|
||||||
|
|
||||||
# 回退到环境变量
|
# 回退到环境变量
|
||||||
env_value = os.getenv(key, default)
|
env_value = os.getenv(key)
|
||||||
return env_value if env_value is not None else default
|
if env_value is not None and env_value != '':
|
||||||
|
return env_value
|
||||||
|
|
||||||
|
# 最后返回默认值
|
||||||
|
return default
|
||||||
|
|
||||||
def _get_trading_config():
|
def _get_trading_config():
|
||||||
"""获取交易配置(支持动态重载)"""
|
"""获取交易配置(支持动态重载)"""
|
||||||
|
|
@ -198,8 +208,10 @@ def _get_trading_config():
|
||||||
}
|
}
|
||||||
|
|
||||||
# 币安API配置(优先从数据库,回退到环境变量和默认值)
|
# 币安API配置(优先从数据库,回退到环境变量和默认值)
|
||||||
BINANCE_API_KEY: Optional[str] = _get_config_value('BINANCE_API_KEY', '')
|
# 注意:在模块加载时,配置管理器可能还未初始化完成,所以先使用默认值
|
||||||
BINANCE_API_SECRET: Optional[str] = _get_config_value('BINANCE_API_SECRET', '')
|
# 在main.py中会调用reload_config()重新加载
|
||||||
|
BINANCE_API_KEY: Optional[str] = _get_config_value('BINANCE_API_KEY', 'your_api_key_here')
|
||||||
|
BINANCE_API_SECRET: Optional[str] = _get_config_value('BINANCE_API_SECRET', 'your_api_secret_here')
|
||||||
USE_TESTNET: bool = _get_config_value('USE_TESTNET', False) if _get_config_value('USE_TESTNET') is not None else os.getenv('USE_TESTNET', 'False').lower() == 'true'
|
USE_TESTNET: bool = _get_config_value('USE_TESTNET', False) if _get_config_value('USE_TESTNET') is not None else os.getenv('USE_TESTNET', 'False').lower() == 'true'
|
||||||
|
|
||||||
# 交易参数配置(优先从数据库读取,支持动态重载)
|
# 交易参数配置(优先从数据库读取,支持动态重载)
|
||||||
|
|
@ -221,13 +233,34 @@ for key, value in defaults.items():
|
||||||
# 提供一个函数来重新加载配置
|
# 提供一个函数来重新加载配置
|
||||||
def reload_config():
|
def reload_config():
|
||||||
"""重新加载配置(供外部调用)"""
|
"""重新加载配置(供外部调用)"""
|
||||||
global TRADING_CONFIG, BINANCE_API_KEY, BINANCE_API_SECRET, USE_TESTNET, _config_manager
|
global TRADING_CONFIG, BINANCE_API_KEY, BINANCE_API_SECRET, USE_TESTNET, _config_manager, USE_DB_CONFIG
|
||||||
global REDIS_URL, REDIS_USE_TLS, REDIS_SSL_CERT_REQS, REDIS_SSL_CA_CERTS, REDIS_USERNAME, REDIS_PASSWORD
|
global REDIS_URL, REDIS_USE_TLS, REDIS_SSL_CERT_REQS, REDIS_SSL_CA_CERTS, REDIS_USERNAME, REDIS_PASSWORD
|
||||||
_init_config_manager() # 重新初始化配置管理器
|
|
||||||
|
# 如果配置管理器不存在,尝试初始化
|
||||||
|
if _config_manager is None:
|
||||||
|
_init_config_manager()
|
||||||
|
|
||||||
|
# 如果配置管理器存在,重新加载
|
||||||
if _config_manager:
|
if _config_manager:
|
||||||
|
try:
|
||||||
_config_manager.reload()
|
_config_manager.reload()
|
||||||
BINANCE_API_KEY = _get_config_value('BINANCE_API_KEY', BINANCE_API_KEY)
|
USE_DB_CONFIG = True
|
||||||
BINANCE_API_SECRET = _get_config_value('BINANCE_API_SECRET', BINANCE_API_SECRET)
|
except Exception as e:
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.warning(f"重新加载配置失败: {e}")
|
||||||
|
USE_DB_CONFIG = False
|
||||||
|
|
||||||
|
# 重新获取API密钥(优先从配置管理器)
|
||||||
|
new_api_key = _get_config_value('BINANCE_API_KEY', 'your_api_key_here')
|
||||||
|
new_api_secret = _get_config_value('BINANCE_API_SECRET', 'your_api_secret_here')
|
||||||
|
|
||||||
|
# 如果获取到有效值,更新全局变量
|
||||||
|
if new_api_key and new_api_key != 'your_api_key_here':
|
||||||
|
BINANCE_API_KEY = new_api_key
|
||||||
|
if new_api_secret and new_api_secret != 'your_api_secret_here':
|
||||||
|
BINANCE_API_SECRET = new_api_secret
|
||||||
|
|
||||||
USE_TESTNET = _get_config_value('USE_TESTNET', False) if _get_config_value('USE_TESTNET') is not None else os.getenv('USE_TESTNET', 'False').lower() == 'true'
|
USE_TESTNET = _get_config_value('USE_TESTNET', False) if _get_config_value('USE_TESTNET') is not None else os.getenv('USE_TESTNET', 'False').lower() == 'true'
|
||||||
TRADING_CONFIG = _get_trading_config()
|
TRADING_CONFIG = _get_trading_config()
|
||||||
# 重新加载 Redis 配置
|
# 重新加载 Redis 配置
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,31 @@ async def main():
|
||||||
|
|
||||||
# 检查配置管理器状态
|
# 检查配置管理器状态
|
||||||
logger.info("检查配置管理器状态...")
|
logger.info("检查配置管理器状态...")
|
||||||
|
|
||||||
|
# 强制重新初始化配置管理器(确保能读取到数据库配置)
|
||||||
|
try:
|
||||||
|
logger.info("重新初始化配置管理器...")
|
||||||
|
# 重置全局变量,强制重新初始化
|
||||||
|
config._config_manager = None
|
||||||
|
config.USE_DB_CONFIG = False
|
||||||
|
config._init_config_manager()
|
||||||
|
|
||||||
|
if config._config_manager:
|
||||||
|
config._config_manager.reload()
|
||||||
|
logger.info(f"✓ 配置管理器初始化成功,已加载 {len(config._config_manager._cache)} 个配置项")
|
||||||
|
# 打印一些关键配置项,用于调试
|
||||||
|
test_key = config._config_manager.get('BINANCE_API_KEY')
|
||||||
|
test_secret = config._config_manager.get('BINANCE_API_SECRET')
|
||||||
|
logger.info(f"从数据库读取: BINANCE_API_KEY存在={bool(test_key)}, BINANCE_API_SECRET存在={bool(test_secret)}")
|
||||||
|
if test_key:
|
||||||
|
logger.info(f"BINANCE_API_KEY前4位: {test_key[:4]}...")
|
||||||
|
else:
|
||||||
|
logger.warning("⚠ 配置管理器初始化失败,返回None")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"配置管理器初始化异常: {e}", exc_info=True)
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
if config.USE_DB_CONFIG:
|
if config.USE_DB_CONFIG:
|
||||||
logger.info("✓ 使用数据库配置")
|
logger.info("✓ 使用数据库配置")
|
||||||
# 尝试重新加载配置(确保获取最新值)
|
# 尝试重新加载配置(确保获取最新值)
|
||||||
|
|
@ -81,21 +106,50 @@ async def main():
|
||||||
config.reload_config()
|
config.reload_config()
|
||||||
logger.info("配置已重新加载")
|
logger.info("配置已重新加载")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"重新加载配置失败: {e}")
|
logger.warning(f"重新加载配置失败: {e}", exc_info=True)
|
||||||
else:
|
else:
|
||||||
logger.warning("⚠ 未使用数据库配置,将使用环境变量和默认配置")
|
logger.warning("⚠ 未使用数据库配置,将使用环境变量和默认配置")
|
||||||
logger.warning("如果前端已配置API密钥,请检查:")
|
logger.warning("如果前端已配置API密钥,请检查:")
|
||||||
logger.warning("1. backend目录是否存在")
|
logger.warning("1. backend目录是否存在")
|
||||||
logger.warning("2. 数据库连接是否正常")
|
logger.warning("2. 数据库连接是否正常")
|
||||||
logger.warning("3. config_manager模块是否可以正常导入")
|
logger.warning("3. config_manager模块是否可以正常导入")
|
||||||
|
logger.warning("4. 数据库配置表中是否有BINANCE_API_KEY和BINANCE_API_SECRET")
|
||||||
|
|
||||||
|
# 强制重新加载配置(确保使用最新值)
|
||||||
|
try:
|
||||||
|
config.reload_config()
|
||||||
|
logger.info("配置已重新加载")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"重新加载配置失败: {e}", exc_info=True)
|
||||||
|
|
||||||
# 检查API密钥(重新获取,确保是最新值)
|
# 检查API密钥(重新获取,确保是最新值)
|
||||||
api_key = config._get_config_value('BINANCE_API_KEY', '')
|
api_key = config._get_config_value('BINANCE_API_KEY', '')
|
||||||
api_secret = config._get_config_value('BINANCE_API_SECRET', '')
|
api_secret = config._get_config_value('BINANCE_API_SECRET', '')
|
||||||
|
|
||||||
logger.info(f"API密钥检查: KEY存在={bool(api_key)}, SECRET存在={bool(api_secret)}")
|
# 如果从配置管理器获取失败,尝试直接从config_manager获取
|
||||||
|
if (not api_key or api_key == 'your_api_key_here') and config._config_manager:
|
||||||
|
try:
|
||||||
|
api_key = config._config_manager.get('BINANCE_API_KEY', '')
|
||||||
|
logger.info(f"直接从config_manager获取API_KEY: 存在={bool(api_key)}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"从config_manager获取API_KEY失败: {e}")
|
||||||
|
|
||||||
if not api_key or not api_secret:
|
if (not api_secret or api_secret == 'your_api_secret_here') and config._config_manager:
|
||||||
|
try:
|
||||||
|
api_secret = config._config_manager.get('BINANCE_API_SECRET', '')
|
||||||
|
logger.info(f"直接从config_manager获取API_SECRET: 存在={bool(api_secret)}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"从config_manager获取API_SECRET失败: {e}")
|
||||||
|
|
||||||
|
logger.info(f"API密钥检查: KEY存在={bool(api_key)}, SECRET存在={bool(api_secret)}")
|
||||||
|
if api_key and api_key != 'your_api_key_here' and len(api_key) > 4:
|
||||||
|
logger.info(f"API密钥前4位: {api_key[:4]}...")
|
||||||
|
else:
|
||||||
|
logger.warning(f"⚠ API密钥未正确加载,当前值: {api_key}")
|
||||||
|
if config._config_manager:
|
||||||
|
logger.info(f"配置管理器缓存中的键: {list(config._config_manager._cache.keys())[:10]}")
|
||||||
|
|
||||||
|
if not api_key or not api_secret or api_key == 'your_api_key_here' or api_secret == 'your_api_secret_here':
|
||||||
logger.error("=" * 60)
|
logger.error("=" * 60)
|
||||||
logger.error("API密钥未配置!")
|
logger.error("API密钥未配置!")
|
||||||
logger.error("=" * 60)
|
logger.error("=" * 60)
|
||||||
|
|
@ -115,6 +169,10 @@ async def main():
|
||||||
# 更新config模块的API密钥(确保使用最新值)
|
# 更新config模块的API密钥(确保使用最新值)
|
||||||
config.BINANCE_API_KEY = api_key
|
config.BINANCE_API_KEY = api_key
|
||||||
config.BINANCE_API_SECRET = api_secret
|
config.BINANCE_API_SECRET = api_secret
|
||||||
|
import os
|
||||||
|
config.USE_TESTNET = config._get_config_value('USE_TESTNET', False) if config._get_config_value('USE_TESTNET') is not None else os.getenv('USE_TESTNET', 'False').lower() == 'true'
|
||||||
|
|
||||||
|
logger.info(f"最终使用的API密钥: KEY前4位={api_key[:4] if api_key and len(api_key) > 4 else 'N/A'}..., SECRET前4位={api_secret[:4] if api_secret and len(api_secret) > 4 else 'N/A'}..., 测试网={config.USE_TESTNET}")
|
||||||
|
|
||||||
# 初始化组件
|
# 初始化组件
|
||||||
client = None
|
client = None
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user