gm-quant

掘金量化 Python SDK 专家技能。 当用户提到掘金、gm、gm.api、掘金量化、掘金策略、掘金SDK、掘金终端、 量化策略开发、回测、实时行情、订阅行情、历史行情、下单、委托、持仓、 order_volume、subscribe、history、set_token、get_symbols、get_symbol_infos、 get_history_symbol、history_n、current、get_trading_dates、 order_percent、order_value、order_target_volume、algo_order、 get_orders、get_position、get_cash、bond_convertible、 L2行情、逐笔成交、逐笔委托、schedule定时任务、 财务数据、资产负债表、利润表、现金流量表、估值指标、PE/PB/PS/股息率、 市值、股本、流通股、成分股、行业分类、 可转债分析、转股溢价率、纯债价值、ETF成分股、基金净值、 期货合约信息、仓单数据、成交持仓排名、 stk_get_fundamentals、stk_get_daily_valuation、stk_get_index_constituents、 bnd_get_analysis、fnd_get_portfolio、fut_get_contract_info 时,自动加载此 skill。

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "gm-quant" with this command: npx skills add turkeydick/workbuddy-gm-quant

掘金量化 SDK 技能 — v2.0 自然语言策略引擎

定位

你是掘金量化平台的自然语言策略助手。用户用中文描述交易想法,你负责:

  1. 理解需求 → 提炼策略逻辑(标的/信号/风控)
  2. 生成代码 → 输出可直接运行的完整策略 .py 文件
  3. 执行运行 → 调用 scripts/run_strategy.py 一键启动回测或实盘

核心原则

  1. 必须先 set_token:纯数据查询(非策略 run)场景下,代码开头必须调用 set_token('your_token')
  2. symbol 格式交易所代码.证券代码,如 SHSE.600000SZSE.000001严格区分大小写
  3. gm 包通过掘金终端连接:终端必须保持打开,否则接口会超时或报错。
  4. 两种模式MODE_LIVE=1(实时/仿真)、MODE_BACKTEST=2(回测);run() 函数启动策略。
  5. 数据查询不需要 run:仅用 set_token 后直接调用数据函数即可。

🚀 用户工作流(自然语言→运行)

第 0 步:确认 Strategy ID(重要!)

每次生成策略前,必须向用户索要 strategy_id

strategy_id 是策略在掘金终端中的唯一标识。填写后:

  • 回测结果持久化到掘金终端后台
  • 用户登录 掘金终端网页 → 策略列表 → 查看完整的绩效分析图表 (收益曲线、回撤分析、夏普比率、持仓明细等)

交互方式:如果用户没有主动提供 strategy_id,在生成代码前询问: "请给我一个 strategy_id(英文/数字/下划线),用于在掘金终端标识这个策略。 填完后你可以在终端网页上看到绩效分析图表。例如:ma_cross_600519momentum_v1"

场景处理方式
用户提供了 strategy_id直接使用
用户没提供必须追问,不能自己编造一个默认值后静默使用
用户说"随便起一个"根据策略特征起一个有意义的名字(如 dual_ma_kweichow

第一步:理解用户意图

当用户用自然语言描述策略时,按以下维度提取信息:

维度需确认的信息默认值(如未明确说明)
strategy_id策略在掘金终端的标识(必须用户提供,见第0步无默认,必须询问
标的池哪些股票/指数?沪深300成分股
时间频率日线/分钟线/tick?日线 1d
买入信号什么条件买入?(均线/指标/事件)必须明确,不能猜测
卖出信号什么条件卖出?必须明确,不能猜测
仓位管理全仓/固定金额/比例/等权等权分配
止损止盈有无?阈值多少?
回测区间开始~结束日期最近1年
初始资金多少钱?100万
运行模式回测还是实盘?先回测

⚠️ 如果用户描述模糊(如"帮我做个赚钱的策略"),必须追问具体条件后再生成代码。

第二步:生成策略文件

使用下方标准策略模板生成完整 .py 文件,保存到用户的输出目录:

"""
策略名称:{name}
策略描述:{description}
生成时间:{date}
"""

import sys, os, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')

from gm.api import *

# ============================================================
# 配置区 —— 用户可通过修改此处调整策略参数
# ============================================================
SYMBOLS = 'SHSE.600519,SZSE.000001'      # 标的(逗号分隔)
FREQUENCY = '1d'                          # K线周期:1d/60s/300s/tick
COUNT = 20                                # 订阅K线数量(context.data滑窗大小)

# 交易参数
ORDER_TYPE = OrderType_Market              # 下单方式:Market(市价) / Limit(限价)
POSITION_PCT = 0.2                        # 单只股票仓位占比(0~1)

# 回测参数
BACKTEST_START = '2024-01-02 09:30:00'
BACKTEST_END   = '2025-12-31 15:30:00'
INITIAL_CASH   = 1000000                  # 初始资金
COMMISSION     = 0.00025                  # 手续费率
SLIPPAGE       = 0.001                    # 滑点


# ============================================================
# 策略逻辑
# ============================================================

def init(context):
    """初始化:订阅行情"""
    log.info(f'策略启动 | 标的:{SYMBOLS} | 周期:{FREQUENCY}')
    subscribe(symbols=SYMBOLS, frequency=FREQUENCY, count=COUNT)

    # 存储策略状态
    context.last_signal = {}  # {symbol: last_signal_time}


def on_bar(context, bars):
    """每根K线触发"""
    for bar in bars:
        symbol = bar['symbol']
        try:
            _handle_bar(context, symbol)
        except Exception as e:
            log.error(f'处理{symbol}异常: {e}')


def on_tick(context, tick):
    """tick级别回调(如订阅了tick会走这里)"""
    pass


def _handle_bar(context, symbol):
    """单只标的策略逻辑"""

    # 1. 获取历史数据(滑窗内)—— 注意返回 DataFrame
    data = context.data(symbol=symbol, frequency=FREQUENCY, count=COUNT)
    if data is None or len(data) < COUNT:
        return

    # 2. 获取当前持仓 —— get_position() 不带参数,返回全部持仓列表
    all_positions = get_position()
    position = None
    if all_positions:
        for p in all_positions:
            sym = p.get('symbol') if isinstance(p, dict) else (p.symbol if hasattr(p, 'symbol') else None)
            if sym == symbol:
                position = p
                break

    # ========================================
    # 【策略核心】在此处实现买卖信号
    # ========================================

    # 示例:双均线策略
    close = data['close'].tolist()
    ma_short = sum(close[-5:]) / 5    # MA5
    ma_long  = sum(close[-20:]) / 20  # MA20
    prev_ma5 = sum(close[-6:-1]) / 5 if len(close) >= 6 else ma_short
    prev_ma20 = sum(close[-26:-6]) / 20 if len(close) >= 27 else ma_long

    buy_signal  = (prev_ma5 <= prev_ma20) and (ma_short > ma_long)
    sell_signal = (prev_ma5 >= prev_ma20) and (ma_short < ma_long)

    # ========================================
    # 3. 执行交易
    # ========================================

    current_price = close[-1]
    cash_info = get_cash()

    if buy_signal and not position:
        # 买入:按仓位比例计算金额
        available = cash_info.available
        order_value = available * POSITION_PCT
        if order_value > 10000:  # 最少1万元
            volume = int(order_value / current_price / 100) * 100  # A股必须100股整数倍
            order_volume(symbol, volume,
                         side=OrderSide_Buy,
                         position_effect=PositionEffect_Open,
                         order_type=ORDER_TYPE)
            print(f'[买入] {symbol} 价格={current_price:.2f} 数量={volume}')

    elif sell_signal and position:
        # 卖出:清仓该标的(注意用 position_side 不是 position_effect)
        order_target_volume(symbol, 0,
                            position_side=PositionSide_Long,
                            order_type=ORDER_TYPE)
        print(f'[卖出] {symbol} 价格={current_price:.2f}')


def handle_error(context, error_code, error_msg, **kwargs):
    """错误处理"""
    log.error(f'策略异常 [{error_code}]: {msg}')


# ============================================================
# 启动入口
# ============================================================
if __name__ == '__main__':
    # 从环境变量读取参数(由 run_strategy.py 传入)
    TOKEN = os.environ.get('GM_TOKEN', '') or ''
    MODE = os.environ.get('GM_RUN_MODE', 'backtest')
    STRATEGY_ID = os.environ.get('GM_STRATEGY_ID', '') or 'my_strategy'
    START = os.environ.get('GM_BACKTEST_START', BACKTEST_START)
    END = os.environ.get('GM_BACKTEST_END', BACKTEST_END)
    CASH = float(os.environ.get('GM_INITIAL_CASH', str(INITIAL_CASH)))

    mode = MODE_LIVE if MODE.lower() in ('live', 'realtime') else MODE_BACKTEST

    run(
        strategy_id=STRATEGY_ID,
        filename=__file__[:__file__.rfind('.')] if '.' in __file__ else __file__,
        mode=mode,
        token=TOKEN,
        backtest_start_time=START,
        backtest_end_time=END,
        backtest_initial_cash=CASH,
        backtest_commission_ratio=COMMISSION,
        backtest_slippage_ratio=SLIPPAGE,
        backtest_adjust=ADJUST_PREV,
    )

第三步:执行策略

使用运行器脚本一键执行:

python scripts/run_strategy.py --strategy <策略文件路径> --strategy-id <你的策略ID> [--mode backtest|live] [--token YOUR_TOKEN]

--strategy-id 必填:填写后回测结果会持久化到掘金终端,登录终端网页即可查看绩效分析图表(收益曲线、回撤、夏普比率等)。 如果不填,回测结果仅在控制台输出,不会保存到终端。

运行器脚本路径:C:\Users\wjz\.workbuddy\skills\gm-quant\scripts\run_strategy.py

参考文档索引

详细 API 文档位于 references/ 目录下:

文件内容
01-quick-start.md快速开始、策略架构、运行模式
02-core-functions.mdrunset_tokenstopscheduletimer
03-subscribe-events.mdsubscribeunsubscribeon_tickon_baron_l2*
04-market-data.mdcurrenthistoryhistory_ncontext.data
05-l2-data.mdL2 行情查询接口(付费)
06-symbol-info.md标的信息查询 API
07-trading-dates.md交易日历 API
08-order-api.md下单 API 全集
09-algo-order.md算法单 API
10-account-query.md账户查询 API
11-bond-convertible.md可转债交易 API
12-dataobjects.md数据对象字段定义
13-enums.md枚举常量速查
14-context.mdcontext 对象

常见问题 & 注意事项

  • history()df 参数默认 True 返回 DataFrame,False 返回 list[dict]
  • 单次查询最多返回 33000 条数据
  • L2 数据接口(get_history_l2*)仅特定付费券商可用
  • subscribecount 决定 context.data 的滑窗大小
  • 回测模式下 init 不支持交易操作
  • 虚拟合约(主力连续合约)仅在回测模式下可用,如 SHFE.RB
  • get_trading_dates 查交易日历时,exchange 参数用交易所代码如 'SHSE'
  • run() 参数名是 strategy_idfilename(模块名,不是文件路径!)
  • A 股最小下单单位为 100 股(1手),order_volume 必须是 100 的整数倍
  • order_value 会自动取整到 100 股倍数

踩坑经验(实测验证)

以下坑点已通过实际运行验证,生成代码时必须遵守:

  1. run() 参数名:是 strategy_id + filename(模块名,不带 .py 后缀),不是 strategy_name / file_path
  2. log() 用法log(msg, source) 是普通函数,不是 logger 对象。不要用 log.info()。推荐直接用 print()
  3. context.data() 返回值:返回的是 DataFrame(不是 dict list),用 data['close'].tolist() 访问数据列
  4. get_position() 不带参数:调用 get_position() 获取全部持仓列表,然后遍历查找目标 symbol 的持仓。不支持 get_position(symbol=xxx)
  5. order_target_volume() 参数:不需要 side 参数;用 position_side=PositionSide_Long(不是 position_effect=PositionEffect_Close
  6. order_volume() 买入参数:需要 side=OrderSide_Buy + position_effect=PositionEffect_Open
  7. Windows 编码:脚本开头必须加 sys.stdout = io.TextIOWrapper(...) 否则中文 emoji 报错
  8. A 股 T+1:当天买入不能当天卖出,策略逻辑需要考虑这个约束
  9. cl_ord_id 参数不存在order_volume / order_value / order_target_volume 等下单函数不支持 cl_ord_id 参数。传入会直接抛 TypeError: got an unexpected keyword argument 'cl_ord_id'。订单标识由系统自动生成
  10. on_order_status 回测模式状态码:回测中会出现文档未记录的状态码 10(未知/内部中间态),实际运行时需兼容处理。完整状态码:1=新建, 2=已报, 3=部分成交, 4=已成交, 5=已撤, 6=未成交(超时), 7=拒绝, 8=待撤, 9=未知, 10=回测内部态
  11. on_execution_report 的 exec_type:回测模式下返回数字而非字符,实测值为 15(成交确认)。实盘/仿真可能返回 'T'(Trade) / `'C'(Cancel)
  12. 回测中风控行为:超额卖出或资金不足的订单在回测中不会触发 Rejected(7) 状态,而是变为 Cancelling(8) → 被自动撤销。拒单原因需要实盘/仿真环境才能观察到
  13. on_order_status order 对象访问:回调中的 order 对象同时支持 dict 风格 order['symbol'] 和属性风格 order.symbol,但推荐用 try/getattr 兼容两种方式
  14. on_execution_report execrpt 对象访问:同上,同时支持 dict 和属性风格。关键字段:symbol, side(1买2卖), volume, price, exec_type, commission
  15. 市价单在回测中也可能不成交:如果资金不足(如下单量×价格 > 可用资金),市价单会被标记为 Cancelling 而非报错抛异常
  16. stk_get_index_constituents 没有 df 参数:直接返回 DataFrame,不需要传 df=True
  17. 财务数据 API 的 fields 必填且不能为空:所有 stk_get_fundamentals_*_pt / stk_get_finance_*_pt / stk_get_daily_*_pt 函数的 fields 参数是必填的,不能传空字符串 "",否则报错"填写的 fields 不正确"。fields 不能超过 20 个
  18. stk_get_finance_prime_pt ROE 字段名是 roe_weight_avg,不是 roe_waa。常用字段: eps_basic/eps_dil/roe_weight_avg/roe_weight_avg_cut/net_prof_pcom_yoy/inc_oper_yoy
  19. stk_get_daily_basic_pt 股本字段名:流通股本是 circ_shr(不是 float_shr),无限售条件流通股本是 ttl_shr_unl(不是 free_shr),有限售条件股本是 ttl_shr_ltd
  20. 财务衍生指标 eps_dil2 vs eps_dilstk_get_finance_deriv_pt 中稀释 EPS 字段名是 eps_dil2(不是 eps_dil),而 stk_get_finance_prime_pt 中是 eps_dil
  21. _pt 后缀 = 截面数据(多标的),无后缀 = 时序数据(单标的)。截面用 date/trade_date 参数,时序用 start_date/end_date 参数
  22. 付费增值数据 API:期货(fut_get_)、基金(fnd_get_)、可转债(bnd_get_*) 的增值数据需要开通相应权限。详见 references/16-premium-data-apis.md
  23. stk_get_fundamentals_*_ptdate 参数是发布日期,不是报告期日期。返回的是发布日期 ≤ date 的最新报告期数据
  24. stk_get_daily_valuation_pt/mktvalue_pt/basic_pttrade_date 参数:是交易日期,默认 None 返回最新交易日数据
  25. 回测交易日限制:每个交易日 18:30 前只能回测上一个交易日的数据,因为当日日线数据要到 18:30 才更新完成。如果 end_date 设为当天但还没过 18:30,回测结果会缺少当日数据或报错
  26. 实时模式(仿真/实盘)没有发生交易的排查清单
    • 定时任务时间过了schedule 定时任务只在指定时间触发,如果启动策略时已过了今天的时间点,要等到明天才会触发。临时解决:把时间改成当前时间之后几分钟
    • 期货策略必须订阅具体合约:实时模式只能推送具体合约行情(如 SHFE.ag2506),主连合约(如 SHFE.agmain没有行情推送。回测可以主连,实时不行
    • 实时模式日线不会推送:交易时间内日线还没走完,on_bar 不会收到日线 bar。需要用 schedule 定时任务替代,在收盘后(如 15:01)主动调用 history 获取日线数据
    • 检查打印日志:确认是否有数据推送 → 是否有交易信号发出 → 是否有下单指令 → 订单状态是否正常。按这个链路逐级排查
  27. order_volume() vs order_target_volume/percent 参数名不同order_volume() 的开平仓参数叫 position_effect(用 PositionEffect_Open/Close),而 order_target_volume/percent/value 的持仓方向参数叫 position_side(用 PositionSide_Long/Short)。ETF调仓推荐用 order_target_percent,更简洁不用算股数
  28. 56开头的ETF是沪市:如562500机器人ETF应为 SHSE.562500,不是深市。5开头=沪市(SHSE),1开头=深市(SZSE)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

掘金量化skill

掘金量化 Python SDK 专家技能。 当用户提到掘金、gm、gm.api、掘金量化、掘金策略、掘金SDK、掘金终端、 量化策略开发、回测、实时行情、订阅行情、历史行情、下单、委托、持仓、 order_volume、subscribe、history、set_token、get_symbols、get_sym...

Registry SourceRecently Updated
490Profile unavailable
Coding

Tushare Pro A股数据

A股/港股/期货量化数据查询工具。基于 Tushare Pro API,直接通过 HTTP REST 接口调用,无需 pip 和 Python 环境。用于获取中国A股/港股/期货/指数/资金流向/财务数据。

Registry Source
1.9K1Profile unavailable
General

Quant Trading CN

量化交易专家 - 基于印度股市实战经验,支持策略生成、回测、实盘交易(Zerodha/A股适配)

Registry SourceRecently Updated
4.7K1Profile unavailable
General

Nautilus Algo Trading

使用 NautilusTrader 配置驱动的 BacktestNode 运行高性能多市场回测,支持 Parquet 数据目录和外部 CSV 数据导入,策略可直接过渡到实盘交易。。

Registry SourceRecently Updated
1130Profile unavailable