# Joinquant Skill

> Generate accurate, runnable quantitative strategy code for the JoinQuant (聚宽) platform. Use this skill when the user asks to write a stock/ETF/futures backtest, paper-trading, or live-trading strategy on JoinQuant — the skill provides progressive-disclosure access to the complete JoinQuant API knowledge base (14 categories, 294KB official docs), 5 production-ready strategy templates (single-stock MA, multi-factor, ETF rotation, momentum, mean-reversion), and a lint tool that catches hallucinated APIs, future-function violations, and unset price-mode/slippage/commission. Chinese-friendly. Code generated by this skill should paste directly into the JoinQuant online editor without modification.

- Skill: `gaaiyun/joinquant-skill` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add gaaiyun/joinquant-skill`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gaaiyun/joinquant-skill/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- Author: gaaiyun (https://skillmd.com/u/gaaiyun)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/gaaiyun/joinquant-skill

---


# JoinQuant Skill

Generate quantitative strategy code that runs on the JoinQuant platform without modification.

## When to Use This Skill

Yes:
- Stock backtest / paper trading / live trading on JoinQuant (聚宽)
- ETF rotation, multi-factor stock selection, momentum, mean reversion strategies
- Futures (期货) strategies on JoinQuant
- Margin trading (融资融券) strategies
- Strategy code review / lint to catch hallucinated APIs and future-function violations
- Translating a strategy idea into JoinQuant API calls

No:
- Local data analysis without JoinQuant (use `jqdatasdk` directly, or pandas/numpy)
- Strategy backtesting on other platforms (vectorbt, backtrader, vn.py — use those skills instead)
- Pure machine learning model training (no JoinQuant-specific API needed)
- Live trading on broker APIs other than JoinQuant simulated trading (CTP, Interactive Brokers, etc. need different skills)

## Default Mode

Most user requests fall into one of three patterns. Detect the pattern first, then route:

| Pattern | Trigger | Action |
|---|---|---|
| **Quick code** | "帮我写一个 X 策略" / "用聚宽实现 Y" | Pick template, fill in user-specific parts, return ready-to-paste code |
| **API question** | "聚宽里 get_price 的 fq 参数是什么意思" / "set_option 都有哪些选项" | Load matching `references/XX-*.md` and answer based on it |
| **Code review** | "帮我审一下我这段聚宽代码" / paste of existing code | Run mental `strategy_lint.py` against it (or actually call it), point out hallucinated APIs and missing safeguards |

## Progressive Disclosure: 14 API Categories

DO NOT load all references at once (294KB total, would burn context). Pattern-match the user request and load only the relevant category file:

| Category | Reference file | Triggered by keywords |
|---|---|---|
| 策略设置 | `references/01-strategy-setup.md` | initialize, set_benchmark, set_option, set_order_cost, set_slippage, run_daily, run_weekly, run_monthly |
| 数据获取 | `references/02-data-getters.md` | get_price, attribute_history, history, get_current_data, get_fundamentals, get_money_flow, get_concept, get_industry |
| jqlib 因子库 | `references/03-jqlib.md` | alpha101, alpha191, technical_analysis, jqfactor |
| 数据处理 | `references/04-data-processing.md` | get_factor_values, calc_factor_history, neutralize, winsorize, standardlize |
| 组合优化 | `references/05-portfolio-optimization.md` | optimizer, max_sharpe, min_variance, target_return, mean_variance |
| 交易函数 | `references/06-trading.md` | order, order_value, order_target, order_target_value, cancel_order, get_open_orders |
| 对象 | `references/07-objects.md` | Order, Position, Portfolio, OrderCost, OrderStyle, MarketOrderStyle, LimitOrderStyle |
| 其他函数 | `references/08-misc-functions.md` | record, log, write_file, send_message |
| 多投资组合 | `references/09-multi-portfolio.md` | set_subportfolios, SubPortfolioConfig, transfer_cash |
| Tick 级 | `references/10-tick-strategy.md` | tick, get_ticks, every_tick |
| 融资融券 | `references/11-margin-trading.md` | margincash_open, margincash_close, marginsec_open, marginsec_close, set_margin_rate |
| 期货 | `references/12-futures.md` | get_dominant_future, futures, set_future_commission |
| 归因分析 | `references/13-attribution-analysis.md` | brinson, factor analysis, attribution |
| 引擎机制 | `references/14-strategy-engine.md` | 撮合, 复权, 滑点, 税费, 风险指标, alpha, beta, sharpe, max drawdown |

If the user mentions a function name not in any keyword list, use `scripts/api_search.py <keyword>` to find it across all references.

## Templates

5 production-ready templates in `templates/`:

| Template | When to use |
|---|---|
| `01-basic-single-stock.py` | First-time users, single stock, simple MA crossover. The "hello world" of JoinQuant. |
| `02-multi-factor.py` | Multi-factor stock selection (PE / market cap / momentum), monthly rebalance. Most common "real" strategy structure. |
| `03-etf-rotation.py` | ETF rotation by momentum ranking. Popular among retail investors. |
| `04-momentum-stock.py` | Cross-sectional momentum on stock pool, weekly rebalance. |
| `05-mean-reversion.py` | Bollinger / RSI mean reversion. Volatility-aware. |

When generating code, **start from a template, modify, do not write from scratch**. Reasons:
1. Templates already include the boilerplate (set_benchmark, set_option, set_order_cost, set_slippage)
2. Templates have correct timing (run_daily / run_weekly with proper time arg)
3. Templates avoid future-function pitfalls (count-based instead of date-based slicing)

## Lint Tool

Before returning generated code to user, mentally (or actually) run `strategy_lint.py`:

```bash
python scripts/strategy_lint.py <user_strategy.py>
```

Critical checks:
- ❌ Hallucinated API calls (e.g., `jqdata.get_stock_data()` doesn't exist)
- ❌ Future function: using non-count `get_price` or `attribute_history` with hardcoded future dates
- ❌ Missing `set_option('use_real_price', True)` (mandatory for accurate backtest)
- ❌ Missing `set_order_cost(...)` and `set_slippage(...)`
- ❌ Order placed in `before_trading_start` / `after_trading_end` (forbidden, will be rejected)
- ❌ Use of deprecated APIs (`update_universe` etc.)
- ⚠️ Recommend `g.` global vars for state across bars instead of module globals
- ⚠️ Recommend cluster-aware sizing for high-correlation assets

## Things That Must Survive Generation

When advising on a strategy, never lose:

- **Always set `use_real_price=True`**. Traditional pre-adjusted price has future-function bias. This is non-negotiable.
- **`set_order_cost` and `set_slippage` are mandatory**. Without them, backtest is unrealistic and will mislead the user.
- **`run_daily` time argument matters**. `'open'` runs at 09:30, `'every_bar'` runs every bar (minute or daily). Wrong choice causes wrong execution timing.
- **`g.` is the only safe global state**. Module-level globals can leak across runs in some JoinQuant environments.
- **`order_value` > `order` for capital management**. Computing share count manually is error-prone with stock splits.
- **`order_target_value` for rebalancing**, never compute "current value - target value" yourself.
- **Don't `pip install` anything inside JoinQuant**. The platform is sandboxed; only its preinstalled libraries work.

## Workflow

A typical end-to-end strategy session:

```
1. User describes idea in natural language
2. AI: pick matching template (e.g., 03-etf-rotation.py)
3. AI: ask 2-3 clarifying questions:
   - 标的池范围（指数成分 / 自定义列表）
   - 调仓频率（日 / 周 / 月）
   - 风险控制（止损 / 仓位上限 / 行业中性）
4. AI: generate strategy code modifying template
5. AI: run mental lint (or actual) — fix issues
6. User: paste into JoinQuant online editor, click 编译运行
7. If errors: re-load relevant references/XX-*.md, fix
8. User: review backtest curve, iterate
```

For high-stakes (live trading) strategies, additionally:
- Reference `references/14-strategy-engine.md` for slippage, commission, risk metrics
- Reference `references/11-margin-trading.md` if leverage involved
- Discuss model risk explicitly (overfitting, regime change, transaction cost realism)

## Files

| File | Role |
|---|---|
| `README.md` | Project intro |
| `WORKFLOW.md` | Strategy development end-to-end (✅ complete) |
| `INSTALL_CN.md` | Chinese install guide (✅ complete) |
| `api文档/api.txt` | Original 294KB API docs (raw backup) |
| `references/01-14-*.md` | 14 progressive-disclosure category files (✅ all complete) |
| `templates/01-05-*.py` | 5 production templates (✅ complete) |
| `scripts/strategy_lint.py` | Lint tool — black/whitelist hybrid (✅ operational) |
| `scripts/strategy_scaffold.py` | Generate scaffold from description (✅ operational) |
| `scripts/api_search.py` | Search API by keyword (✅ operational) |
| `examples/case-mean-reversion/` | End-to-end case: RSI mean reversion (✅) |
| `examples/case-etf-rotation/` | End-to-end case: ETF monthly rotation (✅) |
| `examples/bad-strategy-for-lint-test.py` | Negative-test sample for lint regression (✅) |
| `factors/` | (v2) Barra-style factor library, 7 categories |
| `factor_lab/` | (v2) Single-factor IC / grouping / decay analysis |
| `research_importer/` | (v2) Brokerage research PDF → JoinQuant code |
| `jqskill_mcp/` | (v2) MCP server exposing all skill capabilities |
| `tests/` | pytest (50+ tests passing after v2) |

This skill is at version **0.5.0** as of 2026-04-19. All 14 references + 5 templates + 3 scripts + 13 tests + WORKFLOW + 2 examples complete.

