auto_trade_sys/trading_system/main.py
薇薇安 f99f508b09 a
2026-01-14 13:43:06 +08:00

189 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
主程序 - 币安自动交易系统入口
"""
import asyncio
import logging
import sys
from pathlib import Path
# 支持直接运行和作为模块导入
if __name__ == '__main__':
# 直接运行时,使用相对导入
from binance_client import BinanceClient
from market_scanner import MarketScanner
from risk_manager import RiskManager
from position_manager import PositionManager
from strategy import TradingStrategy
import config
else:
# 作为模块导入时,使用绝对导入
from .binance_client import BinanceClient
from .market_scanner import MarketScanner
from .risk_manager import RiskManager
from .position_manager import PositionManager
from .strategy import TradingStrategy
from . import config
# 配置日志(支持相对路径)
log_file = config.LOG_FILE
if not Path(log_file).is_absolute():
# 如果是相对路径,相对于项目根目录
project_root = Path(__file__).parent.parent
log_file = project_root / log_file
logging.basicConfig(
level=getattr(logging, config.LOG_LEVEL),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(str(log_file), encoding='utf-8'),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
async def main():
"""主函数"""
logger.info("=" * 60)
logger.info("币安自动交易系统启动")
logger.info("=" * 60)
# 检查配置管理器状态
logger.info("检查配置管理器状态...")
if config.USE_DB_CONFIG:
logger.info("✓ 使用数据库配置")
# 尝试重新加载配置(确保获取最新值)
try:
config.reload_config()
logger.info("配置已重新加载")
except Exception as e:
logger.warning(f"重新加载配置失败: {e}")
else:
logger.warning("⚠ 未使用数据库配置,将使用环境变量和默认配置")
logger.warning("如果前端已配置API密钥请检查")
logger.warning("1. backend目录是否存在")
logger.warning("2. 数据库连接是否正常")
logger.warning("3. config_manager模块是否可以正常导入")
# 检查API密钥重新获取确保是最新值
api_key = config._get_config_value('BINANCE_API_KEY', '')
api_secret = config._get_config_value('BINANCE_API_SECRET', '')
logger.info(f"API密钥检查: KEY存在={bool(api_key)}, SECRET存在={bool(api_secret)}")
if not api_key or not api_secret:
logger.error("=" * 60)
logger.error("API密钥未配置")
logger.error("=" * 60)
if config.USE_DB_CONFIG:
logger.error("配置管理器已启用但未从数据库读取到API密钥")
logger.error("请检查:")
logger.error("1. 前端配置界面是否已设置BINANCE_API_KEY和BINANCE_API_SECRET")
logger.error("2. 数据库trading_config表中是否有这些配置项")
logger.error("3. 数据库连接是否正常")
else:
logger.error("请设置 BINANCE_API_KEY 和 BINANCE_API_SECRET 环境变量")
logger.error("或在 config.py 中直接配置")
logger.error("或确保backend目录存在以便从数据库读取配置")
logger.error("=" * 60)
return
# 更新config模块的API密钥确保使用最新值
config.BINANCE_API_KEY = api_key
config.BINANCE_API_SECRET = api_secret
# 初始化组件
client = None
try:
# 1. 初始化币安客户端
logger.info("初始化币安客户端...")
# 再次确认API密钥使用最新值
api_key = config._get_config_value('BINANCE_API_KEY', config.BINANCE_API_KEY)
api_secret = config._get_config_value('BINANCE_API_SECRET', config.BINANCE_API_SECRET)
use_testnet = config._get_config_value('USE_TESTNET', config.USE_TESTNET)
if isinstance(use_testnet, str):
use_testnet = use_testnet.lower() in ('true', '1', 'yes', 'on')
elif not isinstance(use_testnet, bool):
use_testnet = bool(use_testnet)
logger.info(f"测试网模式: {use_testnet}")
logger.info(f"连接超时: {config.CONNECTION_TIMEOUT}")
logger.info(f"重试次数: {config.CONNECTION_RETRIES}")
client = BinanceClient(
api_key=api_key,
api_secret=api_secret,
testnet=use_testnet
)
await client.connect()
# 2. 检查账户余额
logger.info("检查账户余额...")
balance = await client.get_account_balance()
if balance['total'] == 0 and balance['available'] == 0:
logger.error("=" * 60)
logger.error("无法获取账户余额可能是API权限问题")
logger.error("请检查:")
logger.error("1. API密钥是否正确")
logger.error("2. API密钥是否启用了'合约交易'权限")
logger.error("3. IP地址是否在白名单中如果设置了IP限制")
logger.error("4. 测试网/生产网环境是否匹配")
logger.error("=" * 60)
return
logger.info(
f"账户余额: 总余额 {balance['total']:.2f} USDT, "
f"可用余额 {balance['available']:.2f} USDT"
)
if balance['available'] <= 0:
logger.error("账户可用余额不足,无法交易")
logger.error(f"总余额: {balance['total']:.2f} USDT")
logger.error("请先充值到合约账户")
return
# 4. 初始化各个模块
logger.info("初始化交易模块...")
scanner = MarketScanner(client)
risk_manager = RiskManager(client)
position_manager = PositionManager(client, risk_manager)
strategy = TradingStrategy(client, scanner, risk_manager, position_manager)
# 4. 打印配置信息
logger.info("交易配置:")
logger.info(f" 单笔最大仓位: {config.TRADING_CONFIG['MAX_POSITION_PERCENT']*100:.1f}%")
logger.info(f" 总仓位上限: {config.TRADING_CONFIG['MAX_TOTAL_POSITION_PERCENT']*100:.1f}%")
logger.info(f" 最小涨跌幅阈值: {config.TRADING_CONFIG['MIN_CHANGE_PERCENT']:.1f}%")
logger.info(f" 扫描间隔: {config.TRADING_CONFIG['SCAN_INTERVAL']}")
logger.info(f" 止损: {config.TRADING_CONFIG['STOP_LOSS_PERCENT']*100:.1f}%")
logger.info(f" 止盈: {config.TRADING_CONFIG['TAKE_PROFIT_PERCENT']*100:.1f}%")
logger.info(f" 测试网模式: {config.USE_TESTNET}")
logger.info("=" * 60)
# 5. 启动交易策略
logger.info("启动交易策略...")
await strategy.execute_strategy()
except KeyboardInterrupt:
logger.info("收到停止信号,正在关闭...")
except Exception as e:
logger.error(f"程序运行出错: {e}", exc_info=True)
finally:
# 清理资源
if client:
await client.disconnect()
logger.info("程序已退出")
if __name__ == '__main__':
try:
asyncio.run(main())
except KeyboardInterrupt:
logger.info("程序被用户中断")
except Exception as e:
logger.error(f"程序异常退出: {e}", exc_info=True)