2026-01-04 22:43:13 +08:00
|
|
|
# coding:utf-8
|
|
|
|
|
import threading
|
|
|
|
|
import sys
|
2026-01-27 01:21:22 +08:00
|
|
|
import os
|
|
|
|
|
import logging
|
|
|
|
|
import datetime
|
2026-01-04 22:43:13 +08:00
|
|
|
import uvicorn
|
|
|
|
|
|
2026-02-25 21:48:10 +08:00
|
|
|
from .qmt_engine import QMTEngine, ConfigError
|
|
|
|
|
from .api_server import create_api_server
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setup_logger():
|
|
|
|
|
"""配置日志系统"""
|
|
|
|
|
log_dir = "logs"
|
|
|
|
|
if not os.path.exists(log_dir):
|
|
|
|
|
os.makedirs(log_dir)
|
|
|
|
|
|
|
|
|
|
log_file = os.path.join(log_dir, f"{datetime.date.today().strftime('%Y-%m-%d')}.log")
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger("QMT_Main")
|
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
|
|
|
|
|
|
formatter = logging.Formatter(
|
|
|
|
|
'[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s',
|
|
|
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
file_handler = logging.FileHandler(log_file, mode='a', encoding='utf-8')
|
|
|
|
|
file_handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
|
stream_handler = logging.StreamHandler(sys.stdout)
|
|
|
|
|
stream_handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
|
logger.addHandler(file_handler)
|
|
|
|
|
logger.addHandler(stream_handler)
|
|
|
|
|
|
|
|
|
|
return logger
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
"""主函数 - 启动QMT交易引擎和API服务器"""
|
|
|
|
|
logger = setup_logger()
|
|
|
|
|
logger.info("="*50)
|
|
|
|
|
logger.info(">>> QMT交易系统启动中...")
|
|
|
|
|
logger.info("="*50)
|
|
|
|
|
|
|
|
|
|
# 创建QMT引擎实例
|
|
|
|
|
engine = QMTEngine()
|
|
|
|
|
logger.info("QMT引擎实例创建成功")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# 初始化引擎
|
|
|
|
|
engine.initialize('config.json')
|
|
|
|
|
logger.info("✅ QMT引擎初始化成功")
|
|
|
|
|
except ConfigError as e:
|
|
|
|
|
logger.error(f"❌ 配置校验失败: {str(e)}")
|
|
|
|
|
logger.error("请检查 config.json 配置文件")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"❌ QMT引擎初始化失败: {str(e)}", exc_info=True)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
# 启动交易线程
|
|
|
|
|
trading_thread = threading.Thread(target=engine.run_trading_loop, daemon=True)
|
|
|
|
|
trading_thread.start()
|
|
|
|
|
logger.info("✅ 交易线程启动成功")
|
|
|
|
|
|
|
|
|
|
# 创建API服务器
|
|
|
|
|
app = create_api_server(engine)
|
|
|
|
|
logger.info("✅ API服务器创建成功")
|
|
|
|
|
|
|
|
|
|
# 启动Web服务
|
|
|
|
|
logger.info(">>> Web服务启动: http://localhost:8001")
|
|
|
|
|
try:
|
|
|
|
|
uvicorn.run(
|
|
|
|
|
app,
|
|
|
|
|
host="0.0.0.0",
|
|
|
|
|
port=8001,
|
|
|
|
|
log_level="warning",
|
|
|
|
|
access_log=False
|
|
|
|
|
)
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
logger.info(">>> 正在关闭系统...")
|
|
|
|
|
engine.stop()
|
|
|
|
|
logger.info(">>> 系统已关闭")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f">>> 系统异常: {str(e)}", exc_info=True)
|
|
|
|
|
engine.stop()
|
|
|
|
|
logger.info(">>> 系统已关闭")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
# 使用 -u 参数运行是最佳实践: python -u main.py
|
|
|
|
|
# 但这里也在代码里强制 flush 了
|
|
|
|
|
main()
|
|
|
|
|
import threading
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
import logging
|
|
|
|
|
import datetime
|
|
|
|
|
import uvicorn
|
|
|
|
|
|
2026-01-04 22:43:13 +08:00
|
|
|
from .qmt_engine import QMTEngine
|
|
|
|
|
from .api_server import create_api_server
|
|
|
|
|
|
|
|
|
|
|
2026-01-27 01:21:22 +08:00
|
|
|
def setup_logger():
|
|
|
|
|
"""配置日志系统"""
|
|
|
|
|
log_dir = "logs"
|
|
|
|
|
if not os.path.exists(log_dir):
|
|
|
|
|
os.makedirs(log_dir)
|
|
|
|
|
|
|
|
|
|
log_file = os.path.join(log_dir, f"{datetime.date.today().strftime('%Y-%m-%d')}.log")
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger("QMT_Main")
|
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
|
|
|
|
|
|
formatter = logging.Formatter(
|
|
|
|
|
'[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s',
|
|
|
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
file_handler = logging.FileHandler(log_file, mode='a', encoding='utf-8')
|
|
|
|
|
file_handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
|
stream_handler = logging.StreamHandler(sys.stdout)
|
|
|
|
|
stream_handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
|
logger.addHandler(file_handler)
|
|
|
|
|
logger.addHandler(stream_handler)
|
|
|
|
|
|
|
|
|
|
return logger
|
|
|
|
|
|
|
|
|
|
|
2026-01-04 22:43:13 +08:00
|
|
|
def main():
|
|
|
|
|
"""主函数 - 启动QMT交易引擎和API服务器"""
|
2026-01-27 01:21:22 +08:00
|
|
|
logger = setup_logger()
|
|
|
|
|
logger.info("="*50)
|
|
|
|
|
logger.info(">>> QMT交易系统启动中...")
|
|
|
|
|
logger.info("="*50)
|
2026-01-04 22:43:13 +08:00
|
|
|
|
|
|
|
|
# 创建QMT引擎实例
|
|
|
|
|
engine = QMTEngine()
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info("QMT引擎实例创建成功")
|
2026-01-04 22:43:13 +08:00
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# 初始化引擎
|
|
|
|
|
engine.initialize('config.json')
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info("✅ QMT引擎初始化成功")
|
2026-01-04 22:43:13 +08:00
|
|
|
except Exception as e:
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.error(f"❌ QMT引擎初始化失败: {str(e)}", exc_info=True)
|
2026-01-04 22:43:13 +08:00
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
# 启动交易线程
|
|
|
|
|
trading_thread = threading.Thread(target=engine.run_trading_loop, daemon=True)
|
|
|
|
|
trading_thread.start()
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info("✅ 交易线程启动成功")
|
2026-01-04 22:43:13 +08:00
|
|
|
|
|
|
|
|
# 创建API服务器
|
|
|
|
|
app = create_api_server(engine)
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info("✅ API服务器创建成功")
|
2026-01-04 22:43:13 +08:00
|
|
|
|
|
|
|
|
# 启动Web服务
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info(">>> Web服务启动: http://localhost:8001")
|
2026-01-04 22:43:13 +08:00
|
|
|
try:
|
|
|
|
|
uvicorn.run(
|
|
|
|
|
app,
|
|
|
|
|
host="0.0.0.0",
|
|
|
|
|
port=8001,
|
|
|
|
|
log_level="warning",
|
|
|
|
|
access_log=False
|
|
|
|
|
)
|
|
|
|
|
except KeyboardInterrupt:
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info(">>> 正在关闭系统...")
|
|
|
|
|
engine.stop()
|
|
|
|
|
logger.info(">>> 系统已关闭")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f">>> 系统异常: {str(e)}", exc_info=True)
|
2026-01-04 22:43:13 +08:00
|
|
|
engine.stop()
|
2026-01-27 01:21:22 +08:00
|
|
|
logger.info(">>> 系统已关闭")
|
2026-01-04 22:43:13 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
# 使用 -u 参数运行是最佳实践: python -u main.py
|
|
|
|
|
# 但这里也在代码里强制 flush 了
|
|
|
|
|
main()
|