QuantSonar 品牌横幅

过去做一个量化策略原型,学习路线往往是这样的:先学 Python,再学 Pandas,接着找数据、清洗字段、处理交易日,最后才能开始写策略。

真正让很多人停下来的,并不是没有交易想法,而是不知道如何把一句自然语言想法准确地翻译成数据请求和可运行代码。

大语言模型降低了写代码的门槛,但它仍然需要可靠的数据。模型可以生成语法,却无法凭空知道某个数据接口的最新参数,更不能替你保证行情、财务和资金数据真实存在。

这正是 MCP 适合量化研究的地方:把数据工具直接接给 AI,让它先查询真实数据,再基于返回结果生成分析或代码。

本文用 QuantSonar 演示一个完整流程:连接远程 MCP,用一句话描述 RSI 均值回归思路,再用 Python SDK 跑出一条可复现的策略净值曲线。

说明:本文仅演示数据处理和策略研究流程,不构成投资建议。示例参数未经收益优化,也没有考虑所有实盘约束。

先用一条命令安装 QuantSonar Skill(可选)

如果你的电脑已经安装 Node.js,可以直接复制下面这条命令。CSDN 代码块右上角自带复制按钮:

npx --yes skills add QuantSonar/quantsonar-skills --skill quantsonar --global --yes

这条命令会从 GitHub 获取公开的 quantsonar Skill,并安装到当前机器检测到的 Agent 环境。Skill 安装完成后,数据查询仍需要 QuantSonar API Key。

如果希望让 Agent 自动检查 Node.js、Git、网络连通性,再完成 Skill 安装、数据接入和真实查询验证,可以打开下面的网页,点击“复制完整安装指令”,然后粘贴给 Agent:

一键复制 QuantSonar 完整安装指南

也可以直接把原始 Markdown 地址发给 Agent:

https://quantsonar.com/install.md

第一步:准备 QuantSonar API Key

QuantSonar 聚焦中国 A 股市场数据,REST API、Python SDK、MCP 和 Agent Skill 共用同一个 API Key。

先在官网创建账号并生成 Key:

免费注册 QuantSonar

Key 的形式类似:

qs_xxxxxxxxxxxxxxxxxxxx

不要把真实 Key 提交到 GitHub,也不要写进公开文章。日常使用建议放入环境变量或 MCP 客户端的私密请求头配置。

第二步:把 QuantSonar MCP 接给 AI

QuantSonar 提供远程 Streamable HTTP MCP 服务,不需要在本地启动额外的数据服务。

服务器地址:

https://quantsonar.com/mcp

以 Claude Code 为例,可以执行:

claude mcp add --transport http quantsonar https://quantsonar.com/mcp \
  --header "X-API-Key: qs_你的密钥"

连接完成后,AI 可以按需调用日线行情、财务报表、估值、资金流、筹码、龙虎榜、ETF、指数、技术因子、实时行情和财经快讯等工具。

与复制一大段接口说明相比,MCP 的优势是工具名称、参数和返回结构可以被客户端直接发现。当接口更新时,也不需要反复修改提示词里的“接口说明书”。

第三步:用自然语言描述策略

现在可以直接把研究目标告诉 AI。例如:

使用 QuantSonar 查询贵州茅台(600519.SH)从 2024-01-01 到 2026-08-07 的日线行情。

请编写一个 RSI 均值回归策略原型:
1. 计算 14 日 RSI;
2. RSI 低于 35 时产生持有信号;
3. RSI 高于 70 时转为空仓;
4. 信号必须延迟一个交易日执行,避免未来函数;
5. 单边换仓成本按 0.05% 计算;
6. 输出策略与标的的累计净值曲线。

先检查返回字段和日期范围,再生成完整 Python 代码。不要编造缺失数据。

这里最重要的不是“让 AI 猜一个赚钱策略”,而是把研究约束说清楚:标的、时间范围、信号阈值、执行延迟、成本和输出结果都应明确。

第四步:用 Python SDK 跑出净值曲线

如果需要批量计算或保存完整结果,可以使用官方 Python SDK:

pip install quantsonar matplotlib

下面是一份可以继续修改的完整策略原型:

import os

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import quantsonar as qs


# 建议在终端设置 QUANTSONAR_TOKEN,避免把 Key 写进代码
# macOS / Linux:
# export QUANTSONAR_TOKEN="qs_你的密钥"
qs.set_token(os.environ["QUANTSONAR_TOKEN"])


def rsi_backtest(
    symbol="600519.SH",
    start_date="20240101",
    end_date="20260807",
    rsi_window=14,
    buy_level=35,
    sell_level=70,
    one_way_cost=0.0005,
):
    # 1. 获取日线行情
    df = qs.daily(
        symbol=symbol,
        start_date=start_date,
        end_date=end_date,
    )

    if df.empty:
        raise ValueError("指定区间没有返回行情数据")

    required = {"trade_date", "close"}
    missing = required.difference(df.columns)
    if missing:
        raise ValueError(f"缺少必要字段: {sorted(missing)}")

    df = df.copy()
    df["trade_date"] = pd.to_datetime(
        df["trade_date"].astype(str),
        format="%Y%m%d",
    )
    df = (
        df.sort_values("trade_date")
        .drop_duplicates("trade_date")
        .reset_index(drop=True)
    )

    # 2. 计算 14 日 RSI
    delta = df["close"].diff()
    gain = delta.clip(lower=0)
    loss = -delta.clip(upper=0)
    avg_gain = gain.rolling(rsi_window, min_periods=rsi_window).mean()
    avg_loss = loss.rolling(rsi_window, min_periods=rsi_window).mean()
    rs = avg_gain / avg_loss.replace(0, np.nan)
    df["rsi"] = 100 - 100 / (1 + rs)
    df.loc[(avg_loss == 0) & (avg_gain > 0), "rsi"] = 100
    df.loc[(avg_loss == 0) & (avg_gain == 0), "rsi"] = 50

    # 3. 生成目标仓位:低于 35 持有,高于 70 空仓
    target = pd.Series(np.nan, index=df.index, dtype=float)
    target.loc[df["rsi"] < buy_level] = 1.0
    target.loc[df["rsi"] > sell_level] = 0.0
    target = target.ffill().fillna(0.0)

    # 信号延迟一个交易日执行,避免使用当天收盘后才知道的信息
    df["position"] = target.shift(1).fillna(0.0)

    # 4. 计算收益并扣除换仓成本
    df["benchmark_return"] = df["close"].pct_change().fillna(0.0)
    turnover = df["position"].diff().abs().fillna(df["position"])
    df["strategy_return"] = (
        df["position"] * df["benchmark_return"]
        - turnover * one_way_cost
    )

    df["benchmark_nav"] = (1 + df["benchmark_return"]).cumprod()
    df["strategy_nav"] = (1 + df["strategy_return"]).cumprod()
    return df


result = rsi_backtest()

ax = result.plot(
    x="trade_date",
    y=["strategy_nav", "benchmark_nav"],
    figsize=(11, 5),
    title="600519.SH RSI strategy vs. buy and hold",
)
ax.set_xlabel("Date")
ax.set_ylabel("Net asset value")
ax.grid(alpha=0.25)
plt.tight_layout()
plt.show()

print(result[["trade_date", "close", "rsi", "position", "strategy_nav"]].tail())

这段代码做了几项容易被忽略的检查:

  • 先验证返回结果是否为空;
  • 检查 trade_dateclose 是否存在;
  • 按交易日期排序并去重;
  • 使用 shift(1) 延迟执行信号;
  • 在发生仓位变化时扣除交易成本;
  • 同时输出策略净值和买入持有基准。

第五步:不要让 AI 跳过这些回测边界

能画出净值曲线,不等于策略已经可以实盘。继续让 AI 修改代码时,至少要检查下面几项。

1. 复权口径

除权除息会造成价格序列跳变。研究长期收益时,需要明确使用的价格口径,并确认价格与复权因子的处理方式。

2. 未来函数

当天收盘后计算出的指标,不能假设在当天收盘前已经知道。最简单的防线之一,就是让信号至少延迟一个交易日执行。

3. 交易成本

佣金、印花税、滑点、涨跌停和停牌都会影响实际可交易性。本文仅使用了简化的单边成本。

4. 参数过拟合

RSI 35 和 70 只是演示参数。反复试验阈值并只保留最好的一组,会造成明显的数据挖掘偏差。

5. 单标的偏差

一只股票上的结果不能代表策略具有普遍性。后续应扩大标的范围,设置样本内外区间,并进行稳健性检验。

MCP 和 Skill 分别适合什么场景

MCP 适合交互式查询:你提出问题,AI 根据需要选择数据工具并读取结果。

Skill 更像一套研究流程约束:它会提醒 Agent 先解析证券代码、确认交易日期、检查数据时点和字段,再给出结论。QuantSonar 的公开 Skill 可以安装到支持 Agent Skills 的工具中:

npx --yes skills add QuantSonar/quantsonar-skills --skill quantsonar --global --yes

不想手动配置时,也可以使用官网的一键复制安装指南,把完整任务直接交给 Agent。

对于完整数据导出、批量计算和正式研究代码,Python SDK 仍然更合适。三种方式并不冲突,它们共用同一套数据接口和 API Key。

总结

AI 可以显著减少代码编写时间,但量化研究的可信度仍然取决于数据、时点和验证方法。

比较可靠的工作方式是:

  1. 通过 MCP 让 AI 先查询真实数据;
  2. 用自然语言明确策略规则和回测边界;
  3. 使用 Python SDK 保存完整代码和结果;
  4. 检查未来函数、交易成本、复权和样本外表现。

如果你已经有一个 A 股研究想法,却一直卡在数据接口和代码实现上,可以从一个简单、可复现的策略原型开始。

相关入口:

再次提醒:示例只用于技术演示和量化研究,不构成任何投资建议。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐