diff --git a/crontab_setup.txt b/crontab_setup.txt new file mode 100644 index 0000000..c2ac82d --- /dev/null +++ b/crontab_setup.txt @@ -0,0 +1,24 @@ +# 加密货币智能体 crontab 配置示例 +# 将以下内容添加到crontab中: crontab -e + +# 设置环境变量 +SHELL=/bin/bash +PATH=/usr/local/bin:/usr/bin:/bin +PYTHONPATH=/path/to/your/cryptoai + +# 日志文件 +LOGFILE=/path/to/your/cryptoai/logs/cron.log + +# 每天早上8:30运行加密货币智能体 +30 8 * * * cd /path/to/your/cryptoai && python run.py --agent crypto --run-once >> $LOGFILE 2>&1 + +# 每天晚上20:30运行黄金智能体 +30 20 * * * cd /path/to/your/cryptoai && python run.py --agent gold --run-once >> $LOGFILE 2>&1 + +# 每6小时运行一次加密货币智能体 +0 */6 * * * cd /path/to/your/cryptoai && python run.py --agent crypto --run-once >> $LOGFILE 2>&1 + +# 每周一早上9点运行完整分析 +0 9 * * 1 cd /path/to/your/cryptoai && python run.py --agent crypto --symbol BTCUSDT --days 90 >> $LOGFILE 2>&1 + +# 注意:使用前请将路径替换为您实际的项目路径 \ No newline at end of file diff --git a/cryptoai/__pycache__/main.cpython-313.pyc b/cryptoai/__pycache__/main.cpython-313.pyc index a802706..f0d19d4 100644 Binary files a/cryptoai/__pycache__/main.cpython-313.pyc and b/cryptoai/__pycache__/main.cpython-313.pyc differ diff --git a/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc b/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc index 6f5b755..d4fbd7f 100644 Binary files a/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc and b/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc differ diff --git a/cryptoai/agents/crypto_agent.py b/cryptoai/agents/crypto_agent.py index 7c96b17..aebbd90 100644 --- a/cryptoai/agents/crypto_agent.py +++ b/cryptoai/agents/crypto_agent.py @@ -17,6 +17,7 @@ from api.deepseek_api import DeepSeekAPI from models.data_processor import DataProcessor from utils.config_loader import ConfigLoader from utils.dingtalk_bot import DingTalkBot +from utils.db_manager import get_db_manager class CryptoAgent: @@ -73,6 +74,9 @@ class CryptoAgent: ) print("钉钉机器人已启用") + # 初始化数据库管理器 + self.db_manager = get_db_manager() + # 设置支持的加密货币 self.base_currencies = self.crypto_config['base_currencies'] self.quote_currency = self.crypto_config['quote_currency'] @@ -283,6 +287,22 @@ class CryptoAgent: "timestamp": datetime.now().isoformat() } + # 保存分析结果到数据库 + try: + # 保存到数据库 + saved = self.db_manager.save_analysis_result( + agent='crypto', + symbol=symbol, + time_interval=self.time_interval, + analysis_result=analysis_result + ) + if saved: + print(f"{symbol}分析结果已保存到数据库") + else: + print(f"{symbol}分析结果保存到数据库失败") + except Exception as e: + print(f"保存{symbol}分析结果到数据库时出错: {e}") + # 如果钉钉机器人已启用,发送分析报告 if self.dingtalk_bot: try: diff --git a/cryptoai/config/config.example.yaml b/cryptoai/config/config.example.yaml index 59d30fa..e0620dc 100644 --- a/cryptoai/config/config.example.yaml +++ b/cryptoai/config/config.example.yaml @@ -4,14 +4,21 @@ binance: api_secret: "your_binance_api_secret_here" test_mode: true # 设置为false将使用实盘交易 +# OKX API设置 +okx: + api_key: "your_okx_api_key" + api_secret: "your_okx_api_secret" + passphrase: "your_okx_passphrase" + test_mode: false # 设置为true使用测试网络 + # DeepSeek AI设置 deepseek: - api_key: "your_deepseek_api_key_here" + api_key: "your_deepseek_api_key" model: "deepseek-chat" # 使用的模型 # AllTick API设置(用于获取黄金数据) alltick: - api_key: "6c7ba077eee07f6f270e219d4848700e-c-app" + api_key: "your_alltick_api_key" symbols: - "XAUUSD" # 黄金/美元 # - "XAGUSD" # 白银/美元 @@ -19,18 +26,21 @@ alltick: # 加密货币设置 crypto: base_currencies: - # - "BTC" + - "BTC" - "ETH" - # - "BNB" + - "BNB" - "SOL" - # - "ADA" + - "ARB" quote_currency: "USDT" - time_interval: "4h" # 可选: 1m, 5m, 15m, 30m, 1h, 4h, 1d + time_interval: "1d" # 支持: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 1d, 1w, 1M + min_data_points: 100 # 最小数据点数量,不应小于30 # 黄金市场分析配置 gold: # 黄金交易对 - symbols: ["XAUUSD"] + symbols: + - "GOLD" + - "SILVER" # 历史数据天数 historical_days: 180 # 时间间隔 @@ -45,7 +55,7 @@ gold: # 数据设置 data: storage_path: "./cryptoai/data" - historical_days: 30 + historical_days: 60 # 历史数据获取天数 update_interval: 60 # 数据更新间隔(分钟) # Agent设置 @@ -53,9 +63,10 @@ agent: analysis_interval: 120 # 分析间隔(分钟) strategies: - "trend_following" - - "momentum" - - "sentiment" - risk_level: "medium" # 可选: low, medium, high + - "mean_reversion" + - "breakout" + - "rsi_strategy" + risk_level: "medium" # 风险等级: low, medium, high # 日志设置 logging: @@ -64,8 +75,16 @@ logging: # 钉钉机器人设置 dingtalk: - enabled: true # 是否启用钉钉机器人 - webhook_url: "https://oapi.dingtalk.com/robot/send?access_token=your_dingtalk_token_here" - secret: "your_dingtalk_secret_here" # 如果没有设置安全设置,可以为空 + enabled: false # 是否启用钉钉通知 + webhook_url: "https://oapi.dingtalk.com/robot/send?access_token=your_access_token" + secret: "your_secret" # 如果使用了加签安全设置,请填写此项 at_mobiles: [] # 需要@的手机号列表 - at_all: false # 是否@所有人 \ No newline at end of file + at_all: false # 是否@所有人 + +# 数据库配置 +database: + host: "gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com" + port: 27469 + user: "root" + password: "Aa#223388" + db_name: "cryptoai" \ No newline at end of file diff --git a/cryptoai/config/config.yaml b/cryptoai/config/config.yaml index c04d7a0..103a1f6 100644 --- a/cryptoai/config/config.yaml +++ b/cryptoai/config/config.yaml @@ -6,9 +6,9 @@ binance: # OKX API设置 okx: - api_key: "your_okx_api_key_here" - api_secret: "your_okx_api_secret_here" - passphrase: "your_okx_passphrase_here" + api_key: "7abe4037-3d93-40d4-a77b-c77f4a1e9490" + api_secret: "654946A2045F44CC2853D47F96C62F4E" + passphrase: "Aa@123456" test_mode: true # 设置为false将使用实盘交易 # DeepSeek AI设置 @@ -26,11 +26,12 @@ alltick: # 加密货币设置 crypto: base_currencies: - # - "ONDO" + - "BTC" # - "ETH" # - "BNB" # - "SOL" - - "SUI" + # - "SUI" + # - "WLD" quote_currency: "USDT" time_interval: "4h" # 可选: 1m, 5m, 15m, 30m, 1h, 4h, 1d @@ -75,4 +76,12 @@ dingtalk: webhook_url: "https://oapi.dingtalk.com/robot/send?access_token=2278b723cd363bb6f85592c743b59b166e70b9e02a275bb5cedbc33b53a5cbdc" secret: "your_secret" # 如果没有设置安全设置,可以为空 at_mobiles: [] # 需要@的手机号列表 - at_all: false # 是否@所有人 \ No newline at end of file + at_all: false # 是否@所有人 + +# 数据库配置 +database: + host: "gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com" + port: 27469 + user: "root" + password: "Aa#223388" + db_name: "cryptoai" \ No newline at end of file diff --git a/cryptoai/utils/__pycache__/config_loader.cpython-313.pyc b/cryptoai/utils/__pycache__/config_loader.cpython-313.pyc index 005d53f..99ba80b 100644 Binary files a/cryptoai/utils/__pycache__/config_loader.cpython-313.pyc and b/cryptoai/utils/__pycache__/config_loader.cpython-313.pyc differ diff --git a/cryptoai/utils/db_manager.py b/cryptoai/utils/db_manager.py new file mode 100644 index 0000000..04134ed --- /dev/null +++ b/cryptoai/utils/db_manager.py @@ -0,0 +1,263 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import json +import logging +from typing import Dict, Any, List, Optional, Union +from datetime import datetime + +from sqlalchemy import create_engine, Column, Integer, String, Text, DateTime, Index, text +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy.dialects.mysql import JSON +from sqlalchemy.pool import QueuePool + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger('db_manager') + +# 创建模型基类 +Base = declarative_base() + +# 定义分析结果模型 +class AnalysisResult(Base): + """分析结果表模型""" + __tablename__ = 'analysis_results' + + id = Column(Integer, primary_key=True, autoincrement=True) + agent = Column(String(50), nullable=False, comment='智能体类型(crypto, gold)') + symbol = Column(String(50), nullable=False, comment='交易对符号') + time_interval = Column(String(20), nullable=False, comment='时间间隔') + completion_result = Column(JSON, nullable=False, comment='分析结果JSON') + created_at = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间') + updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间') + + # 索引 + __table_args__ = ( + Index('idx_agent', 'agent'), + Index('idx_symbol', 'symbol'), + Index('idx_time_interval', 'time_interval'), + Index('idx_created_at', 'created_at'), + ) + +class DBManager: + """数据库管理工具,用于连接MySQL数据库并保存智能体分析结果""" + + def __init__(self, host: str, port: int, user: str, password: str, db_name: str): + """ + 初始化数据库管理器 + + Args: + host: 数据库主机地址 + port: 数据库端口 + user: 用户名 + password: 密码 + db_name: 数据库名 + """ + self.host = host + self.port = port + self.user = user + self.password = password + self.db_name = db_name + self.engine = None + self.Session = None + + # 初始化数据库连接 + self._init_db() + + def _init_db(self) -> None: + """初始化数据库连接和表""" + try: + # 创建数据库连接 + connection_string = f"mysql+pymysql://{self.user}:{self.password}@{self.host}:{self.port}/{self.db_name}?charset=utf8mb4" + + # 创建引擎,设置连接池 + self.engine = create_engine( + connection_string, + echo=False, # 设置为True可以输出SQL语句(调试用) + pool_size=5, # 连接池大小 + max_overflow=10, # 最大溢出连接数 + pool_timeout=30, # 连接超时时间 + pool_recycle=1800, # 连接回收时间(秒) + pool_pre_ping=True # 在使用连接前先ping一下,确保连接有效 + ) + + # 创建会话工厂 + self.Session = sessionmaker(bind=self.engine) + + # 创建表(如果不存在) + Base.metadata.create_all(self.engine) + + logger.info(f"成功连接到数据库 {self.db_name}") + + except Exception as e: + logger.error(f"数据库初始化失败: {e}") + self.engine = None + + def save_analysis_result(self, agent: str, symbol: str, time_interval: str, + analysis_result: Dict[str, Any]) -> bool: + """ + 保存分析结果到数据库 + + Args: + agent: 智能体类型,例如 'crypto' 或 'gold' + symbol: 交易对符号,例如 'BTCUSDT' + time_interval: 时间间隔,例如 '1h', '4h', '1d' + analysis_result: 分析结果数据 + + Returns: + 保存是否成功 + """ + if not self.engine: + try: + self._init_db() + except Exception as e: + logger.error(f"重新连接数据库失败: {e}") + return False + + try: + # 创建会话 + session = self.Session() + + try: + # 创建新记录 + new_result = AnalysisResult( + agent=agent, + symbol=symbol, + time_interval=time_interval, + completion_result=analysis_result, + created_at=datetime.now(), + updated_at=datetime.now() + ) + + # 添加并提交 + session.add(new_result) + session.commit() + + logger.info(f"成功保存 {agent} 分析结果,交易对: {symbol}, 时间间隔: {time_interval}") + return True + + except Exception as e: + session.rollback() + logger.error(f"保存分析结果失败: {e}") + return False + + finally: + session.close() + + except Exception as e: + logger.error(f"创建数据库会话失败: {e}") + # 如果是连接错误,尝试重新初始化 + try: + self._init_db() + except: + pass + return False + + def get_latest_result(self, agent: str, symbol: str, time_interval: str) -> Optional[Dict[str, Any]]: + """ + 获取最新的分析结果 + + Args: + agent: 智能体类型,例如 'crypto' 或 'gold' + symbol: 交易对符号,例如 'BTCUSDT' + time_interval: 时间间隔,例如 '1h', '4h', '1d' + + Returns: + 最新分析结果,如果查询失败则返回None + """ + if not self.engine: + try: + self._init_db() + except Exception as e: + logger.error(f"重新连接数据库失败: {e}") + return None + + try: + # 创建会话 + session = self.Session() + + try: + # 查询最新的结果 + result = session.query(AnalysisResult).filter( + AnalysisResult.agent == agent, + AnalysisResult.symbol == symbol, + AnalysisResult.time_interval == time_interval + ).order_by(AnalysisResult.created_at.desc()).first() + + if result: + # 转换为字典 + return { + 'id': result.id, + 'agent': result.agent, + 'symbol': result.symbol, + 'time_interval': result.time_interval, + 'completion_result': result.completion_result, + 'created_at': result.created_at + } + else: + return None + + finally: + session.close() + + except Exception as e: + logger.error(f"获取最新分析结果失败: {e}") + return None + + def close(self) -> None: + """关闭数据库连接""" + if self.engine: + self.engine.dispose() + self.engine = None + logger.info("数据库连接已关闭") + + +# 单例模式 +_db_instance = None + +def get_db_manager(host: Optional[str] = None, + port: Optional[int] = None, + user: Optional[str] = None, + password: Optional[str] = None, + db_name: Optional[str] = None) -> DBManager: + """ + 获取数据库管理器实例(单例模式) + + Args: + host: 数据库主机地址 + port: 数据库端口 + user: 用户名 + password: 密码 + db_name: 数据库名 + + Returns: + 数据库管理器实例 + """ + global _db_instance + + # 如果已经初始化过,直接返回 + if _db_instance is not None: + return _db_instance + + # 从环境变量获取配置 + db_host = host or os.environ.get('DB_HOST', 'gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com') + db_port = port or int(os.environ.get('DB_PORT', '27469')) + db_user = user or os.environ.get('DB_USER', 'root') + db_password = password or os.environ.get('DB_PASSWORD', 'Aa#223388') + db_name = db_name or os.environ.get('DB_NAME', 'cryptoai') + + # 创建实例 + _db_instance = DBManager( + host=db_host, + port=db_port, + user=db_user, + password=db_password, + db_name=db_name + ) + + return _db_instance \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index edf2fb7..c2aba77 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,6 @@ aiohttp>=3.8.5 langchain>=0.0.267 pydantic>=2.3.0 fastapi>=0.103.1 -uvicorn>=0.23.2 \ No newline at end of file +uvicorn>=0.23.2 +alltick-api==0.0.1 +okx-api==0.0.1 \ No newline at end of file diff --git a/schedule_task.py b/schedule_task.py new file mode 100644 index 0000000..18f18f9 --- /dev/null +++ b/schedule_task.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +加密货币分析智能体定时任务 +支持以下配置: +- 定时执行:设置每天指定时间执行分析任务 +- 周期执行:设置每隔一定时间执行一次分析任务 +- 同时支持多个智能体:crypto和gold + +使用方法: +python schedule_task.py # 使用默认配置执行 +python schedule_task.py --agent crypto # 指定执行加密货币智能体 +python schedule_task.py --agent gold # 指定执行黄金智能体 +python schedule_task.py --both # 同时执行两种智能体 +python schedule_task.py --time "12:00" # 设置每天执行的时间 +python schedule_task.py --interval 240 # 设置执行间隔(分钟) +""" + +import os +import sys +import time +import argparse +import schedule +import subprocess +from datetime import datetime + +def parse_arguments(): + """解析命令行参数""" + parser = argparse.ArgumentParser(description='加密货币分析智能体定时任务') + + parser.add_argument('--agent', type=str, default='crypto', + choices=['crypto', 'gold'], + help='要执行的智能体类型,默认为加密货币智能体') + + parser.add_argument('--both', action='store_true', + help='同时执行两种智能体') + + parser.add_argument('--time', type=str, default=None, + help='每天执行任务的时间,格式为HH:MM,例如 "08:30"') + + parser.add_argument('--interval', type=int, default=360, + help='自动执行间隔(分钟),默认为360分钟(6小时)') + + return parser.parse_args() + +def run_agent(agent_type='crypto'): + """ + 执行智能体 + + Args: + agent_type: 智能体类型,可选 'crypto' 或 'gold' + """ + current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"[{current_time}] 执行{agent_type}智能体...") + + try: + # 构建命令 + cmd = ["python", "run.py", f"--agent={agent_type}", "--run-once"] + + # 执行命令 + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True + ) + + # 实时输出日志 + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + if output: + print(output.strip()) + + # 获取执行结果 + _, stderr = process.communicate() + + # 检查是否有错误 + if process.returncode != 0: + print(f"执行{agent_type}智能体时出错: {stderr}") + else: + print(f"[{current_time}] {agent_type}智能体执行完成") + + except Exception as e: + print(f"执行{agent_type}智能体时出错: {e}") + +def run_both_agents(): + """执行两种智能体""" + run_agent('crypto') + run_agent('gold') + +def main(): + """主函数""" + args = parse_arguments() + + # 定义任务函数 + if args.both: + job_func = run_both_agents + agent_desc = "加密货币和黄金" + else: + job_func = lambda: run_agent(args.agent) + agent_desc = f"{args.agent}分析" + + # 根据参数设置定时任务 + if args.time: + # 设置每天固定时间执行 + schedule.every().day.at(args.time).do(job_func) + print(f"已设置每天 {args.time} 执行{agent_desc}智能体") + else: + # 设置定时间隔执行 + schedule.every(args.interval).minutes.do(job_func) + print(f"已设置每 {args.interval} 分钟执行一次{agent_desc}智能体") + + # 立即执行一次 + print("立即执行一次任务...") + job_func() + + # 循环等待下次执行 + while True: + # 检查是否有定时任务需要执行 + schedule.run_pending() + + # 打印下次执行时间 + next_run = schedule.next_run().strftime("%Y-%m-%d %H:%M:%S") + print(f"下次执行时间: {next_run}") + + # 等待一段时间再检查 + time.sleep(60) + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\n定时任务已停止") + except Exception as e: + print(f"定时任务出错: {e}") + import traceback + traceback.print_exc() \ No newline at end of file diff --git a/schedule_task.sh b/schedule_task.sh new file mode 100755 index 0000000..6f7cceb --- /dev/null +++ b/schedule_task.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# 加密货币分析智能体定时任务启动脚本 +# 该脚本用于在后台启动智能体定时任务 + +# 使用说明: +# ./schedule_task.sh start crypto 360 # 以360分钟为间隔启动加密货币智能体 +# ./schedule_task.sh start gold "08:30" # 每天08:30运行黄金智能体 +# ./schedule_task.sh start both 240 # 以240分钟为间隔同时启动两种智能体 +# ./schedule_task.sh stop # 停止所有运行中的定时任务 +# ./schedule_task.sh status # 查看运行状态 + +# 获取当前脚本所在目录 +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +LOG_DIR="${SCRIPT_DIR}/logs" +SCHEDULE_LOG="${LOG_DIR}/schedule_task.log" + +# 确保日志目录存在 +mkdir -p "${LOG_DIR}" + +# 激活虚拟环境(如果使用了虚拟环境) +VENV_PATH="${SCRIPT_DIR}/venv" +if [ -d "${VENV_PATH}" ]; then + source "${VENV_PATH}/bin/activate" + echo "已激活虚拟环境: ${VENV_PATH}" +fi + +# 定义启动定时任务的函数 +start_schedule_task() { + local agent_type=$1 + local time_or_interval=$2 + local cmd="python ${SCRIPT_DIR}/schedule_task.py" + + # 如果同时执行两种智能体 + if [ "${agent_type}" == "both" ]; then + cmd="${cmd} --both" + else + cmd="${cmd} --agent ${agent_type}" + fi + + # 判断第二个参数是时间点还是间隔 + if [[ "${time_or_interval}" =~ ^[0-9]+$ ]]; then + # 如果是纯数字,则认为是间隔 + cmd="${cmd} --interval ${time_or_interval}" + else + # 否则认为是时间点 + cmd="${cmd} --time \"${time_or_interval}\"" + fi + + # 使用nohup在后台运行 + echo "启动定时任务: ${cmd}" + nohup ${cmd} > "${SCHEDULE_LOG}" 2>&1 & + + # 保存PID + echo $! > "${SCRIPT_DIR}/.schedule_task.pid" + echo "定时任务已在后台启动,PID: $!" + echo "日志文件: ${SCHEDULE_LOG}" +} + +# 定义停止定时任务的函数 +stop_schedule_task() { + if [ -f "${SCRIPT_DIR}/.schedule_task.pid" ]; then + local pid=$(cat "${SCRIPT_DIR}/.schedule_task.pid") + echo "正在停止定时任务 (PID: ${pid})..." + kill -15 ${pid} 2>/dev/null || echo "进程 ${pid} 不存在" + rm -f "${SCRIPT_DIR}/.schedule_task.pid" + else + echo "没有找到运行中的定时任务" + fi +} + +# 定义查看状态的函数 +check_status() { + if [ -f "${SCRIPT_DIR}/.schedule_task.pid" ]; then + local pid=$(cat "${SCRIPT_DIR}/.schedule_task.pid") + if ps -p ${pid} > /dev/null; then + echo "定时任务正在运行 (PID: ${pid})" + echo "最近的日志:" + tail -n 20 "${SCHEDULE_LOG}" + else + echo "定时任务已停止 (上次PID: ${pid})" + rm -f "${SCRIPT_DIR}/.schedule_task.pid" + fi + else + echo "没有找到运行中的定时任务" + fi +} + +# 主逻辑 +case "$1" in + start) + if [ -f "${SCRIPT_DIR}/.schedule_task.pid" ]; then + pid=$(cat "${SCRIPT_DIR}/.schedule_task.pid") + if ps -p ${pid} > /dev/null; then + echo "定时任务已在运行中 (PID: ${pid})" + echo "如需重启,请先执行: $0 stop" + exit 1 + else + rm -f "${SCRIPT_DIR}/.schedule_task.pid" + fi + fi + + # 检查必要的参数 + if [ -z "$2" ]; then + echo "缺少参数: agent_type (crypto, gold 或 both)" + echo "用法: $0 start [agent_type] [time_or_interval]" + exit 1 + fi + + if [ -z "$3" ]; then + # 使用默认间隔 + start_schedule_task "$2" "360" + else + start_schedule_task "$2" "$3" + fi + ;; + + stop) + stop_schedule_task + ;; + + status) + check_status + ;; + + *) + echo "用法: $0 {start|stop|status}" + echo " start [agent_type] [time_or_interval] - 启动定时任务" + echo " agent_type: crypto, gold 或 both" + echo " time_or_interval: 时间点(HH:MM)或间隔(分钟)" + echo " stop - 停止定时任务" + echo " status - 查看运行状态" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file