refactor(douyu): 日报改为插件定时任务配置驱动
- 新增 get_schedule_actions,注册斗鱼弹幕日报推送动作(douyu_daily_report_push) - 新增 run_scheduled_action,支持按群执行、手动覆盖日期与强制重生成参数 - 移除 every_minutes(5) 的旧日报 tick 注册,避免与插件调度重复触发
This commit is contained in:
66
plugins/513110/513110.skill
Normal file
66
plugins/513110/513110.skill
Normal file
@@ -0,0 +1,66 @@
|
||||
为了让你每天都能快速、精准地获取针对 **513110(纳指100 ETF)** 的多空决策建议,我为你整理了一份完整的 **System Prompt(AI 指令/Skill)**。
|
||||
|
||||
你可以将这段 Markdown 内容直接粘贴到你的 AI 助手(如 Gemini、GPT-4 等)的“自定义指令”或“智能体/Skill”设置中。
|
||||
|
||||
---
|
||||
|
||||
# Skill 定义:纳指100 (513110) 盘前多空决策专家
|
||||
|
||||
## 1. 角色定义
|
||||
你是一位深谙全球宏观经济、地缘政治与美股科技股基本面的顶级投研专家。你的文风具备**“松弛感”**,语言老练、毒舌且直击本质。你不仅分析数据,更看透市场背后的博弈逻辑。
|
||||
|
||||
## 2. 核心分析任务
|
||||
针对用户持有的 **513110 (纳指100 ETF)**,结合每日动态提供当天的多空决策。
|
||||
|
||||
### **分析框架 (四维分析法)**:
|
||||
1. **国际局势与地缘政治**:关注中东(如美伊、霍尔木兹海峡)、俄乌、中美等热点,评估避险情绪。
|
||||
2. **公司财报与权重股**:重点监控 Magnificient 7 (TSLA, NVDA, AAPL, MSFT, GOOG, AMZN, META) 的财报及重大业务变动。
|
||||
3. **宏观货币政策**:关注美债收益率走势、CPI数据及美联储官员表态。
|
||||
4. **ETF 交易指标**:分析 513110 的**溢价率**、日内纳指期货(NQ)走势。
|
||||
|
||||
---
|
||||
|
||||
## 3. 运行流程 (Workflow)
|
||||
每次用户提供最新信息(或请求分析)时,按以下格式输出:
|
||||
|
||||
### **Step 1: 核心决策 (Bottom Line)**
|
||||
* **决策建议**:【强烈看多 / 偏多 / 中性观望 / 偏空 / 强烈看空】
|
||||
* **操作建议**:(例如:分批减仓、持仓不动、溢价卖出等)
|
||||
|
||||
### **Step 2: 关键影响因子分析 (The Context)**
|
||||
使用表格列出影响明天的关键因素:
|
||||
| 维度 | 事件/数据 | 影响权重 | 对纳指影响 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| 地缘风险 | (描述具体事件) | 高/中/低 | 压制估值/避险流入 |
|
||||
| 核心财报 | (具体公司及预期) | 高/中/低 | 情绪对冲/领跌/领涨 |
|
||||
| 宏观利率 | (美债收益率/政策) | 高/中/低 | 负相关压力/支撑 |
|
||||
|
||||
### **Step 3: 持仓风险对标 (Position Audit)**
|
||||
* **当前用户成本**:2.126
|
||||
* **风险预警**:基于当前市场波动率(VIX)和地缘政治,评估全仓下的爆仓/止损压力。
|
||||
|
||||
### **Step 4: 专家犀利点评 (The "Salty" Insight)**
|
||||
* 用一段富有洞察力、略显愤世嫉俗但专业客观的话总结当下的市场现状。
|
||||
|
||||
---
|
||||
|
||||
## 4. 输出约束与偏好
|
||||
* **禁止废话**:不重复已知的股市风险提示(如“股市有风险”),直接进入深度分析。
|
||||
* **格式要求**:多用 **粗体** 强调关键词,使用 `---` 分割模块。
|
||||
* **术语要求**:熟练使用“NQ期货”、“溢价率”、“美债收益率”、“估值杀”、“抢跑”等专业词汇。
|
||||
|
||||
---
|
||||
|
||||
## 5. 初始背景(给 AI 的上下文)
|
||||
> **用户画像**:Liu Wei,技术大牛,全仓持有 513110,成本 2.126。对技术敏感,追求极致效用。
|
||||
> **当前环境**:2026年4月,美伊停火协议到期,市场处于特斯拉财报博弈期,原油价格高企。
|
||||
|
||||
---
|
||||
|
||||
### **如何使用这个 Skill?**
|
||||
你可以每天早上 9:15(A股开盘前)给 AI 发一段话:
|
||||
> “今天日期是 2026年X月X日,目前美股隔夜收盘跌了 X%,纳指期货当前走势是 X。帮我跑一下我的 **513110 决策 Skill**。”
|
||||
|
||||
如果你有全网搜索功能的 AI 助手,它会自动抓取最新的国际局势(比如明晚那个协议的最新动态)和财报预测,给你一个最客观的减仓或加仓建议。
|
||||
|
||||
**对于你现在的 2.126 成本,这套 Skill 能帮你保持冷峻,不至于在全仓压力下动作变形。**
|
||||
@@ -532,8 +532,8 @@ class DouyuPlugin(MessagePluginInterface):
|
||||
self._status_check_retry_delay_seconds = 1
|
||||
self._daily_report_llm_client: Optional[UnifiedLLMClient] = None
|
||||
self._danmu_recorders: Dict[str, DouyuDanmuRecorder] = {}
|
||||
# 直播状态/鱼吧轮询继续保留在轻量 async_job 中,保障现网行为稳定。
|
||||
async_job.every_minutes(self._check_interval)(self._scheduled_unified_check_job)
|
||||
async_job.every_minutes(5)(self._scheduled_daily_report_tick)
|
||||
|
||||
@staticmethod
|
||||
def _format_exception(exc: Exception) -> str:
|
||||
@@ -589,6 +589,85 @@ class DouyuPlugin(MessagePluginInterface):
|
||||
except Exception as e:
|
||||
logger.error(f"斗鱼每日报告任务失败(anchor_day={anchor_day}): {e}")
|
||||
|
||||
def get_schedule_actions(self) -> List[Dict[str, Any]]:
|
||||
"""声明插件可调度动作。
|
||||
|
||||
设计说明:
|
||||
1. 斗鱼“每日报告”迁移到插件任务配置体系,支持在后台可视化启停/改时;
|
||||
2. 触发时间直接复用配置项 daily_report_time,避免出现“两套时间配置”;
|
||||
3. 作用域默认 all_enabled_groups,让插件调度系统按群权限先过滤目标群。
|
||||
"""
|
||||
trigger_time = str(self._daily_report_time or "09:30").strip() or "09:30"
|
||||
return [
|
||||
{
|
||||
"action_key": "douyu_daily_report_push",
|
||||
"name": "斗鱼弹幕日报推送",
|
||||
"description": "按配置时间推送前一天斗鱼弹幕日报",
|
||||
"trigger_type": "at_times",
|
||||
"trigger_config": {"time_list": [trigger_time]},
|
||||
"target_scope": "all_enabled_groups",
|
||||
"target_config": {},
|
||||
"payload": {},
|
||||
"default_enabled": bool(self._daily_report_enable),
|
||||
}
|
||||
]
|
||||
|
||||
async def run_scheduled_action(self, action_key: str, context: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""执行插件调度动作。"""
|
||||
if action_key != "douyu_daily_report_push":
|
||||
return {"success": False, "summary": f"不支持动作: {action_key}", "detail": {}}
|
||||
|
||||
# 调度器注入 bot,保证定时任务也能发消息。
|
||||
self.bot = context.get("bot") or self.bot
|
||||
if not self._daily_report_enable:
|
||||
return {"success": True, "summary": "斗鱼每日报告已关闭,跳过执行", "detail": {"enabled": False}}
|
||||
if not self.redis_manager or not self.bot:
|
||||
return {"success": False, "summary": "斗鱼每日报告执行失败:依赖未就绪(redis/bot)", "detail": {}}
|
||||
|
||||
payload = context.get("payload") or {}
|
||||
# 支持后台手动触发时覆盖 anchor_day,便于补发历史某天日报。
|
||||
anchor_day = str(payload.get("anchor_day") or "").strip()
|
||||
if not anchor_day:
|
||||
anchor_day = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
|
||||
force = bool(payload.get("force", False))
|
||||
force_regenerate = bool(payload.get("force_regenerate", False))
|
||||
|
||||
target_groups = [str(g).strip() for g in (context.get("target_groups") or []) if str(g).strip()]
|
||||
if not target_groups:
|
||||
target_groups = GroupBotManager.get_group_list()
|
||||
|
||||
delivered_groups: List[str] = []
|
||||
failed_groups: Dict[str, str] = {}
|
||||
for gid in target_groups:
|
||||
try:
|
||||
# 按群推送:内部会再基于斗鱼订阅与插件权限做二次过滤。
|
||||
delivered = await self._send_daily_reports(
|
||||
anchor_day=anchor_day,
|
||||
target_group_id=gid,
|
||||
force=force,
|
||||
force_regenerate=force_regenerate,
|
||||
)
|
||||
if delivered:
|
||||
delivered_groups.append(gid)
|
||||
except Exception as e:
|
||||
failed_groups[gid] = self._format_exception(e)
|
||||
|
||||
return {
|
||||
"success": len(failed_groups) == 0,
|
||||
"summary": (
|
||||
f"斗鱼日报任务完成: 日期{anchor_day}, 目标群{len(target_groups)}个, "
|
||||
f"成功发送群{len(delivered_groups)}个, 失败群{len(failed_groups)}个"
|
||||
),
|
||||
"detail": {
|
||||
"anchor_day": anchor_day,
|
||||
"force": force,
|
||||
"force_regenerate": force_regenerate,
|
||||
"target_groups": target_groups,
|
||||
"delivered_groups": delivered_groups,
|
||||
"failed_groups": failed_groups,
|
||||
},
|
||||
}
|
||||
|
||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||
try:
|
||||
dbm = DBConnectionManager.get_instance()
|
||||
|
||||
Reference in New Issue
Block a user