121 lines
4.4 KiB
Python
121 lines
4.4 KiB
Python
"""
|
||
主程序 - 币安自动交易系统入口
|
||
"""
|
||
import asyncio
|
||
import logging
|
||
import sys
|
||
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
|
||
|
||
# 配置日志
|
||
logging.basicConfig(
|
||
level=getattr(logging, config.LOG_LEVEL),
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.FileHandler(config.LOG_FILE, encoding='utf-8'),
|
||
logging.StreamHandler(sys.stdout)
|
||
]
|
||
)
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
async def main():
|
||
"""主函数"""
|
||
logger.info("=" * 60)
|
||
logger.info("币安自动交易系统启动")
|
||
logger.info("=" * 60)
|
||
|
||
# 检查API密钥
|
||
if not config.BINANCE_API_KEY or not config.BINANCE_API_SECRET:
|
||
logger.error("请设置 BINANCE_API_KEY 和 BINANCE_API_SECRET 环境变量")
|
||
logger.error("或在 config.py 中直接配置")
|
||
return
|
||
|
||
# 初始化组件
|
||
client = None
|
||
try:
|
||
# 1. 初始化币安客户端
|
||
logger.info("初始化币安客户端...")
|
||
logger.info(f"测试网模式: {config.USE_TESTNET}")
|
||
logger.info(f"连接超时: {config.CONNECTION_TIMEOUT}秒")
|
||
logger.info(f"重试次数: {config.CONNECTION_RETRIES}次")
|
||
|
||
client = BinanceClient(
|
||
api_key=config.BINANCE_API_KEY,
|
||
api_secret=config.BINANCE_API_SECRET,
|
||
testnet=config.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
|
||
|
||
# 3. 初始化各个模块
|
||
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)
|