SuperAPI AI Directory

joinquant-docs

Data & analytics

View repository

Updated 10-15 23:42

About this skill

JoinQuant strategy development

Based on the offline documentation in this directory, write Python strategies for the JoinQuant official website (backtesting / simulation / research). When answering API questionsyou must first consult the local documentation, and must not fabricate function signatures or parameters from memory.

Differences from jqdatasdk:jqdata Used in the official website strategy environment;jqdatasdk is a local Python library, with slightly different APIs, and cannot be used in official website backtesting/simulation/research.

Documentation consultation process

  1. Determine the question type, and locate files according to reference.md locate files
  2. Use Grep/Read to search forthe target function name or Chinese keyword (e.g., get_price、order_target、市盈率)
  3. cross-validation: for API behavior consult api.md, for fields/table structures consult data/*.md, for pitfalls consult faq.md
  4. When giving an answercite the calling methods, parameters, return values, and example code from the documentation
需要写策略框架?     → api.md「开始写策略」「策略程序架构」
需要查数据 API?      → api.md「数据获取函数」+ data/ 对应品种文档
需要下单/持仓?      → api.md「交易函数」「对象」
需要财务/估值数据?  → data/Stock.md(run_query + valuation/fundamentals 表)
需要行业/概念选股?  → data/plateData.md + api.md get_industry_stocks 等
需要技术指标?       → data/technicalanalysis.md(from jqlib.technical_analysis import *)
需要 Alpha 因子?    → data/Alpha101.md、data/Alpha191.md
需要自定义因子?     → fator.md(jqfactor.Factor、calc_factors)
需要因子看板数据?   → data/factor_values.md

Strategy skeleton

Minimal runnable structure:

# 导入聚宽函数库
import jqdata

def initialize(context):
    g.security = '000001.XSHE'
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)  # 开启动态复权(真实价格),建议开启
    run_daily(trade, time='open')       # 或 time='every_bar' / '9:30'

def trade(context):
    security = g.security
    close_data = attribute_history(security, 5, '1d', ['close'])
    MA5 = close_data['close'].mean()
    current_price = close_data['close'][-1]
    cash = context.portfolio.available_cash

    if current_price > 1.01 * MA5:
        order_value(security, cash)
    elif current_price < MA5 and context.portfolio.positions[security].closeable_amount > 0:
        order_target(security, 0)

Lifecycle functions

Function Description
initialize(context) Global initialization, runs only once; use g to store global variables
run_daily/weekly/monthly(func, ...) Scheduled tasks;func func must bea global function, and cannot be a class method
handle_data(context, data) Driven by the backtest frequency;not recommended to be mixed with run_daily
before_trading_start Before market open (9:00)
after_trading_end After market close (15:30)

APIs marked with ♠ are supported only inbacktest/simulation, and cannot be called in the research module.jqdata The module can be used in both the research and backtest environments.

Security code specifications

Market Suffix Example
Shanghai Stock Exchange .XSHG 600519.XSHG
Shenzhen Stock Exchange .XSHE 000001.XSHE
China Financial Futures Exchange .CCFX IC9999.CCFX
Dalian Commodity Exchange .XDCE A9999.XDCE
Shanghai Futures Exchange .XSGE AU9999.XSGE
Zhengzhou Commodity Exchange .XZCE CY8888.XZCE
OTC funds .OF 519671.OF

For futures strategies, set run_daily 's reference_security to the corresponding main contract (e.g., IF9999.CCFX), to match the night session opening time.

Common API quick reference

Market quotes and history

get_price(security, start_date, end_date, frequency='daily', fields=None, fq='pre')
attribute_history(security, count, unit, fields)  # 回测环境,不含当天
history(count, unit, field, security_list, df=True)
get_bars(security, count, unit, fields, include_now=True)

Universe and sectors

get_all_securities(types=['stock'], date=None)   # date 防未来函数
get_index_stocks('000300.XSHG', date=None)
get_industry_stocks('C15', date=None)
get_concept_stocks('GN036', date=None)
set_universe([...])  # 设置后 history 可不传 security_list

Financial data (SQL query)

from jqdata import *
q = query(valuation).filter(valuation.code == '000001.XSHE')
df = get_fundamentals(q, date='2015-10-15')

# 或 run_query(单次最多 4000 行,不可连表)
df = finance.run_query(query(finance.STK_XXX).filter(...).limit(4000))

Trading

order(security, amount)              # 按股数,正买负卖
order_value(security, value)       # 按金额
order_target(security, amount)       # 调到目标股数
order_target_value(security, value)  # 调到目标市值
order_target_percent(security, percent)  # 调到目标仓位比例

The buy quantity for A-shares must be an integer multiple of 100 (200 minimum for STAR Market); when selling all positions there is no limit. A maximum of 10,000 orders per day.

Technical indicators

from jqlib.technical_analysis import *
# check_date 策略中建议用 context.current_dt,避免盘中取当日收盘指标产生未来数据
result = MACD(security_list, check_date=context.current_dt, SHORT=12, LONG=26, MID=9)

Custom factors

from jqfactor import Factor, calc_factors

class MyFactor(Factor):
    name = 'my_factor'
    max_window = 5
    dependencies = ['close']
    def calc(self, data):
        return data['close'].mean()

factors = calc_factors(securities, [MyFactor()], start_date, end_date)

See fator.md and data/Alpha101.md、data/Alpha191.md。

Key precautions

Prevent look-ahead bias

  • get_all_securities(date=...)、get_index_stocks(..., date=...) etc. must be passedthe historical point-in-time's date, and future dates cannot be used
  • history / attribute_history When fetching daily data withdoes not include the current day; to get the current day's data you need to fetch minute-level data
  • Technical indicator check_date Returns the closing value only when precise to the date; calling intraday on the current day will produce future data
  • Financial data is processed by announcement date by default; note get_fundamentals of date parameter meaning

Run frequency

  • Prefer to use run_daily, avoid mixing with handle_data mixed use
  • run_daily(func, time='every_bar') frequency is consistent with the backtest settings
  • run_weekly/monthly of force=False can avoid nearest execution when registered late

Data query limits

  • run_query / get_fundamentals returns at most 4000 rows
  • run_query Join queries are not supported
  • Default market data isforward-adjusted;fq=None is unadjusted

Environment and product distinction

Product Use case
jqdata(official website) Backtest, simulation, research
jqdatasdk(local) Local quantitative research,cannotbe imported in official website strategies

Choose documentation by scenario

Scenario Read first Further reference
Beginners writing their first strategy api.md"Start Writing Strategies" api.md"Strategy Program Architecture"
Stock selection + financials data/Stock.md api.md get_fundamentals
Index constituent stock strategies data/index.md api.md get_index_stocks
Industry/concept rotation data/plateData.md api.md get_industry_stocks
Futures strategies data/Future.md api.md"Futures Strategy Dedicated Functions"
Options strategies data/Option.md api.md options-related
Funds/ETFs data/fund.md data/OTCfund.md
Convertible bonds data/bond.md —
Macro data data/macroData.md —
Technical analysis indicators data/technicalanalysis.md —
Factor stock selection fator.md + data/factor_values.md data/Alpha101.md
Margin trading and securities lending data/Stock.md margin trading and securities lending chapter api.md margin trading and securities lending dedicated functions
Errors/data questions faq.md api.md"Notes"

Strategy examples

For complete examples, see api.md "Strategy Examples" at the end: moving average strategy, multi-stock positions, chasing rallies strategy, Halloween effect, etc.

Documentation updates

The local data dictionary is synchronized from the official website by script:

bun scripts/get-joinquant-docs.ts
# 强制覆盖已有 md:FORCE_UPDATE=1 bun scripts/get-joinquant-docs.ts

Additional resources