update
This commit is contained in:
parent
e6d17d1e65
commit
926296fc57
@ -94,7 +94,8 @@ class Settings(BaseSettings):
|
||||
binance_api_secret: str = ""
|
||||
|
||||
# 飞书机器人配置
|
||||
feishu_webhook_url: str = "https://open.feishu.cn/open-apis/bot/v2/hook/8a1dcf69-6753-41e2-a393-edc4f7822db0"
|
||||
feishu_crypto_webhook_url: str = "https://open.feishu.cn/open-apis/bot/v2/hook/8a1dcf69-6753-41e2-a393-edc4f7822db0" # 加密货币通知
|
||||
feishu_stock_webhook_url: str = "https://open.feishu.cn/open-apis/bot/v2/hook/408ab727-0dcd-4c7a-bde7-4aad38cbf807" # 股票通知
|
||||
feishu_enabled: bool = True # 是否启用飞书通知
|
||||
|
||||
# Telegram 机器人配置
|
||||
|
||||
@ -155,20 +155,27 @@ class CryptoAgent:
|
||||
async def _notify_breakeven_triggered(self, result: Dict[str, Any]):
|
||||
"""发送移动止损触发通知"""
|
||||
side_text = "做多" if result.get('side') == 'long' else "做空"
|
||||
side_icon = '🟢' if result.get('side') == 'long' else '🔴'
|
||||
pnl_percent = result.get('current_pnl_percent', 0)
|
||||
|
||||
message = f"""📈 移动止损已启动
|
||||
title = f"📈 移动止损已启动 - {result.get('symbol')}"
|
||||
|
||||
交易对: {result.get('symbol')}
|
||||
方向: {side_text}
|
||||
开仓价: ${result.get('filled_price', 0):,.2f}
|
||||
当前盈利: {result.get('current_pnl_percent', 0):.2f}%
|
||||
新止损价: ${result.get('new_stop_loss', 0):,.2f}
|
||||
content_parts = [
|
||||
f"{side_icon} **方向**: {side_text}",
|
||||
f"",
|
||||
f"💰 **开仓价**: ${result.get('filled_price', 0):,.2f}",
|
||||
f"📈 **当前盈利**: {pnl_percent:+.2f}%",
|
||||
f"🛑 **新止损价**: ${result.get('new_stop_loss', 0):,.2f}",
|
||||
f"",
|
||||
f"💰 锁定利润,让利润奔跑"
|
||||
]
|
||||
|
||||
💰 锁定利润,让利润奔跑"""
|
||||
content = "\n".join(content_parts)
|
||||
|
||||
if self.settings.feishu_enabled:
|
||||
await self.feishu.send_text(message)
|
||||
await self.feishu.send_card(title, content, "green")
|
||||
if self.settings.telegram_enabled:
|
||||
message = f"{title}\n\n{content}"
|
||||
await self.telegram.send_message(message)
|
||||
logger.info(f"已发送移动止损通知: {result.get('order_id')}")
|
||||
|
||||
|
||||
@ -136,36 +136,53 @@ async def price_monitor_loop():
|
||||
if event_type == 'stop_loss_moved':
|
||||
move_type = result.get('move_type', '')
|
||||
side_text = "做多" if result.get('side') == 'long' else "做空"
|
||||
side_icon = '🟢' if result.get('side') == 'long' else '🔴'
|
||||
pnl = result.get('current_pnl_percent', 0)
|
||||
symbol_display = result.get('symbol', '')
|
||||
|
||||
if move_type == 'trailing_first':
|
||||
message = f"""📈 移动止损已激活
|
||||
|
||||
交易对: {result.get('symbol')}
|
||||
方向: {side_text}
|
||||
当前盈利: {pnl:+.2f}%
|
||||
新止损价: ${result.get('new_stop_loss', 0):,.2f}
|
||||
💰 锁定利润,让利润奔跑"""
|
||||
title = f"📈 移动止损已激活 - {symbol_display}"
|
||||
content_parts = [
|
||||
f"{side_icon} **方向**: {side_text}",
|
||||
f"",
|
||||
f"📈 **当前盈利**: {pnl:+.2f}%",
|
||||
f"🛑 **新止损价**: ${result.get('new_stop_loss', 0):,.2f}",
|
||||
f"",
|
||||
f"💰 锁定利润,让利润奔跑"
|
||||
]
|
||||
color = "green"
|
||||
elif move_type == 'trailing_update':
|
||||
message = f"""📊 止损已上移
|
||||
|
||||
交易对: {result.get('symbol')}
|
||||
方向: {side_text}
|
||||
当前盈利: {pnl:+.2f}%
|
||||
新止损价: ${result.get('new_stop_loss', 0):,.2f}
|
||||
🎯 继续锁定更多利润"""
|
||||
title = f"📊 止损已上移 - {symbol_display}"
|
||||
content_parts = [
|
||||
f"{side_icon} **方向**: {side_text}",
|
||||
f"",
|
||||
f"📈 **当前盈利**: {pnl:+.2f}%",
|
||||
f"🛑 **新止损价**: ${result.get('new_stop_loss', 0):,.2f}",
|
||||
f"",
|
||||
f"🎯 继续锁定更多利润"
|
||||
]
|
||||
color = "blue"
|
||||
elif move_type == 'breakeven':
|
||||
message = f"""📈 移动止损已启动
|
||||
title = f"📈 移动止损已启动 - {symbol_display}"
|
||||
content_parts = [
|
||||
f"{side_icon} **方向**: {side_text}",
|
||||
f"",
|
||||
f"📈 **当前盈利**: {pnl:+.2f}%",
|
||||
f"🛑 **新止损价**: ${result.get('new_stop_loss', 0):,.2f}",
|
||||
f"",
|
||||
f"💰 锁定利润,让利润奔跑"
|
||||
]
|
||||
color = "green"
|
||||
else:
|
||||
continue
|
||||
|
||||
交易对: {result.get('symbol')}
|
||||
方向: {side_text}
|
||||
当前盈利: {pnl:+.2f}%
|
||||
止损移至: ${result.get('new_stop_loss', 0):,.2f}
|
||||
💰 锁定利润,让利润奔跑"""
|
||||
content = "\n".join(content_parts)
|
||||
|
||||
# 发送通知
|
||||
await feishu.send_text(message)
|
||||
await telegram.send_message(message)
|
||||
await feishu.send_card(title, content, color)
|
||||
if telegram:
|
||||
message = f"{title}\n\n{content}"
|
||||
await telegram.send_message(message)
|
||||
logger.info(f"后台监控触发止损移动: {result.get('order_id')} | {symbol}")
|
||||
continue
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
"""
|
||||
飞书通知服务 - 通过 Webhook 发送交易信号通知
|
||||
支持加密货币和股票两个独立的 webhook
|
||||
"""
|
||||
import json
|
||||
import httpx
|
||||
@ -11,25 +12,40 @@ from app.config import get_settings
|
||||
class FeishuService:
|
||||
"""飞书机器人通知服务"""
|
||||
|
||||
def __init__(self, webhook_url: str = ""):
|
||||
def __init__(self, webhook_url: str = "", service_type: str = "crypto"):
|
||||
"""
|
||||
初始化飞书服务
|
||||
|
||||
Args:
|
||||
webhook_url: 飞书机器人 Webhook URL
|
||||
webhook_url: 飞书机器人 Webhook URL(如果为空,则根据 service_type 从配置读取)
|
||||
service_type: 服务类型 ("crypto" 或 "stock")
|
||||
"""
|
||||
settings = get_settings()
|
||||
self.webhook_url = webhook_url or getattr(settings, 'feishu_webhook_url', '')
|
||||
|
||||
# 如果传入了 webhook_url,直接使用
|
||||
if webhook_url:
|
||||
self.webhook_url = webhook_url
|
||||
else:
|
||||
# 否则根据服务类型从配置读取
|
||||
if service_type == "crypto":
|
||||
self.webhook_url = getattr(settings, 'feishu_crypto_webhook_url', '')
|
||||
elif service_type == "stock":
|
||||
self.webhook_url = getattr(settings, 'feishu_stock_webhook_url', '')
|
||||
else:
|
||||
# 兼容旧配置
|
||||
self.webhook_url = getattr(settings, 'feishu_webhook_url', '')
|
||||
|
||||
# 检查配置开关和 webhook_url 是否都有效
|
||||
config_enabled = getattr(settings, 'feishu_enabled', True)
|
||||
self.enabled = config_enabled and bool(self.webhook_url)
|
||||
self.service_type = service_type
|
||||
|
||||
if not config_enabled:
|
||||
logger.info("飞书通知已通过配置禁用")
|
||||
logger.info(f"飞书通知已通过配置禁用")
|
||||
elif self.enabled:
|
||||
logger.info("飞书通知服务初始化完成")
|
||||
logger.info(f"飞书通知服务初始化完成 ({service_type})")
|
||||
else:
|
||||
logger.warning("飞书 Webhook URL 未配置,通知功能已禁用")
|
||||
logger.warning(f"飞书 Webhook URL 未配置 ({service_type}),通知功能已禁用")
|
||||
|
||||
async def send_text(self, message: str) -> bool:
|
||||
"""
|
||||
@ -266,13 +282,28 @@ class FeishuService:
|
||||
return False
|
||||
|
||||
|
||||
# 全局实例(延迟初始化)
|
||||
_feishu_service: Optional[FeishuService] = None
|
||||
|
||||
# 全局实例(延迟初始化)- 分别用于加密货币和股票
|
||||
_feishu_crypto_service: Optional[FeishuService] = None
|
||||
_feishu_stock_service: Optional[FeishuService] = None
|
||||
|
||||
|
||||
def get_feishu_service() -> FeishuService:
|
||||
"""获取飞书服务实例"""
|
||||
global _feishu_service
|
||||
if _feishu_service is None:
|
||||
_feishu_service = FeishuService()
|
||||
return _feishu_service
|
||||
"""获取飞书服务实例(默认 crypto,保持向后兼容)"""
|
||||
return get_feishu_crypto_service()
|
||||
|
||||
|
||||
def get_feishu_crypto_service() -> FeishuService:
|
||||
"""获取加密货币飞书服务实例"""
|
||||
global _feishu_crypto_service
|
||||
if _feishu_crypto_service is None:
|
||||
_feishu_crypto_service = FeishuService(service_type="crypto")
|
||||
return _feishu_crypto_service
|
||||
|
||||
|
||||
def get_feishu_stock_service() -> FeishuService:
|
||||
"""获取股票飞书服务实例"""
|
||||
global _feishu_stock_service
|
||||
if _feishu_stock_service is None:
|
||||
_feishu_stock_service = FeishuService(service_type="stock")
|
||||
return _feishu_stock_service
|
||||
|
||||
@ -10,7 +10,7 @@ import pandas as pd
|
||||
from app.utils.logger import logger
|
||||
from app.config import get_settings
|
||||
from app.services.yfinance_service import get_yfinance_service
|
||||
from app.services.feishu_service import get_feishu_service
|
||||
from app.services.feishu_service import get_feishu_stock_service
|
||||
from app.services.telegram_service import get_telegram_service
|
||||
from app.services.signal_database_service import get_signal_db_service
|
||||
from app.services.fundamental_service import get_fundamental_service
|
||||
@ -86,7 +86,7 @@ class StockAgent:
|
||||
"""初始化智能体"""
|
||||
self.settings = get_settings()
|
||||
self.yfinance = get_yfinance_service()
|
||||
self.feishu = get_feishu_service()
|
||||
self.feishu = get_feishu_stock_service()
|
||||
self.telegram = get_telegram_service()
|
||||
self.market_analyzer = StockMarketSignalAnalyzer() # 使用新的市场信号分析器
|
||||
self.signal_db = get_signal_db_service() # 信号数据库服务
|
||||
|
||||
Loading…
Reference in New Issue
Block a user