update
This commit is contained in:
parent
bc7b095f40
commit
9f989ce9bb
24
crontab_setup.txt
Normal file
24
crontab_setup.txt
Normal file
@ -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
|
||||||
|
|
||||||
|
# 注意:使用前请将路径替换为您实际的项目路径
|
||||||
Binary file not shown.
Binary file not shown.
@ -17,6 +17,7 @@ from api.deepseek_api import DeepSeekAPI
|
|||||||
from models.data_processor import DataProcessor
|
from models.data_processor import DataProcessor
|
||||||
from utils.config_loader import ConfigLoader
|
from utils.config_loader import ConfigLoader
|
||||||
from utils.dingtalk_bot import DingTalkBot
|
from utils.dingtalk_bot import DingTalkBot
|
||||||
|
from utils.db_manager import get_db_manager
|
||||||
|
|
||||||
|
|
||||||
class CryptoAgent:
|
class CryptoAgent:
|
||||||
@ -73,6 +74,9 @@ class CryptoAgent:
|
|||||||
)
|
)
|
||||||
print("钉钉机器人已启用")
|
print("钉钉机器人已启用")
|
||||||
|
|
||||||
|
# 初始化数据库管理器
|
||||||
|
self.db_manager = get_db_manager()
|
||||||
|
|
||||||
# 设置支持的加密货币
|
# 设置支持的加密货币
|
||||||
self.base_currencies = self.crypto_config['base_currencies']
|
self.base_currencies = self.crypto_config['base_currencies']
|
||||||
self.quote_currency = self.crypto_config['quote_currency']
|
self.quote_currency = self.crypto_config['quote_currency']
|
||||||
@ -283,6 +287,22 @@ class CryptoAgent:
|
|||||||
"timestamp": datetime.now().isoformat()
|
"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:
|
if self.dingtalk_bot:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -4,14 +4,21 @@ binance:
|
|||||||
api_secret: "your_binance_api_secret_here"
|
api_secret: "your_binance_api_secret_here"
|
||||||
test_mode: true # 设置为false将使用实盘交易
|
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 AI设置
|
||||||
deepseek:
|
deepseek:
|
||||||
api_key: "your_deepseek_api_key_here"
|
api_key: "your_deepseek_api_key"
|
||||||
model: "deepseek-chat" # 使用的模型
|
model: "deepseek-chat" # 使用的模型
|
||||||
|
|
||||||
# AllTick API设置(用于获取黄金数据)
|
# AllTick API设置(用于获取黄金数据)
|
||||||
alltick:
|
alltick:
|
||||||
api_key: "6c7ba077eee07f6f270e219d4848700e-c-app"
|
api_key: "your_alltick_api_key"
|
||||||
symbols:
|
symbols:
|
||||||
- "XAUUSD" # 黄金/美元
|
- "XAUUSD" # 黄金/美元
|
||||||
# - "XAGUSD" # 白银/美元
|
# - "XAGUSD" # 白银/美元
|
||||||
@ -19,18 +26,21 @@ alltick:
|
|||||||
# 加密货币设置
|
# 加密货币设置
|
||||||
crypto:
|
crypto:
|
||||||
base_currencies:
|
base_currencies:
|
||||||
# - "BTC"
|
- "BTC"
|
||||||
- "ETH"
|
- "ETH"
|
||||||
# - "BNB"
|
- "BNB"
|
||||||
- "SOL"
|
- "SOL"
|
||||||
# - "ADA"
|
- "ARB"
|
||||||
quote_currency: "USDT"
|
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:
|
gold:
|
||||||
# 黄金交易对
|
# 黄金交易对
|
||||||
symbols: ["XAUUSD"]
|
symbols:
|
||||||
|
- "GOLD"
|
||||||
|
- "SILVER"
|
||||||
# 历史数据天数
|
# 历史数据天数
|
||||||
historical_days: 180
|
historical_days: 180
|
||||||
# 时间间隔
|
# 时间间隔
|
||||||
@ -45,7 +55,7 @@ gold:
|
|||||||
# 数据设置
|
# 数据设置
|
||||||
data:
|
data:
|
||||||
storage_path: "./cryptoai/data"
|
storage_path: "./cryptoai/data"
|
||||||
historical_days: 30
|
historical_days: 60 # 历史数据获取天数
|
||||||
update_interval: 60 # 数据更新间隔(分钟)
|
update_interval: 60 # 数据更新间隔(分钟)
|
||||||
|
|
||||||
# Agent设置
|
# Agent设置
|
||||||
@ -53,9 +63,10 @@ agent:
|
|||||||
analysis_interval: 120 # 分析间隔(分钟)
|
analysis_interval: 120 # 分析间隔(分钟)
|
||||||
strategies:
|
strategies:
|
||||||
- "trend_following"
|
- "trend_following"
|
||||||
- "momentum"
|
- "mean_reversion"
|
||||||
- "sentiment"
|
- "breakout"
|
||||||
risk_level: "medium" # 可选: low, medium, high
|
- "rsi_strategy"
|
||||||
|
risk_level: "medium" # 风险等级: low, medium, high
|
||||||
|
|
||||||
# 日志设置
|
# 日志设置
|
||||||
logging:
|
logging:
|
||||||
@ -64,8 +75,16 @@ logging:
|
|||||||
|
|
||||||
# 钉钉机器人设置
|
# 钉钉机器人设置
|
||||||
dingtalk:
|
dingtalk:
|
||||||
enabled: true # 是否启用钉钉机器人
|
enabled: false # 是否启用钉钉通知
|
||||||
webhook_url: "https://oapi.dingtalk.com/robot/send?access_token=your_dingtalk_token_here"
|
webhook_url: "https://oapi.dingtalk.com/robot/send?access_token=your_access_token"
|
||||||
secret: "your_dingtalk_secret_here" # 如果没有设置安全设置,可以为空
|
secret: "your_secret" # 如果使用了加签安全设置,请填写此项
|
||||||
at_mobiles: [] # 需要@的手机号列表
|
at_mobiles: [] # 需要@的手机号列表
|
||||||
at_all: false # 是否@所有人
|
at_all: false # 是否@所有人
|
||||||
|
|
||||||
|
# 数据库配置
|
||||||
|
database:
|
||||||
|
host: "gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com"
|
||||||
|
port: 27469
|
||||||
|
user: "root"
|
||||||
|
password: "Aa#223388"
|
||||||
|
db_name: "cryptoai"
|
||||||
@ -6,9 +6,9 @@ binance:
|
|||||||
|
|
||||||
# OKX API设置
|
# OKX API设置
|
||||||
okx:
|
okx:
|
||||||
api_key: "your_okx_api_key_here"
|
api_key: "7abe4037-3d93-40d4-a77b-c77f4a1e9490"
|
||||||
api_secret: "your_okx_api_secret_here"
|
api_secret: "654946A2045F44CC2853D47F96C62F4E"
|
||||||
passphrase: "your_okx_passphrase_here"
|
passphrase: "Aa@123456"
|
||||||
test_mode: true # 设置为false将使用实盘交易
|
test_mode: true # 设置为false将使用实盘交易
|
||||||
|
|
||||||
# DeepSeek AI设置
|
# DeepSeek AI设置
|
||||||
@ -26,11 +26,12 @@ alltick:
|
|||||||
# 加密货币设置
|
# 加密货币设置
|
||||||
crypto:
|
crypto:
|
||||||
base_currencies:
|
base_currencies:
|
||||||
# - "ONDO"
|
- "BTC"
|
||||||
# - "ETH"
|
# - "ETH"
|
||||||
# - "BNB"
|
# - "BNB"
|
||||||
# - "SOL"
|
# - "SOL"
|
||||||
- "SUI"
|
# - "SUI"
|
||||||
|
# - "WLD"
|
||||||
quote_currency: "USDT"
|
quote_currency: "USDT"
|
||||||
time_interval: "4h" # 可选: 1m, 5m, 15m, 30m, 1h, 4h, 1d
|
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"
|
webhook_url: "https://oapi.dingtalk.com/robot/send?access_token=2278b723cd363bb6f85592c743b59b166e70b9e02a275bb5cedbc33b53a5cbdc"
|
||||||
secret: "your_secret" # 如果没有设置安全设置,可以为空
|
secret: "your_secret" # 如果没有设置安全设置,可以为空
|
||||||
at_mobiles: [] # 需要@的手机号列表
|
at_mobiles: [] # 需要@的手机号列表
|
||||||
at_all: false # 是否@所有人
|
at_all: false # 是否@所有人
|
||||||
|
|
||||||
|
# 数据库配置
|
||||||
|
database:
|
||||||
|
host: "gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com"
|
||||||
|
port: 27469
|
||||||
|
user: "root"
|
||||||
|
password: "Aa#223388"
|
||||||
|
db_name: "cryptoai"
|
||||||
Binary file not shown.
263
cryptoai/utils/db_manager.py
Normal file
263
cryptoai/utils/db_manager.py
Normal file
@ -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
|
||||||
@ -12,4 +12,6 @@ aiohttp>=3.8.5
|
|||||||
langchain>=0.0.267
|
langchain>=0.0.267
|
||||||
pydantic>=2.3.0
|
pydantic>=2.3.0
|
||||||
fastapi>=0.103.1
|
fastapi>=0.103.1
|
||||||
uvicorn>=0.23.2
|
uvicorn>=0.23.2
|
||||||
|
alltick-api==0.0.1
|
||||||
|
okx-api==0.0.1
|
||||||
140
schedule_task.py
Normal file
140
schedule_task.py
Normal file
@ -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()
|
||||||
137
schedule_task.sh
Executable file
137
schedule_task.sh
Executable file
@ -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
|
||||||
Loading…
Reference in New Issue
Block a user