
Polymarket Analyzer
- 23 installs
- 1 repo stars
- Updated June 13, 2026
- cyberelf/agent_skills
Collect Polymarket prediction-market and multi-source data to support sentiment analysis for Chinese concept stocks and A-shares.
About
Gathers Polymarket prediction-market data plus news and macro proxies as raw input for sentiment analysis of Chinese concept stocks and A-shares. A user invokes it for prediction-market or A-share sentiment context, with the agent doing all interpretation.
- Scripts are pure data collectors that make no directional calls
- Covers specific stocks like BYD, NIO, Alibaba, Tencent, SMIC
Polymarket Analyzer by the numbers
- 23 all-time installs (skills.sh)
- Ranked #704 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Data as of Jul 24, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cyberelf/agent_skills --skill polymarket-analyzerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 23 |
|---|---|
| repo stars | ★ 1 |
| Last updated | June 13, 2026 |
| Repository | cyberelf/agent_skills ↗ |
What it does
Collect Polymarket prediction-market and multi-source data to support sentiment analysis for Chinese concept stocks and A-shares.
Files
Polymarket + Multi-Source China Market Sentiment Analyzer
Collect data from multiple information channels to support comprehensive sentiment analysis for Chinese concept stocks (中概股) and A-shares.
The agent performs all judgment and interpretation. The scripts in this skill are pure data collectors — they fetch raw information without making directional calls.
---
When to Use
- The user asks about Polymarket prediction market data for China/HK topics
- The user wants sentiment context for A-share or 中概股 investment decisions
- The user requests multi-source market intelligence (news, macro, market proxies)
- The user asks about specific stocks: BYD, NIO, Alibaba, Tencent, SMIC, etc.
---
Prerequisites
Polymarket CLI (required for prediction market data)
brew tap Polymarket/polymarket-cli https://github.com/Polymarket/polymarket-cli
brew install polymarket
# or
curl -sSL https://raw.githubusercontent.com/Polymarket/polymarket-cli/main/install.sh | sh
polymarket --versionyfinance (optional — enables market proxy data)
pip install yfinance---
Skill Structure
polymarket-analyzer/
├── SKILL.md
├── references/
│ ├── china_stock_mapping.json # 21 China concept stocks → A-share sector/ticker mapping
│ ├── signal_weights.json # Configurable source weights for composite analyzer
│ ├── workflows/
│ │ ├── scenario-1-macro-geopolitical.md # Top-down macro & geopolitical risk workflow
│ │ ├── scenario-2-sector-catalyst.md # Bottom-up sector/company catalyst workflow
│ │ └── scenario-3-daily-pulse.md # Fast daily digest / delta-only briefing
│ └── templates/
│ ├── comprehensive-insight-report.md # Full deep-dive report template (Scenarios 1 & 2)
│ └── quick-brief.md # 30-second pulse template (Scenario 3)
└── scripts/
├── polymarket_analyzer.py # Full 7-source composite analyzer
├── query-markets.py # Polymarket search — active markets only by default
├── filter-markets.py # Polymarket multi-filter — active markets only by default
├── fetch-market-data.py # Raw price/volume for China proxy instruments
└── fetch-cn-news.py # Raw headlines from Chinese domestic + global sources---
Information Channels
Channel 1 — Polymarket Prediction Markets
Scripts: scripts/query-markets.py, scripts/filter-markets.py
Real-money crowd probabilities on macro, geopolitical, and corporate events. Best for tail risks such as Taiwan conflict, trade war escalation, and rate decisions.
Channel 2 — Financial Market Proxies
Script: scripts/fetch-market-data.py
Raw daily price and volume data for 11 China-sensitive instruments:
| Ticker | Instrument | Relevance |
|---|---|---|
| FXI | iShares China Large-Cap ETF | Direct China equity sentiment |
| KWEB | KraneShares China Internet ETF | China tech/internet |
| ^HSI | Hang Seng Index | HK market |
| HG=F | Copper Futures | China industrial demand |
| AUDUSD=X | AUD/USD | China commodities activity |
| CNY=X | USD/CNY | Renminbi strength |
| ^VIX | CBOE Volatility Index | Global risk appetite |
| GC=F | Gold Futures | Safe-haven demand |
| ^TNX | US 10-yr Treasury Yield | US rate pressure on EM |
| EEM | iShares Emerging Markets ETF | EM flow proxy |
| UUP | US Dollar Index ETF | USD strength |
Channel 3 — Chinese Domestic Financial News
Script: scripts/fetch-cn-news.py
Raw headlines from domestic Chinese financial media:
| Source ID | Name | Coverage |
|---|---|---|
caixin | 财新 Caixin Global | Investigative finance/economy (EN+ZH) |
sina_finance | 新浪财经 | Breaking A-share news, policy |
yicai | 第一财经 | Macro, banking, real estate |
eastmoney | 东方财富 | Retail investor hot topics |
stcn | 证券时报 | Regulatory / official securities news |
21cbh | 21世纪经济报道 | Industry deep dives |
xinhua_finance | 新华财经 | State macro/policy announcements |
Channel 4 — Global / HK China-Focused News
Script: scripts/fetch-cn-news.py (same script, global sources)
| Source ID | Name | Coverage |
|---|---|---|
reuters_china | Reuters China | Breaking, macro, corporate |
scmp | South China Morning Post | HK/Greater China business |
ft_china | Financial Times China | Western institutional view |
nikkei_china | Nikkei Asia China | Japan/Asia regional perspective |
xinhua_en | Xinhua English | Official Chinese government narrative |
Channels 5–7 — Embedded in Composite Analyzer
Invoked automatically by scripts/polymarket_analyzer.py:
- CNN Fear & Greed Index — US market psychology; extreme readings affect EM risk appetite
- Reddit Social Sentiment — r/investing, r/wallstreetbets, r/china, r/ChineseStocks, r/emergingmarkets
- World Bank Macro — China GDP, CPI, export growth, FDI, US real interest rate
---
Scripts Usage
scripts/query-markets.py — Polymarket raw search
Returns active markets only by default. Use --all to include closed/resolved markets.
python3 scripts/query-markets.py "china"
python3 scripts/query-markets.py "taiwan" --limit 100 --format json
python3 scripts/query-markets.py "byd" --limit 50
python3 scripts/query-markets.py "pboc rate"
# Include resolved markets (for historical analysis only):
python3 scripts/query-markets.py "taiwan" --limit 100 --format json --allscripts/filter-markets.py — Polymarket multi-filter
Defaults to --status active. Use --status closed or --status all to override.
python3 scripts/filter-markets.py --keywords taiwan,invasion --volume 100000
python3 scripts/filter-markets.py --keywords byd,nio,xpeng,alibaba,tencent
python3 scripts/filter-markets.py --status active --volume 50000 --format json
# Closed markets (historical reference only):
python3 scripts/filter-markets.py --keywords taiwan --status closed --format jsonscripts/fetch-market-data.py — Market proxy raw data
python3 scripts/fetch-market-data.py
python3 scripts/fetch-market-data.py --format json
python3 scripts/fetch-market-data.py --period 30d
python3 scripts/fetch-market-data.py --tickers "FXI KWEB ^VIX"scripts/fetch-cn-news.py — China news raw headlines
python3 scripts/fetch-cn-news.py
python3 scripts/fetch-cn-news.py --format json --limit 20
python3 scripts/fetch-cn-news.py --source caixin --limit 30
python3 scripts/fetch-cn-news.py --source caixin,scmpscripts/polymarket_analyzer.py — Full composite run
Executes all seven channels and prints a structured report:
python3 scripts/polymarket_analyzer.pyChannels unavailable at runtime degrade gracefully with no crash.
---
Analysis Workflows & Scenarios
Three scenario-specific workflows are defined in references/workflows/. Each workflow applies First Principles Thinking — defining a hypothesis first, then fetching only the data needed to test it.
| Scenario | File | Use When |
|---|---|---|
| 1. Macro & Geopolitical Risk (Top-Down) | references/workflows/scenario-1-macro-geopolitical.md | Taiwan, tariffs, PBOC, elections, USD/CNY stress |
| 2. Sector-Specific Catalyst (Bottom-Up) | references/workflows/scenario-2-sector-catalyst.md | EVs, Semiconductors, Property, Internet, specific companies |
| 3. Daily Market Pulse / Fast Digest | references/workflows/scenario-3-daily-pulse.md | Pre-market briefing, end-of-day delta check |
Core Analytical Principles (applied in all scenarios)
1. Liquidity Weighting: Polymarket odds mean nothing without volume. Verify pool size. A 90% probability with $500 volume is noise; with $5M volume, it's a signal. 2. Divergence Detection: The most profitable insights stem from discrepancies between explicit prediction market odds and implicit market proxy pricing. 3. Probability Momentum: Focus on the delta (change over time). A contract moving from 10% to 30% in two days is highly actionable. 4. Active Markets Only (Data Collection): Scripts default to active-only. Never treat a closed/resolved contract as a current signal. 5. Historical Context (Mandatory): Always compare the current PM probability against: (a) the trend of the last 7–30 days for this specific contract, and (b) how analogous resolved contracts priced and resolved historically. A probability without a trend is not a signal — it is a datapoint. Use --all to retrieve resolved contracts for comparison. 6. Conflict-First Analysis: When any two sources disagree, the conflict itself is the most important finding in the report. Explain the conflict and its likely cause before forming any directional thesis. A thesis built by ignoring a conflict is not a thesis — it is wishful reasoning. 7. Multi-Source Minimum: A directional conclusion requires ≥2 independent channels in agreement. Single-source signals must be labeled "Unconfirmed — Watch Only." State explicitly which channels confirm and which dissent.
Accumulated Experience
Before running any analysis, check EXPERIENCE.md for relevant prior observations:
- Source reliability notes calibrated from past sessions
- Known false signal patterns (e.g., sectors where PM historically misprices)
- Conflict resolution examples from past analyses
- User feedback on conviction thresholds
After the user provides feedback on analysis quality or outcome accuracy, append a new entry to EXPERIENCE.md using the format defined in that file.
---
Standardized Output Templates
Two templates are defined in references/templates/. Always use the appropriate template when generating a response.
| Template | File | Use When |
|---|---|---|
| A: Comprehensive Investment Insight Report | references/templates/comprehensive-insight-report.md | Full analysis from Scenario 1 or 2; includes confidence score, proxy confirmation table, source attribution, and data provenance |
| B: Quick Brief | references/templates/quick-brief.md | Daily pulse (Scenario 3) or when user needs a rapid digest; ALERT / WATCH / No-Change triage format |
---
References
references/china_stock_mapping.json
Maps 21 China concept stocks to A-share sectors, tickers, supply chain names, HK listings, and correlation coefficients. Companies covered: BYD, NIO, XPeng, Li Auto, Tencent, Alibaba, Baidu, Xiaomi, Pinduoduo, JD.com, Meituan, NetEase, Kuaishou, Bilibili, SMIC, Huawei supply chain, Evergrande, Anta, Haier, Midea, Foxconn. Also includes macro factor mappings for: PBOC rate cuts, US-China trade war, Taiwan tensions, China stimulus.
references/signal_weights.json
Configurable source weights for the composite analyzer. Four profiles:
| Profile | Description |
|---|---|
default | Polymarket 35%, market_data 25%, news 20%, fear_greed 10%, … |
news_heavy | Elevates news to 35% when Polymarket coverage is thin |
market_only | 90% weight on market proxies only |
sentiment_focus | Emphasis on social + Fear & Greed for retail sentiment reads |
---
A-share Sector Quick Reference
| Market Signal | A-share Sector | Key Tickers |
|---|---|---|
| EV sales / BYD / NIO | New Energy + Battery | BYD 002594.SZ, CATL 300750.SZ |
| Taiwan tensions | Defense | AVIC 600893.SH, CSGC 000768.SZ |
| US chip restrictions | Semiconductor localization | SMIC 688981.SH, Hua Hong 688347.SH |
| Trade war / tariffs | Export manufacturing | Luxshare 002475.SZ, Hisense 600060.SH |
| PBOC rate cut | Banks + Real estate | ICBC 601398.SH, Vanke 000002.SZ |
| China stimulus | Infrastructure | CRCC 601186.SH, CREC 601390.SH |
| Copper surge | Industrial metals | Jiangxi Copper 600362.SH |
---
Troubleshooting
Polymarket CLI not found
export PATH="$PATH:$HOME/.cargo/bin:$HOME/.local/bin"yfinance not installed — fetch-market-data.py will print an error and exit cleanly; all other channels still work.
Chinese news sources unreachable — Some domestic RSS feeds block non-CN IPs. Use a HK/mainland proxy, or focus on: caixin, reuters_china, scmp, xinhua_en.
{
"_comment": "China concept stock (中概股) to A-share correlation mapping. Used by sentiment analyzer to map Polymarket signals to tradeable A-share sectors.",
"stocks": {
"byd": {
"name": "比亚迪 BYD",
"sector": "新能源车",
"a_shares": [
"比亚迪(002594)",
"宁德时代(300750)",
"亿纬锂能(300014)",
"天齐锂业(002466)",
"赣锋锂业(002460)"
],
"supply_chain": [
"锂电池",
"电机电控",
"汽车零部件",
"充电桩"
],
"hk_listed": "01211.HK",
"correlation": 0.85
},
"nio": {
"name": "蔚来 NIO",
"sector": "新能源车",
"a_shares": [
"江淮汽车(600418)",
"文灿股份(603348)",
"德赛西威(002920)",
"三花智控(002050)"
],
"supply_chain": [
"整车代工",
"换电站",
"智能座舱",
"热管理"
],
"hk_listed": "09866.HK",
"correlation": 0.72
},
"xpeng": {
"name": "小鹏 XPeng",
"sector": "新能源车",
"a_shares": [
"德赛西威(002920)",
"华阳集团(002906)",
"保隆科技(603197)",
"伯特利(603596)"
],
"supply_chain": [
"智能驾驶",
"激光雷达",
"智能座舱",
"ADAS"
],
"hk_listed": "09868.HK",
"correlation": 0.7
},
"li auto": {
"name": "理想汽车 Li Auto",
"sector": "新能源车",
"a_shares": [
"东安动力(600178)",
"保隆科技(603197)",
"德赛西威(002920)",
"拓普集团(601689)"
],
"supply_chain": [
"增程器",
"空气悬架",
"热管理",
"智能驾驶"
],
"hk_listed": "02015.HK",
"correlation": 0.73
},
"tencent": {
"name": "腾讯 Tencent",
"sector": "游戏/互联网",
"a_shares": [
"三七互娱(002555)",
"世纪华通(002602)",
"完美世界(002624)",
"吉比特(603444)",
"恺英网络(002517)"
],
"supply_chain": [
"游戏研发",
"游戏发行",
"IP运营",
"短视频"
],
"hk_listed": "00700.HK",
"correlation": 0.65
},
"alibaba": {
"name": "阿里巴巴 Alibaba",
"sector": "电商/云计算",
"a_shares": [
"石基信息(002153)",
"三江购物(601116)",
"丽人丽妆(605136)",
"华致酒行(300755)"
],
"supply_chain": [
"电商服务",
"云计算",
"新零售",
"物流"
],
"hk_listed": "09988.HK",
"correlation": 0.6
},
"baidu": {
"name": "百度 Baidu",
"sector": "AI/自动驾驶",
"a_shares": [
"科大讯飞(002230)",
"德赛西威(002920)",
"华阳集团(002906)",
"路畅科技(002813)"
],
"supply_chain": [
"AI芯片",
"语音识别",
"自动驾驶",
"地图服务"
],
"hk_listed": "09888.HK",
"correlation": 0.62
},
"xiaomi": {
"name": "小米 Xiaomi",
"sector": "智能硬件/手机",
"a_shares": [
"石头科技(688169)",
"九号公司(689009)",
"小熊电器(002959)",
"极米科技(688696)"
],
"supply_chain": [
"智能家居",
"IoT模块",
"消费电子",
"显示面板"
],
"hk_listed": "01810.HK",
"correlation": 0.68
},
"pinduoduo": {
"name": "拼多多 PDD/Temu",
"sector": "电商/跨境",
"a_shares": [
"供销大集(000564)",
"申通快递(002468)",
"圆通速递(600233)",
"中通快递-W(02057.HK)"
],
"supply_chain": [
"农产品供应链",
"社交电商",
"跨境电商",
"快递物流"
],
"hk_listed": null,
"us_listed": "PDD",
"correlation": 0.55
},
"jd": {
"name": "京东 JD.com",
"sector": "电商/物流",
"a_shares": [
"德邦股份(603056)",
"新宁物流(300013)",
"华贸物流(603128)",
"顺丰控股(002352)"
],
"supply_chain": [
"物流配送",
"仓储管理",
"供应链服务",
"即时配送"
],
"hk_listed": "09618.HK",
"correlation": 0.62
},
"meituan": {
"name": "美团 Meituan",
"sector": "本地生活/外卖",
"a_shares": [
"顺丰控股(002352)",
"圆通速递(600233)",
"韵达股份(002120)",
"中通快递-W"
],
"supply_chain": [
"外卖配送",
"餐饮供应链",
"酒旅预订",
"无人机配送"
],
"hk_listed": "03690.HK",
"correlation": 0.6
},
"netease": {
"name": "网易 NetEase",
"sector": "游戏/教育",
"a_shares": [
"三七互娱(002555)",
"恺英网络(002517)",
"完美世界(002624)"
],
"supply_chain": [
"游戏研发",
"在线教育",
"邮件服务"
],
"hk_listed": "09999.HK",
"correlation": 0.63
},
"kuaishou": {
"name": "快手 Kuaishou",
"sector": "短视频/直播",
"a_shares": [
"浙文互联(600986)",
"天下秀(600556)",
"芒果超媒(300413)"
],
"supply_chain": [
"短视频",
"直播电商",
"内容MCN"
],
"hk_listed": "01024.HK",
"correlation": 0.58
},
"bilibili": {
"name": "哔哩哔哩 Bilibili",
"sector": "视频平台/Z世代",
"a_shares": [
"芒果超媒(300413)",
"三七互娱(002555)",
"游族网络(002174)"
],
"supply_chain": [
"动漫版权",
"游戏联运",
"UP主生态"
],
"hk_listed": "09626.HK",
"correlation": 0.55
},
"smic": {
"name": "中芯国际 SMIC",
"sector": "半导体/芯片制造",
"a_shares": [
"中芯国际(688981)",
"北方华创(002371)",
"澜起科技(688008)",
"芯原股份(688521)",
"华虹半导体(688347)"
],
"supply_chain": [
"晶圆代工",
"AI芯片",
"存储芯片",
"半导体设备"
],
"hk_listed": "00981.HK",
"correlation": 0.8
},
"huawei": {
"name": "华为 Huawei (供应链)",
"sector": "通信设备/手机/AI",
"a_shares": [
"中兴通讯(000063)",
"沪电股份(002463)",
"TCL科技(000100)",
"烽火通信(600498)",
"立讯精密(002475)"
],
"supply_chain": [
"5G设备",
"服务器",
"智能手机",
"光通信"
],
"hk_listed": null,
"correlation": 0.78
},
"evergrande": {
"name": "恒大/房地产 Real Estate",
"sector": "房地产",
"a_shares": [
"万科A(000002)",
"保利发展(600048)",
"招商蛇口(001979)",
"龙湖集团(00960.HK)",
"金地集团(600383)"
],
"supply_chain": [
"房地产开发",
"物业管理",
"建材"
],
"hk_listed": "03333.HK",
"correlation": 0.72
},
"anta": {
"name": "安踏 ANTA Sports",
"sector": "运动服饰/消费",
"a_shares": [
"贵人鸟(603555)",
"特步国际(01368.HK)",
"361度(01361.HK)",
"李宁(02331.HK)"
],
"supply_chain": [
"运动鞋服",
"运动装备",
"品牌授权"
],
"hk_listed": "02020.HK",
"correlation": 0.62
},
"haier": {
"name": "海尔 Haier Smart Home",
"sector": "家电",
"a_shares": [
"海尔智家(600690)",
"美的集团(000333)",
"格力电器(000651)",
"老板电器(002508)"
],
"supply_chain": [
"白色家电",
"智能家居",
"物联网"
],
"hk_listed": "06690.HK",
"correlation": 0.7
},
"midea": {
"name": "美的 Midea",
"sector": "家电/机器人",
"a_shares": [
"美的集团(000333)",
"格力电器(000651)",
"海信家电(000921)",
"华帝股份(002035)"
],
"supply_chain": [
"空调",
"家电",
"工业机器人",
"自动化"
],
"hk_listed": "00300.HK",
"correlation": 0.72
},
"foxconn": {
"name": "富士康/工业富联 Foxconn",
"sector": "电子制造/EMS",
"a_shares": [
"工业富联(601138)",
"立讯精密(002475)",
"鹏鼎控股(002938)",
"蓝思科技(300433)"
],
"supply_chain": [
"EMS代工",
"PCB",
"结构件",
"数据中心"
],
"hk_listed": "02038.HK",
"correlation": 0.76
}
},
"macro_factors": {
"pboc_rate_cut": {
"description": "PBOC interest rate cut (降息)",
"bullish_sectors": [
"房地产",
"银行",
"新能源"
],
"a_share_beneficiaries": [
"万科A(000002)",
"建设银行(601939)",
"宁德时代(300750)"
]
},
"us_china_trade_war": {
"description": "US-China trade war escalation",
"bearish_sectors": [
"出口制造",
"半导体",
"电商"
],
"a_share_impacted": [
"立讯精密(002475)",
"中芯国际(688981)",
"阿里巴巴(09988.HK)"
]
},
"taiwan_tensions": {
"description": "Taiwan strait tensions",
"bullish_sectors": [
"军工",
"稀土",
"国产替代"
],
"bearish_sectors": [
"航空",
"旅游",
"高科技"
],
"a_share_beneficiaries": [
"中航沈飞(600760)",
"北方稀土(600111)",
"中芯国际(688981)"
]
},
"china_stimulus": {
"description": "China fiscal/monetary stimulus package",
"bullish_sectors": [
"基建",
"消费",
"新能源",
"半导体"
],
"a_share_beneficiaries": [
"中国建筑(601668)",
"贵州茅台(600519)",
"比亚迪(002594)"
]
}
}
}{
"_comment": "Configurable signal weights for the Sentiment Aggregator. Weights are normalized automatically. Edit these to tune how much each source influences the composite score.",
"_sources": {
"polymarket": "Real-money prediction markets — highest reliability, skin-in-the-game signal",
"market_data": "Live financial market proxies (FXI, VIX, Copper, AUD/USD) — objective price signals",
"news_rss": "RSS news feed sentiment (Reuters, SCMP, FT, WSJ) — directional but noisy",
"fear_greed": "CNN Fear & Greed Index — market psychology gauge",
"northbound_flow": "ETF volume-based northbound flow proxy — institutional inflow estimate",
"social_sentiment": "Reddit investor sentiment — retail mood, highest noise",
"macro_indicators": "World Bank economic indicators — structural/lagging signal"
},
"_profiles": {
"default": {
"_note": "Balanced weights for general use",
"polymarket": 0.35,
"market_data": 0.25,
"news_rss": 0.20,
"fear_greed": 0.10,
"northbound_flow": 0.05,
"social_sentiment": 0.04,
"macro_indicators": 0.01
},
"news_heavy": {
"_note": "Emphasize news sentiment — use during earnings season or policy announcements",
"polymarket": 0.25,
"market_data": 0.20,
"news_rss": 0.35,
"fear_greed": 0.10,
"northbound_flow": 0.05,
"social_sentiment": 0.03,
"macro_indicators": 0.02
},
"market_only": {
"_note": "Use only objective market price signals — minimal noise from text sources",
"polymarket": 0.50,
"market_data": 0.40,
"news_rss": 0.05,
"fear_greed": 0.05,
"northbound_flow": 0.00,
"social_sentiment": 0.00,
"macro_indicators": 0.00
},
"sentiment_focus": {
"_note": "Emphasize crowd sentiment — useful for contrarian analysis",
"polymarket": 0.20,
"market_data": 0.15,
"news_rss": 0.20,
"fear_greed": 0.25,
"northbound_flow": 0.05,
"social_sentiment": 0.12,
"macro_indicators": 0.03
}
},
"_active_profile": "default",
"_instructions": [
"Copy the weights from your preferred profile into the root level.",
"Or edit the root-level weights directly.",
"The analyzer reads root-level keys first, then falls back to 'default' profile.",
"All weights should sum to 1.0 (the analyzer normalizes anyway, but it's good practice).",
"Set a source weight to 0 to completely exclude it from analysis."
],
"polymarket": 0.35,
"market_data": 0.25,
"news_rss": 0.20,
"fear_greed": 0.10,
"northbound_flow": 0.05,
"social_sentiment": 0.04,
"macro_indicators": 0.01
}
Template A: Comprehensive Investment Insight Report
Use this template for deep-dive analyses triggered by Scenario 1 (Macro/Geopolitical) or Scenario 2 (Sector Catalyst) workflows. This is the primary output format.
Judgment rules that cannot be waived:
- No single-source conclusion is ever valid. Every directional call requires corroboration from ≥2 independent channels.
- All detected conflicts between sources must be explicitly documented and resolved — ignoring a conflict is a disqualifying error.
- Polymarket current probability means little without the trend. Always include the probability trajectory (where it was 7d and 30d ago) alongside the current value.
---
# 🇨🇳 Multi-Source China Market Intelligence Report
**Date:** [YYYY-MM-DD HH:MM CST]
**Triggered by:** [Scenario 1: Macro | Scenario 2: Sector — specify sector]
**Target:** [e.g., "A-share EV sector" / "China-US tariff risk" / "SMIC semiconductor"]
---
## Executive Summary
**Primary Thesis:** [1–2 sentences derived ONLY from cross-channel convergence — do NOT state a thesis that rests on a single source]
**Source Convergence:** [List which channels agree on direction: e.g., "Polymarket ↑, FXI ↑, Reuters ↑ — 3/4 channels bullish"]
**Open Conflicts:** [List any channels that contradict the thesis — e.g., "CNY stable/strengthening, inconsistent with risk narrative"]
**Composite Confidence Score:** [1–10, where 10 requires all channels aligned with high Polymarket volume]
- Deductions: [e.g., "−2 CNY diverges; −1 Polymarket volume moderate ($200k)"]
---
## 1. Prediction Market Signals (Polymarket) — Current + Historical Trend
*Current probability is only meaningful in context of where it has been.*
### 1a. Active Contracts (current state)
| Event / Question | Probability | 24h Δ | 7d Δ | Volume | Reliability |
|-----------------|-------------|-------|------|--------|-------------|
| [Question text] | [X]% | [±pp] | [±pp] | [$Z] | [High >$500k / Med $50–500k / Low <$50k] |
**Trend interpretation:**
- Flat probability + high volume = market has made up its mind; less alpha in the direction signal
- Rapidly rising probability (>10pp in 7d) + rising volume = active re-pricing; high actionability
- High probability + falling volume = market thinning out; probability may be stale
- [Note: if no relevant active markets found, state this explicitly — absence of coverage is itself a signal]
### 1b. Historical Context — Resolved Similar Contracts
*What happened last time a similar event was priced? Use `--all` to retrieve past contracts.*
| Past Event | Resolved Probability | Actual Outcome | Lesson |
|------------|---------------------|----------------|--------|
| [Past contract title] | [X]% at close | [Resolved Yes/No] | [e.g., "PM overpriced Taiwan risk by ~20pp historically"] |
---
## 2. Financial Market Proxy Confirmation
*Implicit pricing — do traditional financial markets agree with Polymarket?*
| Instrument | Current | 1D% | 5D% | 14D% | Reading | vs. Polymarket |
|------------|---------|-----|-----|------|---------|----------------|
| FXI (China Large-Cap) | | | | | [Risk-On/Off] | [Confirms / Conflicts] |
| KWEB (China Internet) | | | | | | |
| CNY=X (USD/CNY) | | | | | [CNY strength] | |
| ^VIX (Volatility) | | | | | | |
| GC=F (Gold) | | | | | [Safe-haven] | |
| HG=F (Copper) | | | | | [Industrial demand] | |
| [Sector-specific] | | | | | | |
**Proxy Trend Assessment:** [Is the 14d trend consistent with the 5d trend, or is momentum reversing? State explicitly.]
---
## 3. News & Narrative Context
*State media vs. global media consensus. Bias explicitly noted. Conflicts flagged.*
| Source | Bias | Headline / Theme | Direction | Confidence in Source |
|--------|------|-----------------|-----------|---------------------|
| Xinhua / 新华 | Official PRC — expect optimistic framing | [Summary] | ↑↓ | [Notes on reliability] |
| Caixin / 财新 | Independent CN — investigative, higher credibility | [Summary] | | |
| Reuters China | Western wire — institutional, fast | [Summary] | | |
| SCMP / FT China | HK/Western — balanced but pro-market | [Summary] | | |
| [Sector source] | | [Summary] | | |
**State vs. International Media Gap:** [Explicitly state whether official PRC narrative and international narrative agree. A gap here is often the most important signal in the report.]
---
## 4. ⚠️ Cross-Source Conflict Register
*This section is MANDATORY. If sources fully agree, state "No conflicts detected — all channels aligned." Never leave blank.*
| Conflict | Source A says | Source B says | Likely Explanation | Resolution / Which to Trust |
|----------|--------------|---------------|-------------------|----------------------------|
| [e.g., FXI rising but Polymarket tariff odds also rising] | FXI +2.5% (bullish) | PM tariff probability 75% (bearish for exports) | Markets may be pricing in stimulus outweighing tariff drag | Weight PM higher for export-specific stocks; FXI reflects broader China buying |
| [Another conflict] | | | | |
**Conflict severity:** [None / Minor (reconcilable) / Major (invalidates thesis partially) / Critical (do not trade — conflicting signals too strong)]
---
## 5. 🎯 Multi-Dimensional Judgment & Actionable Equity Impact
*A directional call is only valid if supported by ≥2 independent channels. Single-source signals are flagged Watch-only.*
| Catalyst | Channels Supporting | Channels Conflicting | Sector | Tickers | Conviction | Setup |
|----------|--------------------|--------------------|--------|---------|------------|-------|
| [Event] | [PM + FXI + News] | [CNY flat] | [Sector] | [Ticker] | [H/M/L] | [Long/Short/Watch] |
**Conviction Rules:**
- **High (H):** ≥3 channels aligned + Polymarket volume >$500k + PM trend rising
- **Medium (M):** 2 channels aligned + no critical conflicts
- **Low (L/Watch):** Single-source signal, or major conflict unresolved — monitor only, do not act
- **No Signal:** All channels conflicting or insufficient data — state this explicitly
---
## 6. Risk Factors & Blind Spots
*Where data is incomplete, contradictory, or could invalidate the thesis.*
- **Coverage Gap:** [e.g., "No active Polymarket contracts for PBOC this week — PM dimension missing"]
- **Stale Trend:** [e.g., "Polymarket probability flat for 14d — market conviction set, less leading value"]
- **Narrative Risk:** [e.g., "Xinhua calm on trade likely managing expectations pre-announcement — binary event risk high"]
- **Liquidity Risk:** [e.g., "All EV PM contracts <$50k volume — PM dimension is noise, not signal"]
- **Model Risk:** [e.g., "FXI trend driven by broad EM flows unrelated to China-specific fundamentals"]
---
## 7. Data Provenance & Timestamps
*For auditability and reproducibility.*
| Source | Command Run | Timestamp (UTC) | Records |
|--------|-------------|-----------------|---------|
| Polymarket (active) | `python3 scripts/filter-markets.py --keywords ... --volume ...` | [HH:MM] | [N] |
| Polymarket (historical) | `python3 scripts/query-markets.py "..." --all` | [HH:MM] | [N] |
| Market Proxies | `python3 scripts/fetch-market-data.py --tickers "..." --period ...` | [HH:MM] | [N] |
| News (CN domestic) | `python3 scripts/fetch-cn-news.py --source ...` | [HH:MM] | [N] |
| News (Global/HK) | `python3 scripts/fetch-cn-news.py --source ...` | [HH:MM] | [N] |Template B: Quick Brief
Use this template for Scenario 3 (Daily Pulse) and any situation where the user needs a rapid digest rather than a full analysis. Target reading time: 30 seconds.
---
## 🇨🇳 China Market Pulse — [YYYY-MM-DD]
*Pre-[HK/Shanghai] open | [HH:MM] UTC+8*
### 🔴 ALERTS (action required)
- [Event]: Polymarket [X]% → [Y]% (+[Z]pp, $[Vol]) | Confirmed by [proxy/news] | → Review [Scenario 1/2]
*(if none: "No alert-level signals")*
### 🟡 WATCH (monitor, no action yet)
- [FXI/KWEB/CNY]: [Trend direction since yesterday] | Awaiting [confirmation signal]
*(max 3 items)*
### 📊 Key Numbers
| Instrument | Value | 1-Day Change |
|------------|-------|-------------|
| FXI | | |
| KWEB | | |
| USD/CNY | | |
| VIX | | |
| Top Polymarket Odds | [Event]: [X]% | [±Y pp] |
### 📰 Top Headline
- **[Source]:** "[Headline]" — *[1-line implication for A-shares/HK]*
### ✅ No Change
- [List signals that are flat / unchanged — confirms prior thesis still holds]Scenario 1: Macro & Geopolitical Risk Assessment (Top-Down)
Use when: Assessing macro tail risks — Taiwan conflict, US-China trade war escalation, PBOC policy shifts, USD/CNY stress, US elections.
---
First Principles Anchor
Before running any script, define the specific risk hypothesis being tested. Examples:
- "What is the market-implied probability of new US chip sanctions on China this quarter?"
- "Is a PBOC surprise rate cut being priced into prediction markets?"
- "How elevated is contagion risk from a Taiwan Strait incident?"
This prevents data-gathering without purpose.
---
Step 1 — Collect Explicit Risk Pricing (Polymarket)
Fetch active-only markets to avoid resolved/expired noise:
# High-volume macro events (minimum $50k volume)
python3 scripts/filter-markets.py --keywords taiwan,invasion,conflict --volume 50000
# Trade war & tariffs
python3 scripts/filter-markets.py --keywords tariff,trade,sanctions --volume 50000
# Monetary policy
python3 scripts/filter-markets.py --keywords pboc,rate,fed,interest --volume 30000
# Election / political risk
python3 scripts/filter-markets.py --keywords election,president,congress --volume 100000Quality gate: Discard any result with volume < $25,000. Document the volume alongside each probability in the output.
---
Step 1b — Establish Historical PM Trend (Mandatory)
A single probability snapshot is not a signal. Compare against history:
# Fetch all (active + resolved) contracts to see past outcomes
python3 scripts/query-markets.py "taiwan conflict" --all --limit 100 --format json
python3 scripts/query-markets.py "china tariff sanctions" --all --limit 100 --format json
python3 scripts/query-markets.py "pboc rate cut" --all --limit 100 --format jsonFor each active contract found in Step 1, answer these questions:
| Question | Source |
|---|---|
| What probability did analogous resolved contracts reach at peak before resolving? | --all results |
| Did those contracts resolve Yes or No? At what threshold probability? | --all results |
| Is the current probability above or below the historical "resolve Yes" average? | Comparison |
Interpretation rules:
- If current probability is materially (>15pp) above historical base rate for similar events → PM may be overpricing risk; weight other channels more heavily
- If current probability has been rising steadily for >7 days → active re-pricing in progress; trend is more reliable than any single snapshot
- If current probability is flat and volume is declining → market conviction is set; less informational value going forward
- If no historical analogues exist → note this as a Coverage Gap in the final report
---
Step 2 — Collect Implicit Market Risk (Financial Proxies)
Focus on safe-haven and capital-flight instruments for macro risk:
python3 scripts/fetch-market-data.py --tickers "^VIX CNY=X GC=F UUP ^TNX" --period 7d --format json| Ticker | What to Look For |
|---|---|
^VIX | >25 = elevated fear; >35 = crisis mode |
CNY=X | Rising USD/CNY = capital leaving China; a falling CNY weakens A-shares |
GC=F | Rising Gold = safe-haven demand; signals risk-off globally |
UUP | Rising USD = pressure on all EM assets including A-shares |
^TNX | Rising US yields = higher discount rate on Chinese tech; headwind for 科创板 |
---
Step 3 — Verify State Narrative
Determine the official Chinese government and central-bank communication tone:
# Official state/policy voice
python3 scripts/fetch-cn-news.py --source xinhua_en,xinhua_finance --limit 10
# Western institutional view for contrast
python3 scripts/fetch-cn-news.py --source reuters_china,ft_china --limit 10Key divergence signal: If Xinhua is projecting stability while Reuters/FT is reporting escalation risk, the two narratives are diverging. This divergence itself is a market signal.
---
Step 4 — Cross-Reference, Conflict Detection & Synthesis
Apply the three-way divergence check:
1. Polymarket (explicit probability) — Does the crowd assign high probability to the risk event? 2. Market proxies (implicit pricing) — Are financial markets pricing in the same risk? 3. News narrative (momentum) — Is the media narrative driving sentiment toward or away from the risk?
Step 4a — Detect Conflicts First (do this before forming a thesis)
Explicitly check every possible pair of sources for disagreement:
| Conflict Pair | How to Detect | Significance |
|---|---|---|
| PM high, proxies flat | PM >60% but FXI/VIX not moving | PM may be leading; or PM volume is too low to trust |
| Proxies stressed, PM flat | FXI/VIX spiking but no relevant PM contracts | PM coverage gap; use proxy signal as primary |
| State media calm, Western media bearish | Xinhua stable, Reuters escalation narrative | Official PRC expectation management likely — weight Reuters |
| PM rising historically but resolved No | Past analogues show mean reversion | Current elevated PM may be overpriced fear |
| PM trend up, but proxy trend reversing | PM still rising while FXI starts recovering | Market makers may be fading the PM move |
Step 4b — Resolution Hierarchy
When sources conflict, apply this precedence (most reliable to least): 1. High-volume PM (>$500k) + trend momentum — specific, continuous crowd updating 2. Market proxies with clear 14d trend — implicit but liquid and manipulation-resistant 3. Western institutional media (Reuters, FT) — fast, professional, less biased but can amplify 4. State media (Xinhua) — useful for official intent signals; unreliable for objective risk assessment 5. Low-volume PM (<$50k) — discard; treat as anecdote not signal
Step 4c — Decision Rules
- All three align → High confidence in direction; proceed to Scenario 1 full equity mapping
- Polymarket high, proxies flat → Prediction market may be leading; watch for proxy catch-up within 2–3 sessions; do not size positions yet
- Proxies spiking, Polymarket flat → Low PM volume likely; use proxy signal but note PM as unconfirmed; medium confidence only
- News bullish, PM and proxies bearish → Narrative likely wishful or managed; weight proxies + PM over media
- Any critical conflict unresolved → No directional call; document the conflict and escalate to the user
---
Step 5 — Map to A-Share / HK Sectors
Load references/china_stock_mapping.json and apply the Macro Factor Mappings section:
| Risk Event | A-Share Sector Impact | Tickers |
|---|---|---|
| Taiwan military escalation | Defense ↑, Tech ↓, Travel ↓ | AVIC 600893.SH |
| US-China tariffs | Export mfg ↓, Domestic consumer ↑ | Luxshare 002475.SZ |
| PBOC rate cut | Banks ↓ (NIM), Real estate ↑ | Vanke 000002.SZ |
| CNY devaluation | Exporters ↑, Importers ↓ | COSCO 601919.SH |
| US yield spike | 科创板 (STAR) ↓, Growth stocks ↓ | SMIC 688981.SH |
---
Output
Use Template A: Comprehensive Investment Insight Report from references/templates/comprehensive-insight-report.md.
Scenario 2: Sector-Specific Catalyst Tracker (Bottom-Up)
Use when: Analyzing a specific industry vertical — EVs, Semiconductors, Property, Internet/Tech, Consumer, Energy, or a specific company.
---
First Principles Anchor
Identify the single most important near-term catalyst for the target sector. Examples:
- "NIO monthly delivery figures are due — what is Polymarket pricing for Q1 delivery targets?"
- "SMIC Q4 earnings beat — how has semiconductor sentiment shifted in prediction markets?"
- "Property developer defaults — what probability does Polymarket assign to a Evergrande-style contagion?"
This focuses data collection so that only relevant instruments are fetched.
---
Step 1 — Targeted Prediction Market Search (Active)
Search with industry-specific keywords to find markets with direct sector relevance:
# EV / Auto sector
python3 scripts/query-markets.py "byd" --limit 50 --format json
python3 scripts/query-markets.py "nio delivery" --limit 50 --format json
python3 scripts/query-markets.py "xpeng li auto" --limit 50 --format json
python3 scripts/query-markets.py "ev sales china" --limit 50 --format json
# Semiconductor sector
python3 scripts/query-markets.py "semiconductor export china" --limit 50 --format json
python3 scripts/query-markets.py "chip ban smic" --limit 50 --format json
python3 scripts/query-markets.py "nvidia china" --limit 50 --format json
# Internet / Tech platform
python3 scripts/query-markets.py "alibaba antitrust" --limit 50 --format json
python3 scripts/query-markets.py "tencent gaming license" --limit 50 --format json
python3 scripts/query-markets.py "didi" --limit 50 --format json
# Property / Real estate
python3 scripts/query-markets.py "china property evergrande" --limit 50 --format json
python3 scripts/query-markets.py "country garden" --limit 50 --format json
# Energy & Commodities
python3 scripts/query-markets.py "copper china demand" --limit 50 --format json
python3 scripts/query-markets.py "lng china" --limit 50 --format jsonQuality gate: Document each result's active status and volume. If no markets exist for a keyword, note the gap — absence of prediction market coverage itself implies that professional bettors see no near-term catalyst.
---
Step 1b — Sector Historical Base Rate (Mandatory)
Before interpreting any active probability, establish the sector's base rate from resolved contracts:
# Fetch resolved contracts for same sector to see historical accuracy
python3 scripts/query-markets.py "ev china" --all --limit 100 --format json
python3 scripts/query-markets.py "semiconductor china" --all --limit 100 --format json
# Replace keywords with current target sectorFor each resolved contract returned, record:
- Contract question, resolution (Yes/No), peak probability before resolution
- Was the crowd right? Did high probability (>70%) actually resolve Yes?
Sector-specific calibration patterns to check:
- EV delivery numbers: PM historically underprices beat probability at peak of news cycle
- Regulatory crackdowns: PM historically sharp and accurate (Didi/Edu-tech had >80% probability days before announcement)
- Property default contagion: PM historically overprices systemic spread; single developer ≠ sector ≠ systemic
- Chip/export controls: High base-rate Yes — US export restrictions have a >70% historical resolution rate when probabilities are above 60%
---
Step 2 — Sector-Relevant Market Proxies
Select the proxy instruments most correlated with the target sector:
# EV / New Energy
python3 scripts/fetch-market-data.py --tickers "BYD.HK NIO XPEV LI HG=F" --period 14d --format json
# Tech / Internet
python3 scripts/fetch-market-data.py --tickers "KWEB BABA TCEHY BIDU" --period 14d --format json
# Broad China equity + FX (applicable to all sectors)
python3 scripts/fetch-market-data.py --tickers "FXI ^HSI CNY=X" --period 14d --format json
# Semiconductors / hardware
python3 scripts/fetch-market-data.py --tickers "SOXX SMH FXI" --period 14d --format jsonMomentum check: Look for 5-day trend vs. 14-day trend. A proxy that has diverged from its 14-day average by >±3% in the last 5 days signals acceleration — the catalyst may already be in motion.
---
Step 3 — Industry-Deep News Flow
# Industry deep dives (Chinese domestic)
python3 scripts/fetch-cn-news.py --source 21cbh,yicai --limit 15
# Regulatory / official securities perspective
python3 scripts/fetch-cn-news.py --source stcn --limit 10
# International trade angle
python3 scripts/fetch-cn-news.py --source reuters_china,nikkei_china --limit 10Filter for: Regulatory actions, supply chain news, policy announcements (subsidies, restrictions), leadership guidance, M&A events.
---
Step 4 — Map to A-Share Tickers
Load references/china_stock_mapping.json. For sector-level analysis, apply the company-level mappings:
| Segment | Key Entities | A-Share / HK Tickers | Supply Chain Plays |
|---|---|---|---|
| New Energy Vehicles | BYD, NIO, XPeng, Li Auto | 002594.SZ, NIO (NYSE), XPEV, LI | CATL 300750.SZ, Ganfeng 002460.SZ |
| Semiconductors | SMIC, Hua Hong | 688981.SH, 688347.SH | Anji Technology 688019.SH |
| Internet Platform | Alibaba, Tencent | 09988.HK, 00700.HK | — |
| Property | Vanke, Poly | 000002.SZ, 600048.SH | — |
| EV Battery | CATL, BYD | 300750.SZ, 002594.SZ | — |
---
Step 5 — Evaluate Catalyst Timing & Multi-Source Verdict
Rule: No catalyst call without ≥2 independent channels confirming direction.
Before assigning any horizon or weight, perform an explicit cross-source check:
| Channel | Evidence Found | Direction | Confidence (H/M/L) |
|---|---|---|---|
| Polymarket (active, >$50k volume) | [Y/N, summary] | ↑↓ | |
| Polymarket (historical base rate) | [Y/N, summary] | ↑↓ | |
| Sector proxy (5d vs 14d trend) | [Y/N, summary] | ↑↓ | |
| Industry news (CN domestic) | [Y/N, summary] | ↑↓ | |
| International trade/policy news | [Y/N, summary] | ↑↓ |
Verdict rules:
- ≥3 channels agree → High conviction, proceed to directional call
- Exactly 2 channels agree, no critical conflicts → Medium conviction, state which 2 and why
- 1 channel only → Label as "Unconfirmed Signal — Watch Only", do not make a directional call
- Channels conflict critically → No verdict; document the conflict explicitly and escalate
Assign a catalyst timeline only after the multi-source verdict is established:
| Horizon | Signal Type | Weight |
|---|---|---|
| <1 week | Polymarket delta movement + news momentum | 60% |
| 1–4 weeks | Market proxy trend + earnings/event calendar | 30% |
| 1–3 months | Macro factors (PBOC, trade tensions) | 10% |
---
Output
Use Template A: Comprehensive Investment Insight Report from references/templates/comprehensive-insight-report.md.
If the user only wants a quick sector check, use Template B: Quick Sector Brief from references/templates/quick-brief.md.
Scenario 3: Daily Market Pulse / Fast Digest
Use when: The user wants a rapid pre-market briefing before Asian market open (typically 08:30–09:15 CST), an end-of-day summary, or a quick delta check on what changed since the previous session.
---
First Principles Anchor
The goal is actionable deltas, not data dumps. The daily pulse must answer three questions in under 60 seconds of reading: 1. Did any Polymarket probabilities shift materially (>5 percentage points) since yesterday? 2. Are key proxies (FXI, CNY, VIX) trending in a consistent direction? 3. Is any major news event forcing a re-evaluation of existing positions?
---
Step 1 — Run Full Composite Analyzer
Execute all seven channels in a single command:
python3 scripts/polymarket_analyzer.py --profile defaultIf the composite analyzer is unavailable, run channels manually in this priority order:
# Priority 1: Prediction market deltas (active only)
python3 scripts/filter-markets.py --keywords china,taiwan,tariff,pboc --volume 50000 --format json
# Priority 2: Key proxy snapshot
python3 scripts/fetch-market-data.py --tickers "FXI KWEB ^VIX CNY=X" --period 2d --format json
# Priority 3: Overnight news (last 12 hours)
python3 scripts/fetch-cn-news.py --source caixin,reuters_china,xinhua_en --limit 10---
Step 2 — Identify Deltas (24h and 7d)
Compare current readings against the previous session baseline. Both 24h and 7d deltas matter — a small 24h change within a strong 7d trend is often more significant than a large 24h spike with no trend.
| Metric | 24h Threshold | 7d Threshold | Notes |
|---|---|---|---|
| Polymarket probability | ≥5pp shift | ≥10pp shift (trend) | 7d trend is more reliable than 24h noise |
| FXI / KWEB price | ≥1.5% overnight | ≥3% weekly | |
| CNY/USD | ≥0.3% daily | ≥0.8% weekly | |
| VIX | ≥2 pts daily | ≥5 pts weekly | |
| Regulatory news | Any new CSRC/PBOC/NDRC announcement | Sustained silence → binary event risk building | |
| Geopolitical | Any Taiwan Strait / South China Sea / US-China event | Escalation frequency increasing? |
Anything below both thresholds is background noise — do not include it in the output.
PM 7d trend check: For any contract with a ≥5pp 24h move, also check whether this is acceleration of a trend or a reversion:
# Fetch resolved + active to see trajectory pattern
python3 scripts/query-markets.py "china tariff" --all --limit 50 --format json---
Step 3 — Triage (Multi-Source Confirmation Required)
Classify each material delta into one of three buckets:
| Bucket | Criteria | Action |
|---|---|---|
| ALERT | ≥2 independent sources pointing same direction + Polymarket volume >$100k | Run full Scenario 1 or Scenario 2 workflow immediately |
| WATCH | Single source moving, or PM volume too low to confirm, or sources conflict | Monitor; explicitly note which source is moving and which are flat; do not act without confirmation |
| NOISE | Movement below thresholds, low PM volume, no corroborating source | Discard from output |
A single source moving is always WATCH, never ALERT — even if the magnitude is large.
Example triage application:
- VIX up 4pts + PM tariff probability up 8pp + Reuters China trade headline → ALERT (3 sources aligned)
- FXI down 2% but PM flat + CNY stable + news neutral → WATCH (FXI may be noise or EM selloff unrelated to China)
- Xinhua headline on tech policy + no PM movement + proxies flat → NOISE (single official-media signal, not independently confirmed)
---
Step 4 — Synthesise Briefing
Prepare the output using Template B: Quick Brief from references/templates/quick-brief.md.
The output must be completeable in a 30-second read — no more than 10 bullet points total.
---
Escalation Path
If the daily pulse reveals an ALERT-level delta, immediately switch to the full analysis workflow:
- Macro/geopolitical risk →
references/workflows/scenario-1-macro-geopolitical.md - Sector-specific event →
references/workflows/scenario-2-sector-catalyst.md
#!/usr/bin/env python3
"""
Fetch raw news headlines about China markets from Chinese and global sources.
Outputs headlines only — no scoring, no sentiment judgment.
Sources covered:
Chinese domestic : 财新(Caixin), 新浪财经, 第一财经(Yicai), 东方财富(Eastmoney),
证券时报, 21世纪经济报道, 新华财经
Global/HK : Reuters China, SCMP, FT China, Nikkei Asia China, Xinhua EN
Usage:
python3 fetch-cn-news.py # All sources, table output
python3 fetch-cn-news.py --format json # JSON output (for agent parsing)
python3 fetch-cn-news.py --limit 30 # Headlines per source (default: 20)
python3 fetch-cn-news.py --source caixin # Single source only
python3 fetch-cn-news.py --source caixin,scmp # Multiple sources
"""
import argparse
import json
import re
import sys
import urllib.error
import urllib.request
import xml.etree.ElementTree as ET
from datetime import datetime
# ── Source registry ───────────────────────────────────────────────────────────
SOURCES = [
# Chinese domestic
{
"id": "caixin", "name": "财新 Caixin Global",
"region": "CN", "lang": "en", "type": "rss",
"url": "https://www.caixinglobal.com/rss/",
},
{
"id": "sina_finance", "name": "新浪财经",
"region": "CN", "lang": "zh", "type": "rss",
"url": "https://rss.sina.com.cn/news/stock/stockmarket.xml",
},
{
"id": "yicai", "name": "第一财经 Yicai",
"region": "CN", "lang": "zh", "type": "rss",
"url": "https://www.yicai.com/rss/news.xml",
},
{
"id": "eastmoney", "name": "东方财富 Eastmoney",
"region": "CN", "lang": "zh", "type": "eastmoney_api",
"url": (
"https://np-listapi.eastmoney.com/comm/web/getNewsByColumns"
"?client=web&columns=294&pageSize=30&fields=title,date,newsId,mediaName,summary"
),
},
{
"id": "stcn", "name": "证券时报 Securities Times",
"region": "CN", "lang": "zh", "type": "rss",
"url": "http://www.stcn.com/content/rss.xml",
},
{
"id": "21cbh", "name": "21世纪经济报道",
"region": "CN", "lang": "zh", "type": "rss",
"url": "http://rss.21cbh.com/list/115.xml",
},
{
"id": "xinhua_finance", "name": "新华财经 Xinhua Finance",
"region": "CN", "lang": "zh", "type": "rss",
"url": "http://www.xinhuanet.com/money/news/rss.xml",
},
# Global / HK
{
"id": "reuters_china", "name": "Reuters China",
"region": "GLOBAL", "lang": "en", "type": "rss",
"url": "https://feeds.reuters.com/reuters/CNTopGenNews",
},
{
"id": "scmp", "name": "South China Morning Post",
"region": "HK", "lang": "en", "type": "rss",
"url": "https://www.scmp.com/rss/5/feed",
},
{
"id": "ft_china", "name": "Financial Times China",
"region": "GLOBAL", "lang": "en", "type": "rss",
"url": "https://www.ft.com/rss/home/chinese-mainland",
},
{
"id": "nikkei_china", "name": "Nikkei Asia China",
"region": "GLOBAL", "lang": "en", "type": "rss",
"url": "https://asia.nikkei.com/rss/feed/section/china",
},
{
"id": "xinhua_en", "name": "Xinhua English",
"region": "CN", "lang": "en", "type": "rss",
"url": "https://www.xinhuanet.com/english/rss/chinalatestnews.xml",
},
]
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
}
# ── Helpers ───────────────────────────────────────────────────────────────────
def http_get(url: str, timeout: int = 10) -> str | None:
try:
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=timeout) as r:
return r.read().decode("utf-8", errors="replace")
except Exception:
return None
def clean_xml(text: str) -> str:
text = re.sub(r"&(?!(?:amp|lt|gt|apos|quot|#\d+|#x[0-9a-fA-F]+);)", "&", text)
text = re.sub(r"[^\x09\x0A\x0D\x20-\xD7FF\xE000-\xFFFD]", "", text)
return text
def strip_tags(text: str) -> str:
return re.sub(r"<[^>]+>", "", text or "").strip()
def parse_rss(source: dict, raw: str, limit: int) -> list:
try:
root = ET.fromstring(clean_xml(raw))
except ET.ParseError:
return []
ns = {"atom": "http://www.w3.org/2005/Atom"}
items = root.findall(".//item") or root.findall(".//atom:entry", ns)
articles = []
for item in items[:limit]:
def txt(tag: str, fallback: str = "") -> str:
el = item.find(tag) or item.find(f"atom:{tag}", ns)
return strip_tags(getattr(el, "text", None) or fallback)
def get_url() -> str:
link = item.find("link") or item.find("atom:link", ns)
if link is None:
return ""
return link.get("href") or getattr(link, "text", "") or ""
title = txt("title")
if not title:
continue
articles.append({
"source": source["name"],
"source_id": source["id"],
"region": source["region"],
"lang": source["lang"],
"title": title[:200],
"url": get_url(),
"pubdate": txt("pubDate") or txt("published"),
"summary": (txt("description") or txt("summary"))[:300],
})
return articles
def parse_eastmoney(source: dict, raw: str, limit: int) -> list:
articles = []
try:
wrapper = json.loads(raw)
items: list = []
if isinstance(wrapper, dict):
items = (
wrapper.get("data", {}).get("list", [])
or wrapper.get("list", [])
or wrapper.get("result", {}).get("data", [])
or []
)
elif isinstance(wrapper, list):
items = wrapper
for item in items[:limit]:
title = item.get("title") or item.get("Title", "")
if not title:
continue
news_id = item.get("newsId") or item.get("NewsID", "")
articles.append({
"source": source["name"],
"source_id": source["id"],
"region": source["region"],
"lang": source["lang"],
"title": strip_tags(title)[:200],
"url": f"https://finance.eastmoney.com/a/{news_id}.html" if news_id else "",
"pubdate": item.get("date") or item.get("Date", ""),
"summary": strip_tags(item.get("summary") or item.get("Summary") or "")[:300],
})
except Exception:
pass
return articles
# ── Main ──────────────────────────────────────────────────────────────────────
def main() -> None:
parser = argparse.ArgumentParser(
description="Fetch raw China market news headlines from domestic and global sources.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""Examples:
python3 fetch-cn-news.py
python3 fetch-cn-news.py --format json
python3 fetch-cn-news.py --source caixin --limit 30
python3 fetch-cn-news.py --source caixin,scmp
python3 fetch-cn-news.py --source eastmoney""",
)
parser.add_argument("--format", "-f", choices=["table", "json"], default="table",
help="Output format (default: table)")
parser.add_argument("--limit", "-n", type=int, default=20,
help="Headlines per source (default: 20)")
parser.add_argument("--source", "-s", default="",
help="Comma-separated source IDs to fetch (default: all)")
args = parser.parse_args()
filter_ids = {s.strip().lower() for s in args.source.split(",") if s.strip()}
if filter_ids:
sources_to_fetch = [
s for s in SOURCES
if s["id"] in filter_ids or any(f in s["name"].lower() for f in filter_ids)
]
else:
sources_to_fetch = SOURCES
all_articles: list = []
source_stats: list = []
for source in sources_to_fetch:
raw = http_get(source["url"])
if not raw:
source_stats.append({"source": source, "count": 0, "status": "unreachable"})
continue
if source["type"] == "eastmoney_api":
articles = parse_eastmoney(source, raw, args.limit)
else:
articles = parse_rss(source, raw, args.limit)
source_stats.append({"source": source, "count": len(articles), "status": "ok"})
all_articles.extend(articles)
if args.format == "json":
print(json.dumps({
"as_of": datetime.now().isoformat(),
"total": len(all_articles),
"sources": [
{"id": s["source"]["id"], "name": s["source"]["name"],
"count": s["count"], "status": s["status"]}
for s in source_stats
],
"articles": all_articles,
}, ensure_ascii=False, indent=2))
return
# ── Table output ──────────────────────────────────────────────────────────
print()
print(f" China Market News Headlines | {datetime.now().strftime('%Y-%m-%d %H:%M')}")
sep = " " + "─" * 76
print(sep)
print(f" {'Source':<32} {'Lang':<5} {'Region':<8} Articles Status")
print(sep)
for s in source_stats:
src = s["source"]
status = "✓" if s["status"] == "ok" else "✗ unreachable"
print(f" {src['name']:<32} {src['lang']:<5} {src['region']:<8} {s['count']:>5} {status}")
print()
print(f" {'─── Headlines (' + str(len(all_articles)) + ' total) ':-<76}")
print()
for a in all_articles:
lang_tag = "[ZH] " if a["lang"] == "zh" else ""
date_short = a["pubdate"][:16] if a["pubdate"] else ""
print(f" [{a['source_id']}] {lang_tag}{a['title']}")
if a.get("summary"):
print(f" ↳ {a['summary'][:120]}")
if date_short:
print(f" @ {date_short}")
print()
print(sep)
ok_count = sum(1 for s in source_stats if s["status"] == "ok")
print(f" Total: {len(all_articles)} headlines from {ok_count} source(s)")
print()
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Fetch raw price and volume data for China-related market proxy instruments.
Outputs data only — no signals, no judgments.
Requires: pip install yfinance
Usage:
python3 fetch-market-data.py # Default tickers, table output
python3 fetch-market-data.py --format json # JSON output (for agent parsing)
python3 fetch-market-data.py --tickers "FXI KWEB ^VIX" # Custom tickers
python3 fetch-market-data.py --period 30d # Longer history (default: 7d)
"""
import argparse
import json
import sys
from datetime import datetime
# China proxy instruments — ordered by relevance to China market
DEFAULT_TICKERS = [
("FXI", "iShares FTSE China Large-Cap ETF", "China equity"),
("KWEB", "KraneShares China Internet ETF", "China tech equity"),
("^HSI", "Hang Seng Index", "HK equity index"),
("HG=F", "Copper Futures", "China industrial demand"),
("AUDUSD=X", "AUD/USD Exchange Rate", "China commodities proxy"),
("CNY=X", "USD/CNY Exchange Rate", "Renminbi vs USD"),
("^VIX", "CBOE Volatility Index", "Global risk appetite"),
("GC=F", "Gold Futures", "Safe-haven demand"),
("^TNX", "US 10-Year Treasury Yield", "US rates pressure"),
("EEM", "iShares Emerging Markets ETF", "Broader EM proxy"),
("UUP", "Invesco DB USD Index Bullish Fund ETF", "US Dollar strength"),
]
def fetch_data(tickers: list[tuple], period: str) -> list[dict]:
try:
import yfinance as yf
except ImportError:
print("Error: yfinance not installed. Run: pip install yfinance", file=sys.stderr)
sys.exit(1)
rows = []
for ticker, name, category in tickers:
try:
t = yf.Ticker(ticker)
hist = t.history(period=period, interval="1d", auto_adjust=True)
if hist.empty or len(hist) < 2:
rows.append({"ticker": ticker, "name": name, "error": "insufficient data"})
continue
c = hist["Close"]
v = hist["Volume"]
p1 = (c.iloc[-1] - c.iloc[-2]) / c.iloc[-2] * 100
p5 = (c.iloc[-1] - c.iloc[max(0, len(c) - 6)]) / c.iloc[max(0, len(c) - 6)] * 100
rows.append({
"ticker": ticker,
"name": name,
"category": category,
"price": round(float(c.iloc[-1]), 4),
"pct_1d": round(p1, 4),
"pct_5d": round(p5, 4),
"avg_volume": int(v.mean()) if not v.empty else 0,
"period": period,
"as_of": datetime.now().strftime("%Y-%m-%d %H:%M"),
})
except Exception as e:
rows.append({"ticker": ticker, "name": name, "error": str(e)})
return rows
def print_table(rows: list[dict], period: str) -> None:
print()
print(f" China Market Proxy Data | period={period} | {datetime.now().strftime('%Y-%m-%d %H:%M')}")
sep = " " + "─" * 72
print(sep)
print(f" {'Ticker':<12} {'1D%':>8} {'5D%':>8} {'Avg Vol':>14} Category")
print(sep)
for r in rows:
if "error" in r:
print(f" {r['ticker']:<12} ERROR: {r['error']}")
else:
print(
f" {r['ticker']:<12} {r['pct_1d']:>+8.2f}% {r['pct_5d']:>+8.2f}%"
f" {r['avg_volume']:>14,} {r['category']}"
)
print(sep)
ok = sum(1 for r in rows if "error" not in r)
print(f" {ok}/{len(rows)} instruments fetched")
print()
def main() -> None:
parser = argparse.ArgumentParser(
description="Fetch raw China market proxy data via yfinance.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""Examples:
python3 fetch-market-data.py
python3 fetch-market-data.py --format json
python3 fetch-market-data.py --tickers "FXI KWEB ^VIX"
python3 fetch-market-data.py --period 30d""",
)
parser.add_argument("--format", "-f", choices=["table", "json"], default="table",
help="Output format (default: table)")
parser.add_argument("--period", "-p", default="7d",
help="History period, e.g. 7d, 30d, 90d (default: 7d)")
parser.add_argument("--tickers", "-t", default="",
help="Space-separated custom tickers (default: all 11 China proxies)")
args = parser.parse_args()
if args.tickers:
tickers = [(t, t, "") for t in args.tickers.split()]
else:
tickers = DEFAULT_TICKERS
rows = fetch_data(tickers, args.period)
if args.format == "json":
print(json.dumps(rows, ensure_ascii=False, indent=2))
else:
print_table(rows, args.period)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Filter Polymarket markets with multiple criteria.
By default, only ACTIVE markets with volume >= 50,000 are returned.
Usage:
python3 filter-markets.py [--keywords k1,k2,...] [--volume N]
[--status active|closed|all] [--limit N]
[--format table|json]
Examples:
python3 filter-markets.py --keywords taiwan,invasion --volume 100000
python3 filter-markets.py --keywords byd,nio,xpeng --limit 50
python3 filter-markets.py --status closed --format json
"""
import argparse
import json
import shutil
import subprocess
import sys
DEFAULT_KEYWORDS = "china,taiwan,byd,nio,alibaba,tencent"
DEFAULT_MIN_VOLUME = 50_000
DEFAULT_STATUS = "active"
DEFAULT_LIMIT = 100
def check_polymarket() -> None:
if not shutil.which("polymarket"):
print("Error: polymarket CLI not found. Please install it first.", file=sys.stderr)
sys.exit(1)
def run_search(term: str, limit: int) -> list:
result = subprocess.run(
["polymarket", "-o", "json", "markets", "search", term.strip(), "--limit", str(limit)],
capture_output=True, text=True,
)
if result.returncode != 0:
return []
try:
data = json.loads(result.stdout)
return data if isinstance(data, list) else []
except json.JSONDecodeError:
return []
def deduplicate(markets: list) -> list:
seen, out = set(), []
for m in markets:
key = m.get("conditionId") or m.get("slug") or m.get("question")
if key and key not in seen:
seen.add(key)
out.append(m)
return out
def apply_filters(markets: list, min_volume: int, status: str) -> list:
out = []
for m in markets:
if float(m.get("volume") or 0) < min_volume:
continue
active = m.get("active") is True
if status == "active" and not active:
continue
if status == "closed" and active:
continue
out.append(m)
return out
def print_table(markets: list) -> None:
if not markets:
print(" No markets matched the criteria.")
return
q_width = 56
sep = " " + "-" * 108
fmt = f" {{:<{q_width}}} {{:>12}} {{:>14}} {{:>12}} {{:<8}}"
print(sep)
print(fmt.format("Question", "Price (Yes)", "Volume", "Liquidity", "Status"))
print(sep)
for m in markets:
question = (m.get("question") or "N/A")[:q_width]
price = str((m.get("outcomePrices") or ["N/A"])[0])
volume = str(m.get("volume") or "0")
liquidity = str(m.get("liquidity") or "0")
status = "Active" if m.get("active") else "Closed"
print(fmt.format(question, price, volume, liquidity, status))
print(sep)
print(f" {len(markets)} market(s) matched")
def main() -> None:
parser = argparse.ArgumentParser(
description="Filter Polymarket markets with multiple criteria. Active-only by default.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""Examples:
python3 filter-markets.py --keywords taiwan,invasion --volume 100000
python3 filter-markets.py --keywords byd,nio,xpeng --limit 50
python3 filter-markets.py --status closed --format json""",
)
parser.add_argument("--keywords", "-k", default=DEFAULT_KEYWORDS,
help=f"Comma-separated keywords (default: {DEFAULT_KEYWORDS})")
parser.add_argument("--volume", "-v", type=int, default=DEFAULT_MIN_VOLUME,
help=f"Minimum volume threshold (default: {DEFAULT_MIN_VOLUME})")
parser.add_argument("--status", "-s", choices=["active", "closed", "all"],
default=DEFAULT_STATUS,
help=f"Market status filter (default: {DEFAULT_STATUS})")
parser.add_argument("--limit", "-n", type=int, default=DEFAULT_LIMIT,
help=f"Max results per keyword fetch (default: {DEFAULT_LIMIT})")
parser.add_argument("--format", "-f", choices=["table", "json"], default="table",
help="Output format (default: table)")
args = parser.parse_args()
check_polymarket()
keywords = [k.strip() for k in args.keywords.split(",") if k.strip()]
print(
f"Filtering markets... keywords={keywords}, volume>={args.volume}, status={args.status}",
file=sys.stderr,
)
all_markets: list = []
for kw in keywords:
print(f" Searching: '{kw}'...", file=sys.stderr)
all_markets.extend(run_search(kw, args.limit))
all_markets = deduplicate(all_markets)
filtered = apply_filters(all_markets, args.volume, args.status)
if args.format == "json":
print(json.dumps(filtered, ensure_ascii=False, indent=2))
else:
print_table(filtered)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Query Polymarket markets matching specific criteria.
By default, only ACTIVE (open) markets are returned.
Usage:
python3 query-markets.py <search-term> [--limit N] [--format table|json] [--all]
Examples:
python3 query-markets.py "china"
python3 query-markets.py "taiwan" --limit 100 --format json
python3 query-markets.py "taiwan" --format json --all
"""
import argparse
import json
import shutil
import subprocess
import sys
def check_polymarket() -> None:
if not shutil.which("polymarket"):
print("Error: polymarket CLI not found. Please install it first.", file=sys.stderr)
print("See: https://github.com/Polymarket/polymarket-cli", file=sys.stderr)
sys.exit(1)
def run_search(term: str, limit: int) -> list:
result = subprocess.run(
["polymarket", "-o", "json", "markets", "search", term, "--limit", str(limit)],
capture_output=True, text=True,
)
if result.returncode != 0:
return []
try:
data = json.loads(result.stdout)
return data if isinstance(data, list) else []
except json.JSONDecodeError:
return []
def print_table(markets: list) -> None:
if not markets:
print(" No markets found.")
return
q_width = 60
sep = " " + "-" * 96
fmt = f" {{:<{q_width}}} {{:>12}} {{:>14}} {{:<8}}"
print(sep)
print(fmt.format("Question", "Price (Yes)", "Volume", "Status"))
print(sep)
for m in markets:
question = (m.get("question") or "N/A")[:q_width]
price = str((m.get("outcomePrices") or ["N/A"])[0])
volume = str(m.get("volume") or "0")
status = "Active" if m.get("active") else "Closed"
print(fmt.format(question, price, volume, status))
print(sep)
print(f" {len(markets)} market(s)")
def main() -> None:
parser = argparse.ArgumentParser(
description="Query Polymarket markets. Returns active markets only by default.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""Examples:
python3 query-markets.py "china"
python3 query-markets.py "taiwan" --limit 100 --format json
python3 query-markets.py "taiwan" --format json --all""",
)
parser.add_argument("search_term", help="Keywords to search for")
parser.add_argument("--limit", "-n", type=int, default=50,
help="Maximum results to return (default: 50)")
parser.add_argument("--format", "-f", choices=["table", "json"], default="table",
help="Output format (default: table)")
parser.add_argument("--all", dest="include_all", action="store_true",
help="Include closed and resolved markets")
args = parser.parse_args()
check_polymarket()
active_label = "all statuses" if args.include_all else "active-only"
print(f"Searching Polymarket for: '{args.search_term}' (limit: {args.limit}, {active_label})",
file=sys.stderr)
# Fetch extra to compensate for post-filter attrition when filtering active-only
fetch_limit = args.limit if args.include_all else args.limit * 3
markets = run_search(args.search_term, fetch_limit)
if not args.include_all:
markets = [m for m in markets if m.get("active") is True]
markets = markets[:args.limit]
if args.format == "json":
print(json.dumps(markets, ensure_ascii=False, indent=2))
else:
print_table(markets)
if __name__ == "__main__":
main()