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