Xpulse — Real-Time Social Signal Scanner
Overview
Xpulse is a real-time X/Twitter signal scanner optimized for prediction market traders. It detects market-relevant signals on configurable topics using a three-stage intelligence pipeline:
- 1. Stage 1: Signal Detection — Scans X via DuckDuckGo (site:x.com queries), analyzes posts with local Qwen for tradeable signals
- Stage 2: Materiality Gate — Compares against 48h signal history, filters out noise and repeat signals (fail-closed)
- Stage 3: Position Matching — Only alerts on signals that match active Kalshi positions (keyword overlap, 2+ keywords required)
Key philosophy: Zero API costs (DuckDuckGo + local Qwen), fail-closed design (silence over noise), position-aware filtering (no irrelevant alerts).
When to Use This Skill
- - You're actively trading prediction markets on Kalshi
- You want real-time social signals for your active positions
- You prefer local LLM analysis over expensive API calls
- You need to prevent notification fatigue from generic social signals
- You want signals cached for morning brief consumption
Requirements
Python & Dependencies
- - Python 3.10 or higher
- Required packages:
CODEBLOCK0
Local Infrastructure
- - Ollama (https://ollama.ai) with Qwen model
- Install from https://ollama.ai (macOS, Linux, Windows)
- Then:
ollama pull qwen3:latest
- Must be running:
ollama serve (background process)
Kalshi API (for position matching)
- - Free Kalshi account with API credentials (https://kalshi.com)
- API key ID
- Private key file (ES256 format)
- Cost: Free (read-only access to positions)
Configuration
Create or update your config.yaml:
CODEBLOCK1
Topics Configuration
INLINECODE3 list should contain:
- - Market-relevant keywords you're interested in
- DuckDuckGo will search: INLINECODE4
- Examples: "Trump tariff", "inflation CPI", "Fed rate", "crypto SEC", "presidential election"
Thresholds
| Parameter | Default | Meaning |
|---|
| INLINECODE5 | 0.7 | Stage 1: Only keep signals with ≥70% AI confidence of being tradeable |
| INLINECODE6 |
30 | Minimum minutes between scans (prevent API hammering) |
|
materiality_gate | true | Stage 2: Enable/disable deduplication filter |
|
position_gate | true | Stage 3: Enable/disable Kalshi position matching |
|
max_history_entries | 200 | Max entries in 48h signal history (auto-trimmed) |
The Three-Stage Pipeline
Stage 1: Signal Detection
Input: List of topics (e.g., ["tariff", "inflation", "Ukraine"])
Process:
- 1. For each topic, search X/Twitter via DuckDuckGo: INLINECODE10
- Fetch up to 5 recent posts
- Feed posts to local Qwen with this prompt:
CODEBLOCK2
Thresholding: Only keep signals where:
- - INLINECODE11
- INLINECODE12 (default 0.7)
Output: List of candidate signals with direction + confidence
Stage 2: Materiality Gate (Fail-Closed)
Input: Candidate signals from Stage 1 + 48h signal history
Purpose: Prevent alert fatigue by filtering out:
- - Repeat signals about the same story (different wording)
- Ongoing background noise (tariffs in news for days)
- Speculation with no concrete new event
- Minor updates to previously alerted developments
Process:
- 1. Load recently sent signal history (last 20 alerts, 48h window)
- Build prompt with:
- Candidate new signals
- What the user already knows (recent alerts)
- 3. Send to Qwen:
CODEBLOCK3
Fail-Closed Design:
- - If Qwen fails (timeout, error, unparseable): drop all signals
- This prevents spam of uncertain signals when the filter breaks
- Better to miss a signal than spam the user
Output: Filtered list (subset of Stage 1 candidates)
Stage 3: Position Matching Gate
Input: Filtered signals from Stage 2 + active Kalshi positions
Purpose: Only alert the user about signals that match their active positions
Process:
- 1. Fetch active Kalshi positions (unsettled)
- Extract keywords from ticker + market title (>2 char words)
- Example: "POTUS-2028-DEM" → keywords: {potus, 2028, dem}
- 3. For each signal, extract keywords from topic + summary
- Match if 2+ keyword overlap
Example:
CODEBLOCK4
Suppressed Signals:
- - Signals without matching positions are logged silently
- Available in cache (
.x_signal_cache.json) for morning brief - Not sent to user
Output: Critical signals matched to positions → iMessage alert
Signal Caching
All signals (pre-filter) are cached in .x_signal_cache.json:
CODEBLOCK5
Used for:
- - Morning brief consumption (all signals, even suppressed ones)
- On-demand signal review (what was detected but not alerted)
- Debugging signal pipeline
Running Xpulse
Command Line
CODEBLOCK6
Scheduled (Every 30 Minutes)
Via OpenClaw config:
CODEBLOCK7
Via crontab:
CODEBLOCK8
Via launchd (macOS):
<!-- ~/.launchd/com.xpulse.scanner.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.xpulse.scanner</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>/path/to/xpulse.py</string>
</array>
<key>StartInterval</key>
<integer>1800</integer>
<key>StandardOutPath</key>
<string>/tmp/xpulse.log</string>
<key>StandardErrorPath</key>
<string>/tmp/xpulse.log</string>
</dict>
</plist>
Example Output
Alert to iMessage (Stage 3 Pass)
CODEBLOCK10
Signal Cache (Stage 1 → Morning Brief)
CODEBLOCK11
Materiality Gate — Technical Details
See references/materiality-gate.md for detailed explanation of:
- - How the 48h rolling window works
- Example filtering scenarios (signal vs noise)
- Fail-closed behavior
Position Matching — Technical Details
See references/position-matching.md for:
- - Keyword extraction algorithm (>2 char threshold)
- Overlap matching logic (2+ keyword requirement)
- Example position-signal pairs
Troubleshooting
Ollama Not Running
Error: Connection refused or INLINECODE18
Fix:
CODEBLOCK12
Qwen Model Not Found
Error: ollama run qwen:latest fails
Fix:
CODEBLOCK13
DuckDuckGo Returning No Results
Likely causes:
- - Topic is too specific or niche
- No recent posts on X about that topic
- DuckDuckGo rate limiting (try again later)
Debug:
CODEBLOCK14
No Kalshi Positions (Stage 3 Suppresses All)
Expected behavior: If you have no active Kalshi positions, all signals are suppressed (logged silently). This is intentional — position-aware alerting is the goal.
To test: Either:
- 1. Create a test Kalshi position matching your topic
- Disable Stage 3: set
position_gate: false in config (alerts all non-materiality signals)
Signal History Growing Too Large
Automatic: History is capped at 200 entries (oldest trimmed first)
Manual reset:
rm ~/.openclaw/state/x_signal_history.json
Qwen Prompts (Core IP)
Stage 1 Prompt: Signal Detection
CODEBLOCK16
Stage 2 Prompt: Materiality Gate
CODEBLOCK17
OpenClaw Ecosystem Integration
Social signal intelligence layer for the Prediction Market Trading Stack.
| Connected Skill | How It Connects |
|---|
| Market Morning Brief | X signals appear in your daily morning digest |
| Kalshalyst |
Social signals validate or challenge contrarian edges |
|
Prediction Market Arbiter | Correlate social sentiment with cross-platform divergences |
|
Kalshi Command Center | Act on position-matched signals via trade execution |
Install the complete stack:
CODEBLOCK18
Implementation Notes
Battle-tested in production trading environments. Design principles:
- 1. Standalone implementation — zero external dependencies beyond listed packages
- Direct alerts — sends signals straight to you via your OpenClaw agent
- All thresholds, filters, and prompts — refined through live social signal monitoring
- Fail-closed design — no signal is better than a false positive
- Scripts are standalone — works with any OpenClaw setup
Performance & Cost
Typical Run
- - Runtime: 1-2 minutes (5 topics, Qwen Stage 1+2)
- API calls:
- DuckDuckGo: 5 calls (1 per topic)
- Kalshi: 1 call (fetch positions)
- Ollama (local): 2 calls (Stage 1 + 2)
- - Cost: $0 (DuckDuckGo free, Ollama local, Kalshi free read-only)
Scaling
10 runs per day = ~10-20 minutes total runtime + zero API cost. Minimal resource usage.
Further Reading
- -
references/materiality-gate.md — Signal deduplication + 48h window - INLINECODE22 — Keyword overlap logic
API Reference
Main Function
CODEBLOCK19
State Management
CODEBLOCK20
Support & Iteration
Xpulse is designed for iteration:
- 1. Topic Tuning: Add/remove topics as your trading focus changes
- Confidence Threshold: Lower
min_confidence to catch more signals (noisier), raise to reduce false positives - Materiality Gate: Disable if you're missing important signals, enable if too noisy
- Position Gate: Disable
position_gate: false if you want ALL signals (not recommended) - Qwen Prompts: Customize Stage 1/2 prompts for your trading style
License & Attribution
Author: KingMadeLLC
Feedback & Issues
Found a bug? Have a feature request? Want to share results?
Part of the OpenClaw Prediction Stack — the first prediction market skill suite on ClawHub.
Xpulse — 实时社交信号扫描器
概述
Xpulse 是一款专为预测市场交易者优化的实时 X/Twitter 信号扫描器。它通过三级智能流水线检测可配置主题上的市场相关信号:
- 1. 第一级:信号检测 — 通过 DuckDuckGo(site:x.com 查询)扫描 X,使用本地 Qwen 分析帖子中的可交易信号
- 第二级:实质性门控 — 与 48 小时信号历史对比,过滤噪音和重复信号(故障关闭)
- 第三级:持仓匹配 — 仅对匹配活跃 Kalshi 持仓的信号发出警报(关键词重叠,需 2 个以上关键词)
核心理念: 零 API 成本(DuckDuckGo + 本地 Qwen),故障关闭设计(沉默优于噪音),持仓感知过滤(无无关警报)。
何时使用此技能
- - 您在 Kalshi 上积极交易预测市场
- 您希望获取活跃持仓的实时社交信号
- 您偏好本地 LLM 分析而非昂贵的 API 调用
- 您需要防止通用社交信号导致的通知疲劳
- 您希望缓存信号供晨间简报使用
要求
Python 与依赖
bash
pip install ddgs pyyaml
本地基础设施
- - Ollama (https://ollama.ai) 搭配 Qwen 模型
- 从 https://ollama.ai 安装(macOS、Linux、Windows)
- 然后:ollama pull qwen3:latest
- 必须保持运行:ollama serve(后台进程)
Kalshi API(用于持仓匹配)
- - 拥有 API 凭证的免费 Kalshi 账户 (https://kalshi.com)
- API 密钥 ID
- 私钥文件(ES256 格式)
- 成本:免费(只读访问持仓)
配置
创建或更新您的 config.yaml:
yaml
kalshi:
enabled: true
apikeyid: your-key-id
privatekeyfile: /path/to/private.key
ollama:
enabled: true
model: qwen3:latest
timeout_seconds: 30
xpulse:
enabled: true
checkintervalminutes: 30
topics:
- tariff
- Ukraine
- inflation
- Fed rate
- Trump policy
min_confidence: 0.7 # 第一级:信号置信度阈值
materiality_gate: true # 第二级:启用 48 小时去重
position_gate: true # 第三级:仅对匹配持仓发出警报
maxhistoryentries: 200
主题配置
topics 列表应包含:
- - 您感兴趣的市场相关关键词
- DuckDuckGo 将搜索:site:x.com {topic}
- 示例:Trump tariff、inflation CPI、Fed rate、crypto SEC、presidential election
阈值
| 参数 | 默认值 | 含义 |
|---|
| minconfidence | 0.7 | 第一级:仅保留 AI 置信度 ≥70% 的可交易信号 |
| checkinterval_minutes |
30 | 扫描间最小间隔(防止 API 滥用) |
| materiality_gate | true | 第二级:启用/禁用去重过滤器 |
| position_gate | true | 第三级:启用/禁用 Kalshi 持仓匹配 |
| max
historyentries | 200 | 48 小时信号历史的最大条目数(自动修剪) |
三级流水线
第一级:信号检测
输入: 主题列表(例如 [tariff, inflation, Ukraine])
过程:
- 1. 对每个主题,通过 DuckDuckGo 搜索 X/Twitter:site:x.com {topic}
- 获取最多 5 条最新帖子
- 将帖子输入本地 Qwen,使用以下提示:
你是一名预测市场分析师。根据这些关于{topic}的最新 X/Twitter 帖子,
判断是否存在可交易信号。
{combined_posts}
以 JSON 格式响应:{has_signal: true/false, confidence: 0.0-1.0,
direction: bullish/bearish/neutral, summary: 一行摘要}
阈值过滤: 仅保留满足以下条件的信号:
- - hassignal == true
- confidence >= minconfidence(默认 0.7)
输出: 包含方向和置信度的候选信号列表
第二级:实质性门控(故障关闭)
输入: 来自第一级的候选信号 + 48 小时信号历史
目的: 通过过滤以下内容防止警报疲劳:
- - 关于同一事件的重复信号(不同措辞)
- 持续的背景噪音(例如关税新闻持续数天)
- 没有具体新事件的猜测
- 对已警报事件的小幅更新
过程:
- 1. 加载最近发送的信号历史(最近 20 条警报,48 小时窗口)
- 使用以下内容构建提示:
- 候选新信号
- 用户已知的信息(最近警报)
- 3. 发送给 Qwen:
你是一名预测市场交易者的个人警报过滤器。
你的工作是防止通知疲劳。
最近发送的警报(用户已知的信息):
- - [3 小时前] tariff:特朗普宣布新钢铁关税(置信度:0.82)
- [6 小时前] inflation:核心 CPI 稳定在 3.2%(置信度:0.75)
候选新信号:
- - [tariff] 特朗普讨论额外关税(置信度:0.68)
- [inflation] 美联储暗示近期不会降息(置信度:0.79)
规则:
- - 如果与最近警报是同一事件则拒绝(即使措辞不同)
- 如果是持续的背景噪音则拒绝
- 如果没有具体新事件则拒绝
- 仅在真正的新进展或重大升级时接受
- 如有疑问,拒绝。用户偏好沉默而非噪音。
以 JSON 格式响应:{keep: [要保留的主题字符串列表], reasoning: ...}
故障关闭设计:
- - 如果 Qwen 失败(超时、错误、无法解析):丢弃所有信号
- 这防止了过滤器损坏时不确定信号的泛滥
- 错过信号比向用户发送垃圾信息更好
输出: 过滤后的列表(第一级候选的子集)
第三级:持仓匹配门控
输入: 来自第二级的过滤信号 + 活跃的 Kalshi 持仓
目的: 仅向用户发送与其活跃持仓匹配的信号警报
过程:
- 1. 获取活跃的 Kalshi 持仓(未结算)
- 从代码 + 市场标题中提取关键词(>2 个字符的词)
- 示例:POTUS-2028-DEM → 关键词:{potus, 2028, dem}
- 3. 对每个信号,从主题 + 摘要中提取关键词
- 如果有 2 个以上关键词重叠则匹配
示例:
信号:主题=Trump tariff,摘要=特朗普宣布新钢铁关税
信号词:{trump, tariff, steel, announces, new}
Kalshi 持仓:代码=TRUMP-TARIFF-2025,标题=特朗普会实施钢铁关税吗?
持仓关键词:{trump, tariff, 2025, steel, enact}
重叠:{trump, tariff, steel} = 3 个关键词 ✓ 匹配
→ 信号通过,发送 iMessage 警报
被抑制的信号:
- - 没有匹配持仓的信号被静默记录
- 可在缓存中获取(.xsignalcache.json)供晨间简报使用
- 不发送给用户
输出: 匹配持仓的关键信号 → iMessage 警报
信号缓存
所有信号(预过滤)缓存在 .xsignalcache.json 中:
json
{
signals: [
{
topic: tariff,
confidence: 0.82,
direction: bearish,
summary: 特朗普宣布新钢铁关税,
post_count: 3
}
],
topics_scanned: 5,
timestamp: 1709990400.0
}
用途:
- - 晨间简报消费(所有信号,包括被抑制的)
- 按需信号审查(检测到但未警报的内容)
- 调试信号流水线
运行 Xpulse
命令行
bash
单次运行
python -m xpulse.xpulse
完整日志
DEBUG=1 python -m xpulse.xpulse
#