#!/bin/bash # 确保使用 bash 执行此脚本 if [ -z "$BASH_VERSION" ]; then echo "错误: 此脚本需要使用 bash 执行,请使用以下命令之一:" echo " bash start.sh [参数]" echo " 或" echo " ./start.sh [参数]" exit 1 fi # ETF基金筛选工具启动脚本 # 默认后台执行(脚本立即返回,输出见 out/git_push.log 与 out/<日期>/ 下日志);加 --foreground/--fg/-f 可改为前台执行(等待完成,输出到终端,可交互)。 # # 使用方式: # 1. 正常分析流程: # ./start.sh [--a|--archive|-a] [--s|--with-summary|-s] # 示例: # ./start.sh 1 # 执行1次分析 # ./start.sh 2 --a # 执行2次分析,归档 # ./start.sh 1 --s # 执行1次分析,完成后汇总 # ./start.sh 2 --a --s # 执行2次分析,归档,完成后汇总 # # 2. 仅生成CSV文件(不调用大模型): # ./start.sh --csv-only [--full-fields|-F|--csv-full] [--a|--archive|-a] # 示例: # ./start.sh --csv-only # 仅生成CSV文件(37列简化字段) # ./start.sh --csv-only --a # 仅生成CSV文件并归档 # ./start.sh --csv-only --full-fields # 仅生成CSV文件,输出完整字段 # ./start.sh --csv-only --full-fields --a # ./start.sh --only-csv # 简写形式 # # 3. 从CSV文件生成报告: # ./start.sh --csv [--count ] [--a|--archive|-a] [--s|--with-summary|-s] # 示例: # ./start.sh --csv out/20260113/20260113_161427_etf_all_data.csv # ./start.sh --csv out/20260113/20260113_161427_etf_all_data.csv --count 2 --s # ./start.sh --csv out/20260113/20260113_161427_etf_all_data.csv --a --s # # 4. 从归档执行汇总分析: # ./start.sh --date 或 ./start.sh -d # 示例: # ./start.sh --date 20260109 # 从20260109的归档读取并汇总 # ./start.sh -d 20260109 # 简写形式 # # 参数说明: # count: 并行调用大模型的次数(仅用于正常分析流程和CSV模式) # --archive/-a/--a: 启用归档功能 # --with-summary/-s/--s: 启用汇总分析功能(仅用于正常分析流程和CSV模式) # --csv-only/--only-csv: 仅生成CSV文件,不调用大模型生成报告 # --full-fields/-F/--csv-full: 与 --csv-only 同时使用时输出完整字段的 CSV(文件名为 *_etf_all_data.csv) # --csv: 指定CSV文件路径,基于已有CSV文件生成报告(时间戳使用当前时间) # --date/-d: 从归档目录读取并执行汇总分析(格式: YYYYMMDD) # --git/--commit: 启用git提交功能(默认不提交) # --foreground/--fg/-f: 前台执行(等待完成,输出到终端,可交互);默认后台执行(脚本立即返回,输出见 out/git_push.log 与 out/<日期>/ 下日志) # 解析传入的参数 # 支持以下格式: # ./start.sh [--a|--archive|-a] [--s|--with-summary|-s] # ./start.sh --csv-only [--a|--archive|-a] # ./start.sh --csv [--count ] [--a|--archive|-a] [--s|--with-summary|-s] # ./start.sh --date 或 ./start.sh -d COUNT_PARAM="" ARCHIVE_FLAG=false WITH_SUMMARY_FLAG=false DATE_PARAM="" CSV_FILE_PARAM="" CSV_ONLY_FLAG=false CSV_FULL_FIELDS_FLAG=false GIT_COMMIT_FLAG=false BACKGROUND_FLAG=true # 遍历所有参数 i=1 while [ $i -le $# ]; do arg="${!i}" case "$arg" in --a|--archive|-a) ARCHIVE_FLAG=true ;; --s|--with-summary|-s) WITH_SUMMARY_FLAG=true ;; --csv-only|--only-csv) CSV_ONLY_FLAG=true ;; --full-fields|-F|--csv-full) CSV_FULL_FIELDS_FLAG=true ;; --csv) # 获取下一个参数作为CSV文件路径 if [ $i -lt $# ]; then i=$((i+1)) CSV_FILE_PARAM="${!i}" else echo "错误: --csv 参数需要指定CSV文件路径" exit 1 fi ;; --count|-c) # 获取下一个参数作为并行次数 if [ $i -lt $# ]; then i=$((i+1)) COUNT_PARAM="${!i}" else echo "错误: --count 参数需要指定并行次数" exit 1 fi ;; --date|-d) # 获取下一个参数作为日期 if [ $i -lt $# ]; then i=$((i+1)) DATE_PARAM="${!i}" else echo "错误: --date 参数需要指定日期(格式: YYYYMMDD)" exit 1 fi ;; --git|--commit) GIT_COMMIT_FLAG=true ;; --background|--bg|-b) BACKGROUND_FLAG=true ;; --foreground|--fg|-f) BACKGROUND_FLAG=false ;; *) # 如果不是已知标志,按顺序分配:第一个是count(仅在没有使用--count时) # 但需要排除已经被其他参数使用的参数 if [ -z "$COUNT_PARAM" ] && [ "$arg" != "$DATE_PARAM" ] && [ "$arg" != "$CSV_FILE_PARAM" ]; then # 检查是否是数字(count参数) if [[ "$arg" =~ ^[0-9]+$ ]]; then COUNT_PARAM="$arg" fi fi ;; esac i=$((i+1)) done export COUNT_PARAM export ARCHIVE_FLAG export WITH_SUMMARY_FLAG export DATE_PARAM export CSV_FILE_PARAM export CSV_ONLY_FLAG export GIT_COMMIT_FLAG export BACKGROUND_FLAG # 进入项目根目录 cd "$(dirname "$0")" || exit 1 mkdir -p out # 生成统一的时间戳前缀(格式:YYYYMMDD_HHMMSS) DATE_DIR=$(date '+%Y%m%d') TIMESTAMP=$(date '+%Y%m%d_%H%M%S') # 如果使用 --date 参数,使用指定的日期作为目录 if [ -n "$DATE_PARAM" ]; then DATE_DIR="$DATE_PARAM" # 验证日期格式 if ! [[ "$DATE_PARAM" =~ ^[0-9]{8}$ ]]; then echo "错误: 日期格式不正确,应为 YYYYMMDD(例如: 20260109)" exit 1 fi fi mkdir -p "out/${DATE_DIR}" LOG_FILE="out/${DATE_DIR}/${TIMESTAMP}_crew_output.log" # 构建命令行参数 PYTHON_ARGS=() # 优先级:--csv > --date > 正常分析流程 if [ -n "$CSV_FILE_PARAM" ]; then # CSV文件模式 PYTHON_ARGS+=("--csv-file" "$CSV_FILE_PARAM") PYTHON_ARGS+=("--timestamp" "$TIMESTAMP") if [ -n "$COUNT_PARAM" ]; then PYTHON_ARGS+=("--count" "$COUNT_PARAM") fi if [ "$ARCHIVE_FLAG" = true ]; then PYTHON_ARGS+=("--archive") fi if [ "$WITH_SUMMARY_FLAG" = true ]; then PYTHON_ARGS+=("--with-summary") fi elif [ -n "$DATE_PARAM" ]; then PYTHON_ARGS+=("--date" "$DATE_PARAM") else # 正常分析流程 PYTHON_ARGS+=("--timestamp" "$TIMESTAMP") if [ "$CSV_ONLY_FLAG" = true ]; then PYTHON_ARGS+=("--csv-only") if [ "$CSV_FULL_FIELDS_FLAG" = true ]; then PYTHON_ARGS+=("--full-fields") fi fi if [ -n "$COUNT_PARAM" ] && [ "$CSV_ONLY_FLAG" != true ]; then PYTHON_ARGS+=("--count" "$COUNT_PARAM") fi if [ "$ARCHIVE_FLAG" = true ]; then PYTHON_ARGS+=("--archive") fi if [ "$WITH_SUMMARY_FLAG" = true ] && [ "$CSV_ONLY_FLAG" != true ]; then PYTHON_ARGS+=("--with-summary") fi fi if [ "$BACKGROUND_FLAG" = true ]; then # 后台执行:子 shell 内完成 git pull、激活环境、运行主程序、可选 git 提交,脚本立即返回 ( git pull || exit 1 . .venv/bin/activate python -u -m investment_team.main "${PYTHON_ARGS[@]}" 2>&1 | python -u scripts/add_timestamp.py > "$LOG_FILE" & wait if [ "$GIT_COMMIT_FLAG" = true ]; then git add . git commit -m "Auto commit: crewai run completed at $(date '+%Y-%m-%d %H:%M:%S')" git pull --rebase git push fi ) > out/git_push.log 2>&1 & disown else # 前台执行:输出到终端并写入日志,支持交互(如有头验证时可在本终端按回车) git pull || exit 1 . .venv/bin/activate python -u -m investment_team.main "${PYTHON_ARGS[@]}" 2>&1 | python -u scripts/add_timestamp.py | tee "$LOG_FILE" if [ "$GIT_COMMIT_FLAG" = true ]; then git add . git commit -m "Auto commit: crewai run completed at $(date '+%Y-%m-%d %H:%M:%S')" git pull --rebase git push fi fi