This commit is contained in:
aaron 2025-05-01 13:46:37 +08:00
parent 284a3f463a
commit b573ac1dfe
14 changed files with 161 additions and 39 deletions

2
.gitignore vendored
View File

@ -20,6 +20,8 @@ wheels/
.installed.cfg
*.egg
# 虚拟环境
venv/
ENV/

View File

@ -8,7 +8,7 @@
- 利用DeepSeek大模型进行市场分析和预测
- 提供市场趋势、价格预测和交易建议
- 支持多种加密货币分析
- 通过钉钉机器人发送分析结果
- 通过钉钉机器人和Discord Webhook发送分析结果
## 项目结构
@ -98,6 +98,10 @@ OKX_PASSPHRASE=OKX密码
DINGTALK_ENABLED=true/false
DINGTALK_WEBHOOK_URL=钉钉Webhook地址
DINGTALK_SECRET=钉钉密钥
# Discord机器人
DISCORD_ENABLED=true/false
DISCORD_WEBHOOK_URL=Discord Webhook地址
```
在Docker中可以通过`-e`参数或`.env`文件传递环境变量。
@ -176,3 +180,38 @@ curl -X POST "http://localhost:8000/api/analyze" \
"task_type": "市场分析"
}'
```
## 消息通知
项目支持多种消息通知方式,可以将分析结果发送到不同的平台。
### 钉钉机器人
在配置文件中设置钉钉机器人的Webhook URL和密钥启用后会将分析结果发送到钉钉群聊。
```yaml
dingtalk:
enabled: true
webhook_url: your_dingtalk_webhook_url
secret: your_dingtalk_secret
```
### Discord机器人
在配置文件中设置Discord Webhook URL启用后会将分析结果以精美的嵌入式消息发送到Discord频道。
```yaml
discord:
enabled: true
webhook_url: your_discord_webhook_url
username: CryptoAI分析机器人
avatar_url: https://cdn-icons-png.flaticon.com/512/2878/2878497.png
```
#### 测试Discord机器人
可以使用以下命令测试Discord机器人的功能
```bash
python -m cryptoai.tests.test_discord_bot --webhook your_webhook_url
```

View File

@ -18,7 +18,7 @@ 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
from utils.discord_bot import DiscordBot
class CryptoAgent:
"""加密货币智能体,用于分析市场数据并生成交易策略"""
@ -40,6 +40,7 @@ class CryptoAgent:
self.crypto_config = self.config_loader.get_crypto_config()
self.data_config = self.config_loader.get_data_config()
self.dingtalk_config = self.config_loader.get_dingtalk_config()
self.discord_config = self.config_loader.get_discord_config()
# 初始化API客户端
self.binance_api = BinanceAPI(
@ -70,6 +71,14 @@ class CryptoAgent:
)
print("钉钉机器人已启用")
# 初始化Discord机器人如果启用
self.discord_bot = None
if self.discord_config.get('enabled', False):
self.discord_bot = DiscordBot(
webhook_url=self.discord_config['crypto_webhook_url']
)
print("Discord机器人已启用")
# 初始化数据库管理器
self.db_manager = get_db_manager()
@ -346,6 +355,9 @@ class CryptoAgent:
if self.dingtalk_bot:
self.dingtalk_bot.send_markdown(title="加密货币交易建议", text=message)
if self.discord_bot:
self.discord_bot.send_message(content=message)
# 导出 DeepSeek API token 使用情况
self._export_token_usage()

View File

@ -17,7 +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.discord_bot import DiscordBot
class GoldAgent:
"""黄金分析智能体,用于分析黄金市场数据并生成交易策略"""
@ -39,6 +39,7 @@ class GoldAgent:
self.gold_config = self.config_loader.get_gold_config() # 黄金特定配置
self.data_config = self.config_loader.get_data_config()
self.dingtalk_config = self.config_loader.get_dingtalk_config()
self.discord_config = self.config_loader.get_discord_config()
# 初始化API客户端
self.binance_api = BinanceAPI(
@ -66,6 +67,14 @@ class GoldAgent:
)
print("钉钉机器人已启用")
# 初始化Discord机器人如果启用
self.discord_bot = None
if self.discord_config.get('enabled', False):
self.discord_bot = DiscordBot(
webhook_url=self.discord_config['gold_webhook_url']
)
print("Discord机器人已启用")
# 设置黄金交易对
self.gold_symbols = self.gold_config.get('symbols', ["XAUUSD"]) # 默认黄金/美元
@ -336,6 +345,9 @@ class GoldAgent:
if self.dingtalk_bot:
self.dingtalk_bot.send_markdown(title="黄金交易建议", text=trading_suggestions)
if self.discord_bot:
self.discord_bot.send_message(content=trading_suggestions)
return results, trading_suggestions
def convert_analysis_to_trading_suggestions(self, results: Dict[str, Any]) -> str:

View File

@ -27,8 +27,10 @@ crypto:
base_currencies:
- "BTC"
- "ETH"
# - "SOL"
# - "SUI"
- "SOL"
- "SUI"
- "XRP"
- “DOGE”
quote_currency: "USDT"
time_interval: "4h" # 可选: 1m, 5m, 15m, 30m, 1h, 4h, 1d
historical_days: 90
@ -38,7 +40,7 @@ gold:
# 黄金交易对
symbols: ["GOLD"]
# 历史数据天数
historical_days: 30
historical_days: 90
# 时间间隔
time_interval: "4h"
@ -60,6 +62,13 @@ dingtalk:
at_mobiles: [] # 需要@的手机号列表
at_all: false # 是否@所有人
# Discord机器人配置
discord:
enabled: true
crypto_webhook_url: "https://discord.com/api/webhooks/1286585288986198048/iQ-yr26ViW45GM48ql8rPu70Iumqcmn_XXAmxAcKGeiQBmTQoDPeq-TmlChvIHkw_HJ-"
gold_webhook_url: "https://discord.com/api/webhooks/1367341235987021914/XVcjs6ZAZad3ZezzuudyiK_KqNUowqz2o2NJPdvwWY_EvwZVJcnVHq5M0-RQhkKV-FEQ"
# 数据库配置
database:
host: "gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com"

View File

@ -26,13 +26,18 @@ def main():
print("定时程序启动")
CryptoAgent().start_agent()
# 设置 08:00, 20:00 运行一次
schedule.every().day.at("00:00").do(CryptoAgent().start_agent)
schedule.every().day.at("08:00").do(CryptoAgent().start_agent)
schedule.every().day.at("12:00").do(CryptoAgent().start_agent)
schedule.every().day.at("16:00").do(CryptoAgent().start_agent)
schedule.every().day.at("20:00").do(CryptoAgent().start_agent)
schedule.every().day.at("00:00").do(GoldAgent().start_agent)
schedule.every().day.at("08:00").do(GoldAgent().start_agent)
schedule.every().day.at("12:00").do(GoldAgent().start_agent)
schedule.every().day.at("16:00").do(GoldAgent().start_agent)
schedule.every().day.at("20:00").do(GoldAgent().start_agent)
# 启动定时任务
while True:
schedule.run_pending()
time.sleep(1)

View File

@ -2,3 +2,7 @@
# -*- coding: utf-8 -*-
"""工具模块,提供各种辅助功能。"""
from cryptoai.utils.dingtalk_bot import DingTalkBot
from cryptoai.utils.discord_bot import DiscordBot
from cryptoai.utils.config_loader import ConfigLoader

View File

@ -96,35 +96,11 @@ class ConfigLoader:
"""获取钉钉机器人配置"""
return self.get_config('dingtalk')
def get_discord_config(self) -> Dict[str, Any]:
"""获取Discord机器人配置"""
return self.get_config('discord')
def get_database_config(self) -> Dict[str, Any]:
"""获取数据库配置"""
# 首先从配置文件获取
db_config = self.get_config('database')
# 使用环境变量覆盖(如果存在)
if os.environ.get('DB_HOST'):
db_config['host'] = os.environ.get('DB_HOST')
if os.environ.get('DB_PORT'):
db_config['port'] = int(os.environ.get('DB_PORT'))
if os.environ.get('DB_USER'):
db_config['user'] = os.environ.get('DB_USER')
if os.environ.get('DB_PASSWORD'):
db_config['password'] = os.environ.get('DB_PASSWORD')
if os.environ.get('DB_NAME'):
db_config['db_name'] = os.environ.get('DB_NAME')
# 确保返回默认值(如果配置不存在)
default_config = {
'host': 'gz-cynosdbmysql-grp-2j1cnopr.sql.tencentcdb.com',
'port': 27469,
'user': 'root',
'password': 'Aa#223388',
'db_name': 'cryptoai'
}
# 合并默认配置和实际配置
for key, value in default_config.items():
if key not in db_config:
db_config[key] = value
return db_config
return self.get_config('database')

View File

@ -0,0 +1,63 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import requests
import traceback
import datetime
from typing import Dict, Any, List, Optional, Union
class DiscordBot:
"""Discord Webhook机器人用于发送分析结果到Discord频道"""
def __init__(self, webhook_url: str):
"""
初始化Discord Webhook机器人
Args:
webhook_url: Discord Webhook的URL
"""
self.webhook_url = webhook_url
def send_message(self, content: str, username: str = None, avatar_url: str = None) -> Dict[str, Any]:
"""
发送普通消息
Args:
content: 消息内容
username: 自定义机器人名称
avatar_url: 自定义机器人头像URL
Returns:
接口返回结果
"""
data = {"content": content}
if username:
data["username"] = username
if avatar_url:
data["avatar_url"] = avatar_url
return self._post(data)
def _post(self, data: Dict[str, Any]) -> Dict[str, Any]:
"""
发送数据到Discord Webhook
Args:
data: 要发送的数据
Returns:
接口返回结果
"""
try:
headers = {'Content-Type': 'application/json'}
response = requests.post(self.webhook_url, json=data, headers=headers)
if response.status_code == 204: # Discord返回成功时无内容
return {"success": True}
return response.json()
except Exception as e:
print(f"发送Discord消息时出错: {e}")
traceback.print_exc()
return {"success": False, "error": str(e)}

View File

@ -4,7 +4,7 @@ services:
cryptoai:
build: .
container_name: cryptoai-task
image: cryptoai:0.0.9
image: cryptoai:0.0.10
restart: always
volumes:
- ./cryptoai/data:/app/cryptoai/data