Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

QMT

QMT迅投量化交易终端 - 内置Python策略开发、回测引擎和实盘交易,支持中国证券市场全品种。

MIT-0 · Free to use, modify, and redistribute. No attribution required.
2 · 206 · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The name/description and SKILL.md consistently describe a QMT/xtquant trading terminal and Python strategy examples; requiring python3 and the xtquant/numpy packages matches the documented miniQMT usage. However, there are metadata mismatches (registry shows version 1.0.2 while files declare 1.2.0; different ownerId values appear in registry vs _meta.json) and the skill claims QMT runs only on Windows while the declared required binary is 'python3' (on Windows the interpreter is often 'python'), and no OS restriction is declared. These inconsistencies are unexplained and should be verified with the publisher.
Instruction Scope
SKILL.md contains examples and instructions that stay within the stated purpose (writing strategies, fetching market data, placing orders). It does not instruct the agent to read arbitrary system files or to exfiltrate environment variables or credentials. Example code references local QMT installation paths and account IDs (which are normal for trading), but the document does not autonomously request or require user secrets.
Install Mechanism
This is an instruction-only skill (no install spec), which is lower risk. However, requirements.txt and README recommend pip installing xtquant/numpy for miniQMT usage, yet there is no automated install or guidance integrated into the skill runtime. The absence of an install spec means dependencies won't be installed by the platform automatically; the user/agent would have to install xtquant from PyPI or another source. Confirming the provenance of the xtquant package and its release source is recommended.
Credentials
The skill does not request any environment variables, credentials, or config paths. The examples reference broker account IDs and local installation paths (expected for a trading integration) but do not require injecting secrets into the skill manifest. This is proportionate to the stated trading purpose.
Persistence & Privilege
always is false and model invocation is allowed (the platform default). The skill does not request elevated persistence or access to other skills' configs. There is no evidence it would automatically enable itself or demand permanent inclusion.
What to consider before installing
This skill appears to be a documentation/instruction bundle for QMT/xtquant trading, not a binary installer. Before installing or using it: (1) Verify the publisher and source — metadata files show inconsistent owner/version information and the repository/source is unknown. (2) Confirm you intend to run real trading code: examples include functions that place orders and query live accounts — make sure you have broker permissions and test in a sandbox before connecting live accounts. (3) The skill references Windows-only QMT but requires 'python3' — ensure your environment (Windows vs Linux/macOS) and interpreter naming match or use miniQMT mode as documented. (4) If you plan to use miniQMT, explicitly review and install the xtquant package from a trusted source (PyPI or vendor site) and inspect that package for network endpoints or unexpected behavior. (5) Do not provide broker credentials or private keys to the skill unless you fully trust the source and have verified the package provenance. If you need higher assurance, ask the publisher for a canonical release URL, signed artifacts, or an official vendor statement aligning versions/owner info.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.2
Download zip
backtestvk9773tzef69fpvjvg3rvergfah82ptfechinavk9773tzef69fpvjvg3rvergfah82ptfefuturesvk9773tzef69fpvjvg3rvergfah82ptfelatestvk970wf90jt0p981p8p5shkg8jh831xm8optionsvk9773tzef69fpvjvg3rvergfah82ptfequantitativevk9773tzef69fpvjvg3rvergfah82ptfestockvk9773tzef69fpvjvg3rvergfah82ptfestrategyvk9773tzef69fpvjvg3rvergfah82ptfetradingvk9773tzef69fpvjvg3rvergfah82ptfe

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

🖥️ Clawdis
Binspython3

SKILL.md

QMT(迅投量化交易终端)

QMT(Quant Market Trading)是迅投科技开发的专业量化交易平台。提供完整的桌面客户端,内置Python策略开发、回测引擎和实盘交易功能,支持中国证券市场全品种。

⚠️ 需要通过券商开通QMT权限。QMT仅在Windows上运行。可通过国金、华鑫、中泰、东方财富等券商获取。

两种运行模式

模式说明
QMT(完整版)完整桌面GUI,内置Python编辑器、图表和回测引擎
miniQMT极简模式 — 通过外部Python使用xtquant SDK(参见 miniqmt skill)

内置Python策略框架

QMT提供事件驱动策略框架,内置Python运行时(类似聚宽/米筐)。

策略生命周期

def init(ContextInfo):
    """初始化函数 - 策略启动时调用一次,用于设置股票池和参数"""
    ContextInfo.set_universe(['000001.SZ', '600519.SH'])

def handlebar(ContextInfo):
    """K线处理函数 - 每根K线触发一次(tick/1m/5m/1d等),在此编写交易逻辑"""
    close = ContextInfo.get_market_data(['close'], stock_code='000001.SZ', period='1d', count=20)
    # 在此编写交易逻辑

def stop(ContextInfo):
    """停止函数 - 策略停止时调用"""
    pass

获取行情数据(内置)

def handlebar(ContextInfo):
    # 获取最近20根K线的收盘价
    data = ContextInfo.get_market_data(
        ['open', 'high', 'low', 'close', 'volume'],
        stock_code='000001.SZ',
        period='1d',
        count=20
    )

    # 获取历史数据
    history = ContextInfo.get_history_data(
        20, '1d', 'close', stock_code='000001.SZ'
    )

    # 获取板块股票列表
    stocks = ContextInfo.get_stock_list_in_sector('沪深A股')

    # 获取财务数据
    fin = ContextInfo.get_financial_data('000001.SZ')

下单(内置)

def handlebar(ContextInfo):
    # 限价买入100股,价格11.50
    order_shares('000001.SZ', 100, 'fix', 11.50, ContextInfo)

    # 限价卖出100股,价格12.00
    order_shares('000001.SZ', -100, 'fix', 12.00, ContextInfo)

    # 按目标金额买入(10万元)
    order_target_value('000001.SZ', 100000, 'fix', 11.50, ContextInfo)

    # 撤单
    cancel('order_id', ContextInfo)

查询持仓与账户

def handlebar(ContextInfo):
    # 获取持仓信息
    positions = get_trade_detail_data('your_account', 'stock', 'position')
    for pos in positions:
        print(pos.m_strInstrumentID, pos.m_nVolume, pos.m_dMarketValue)

    # 获取委托信息
    orders = get_trade_detail_data('your_account', 'stock', 'order')

    # 获取账户资产信息
    account = get_trade_detail_data('your_account', 'stock', 'account')

回测

QMT内置回测引擎:

  1. 在内置Python编辑器中编写策略
  2. 设置回测参数(日期范围、初始资金、手续费、滑点)
  3. 点击"运行回测"
  4. 查看结果:资金曲线、最大回撤、夏普比率、交易记录

回测参数设置

def init(ContextInfo):
    ContextInfo.capital = 1000000          # 初始资金
    ContextInfo.set_commission(0.0003)     # 手续费率
    ContextInfo.set_slippage(0.01)         # 滑点
    ContextInfo.set_benchmark('000300.SH') # 基准指数

完整示例:双均线策略

import numpy as np

def init(ContextInfo):
    ContextInfo.stock = '000001.SZ'
    ContextInfo.set_universe([ContextInfo.stock])
    ContextInfo.fast = 5    # 快速均线周期
    ContextInfo.slow = 20   # 慢速均线周期

def handlebar(ContextInfo):
    stock = ContextInfo.stock
    # 获取最近slow+1根K线的收盘价
    closes = ContextInfo.get_history_data(ContextInfo.slow + 1, '1d', 'close', stock_code=stock)

    if len(closes) < ContextInfo.slow:
        return  # 数据不足,跳过

    # 计算当前和前一根K线的快慢均线值
    ma_fast = np.mean(closes[-ContextInfo.fast:])
    ma_slow = np.mean(closes[-ContextInfo.slow:])
    prev_fast = np.mean(closes[-ContextInfo.fast-1:-1])
    prev_slow = np.mean(closes[-ContextInfo.slow-1:-1])

    # 查询当前持仓
    positions = get_trade_detail_data(ContextInfo.accID, 'stock', 'position')
    holding = any(p.m_strInstrumentID == stock and p.m_nVolume > 0 for p in positions)

    # 金叉信号:快速均线上穿慢速均线,买入
    if prev_fast <= prev_slow and ma_fast > ma_slow and not holding:
        order_shares(stock, 1000, 'fix', closes[-1], ContextInfo)

    # 死叉信号:快速均线下穿慢速均线,卖出
    elif prev_fast >= prev_slow and ma_fast < ma_slow and holding:
        order_shares(stock, -1000, 'fix', closes[-1], ContextInfo)

数据覆盖范围

类别内容
股票A股(沪、深、北交所)、港股通
指数所有主要指数
期货中金所、上期所、大商所、郑商所、能源中心、广期所
期权ETF期权、股票期权、商品期权
ETF所有交易所交易基金
债券可转债、国债
周期Tick、1分钟、5分钟、15分钟、30分钟、1小时、日、周、月
Level 2逐笔委托、逐笔成交(取决于券商权限)
财务资产负债表、利润表、现金流量表、关键指标

QMT vs miniQMT vs Ptrade 对比

特性QMTminiQMTPtrade
厂商迅投科技迅投科技恒生电子
Python内置(版本受限)外部(任意版本)内置(版本受限)
界面完整GUI极简完整(网页端)
回测内置需自行实现内置
部署本地本地券商服务器(云端)
外网访问支持支持不支持(仅内网)

使用技巧

  • QMT仅在Windows上运行。
  • 内置Python版本由QMT固定,无法安装任意pip包。
  • 如需不受限的Python环境,使用miniQMT模式配合xtquant SDK。
  • 策略文件存储在QMT安装目录中。
  • 文档:http://dict.thinktrader.net/freshman/rookie.html
  • 也支持VBA接口用于Excel集成。

进阶示例

多股票轮动策略

import numpy as np

def init(ContextInfo):
    # 设置股票池:银行龙头股
    ContextInfo.stock_pool = ['601398.SH', '601939.SH', '601288.SH', '600036.SH', '601166.SH']
    ContextInfo.set_universe(ContextInfo.stock_pool)
    ContextInfo.hold_num = 2  # 最多持有2只股票

def handlebar(ContextInfo):
    # 计算每只股票的20日收益率
    momentum = {}
    for stock in ContextInfo.stock_pool:
        closes = ContextInfo.get_history_data(21, '1d', 'close', stock_code=stock)
        if len(closes) >= 21:
            ret = (closes[-1] - closes[0]) / closes[0]  # 20日收益率
            momentum[stock] = ret

    # 按动量排序,选择前N只股票
    sorted_stocks = sorted(momentum.items(), key=lambda x: x[1], reverse=True)
    target_stocks = [s[0] for s in sorted_stocks[:ContextInfo.hold_num]]

    # 获取当前持仓
    positions = get_trade_detail_data(ContextInfo.accID, 'stock', 'position')
    holding = {p.m_strInstrumentID: p.m_nVolume for p in positions if p.m_nVolume > 0}

    # 卖出不在目标列表中的股票
    for stock, vol in holding.items():
        if stock not in target_stocks:
            closes = ContextInfo.get_history_data(1, '1d', 'close', stock_code=stock)
            if len(closes) > 0:
                order_shares(stock, -vol, 'fix', closes[-1], ContextInfo)

    # 买入目标股票
    account = get_trade_detail_data(ContextInfo.accID, 'stock', 'account')
    if account:
        cash = account[0].m_dAvailable
        per_stock_cash = cash / ContextInfo.hold_num  # 等权分配
        for stock in target_stocks:
            if stock not in holding:
                closes = ContextInfo.get_history_data(1, '1d', 'close', stock_code=stock)
                if len(closes) > 0 and closes[-1] > 0:
                    vol = int(per_stock_cash / closes[-1] / 100) * 100  # 向下取整到整手
                    if vol >= 100:
                        order_shares(stock, vol, 'fix', closes[-1], ContextInfo)

RSI策略

import numpy as np

def init(ContextInfo):
    ContextInfo.stock = '000001.SZ'
    ContextInfo.set_universe([ContextInfo.stock])
    ContextInfo.rsi_period = 14     # RSI周期
    ContextInfo.oversold = 30       # 超卖阈值
    ContextInfo.overbought = 70     # 超买阈值

def handlebar(ContextInfo):
    stock = ContextInfo.stock
    closes = ContextInfo.get_history_data(ContextInfo.rsi_period + 2, '1d', 'close', stock_code=stock)

    if len(closes) < ContextInfo.rsi_period + 1:
        return

    # 计算RSI
    deltas = np.diff(closes)
    gains = np.where(deltas > 0, deltas, 0)
    losses = np.where(deltas < 0, -deltas, 0)
    avg_gain = np.mean(gains[-ContextInfo.rsi_period:])
    avg_loss = np.mean(losses[-ContextInfo.rsi_period:])

    if avg_loss == 0:
        rsi = 100
    else:
        rs = avg_gain / avg_loss
        rsi = 100 - (100 / (1 + rs))

    # 查询持仓
    positions = get_trade_detail_data(ContextInfo.accID, 'stock', 'position')
    holding = any(p.m_strInstrumentID == stock and p.m_nVolume > 0 for p in positions)

    # RSI超卖 — 买入
    if rsi < ContextInfo.oversold and not holding:
        order_shares(stock, 1000, 'fix', closes[-1], ContextInfo)

    # RSI超买 — 卖出
    elif rsi > ContextInfo.overbought and holding:
        order_shares(stock, -1000, 'fix', closes[-1], ContextInfo)

布林带策略

import numpy as np

def init(ContextInfo):
    ContextInfo.stock = '600519.SH'
    ContextInfo.set_universe([ContextInfo.stock])
    ContextInfo.boll_period = 20    # 布林带周期
    ContextInfo.boll_std = 2        # 标准差倍数

def handlebar(ContextInfo):
    stock = ContextInfo.stock
    closes = ContextInfo.get_history_data(ContextInfo.boll_period + 1, '1d', 'close', stock_code=stock)

    if len(closes) < ContextInfo.boll_period:
        return

    # 计算布林带
    recent = closes[-ContextInfo.boll_period:]
    mid = np.mean(recent)                          # 中轨
    std = np.std(recent)                           # 标准差
    upper = mid + ContextInfo.boll_std * std       # 上轨
    lower = mid - ContextInfo.boll_std * std       # 下轨
    price = closes[-1]                             # 当前价格

    positions = get_trade_detail_data(ContextInfo.accID, 'stock', 'position')
    holding = any(p.m_strInstrumentID == stock and p.m_nVolume > 0 for p in positions)

    # 价格触及下轨 — 买入
    if price <= lower and not holding:
        order_shares(stock, 1000, 'fix', price, ContextInfo)

    # 价格触及上轨 — 卖出
    elif price >= upper and holding:
        order_shares(stock, -1000, 'fix', price, ContextInfo)

定时任务

def init(ContextInfo):
    ContextInfo.stock = '000001.SZ'
    ContextInfo.set_universe([ContextInfo.stock])

def handlebar(ContextInfo):
    import datetime
    now = ContextInfo.get_bar_timetag(ContextInfo.barpos)
    dt = datetime.datetime.fromtimestamp(now / 1000)
    # 仅在每変14:50执行调仓逻辑
    if dt.hour == 14 and dt.minute == 50:
        pass  # 执行调仓

常见错误处理

错误原因解决方法
账户未登录QMT未连接券商检查QMT登录状态,确认券商账户已连接
委托失败资金不足或超出涨跌停检查可用资金和委托价格
数据为空股票代码错误或停牌校验代码格式(如000001.SZ),检查是否停牌
Python版本不兼容内置Python版本受限改用miniQMT模式
策略运行缓慢数据量过大减少get_history_data的count参数

内置函数参考

行情数据函数

函数说明返回值
ContextInfo.get_market_data(fields, stock_code, period, count)获取K线数据dict/DataFrame
ContextInfo.get_history_data(count, period, field, stock_code)获取历史数据序列list
ContextInfo.get_stock_list_in_sector(sector)获取板块成分股list
ContextInfo.get_financial_data(stock_code)获取财务数据dict
ContextInfo.get_instrument_detail(stock_code)获取合约详情dict
ContextInfo.get_full_tick(stock_list)获取全推行情快照dict

交易函数

函数说明
order_shares(code, volume, style, price, ContextInfo)按股数下单(正买负卖)
order_target_value(code, value, style, price, ContextInfo)按目标市值下单
order_lots(code, lots, style, price, ContextInfo)按手数下单
order_percent(code, percent, style, price, ContextInfo)按组合比例下单
cancel(order_id, ContextInfo)撤单
get_trade_detail_data(account, market, data_type)查询交易数据

交易数据类型

data_type说明常用字段
'position'持仓m_strInstrumentID(代码), m_nVolume(数量), m_dMarketValue(市值)
'order'委托m_strOrderSysID(委托号), m_nVolumeTraded(成交量), m_dLimitPrice(委托价)
'deal'成交m_strTradeID(成交号), m_dPrice(成交价), m_nVolume(成交量)
'account'账户m_dAvailable(可用资金), m_dBalance(总资产), m_dMarketValue(持仓市值)

进阶示例:MACD策略

import numpy as np

def init(ContextInfo):
    ContextInfo.stock = '600519.SH'
    ContextInfo.set_universe([ContextInfo.stock])

def handlebar(ContextInfo):
    stock = ContextInfo.stock
    closes = ContextInfo.get_history_data(60, '1d', 'close', stock_code=stock)
    if len(closes) < 35:
        return
    closes = np.array(closes, dtype=float)

    def ema(data, period):
        result = np.zeros_like(data)
        result[0] = data[0]
        k = 2 / (period + 1)
        for i in range(1, len(data)):
            result[i] = data[i] * k + result[i-1] * (1 - k)
        return result

    ema12 = ema(closes, 12)
    ema26 = ema(closes, 26)
    dif = ema12 - ema26
    dea = ema(dif, 9)

    positions = get_trade_detail_data(ContextInfo.accID, 'stock', 'position')
    holding = any(p.m_strInstrumentID == stock and p.m_nVolume > 0 for p in positions)

    # 金叉:DIF上穿DEA
    if dif[-2] <= dea[-2] and dif[-1] > dea[-1] and not holding:
        order_shares(stock, 1000, 'fix', closes[-1], ContextInfo)
    # 死叉:DIF下穿DEA
    elif dif[-2] >= dea[-2] and dif[-1] < dea[-1] and holding:
        order_shares(stock, -1000, 'fix', closes[-1], ContextInfo)

进阶示例:止盈止损策略

import numpy as np

def init(ContextInfo):
    ContextInfo.stock = '000001.SZ'
    ContextInfo.set_universe([ContextInfo.stock])
    ContextInfo.entry_price = 0
    ContextInfo.stop_loss = 0.05      # 止损5%
    ContextInfo.take_profit = 0.10    # 止盈10%

def handlebar(ContextInfo):
    stock = ContextInfo.stock
    closes = ContextInfo.get_history_data(21, '1d', 'close', stock_code=stock)
    if len(closes) < 21:
        return
    price = closes[-1]
    ma20 = np.mean(closes[-20:])

    positions = get_trade_detail_data(ContextInfo.accID, 'stock', 'position')
    pos = None
    for p in positions:
        if p.m_strInstrumentID == stock and p.m_nVolume > 0:
            pos = p
            break

    if pos is None:
        if price > ma20:
            order_shares(stock, 1000, 'fix', price, ContextInfo)
            ContextInfo.entry_price = price
    else:
        if ContextInfo.entry_price > 0:
            pnl = (price - ContextInfo.entry_price) / ContextInfo.entry_price
            if pnl <= -ContextInfo.stop_loss:
                order_shares(stock, -pos.m_nVolume, 'fix', price, ContextInfo)
                ContextInfo.entry_price = 0
            elif pnl >= ContextInfo.take_profit:
                order_shares(stock, -pos.m_nVolume, 'fix', price, ContextInfo)
                ContextInfo.entry_price = 0

社区与支持

大佬量化 (BossQuant) 维护 — 量化交易教学与策略研发团队。

微信客服: bossquant1 · Bilibili · 搜索 大佬量化 — 微信公众号 / Bilibili / 抖音

Files

8 total
Select a file
Select a file to preview.

Comments

Loading comments…