main.py
#!/usr/bin/env python3
"""
QTrading 量化选股系统主入口
"""
import argparse
import sys
from typing import List, Dict, Optional
from data.data_manager import DataManager
from engine.selector_engine import SelectorEngine
from backtest.backtest_engine import BacktestEngine
from strategy.strategy_manager import StrategyManager
from config.config import config, ADJUST_METHOD
from utils.logger import get_logger
logger = get_logger(__name__)
def parse_args():
"""解析命令行参数"""
parser = argparse.ArgumentParser(
description="QTrading 量化选股系统"
)
# 模式选择
parser.add_argument(
"-m", "--mode",
choices=["web", "cli"],
default="web",
help="运行模式:web (Web GUI,默认) 或 cli (命令行)"
)
# Tushare 令牌
parser.add_argument(
"-t", "--tushare-token",
help="Tushare 接口令牌"
)
# Web 服务器参数
parser.add_argument(
"--host",
default=config.web.host,
help=f"Web 服务器地址(默认: {config.web.host})"
)
parser.add_argument(
"--port",
type=int,
default=config.web.port,
help=f"Web 服务器端口(默认: {config.web.port})"
)
parser.add_argument(
"--debug",
action="store_true",
help="启用调试模式"
)
# 命令行模式参数
parser.add_argument(
"-s", "--strategy",
help="选股策略名称(默认: %s)" % config.strategy.default_strategy
)
parser.add_argument(
"-a", "--adjust-method",
choices=["qfq", "hfq", "none"],
default="qfq",
help="复权方式:qfq (前复权,默认), hfq (后复权), none (不复权)"
)
parser.add_argument(
"-n", "--top-n",
type=int,
default=10,
help="选股数量(默认: 10)"
)
parser.add_argument(
"-u", "--update-data",
action="store_true",
help="更新股票数据"
)
parser.add_argument(
"-b", "--backtest",
action="store_true",
help="回测策略"
)
parser.add_argument(
"-d", "--start-date",
help="回测开始日期(YYYYMMDD)"
)
parser.add_argument(
"-e", "--end-date",
help="回测结束日期(YYYYMMDD)"
)
return parser.parse_args()
def run_cli_mode(args):
"""运行命令行模式"""
logger.info("启动 QTrading 量化选股系统(命令行模式)")
# 初始化组件
selector_engine = SelectorEngine(tushare_token=args.tushare_token)
backtest_engine = BacktestEngine(tushare_token=args.tushare_token)
strategy_manager = StrategyManager()
data_manager = DataManager(tushare_token=args.tushare_token)
# 更新数据
if args.update_data:
logger.info("开始更新股票数据")
data_manager.update_all_stocks()
# 选股
if args.strategy or args.mode == "cli":
strategy_name = args.strategy or config.strategy.default_strategy
logger.info(f"开始选股:策略={strategy_name},复权方式={args.adjust_method},选股数量={args.top_n}")
results = selector_engine.select_top_n(
strategy_name=strategy_name,
n=args.top_n,
adjust_method=args.adjust_method
)
if results:
print(f"\n选股结果(策略: {strategy_name}):")
print(f"{'股票代码':<10} | {'收盘价':<10} | {'成交量':<15} | {'得分':<10}")
print("-" * 60)
for stock in results:
print(f"{stock['code']:<10} | {stock['close']:<10.2f} | {stock['vol']:<15} | {stock['score']:<10.2f}")
else:
logger.warning("未找到符合条件的股票")
# 回测
if args.backtest:
strategy_name = args.strategy or config.strategy.default_strategy
logger.info(f"开始回测:策略={strategy_name},复权方式={args.adjust_method}")
results = backtest_engine.backtest_strategy(
strategy_name=strategy_name,
adjust_method=args.adjust_method,
start_date=args.start_date,
end_date=args.end_date
)
if results:
print(f"\n回测结果(策略: {strategy_name}):")
print(f"总收益率: {results['total_return']}%")
print(f"年化收益率: {results['annual_return']}%")
print(f"最大回撤: {results['max_drawdown']}%")
print(f"年化波动率: {results['annual_volatility']}%")
print(f"夏普比率: {results['sharpe_ratio']:.2f}")
print(f"胜率: {results['win_rate']}%")
print(f"盈亏比: {results['profit_loss_ratio']:.2f}")
print(f"交易天数: {results['total_trading_days']}")
else:
logger.warning("回测失败")
logger.info("QTrading 量化选股系统执行完毕")
def run_web_mode(args):
"""运行 Web 模式"""
logger.info("启动 QTrading 量化选股系统(Web 模式)")
from web.app import run_app
run_app(
host=args.host,
port=args.port,
debug=args.debug
)
def main():
"""主函数"""
args = parse_args()
try:
if args.mode == "cli":
run_cli_mode(args)
else:
run_web_mode(args)
except Exception as e:
logger.error(f"程序执行错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()