尧图精选

Vibe-Trading 事件驱动策略实战指南:从情感打分到信号聚合的完整实现

🕒 发布时间:2026/9/10 4:39:12 📁 来源:尧图网络
Vibe-Trading 事件驱动策略实战指南从情感打分到信号聚合的完整实现【免费下载链接】Vibe-TradingVibe-Trading: Your Personal Trading Agent项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading事件驱动Event-Driven是 Vibe-Trading 中一类以新闻、公告与宏观事件为数据源、由 LLM 充当 NLP 引擎的策略形态。本文将完整拆解仓库内agent/src/skills/event-driven/SKILL.md所定义的工作流、事件 CSV 数据规范、时间衰减与信号加权算法并结合 示例信号引擎 与 RSSHub 事件提供器 的源码实现为你呈现一条「数据采集 → LLM 打分 → CSV 落盘 → 信号聚合 → 回测接入」的端到端落地路径读完即可在自己的策略中复现。一、技能定位与整体架构agent/src/skills/event-driven/SKILL.md的元信息将该技能归类为category: strategy其核心思想是把 LLM 当作 NLP 引擎来打分新闻事件事件数据统一管理为 CSV再将技术信号与事件信号做加权聚合得到最终交易信号。该文档强调一条贯穿全流程的关键原则事件 CSV 是数据层signal_engine.py是逻辑层两者必须保持解耦。这一分层设计在仓库源码中得到了印证事件侧的数据层由 rsshub_events.py 承担负责抓取、归一化、打分、落列逻辑层则由策略开发者自行实现的signal_engine类承担文档同目录提供了完整范本 example_signal_engine.py。数据层不关心策略逻辑逻辑层不关心数据来源二者通过统一的event_score列衔接。二、四步工作流文档定义的标准工作流如下数据采集使用read_url工具抓取新闻与公告全文LLM 分析LLM 阅读新闻用标准化提示词在-1.0到1.0区间打分极度看空到极度看多生成事件 CSV按date,event_type,score,source,summary五列 Schema 写入数据信号聚合signal_engine.py读取事件 CSV施加时间衰减并与技术信号合并。其中read_url是 Agent 内置工具其实现位于 web_reader_tool.py它通过 Jina Readerr.jina.ai把目标 URL 转为 Markdown 文本内置 30 秒超时、8000 字符截断并对目标地址做了严格的安全过滤拒绝localhost、私网 IP、带凭据的 URL 等返回结果包含title、content、url字段。也就是说Agent 抓取到的是已经清洗过的正文可直接交给 LLM 打分无需额外做网页解析。三、事件 CSV Schema 与字段语义事件数据统一落盘为 CSV文档给出了可直接复制的示例date,event_type,score,source,summary 2024-01-15,earnings,0.8,read_url,Q4 revenue beat expectations by 30% 2024-01-20,macro,-0.5,read_url,Central bank raised rates by 25bp 2024-02-01,policy,0.3,read_url,New-energy subsidies extended 2024-02-10,sentiment,-0.7,read_url,Bearish sentiment surged on social media 2024-03-05,insider,0.4,read_url,CEO bought 5 million shares五个字段的语义如下字段类型说明datestrYYYY-MM-DD事件变得可知的日期发布时间而非发生时间若收盘后发布则顺延到下一交易日event_typestrearnings / macro / policy / sentiment / insider / technical_breakscorefloat-1.0 ~ 1.0标准化 LLM 打分sourcestr数据源标签如read_urlsummarystr事件摘要一句话不要包含逗号关于date的「可知日期」约定仓库级实现给出了严格的落地方案在 rsshub_events.py 中定义了收盘截断小时DEFAULT_CLOSE_CUTOFF_HOUR 16_knowable_date()函数见第 264-278 行会把当日 16 点及以后发布的条目滚动到下一个自然日与技能文档「收盘后发布 → 使用下一交易日」的规则完全对齐。这正是回测避免未来函数look-ahead bias的第一道闸门。四、事件类型体系与影响周期文档按事件类型规定了各自的影响周期这决定了时间衰减参数的调优方向类型含义典型影响持续时间earnings财报发布短期冲击1-5 天macro宏观数据 / 央行政策中期影响5-20 天policy行业政策 / 监管变化长期影响20-60 天sentiment市场情绪 / 舆情短期冲击1-3 天insider内部交易 / 大宗交易中期信号5-10 天technical_break关键技术位突破短期催化剂1-5 天从实现细节看这一事件分类法也被 FeedSpec 数据结构继承——每个 RSSHub 订阅源在注册时必须声明自己产出的事件类型event_type从而在数据源头就完成事件分类而非在策略层事后打标。五、信号聚合时间衰减与加权组合5.1 事件信号的时间衰减事件对价格的影响随天数呈指数衰减。文档给出的核心算法如下import numpy as np import pandas as pd def compute_event_signal(event_df: pd.DataFrame, dates: pd.DatetimeIndex, decay_lambda: float 0.1, min_score_threshold: float 0.2, event_lookback: int 30) - pd.Series: Compute an event-driven signal with time decay. event_df event_df[event_df[score].abs() min_score_threshold].copy() event_df[date] pd.to_datetime(event_df[date]) signal pd.Series(0.0, indexdates) for trade_date in dates: # Only consider events published on or before trade_date (avoid look-ahead) mask (event_df[date] trade_date) \ (event_df[date] trade_date - pd.Timedelta(daysevent_lookback)) relevant event_df[mask] if relevant.empty: continue days_since (trade_date - relevant[date]).dt.days.values scores relevant[score].values # Exponential decay: score * exp(-lambda * days) decayed scores * np.exp(-decay_lambda * days_since) # Sum multiple events and clip to [-1, 1] signal[trade_date] np.clip(decayed.sum(), -1.0, 1.0) return signal算法的三个要点防未来函数只取date trade_date的事件保证任一交易日只能看到当日及之前已知的事件回看窗口event_lookback 30天之外的事件直接排除避免陈旧事件长期滞留阈值过滤|score| min_score_threshold的事件先被剔除只保留有实质信息量的条目多事件叠加窗口内多个事件做衰减后求和再clip到[-1.0, 1.0]。值得注意的是这套「衰减求和 窗口 截断」公式在仓库生产级实现 enrich_price_frames_with_events 中得到了向量化复刻它为每根 bar 计算event_score衰减求和、clip 到[-1,1]与event_count窗口内事件数两个附加列直接用 NumPy 的 datetime64 与np.exp完成逐 bar 计算逻辑与技能文档完全一致。5.2 技术信号与事件信号的加权融合最终交易信号由技术信号与事件信号按权重合成def combine_signals(tech_signal: pd.Series, event_signal: pd.Series, alpha: float 0.6) - pd.Series: Combine technical and event signals with weights. combined alpha * tech_signal (1 - alpha) * event_signal return combined.clip(-1.0, 1.0)默认alpha 0.6技术信号占 60%事件信号占 40%。当没有事件时event_signal 0组合信号退化为纯技术信号这是设计上的刻意行为——事件驱动是增强层而非主策略。六、可调参数速查文档给出的参数表及默认值如下参数默认值说明alpha0.6技术信号权重1-alpha为事件权重decay_lambda0.1衰减系数越大衰减越快0.1≈ 10 天衰减到 37%event_lookback30事件回看窗口天更早的事件被排除min_score_threshold0.2最低分数阈值|score|低于此值的事件被忽略这些默认值同样体现在生产实现中enrich_price_frames_with_events 的decay_lambda0.1、lookback30、min_abs_score0.0与技能默认保持对齐min_abs_score在技能侧为 0.2属于文档中「策略层过滤」与「数据层过滤」的粒度差异——数据层默认不丢事件把阈值判断留给策略。七、LLM 打分提示词模板为保证打分跨时间、跨模型版本的一致性文档规定抓取新闻后必须使用以下标准化提示词You are a financial event analyst. Read the following news / announcement and score its impact on the stock price. Scoring scale: - 1.0: extremely bullish (for example, earnings far above expectations, major favorable policy) - 0.5: moderately bullish (for example, earnings slightly above expectations, favorable industry news) - 0.2: mildly bullish - 0.0: neutral (no obvious impact) - -0.2: mildly bearish - -0.5: moderately bearish (for example, earnings below expectations, tighter industry regulation) - -1.0: extremely bearish (for example, accounting fraud, major violations, black-swan event) Score strictly on the scale above. Output one number only. Do not explain. News content: {news_content} Score:模板的关键约束是「只输出一个数字、不做解释」从而让打分结果可以机械化地解析进 CSV 的score列。值得注意的是仓库在数据层还内置了一套确定性的词典打分器作为无需 LLM 的兜底基线——default_lexicon_scorer 通过统计标题与摘要中正负面词条如 beat/beat、surge、record、growth 等正面词与 miss、plunge、fraud、bankruptcy 等负面词的净占比产出[-1.0, 1.0]的分数。query_events接受可插拔的scorer参数既可以用词典打分器做离线快速验证也可以如技能文档描述的那样注入 LLM 裁判两种打分路径共享同一套数据流。八、回测中的事件数据从 CSV 到手写引擎技能文档明确指出历史回测要求提前备好完整的历史事件 CSV不能在回测中实时抓取且建议按标的维护独立的事件文件。文档同目录的 example_signal_engine.py 给出了一种可直接套用的手写引擎范式class SignalEngine: Long-only sentiment pre-filter over the enriched event_score column. def __init__(self, score_threshold: float 0.2, top_n: int | None None) - None: self.score_threshold score_threshold self.top_n top_n def generate(self, data_map: Dict[str, pd.DataFrame]) - Dict[str, pd.Series]: ... for dt in date_index: scored: List[tuple[str, float]] [] for code, df in data_map.items(): if dt not in df.index: continue score df.loc[dt].get(event_score, np.nan) if pd.notna(score) and score self.score_threshold: scored.append((code, float(score))) ... weight 1.0 / len(scored) for code, _ in scored: signals[code].at[dt] weight ...这个引擎实现了一个典型的情绪预筛sentiment pre-filter多头策略每个 bar 上选出event_score score_threshold的标的按分数降序可top_n截断对入选标的等权做多。event_score列由回测配置中的event_feeds触发数据层富化enrichment自动生成并且天然防未来——它只反映t日及之前可知的事件引擎本身从不主动前移数据。九、常见陷阱与规避清单文档共列出 7 条实战中反复踩坑的经验这些在源码中都有对应的工程化对策未来函数CSV 的date必须是「可知日期」收盘后发布的事件要用下一交易日回测中严格执行event_date trade_date。对应实现_knowable_date的收盘截断 query_events的knowable_date as_of过滤[rsshub_events.py](https://link.gitcode.com/i/4fd762b20e7059ba31bdb1f3d3d58e6a#L264-L278, L397)。重复打分同一事件可能被多个新闻源重复报道而产生多行。按(date, event_type)去重或取均值。对应实现query_events按(ts_code, knowable_date, event_type, summary)去重第 398 行。情绪漂移提示词或模型版本变化会导致 LLM 打分尺度漂移。对策是固定提示词模板、定期重新校准。数据层的词典打分器可作为稳定的比对基线。事件稀疏性大多数交易日没有事件事件信号为 0、最终信号由技术面主导是正常现象严禁为「填空」而捏造数据。回测事件数据必须提前备好历史事件 CSV建议按标的分文件不能回测时实时抓取。summary字段中的逗号这是 CSV 解析错误的常见原因——摘要中避免逗号或用pd.read_csv(quotingcsv.QUOTE_ALL)读取。对应实现_clean_summary在数据层直接做逗号剥离第 281-285 行。衰减参数敏感性decay_lambda过大事件影响消失过快、过小则陈旧事件长期存活理想上不同事件类型财报 vs 政策应有不同衰减曲线但默认统一为0.1是一种可接受的简化。十、信号约定与依赖信号约定纯事件信号[-1.0, 1.0]由事件分数 时间衰减计算得出组合信号alpha * tech_signal (1 - alpha) * event_signalclip 到[-1.0, 1.0]无事件时event_signal 0组合信号退化为纯技术信号。依赖仅需pip install pandas numpy。LLM 分析由 Agent 自身完成read_url工具内置无额外依赖。这意味着该技能可以零成本地在任意回测框架中接入——只要数据层产出了合规的event_score列手写引擎即可直接消费。总结事件驱动策略的本质是把「信息冲击」变成可回测、可调参、可叠加在技术信号之上的量化信号。Vibe-Trading 的这套技能设计通过三层保障让这件事变得工程上可靠标准化提示词保证 LLM 打分可复现CSV 可知日期约定保证数据层与逻辑层解耦且天然防未来指数衰减 加权合成保证信号可解释、可调参。若要进一步深入推荐阅读 示例信号引擎完整实现 与 RSSHub 事件提供器前者是技能文档的最小可运行范本后者则是生产级的 point-in-time 事件数据管线两者对照阅读即可完整掌握该技能的落地全貌。【免费下载链接】Vibe-TradingVibe-Trading: Your Personal Trading Agent项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →