a
This commit is contained in:
parent
150eea7a28
commit
fad8a1d6fd
|
|
@ -90,9 +90,13 @@ def get_account_id(
|
||||||
) -> int:
|
) -> int:
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
# 注意:x_account_id 可能是 None,需要处理
|
||||||
|
raw_header_value = x_account_id
|
||||||
aid = int(x_account_id or 1)
|
aid = int(x_account_id or 1)
|
||||||
logger.info(f"get_account_id: X-Account-Id header={x_account_id}, parsed account_id={aid}, user_id={user.get('id')}")
|
logger.info(f"get_account_id: X-Account-Id header={raw_header_value}, parsed account_id={aid}, user_id={user.get('id')}, username={user.get('username')}")
|
||||||
return require_account_access(aid, user)
|
result = require_account_access(aid, user)
|
||||||
|
logger.info(f"get_account_id: 最终返回 account_id={result}")
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def require_system_admin(
|
def require_system_admin(
|
||||||
|
|
|
||||||
|
|
@ -398,15 +398,25 @@ async def get_realtime_account_data(account_id: int = 1):
|
||||||
|
|
||||||
# 创建客户端
|
# 创建客户端
|
||||||
logger.info("步骤3: 创建BinanceClient实例...")
|
logger.info("步骤3: 创建BinanceClient实例...")
|
||||||
client = BinanceClient(
|
|
||||||
api_key=api_key,
|
|
||||||
api_secret=api_secret,
|
|
||||||
testnet=use_testnet
|
|
||||||
)
|
|
||||||
logger.info(f" - 使用的 account_id: {account_id}")
|
logger.info(f" - 使用的 account_id: {account_id}")
|
||||||
logger.info(f" - API Key 前4位: {api_key[:4] if api_key and len(api_key) >= 4 else 'N/A'}...")
|
logger.info(f" - API Key 前4位: {api_key[:4] if api_key and len(api_key) >= 4 else 'N/A'}...")
|
||||||
|
logger.info(f" - API Key 后4位: ...{api_key[-4:] if api_key and len(api_key) >= 4 else 'N/A'}")
|
||||||
logger.info(f" - API Secret 前4位: {api_secret[:4] if api_secret and len(api_secret) >= 4 else 'N/A'}...")
|
logger.info(f" - API Secret 前4位: {api_secret[:4] if api_secret and len(api_secret) >= 4 else 'N/A'}...")
|
||||||
logger.info(f" ✓ 客户端创建成功 (testnet={use_testnet})")
|
logger.info(f" - API Secret 后4位: ...{api_secret[-4:] if api_secret and len(api_secret) >= 4 else 'N/A'}")
|
||||||
|
logger.info(f" - testnet: {use_testnet}")
|
||||||
|
|
||||||
|
# 确保传递了正确的 api_key 和 api_secret,避免 BinanceClient 从 config 读取
|
||||||
|
if not api_key or not api_secret:
|
||||||
|
error_msg = f"API密钥为空 (account_id={account_id}),无法创建BinanceClient"
|
||||||
|
logger.error(f" ✗ {error_msg}")
|
||||||
|
raise HTTPException(status_code=400, detail=error_msg)
|
||||||
|
|
||||||
|
client = BinanceClient(
|
||||||
|
api_key=api_key, # 明确传递,避免从 config 读取
|
||||||
|
api_secret=api_secret, # 明确传递,避免从 config 读取
|
||||||
|
testnet=use_testnet
|
||||||
|
)
|
||||||
|
logger.info(f" ✓ 客户端创建成功 (testnet={use_testnet}, account_id={account_id})")
|
||||||
|
|
||||||
# 连接币安API
|
# 连接币安API
|
||||||
logger.info("步骤4: 连接币安API...")
|
logger.info("步骤4: 连接币安API...")
|
||||||
|
|
@ -562,8 +572,8 @@ async def get_realtime_account_data(account_id: int = 1):
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("=" * 60)
|
logger.info("=" * 60)
|
||||||
logger.info("账户数据获取成功!")
|
logger.info(f"账户数据获取成功! (account_id={account_id})")
|
||||||
logger.info(f"最终结果: {result}")
|
logger.info(f"最终结果 - total_balance={result.get('total_balance', 'N/A')}, available_balance={result.get('available_balance', 'N/A')}, open_positions={result.get('open_positions', 'N/A')}")
|
||||||
logger.info("=" * 60)
|
logger.info("=" * 60)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
@ -596,6 +606,7 @@ async def get_realtime_positions(account_id: int = Depends(get_account_id)):
|
||||||
logger.info(f"get_realtime_positions: 请求的 account_id={account_id}")
|
logger.info(f"get_realtime_positions: 请求的 account_id={account_id}")
|
||||||
api_key, api_secret, use_testnet, status = Account.get_credentials(account_id)
|
api_key, api_secret, use_testnet, status = Account.get_credentials(account_id)
|
||||||
logger.info(f"get_realtime_positions: 获取到的 account_id={account_id}, status={status}, api_key exists={bool(api_key)}")
|
logger.info(f"get_realtime_positions: 获取到的 account_id={account_id}, status={status}, api_key exists={bool(api_key)}")
|
||||||
|
logger.info(f"get_realtime_positions: API Key 前4位={api_key[:4] if api_key and len(api_key) >= 4 else 'N/A'}, 后4位=...{api_key[-4:] if api_key and len(api_key) >= 4 else 'N/A'}")
|
||||||
|
|
||||||
logger.info(f"尝试获取实时持仓数据 (testnet={use_testnet}, account_id={account_id})")
|
logger.info(f"尝试获取实时持仓数据 (testnet={use_testnet}, account_id={account_id})")
|
||||||
|
|
||||||
|
|
@ -615,11 +626,13 @@ async def get_realtime_positions(account_id: int = Depends(get_account_id)):
|
||||||
sys.path.insert(0, str(trading_system_path))
|
sys.path.insert(0, str(trading_system_path))
|
||||||
from binance_client import BinanceClient
|
from binance_client import BinanceClient
|
||||||
|
|
||||||
|
# 确保传递了正确的 api_key 和 api_secret,避免 BinanceClient 从 config 读取
|
||||||
client = BinanceClient(
|
client = BinanceClient(
|
||||||
api_key=api_key,
|
api_key=api_key, # 明确传递,避免从 config 读取
|
||||||
api_secret=api_secret,
|
api_secret=api_secret, # 明确传递,避免从 config 读取
|
||||||
testnet=use_testnet
|
testnet=use_testnet
|
||||||
)
|
)
|
||||||
|
logger.info(f"BinanceClient 创建成功 (account_id={account_id})")
|
||||||
|
|
||||||
logger.info("连接币安API获取持仓...")
|
logger.info("连接币安API获取持仓...")
|
||||||
await client.connect()
|
await client.connect()
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,9 @@ async def get_performance_stats(
|
||||||
@router.get("/dashboard")
|
@router.get("/dashboard")
|
||||||
async def get_dashboard_data(account_id: int = Depends(get_account_id)):
|
async def get_dashboard_data(account_id: int = Depends(get_account_id)):
|
||||||
"""获取仪表板数据"""
|
"""获取仪表板数据"""
|
||||||
logger.info(f"获取仪表板数据 (account_id={account_id})")
|
logger.info("=" * 60)
|
||||||
|
logger.info(f"获取仪表板数据 - account_id={account_id}")
|
||||||
|
logger.info("=" * 60)
|
||||||
try:
|
try:
|
||||||
account_data = None
|
account_data = None
|
||||||
account_error = None
|
account_error = None
|
||||||
|
|
@ -53,8 +55,9 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
|
||||||
# 优先尝试获取实时账户数据
|
# 优先尝试获取实时账户数据
|
||||||
try:
|
try:
|
||||||
from api.routes.account import get_realtime_account_data
|
from api.routes.account import get_realtime_account_data
|
||||||
|
logger.info(f"调用 get_realtime_account_data(account_id={account_id})")
|
||||||
account_data = await get_realtime_account_data(account_id=account_id)
|
account_data = await get_realtime_account_data(account_id=account_id)
|
||||||
logger.info("成功获取实时账户数据")
|
logger.info(f"成功获取实时账户数据,返回的 total_balance={account_data.get('total_balance', 'N/A') if account_data else 'N/A'}")
|
||||||
except HTTPException as e:
|
except HTTPException as e:
|
||||||
# HTTPException 需要特殊处理,提取错误信息
|
# HTTPException 需要特殊处理,提取错误信息
|
||||||
account_error = e.detail
|
account_error = e.detail
|
||||||
|
|
@ -98,10 +101,11 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
|
||||||
positions_error = None
|
positions_error = None
|
||||||
try:
|
try:
|
||||||
from api.routes.account import get_realtime_positions
|
from api.routes.account import get_realtime_positions
|
||||||
|
logger.info(f"调用 get_realtime_positions(account_id={account_id})")
|
||||||
positions = await get_realtime_positions(account_id=account_id)
|
positions = await get_realtime_positions(account_id=account_id)
|
||||||
# 转换为前端需要的格式
|
# 转换为前端需要的格式
|
||||||
open_trades = positions
|
open_trades = positions
|
||||||
logger.info(f"成功获取实时持仓数据: {len(open_trades)} 个持仓")
|
logger.info(f"成功获取实时持仓数据: {len(open_trades)} 个持仓 (account_id={account_id})")
|
||||||
except HTTPException as e:
|
except HTTPException as e:
|
||||||
positions_error = e.detail
|
positions_error = e.detail
|
||||||
logger.warning(f"获取实时持仓失败 (HTTP {e.status_code}): {positions_error}")
|
logger.warning(f"获取实时持仓失败 (HTTP {e.status_code}): {positions_error}")
|
||||||
|
|
@ -257,7 +261,12 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
|
||||||
"recent_scans": recent_scans,
|
"recent_scans": recent_scans,
|
||||||
"recent_signals": recent_signals,
|
"recent_signals": recent_signals,
|
||||||
"position_stats": position_stats,
|
"position_stats": position_stats,
|
||||||
"trading_config": trading_config # 添加交易配置
|
"trading_config": trading_config, # 添加交易配置
|
||||||
|
"_debug": { # 添加调试信息
|
||||||
|
"account_id": account_id,
|
||||||
|
"account_data_total_balance": account_data.get('total_balance', 'N/A') if account_data else 'N/A',
|
||||||
|
"open_trades_count": len(open_trades),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# 如果有错误,在响应中包含错误信息(但不影响返回)
|
# 如果有错误,在响应中包含错误信息(但不影响返回)
|
||||||
|
|
@ -268,6 +277,14 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
|
||||||
if positions_error:
|
if positions_error:
|
||||||
result["warnings"]["positions"] = positions_error
|
result["warnings"]["positions"] = positions_error
|
||||||
|
|
||||||
|
logger.info(f"返回仪表板数据:")
|
||||||
|
logger.info(f" - account_id: {account_id}")
|
||||||
|
logger.info(f" - total_balance: {account_data.get('total_balance', 'N/A') if account_data else 'N/A'}")
|
||||||
|
logger.info(f" - available_balance: {account_data.get('available_balance', 'N/A') if account_data else 'N/A'}")
|
||||||
|
logger.info(f" - open_trades count: {len(open_trades)}")
|
||||||
|
if open_trades and len(open_trades) > 0:
|
||||||
|
logger.info(f" - 第一个持仓: {open_trades[0].get('symbol', 'N/A')}")
|
||||||
|
logger.info("=" * 60)
|
||||||
return result
|
return result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"获取仪表板数据失败: {e}", exc_info=True)
|
logger.error(f"获取仪表板数据失败: {e}", exc_info=True)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,15 @@ class Account:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get(account_id: int):
|
def get(account_id: int):
|
||||||
return db.execute_one("SELECT * FROM accounts WHERE id = %s", (int(account_id),))
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.info(f"Account.get called with account_id={account_id}")
|
||||||
|
row = db.execute_one("SELECT * FROM accounts WHERE id = %s", (int(account_id),))
|
||||||
|
if row:
|
||||||
|
logger.info(f"Account.get: found account_id={account_id}, name={row.get('name', 'N/A')}, status={row.get('status', 'N/A')}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"Account.get: account_id={account_id} not found in database")
|
||||||
|
return row
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_all():
|
def list_all():
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class BinanceClient:
|
||||||
testnet: 是否使用测试网(如果为None,从config读取)
|
testnet: 是否使用测试网(如果为None,从config读取)
|
||||||
"""
|
"""
|
||||||
# 如果未提供参数,从config读取(确保使用最新值)
|
# 如果未提供参数,从config读取(确保使用最新值)
|
||||||
|
# 注意:如果明确传递了 api_key 和 api_secret,应该使用传递的值,而不是从 config 读取
|
||||||
if api_key is None:
|
if api_key is None:
|
||||||
# 尝试从配置管理器直接获取
|
# 尝试从配置管理器直接获取
|
||||||
if config._config_manager:
|
if config._config_manager:
|
||||||
|
|
@ -59,6 +60,13 @@ class BinanceClient:
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
self.api_secret = api_secret
|
self.api_secret = api_secret
|
||||||
self.testnet = testnet
|
self.testnet = testnet
|
||||||
|
|
||||||
|
# 记录使用的 API Key(用于调试,只显示前后4位)
|
||||||
|
if api_key:
|
||||||
|
key_display = f"{api_key[:4]}...{api_key[-4:]}" if len(api_key) > 8 else api_key
|
||||||
|
logger.info(f"BinanceClient.__init__: 使用 API Key {key_display}, testnet={testnet}")
|
||||||
|
else:
|
||||||
|
logger.warning("BinanceClient.__init__: API Key 为空!")
|
||||||
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] = {} # 缓存交易对信息
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user