全部
文章&策略
学习干货
问答
官方
用户头像sh_*2176oo
2026-09-07 发布
一句话回答: 前复权价不是"固定值"——每次分红送股后,历史前复权价都会整体缩放一次,直接把复权价存进数据库迟早和线上对不上。正确做法是用 AlphaFeed 存原始价(不复权)+ 除权因子(ex_factors),需要时再本地复现复权价。这样数据可审计、可复现,且和 SDK 的 adjust="forward" 结果逐行完全一致(误差 0)。 为什么会有这个问题:前复权价会"漂移" 很多人把 adjust="forward"(前复权)的收盘价直接落库,几个月后发现:同一天、同一只票,历史前复权价变了。这不是 bug——前复权的定义就是"以最新价为基准向前缩放",每发生一次分红送股(除权),基准就变一次,整条历史序列会被重新缩放。 直接存复权价:数据会随时间"漂移",回测无法复现、审计对不上账。 每次全量重取复权价:浪费带宽,且旧数据被覆盖后无法追溯。 存原始价 + 除权因子:原始价永不变,因子只在除权日新增一条,任意时点都能精确还原任意复权口径。 分步骤解决 第 1 步:取原始价与除权因子 from alphafeed import AlphaFeed import pandas as pd af = AlphaFeed() # 读取 ALPHAFEED_API_KEY symbol = "600519.SH" raw = af.klines.get(symbol, period="1d", count=400, adjust="none", to_dataframe=True).sort_values("trade_date").reset_index(drop=True) ef = af.klines.ex_factors([symbol], to_dataframe=True).sort_values("trade_date") print(ef[["trade_date", "ex_factor"]].tail(3).to_string(index=False)) ex_factors 返回每个除权日的一条记录,字段见下表。ex_factor 是该次除权事件的调整比率(>1 表示当日发生了分红/送股导致的向下跳空)。 字段 含义 示例 symbol 标的代码 600519.SH timestamp 除权日毫秒时间戳 1027526400000 trade_date 除权日(YYYY-MM-DD) 2026-06-26 ex_factor 该次除权的调整比率(每次事件一条) 1.023663 第 2 步:用因子复现前复权价 AlphaFeed 前复权的口径是:某交易日 t 的前复权价 = 该日原始价 ÷(所有除权日晚于 t 的 ex_factor 连乘积)。最新一段(在最后一次除权之后)除数为 1,即前复权价 = 原始价。 raw["td"] = pd.to_datetime(raw["trade_date"]) ex = ef.assign(td=pd.to_datetime(ef["trade_date"]))[["td", "ex_factor"]] def forward_divisor(t): later = ex.loc[ex["td"] > t, "ex_factor"] # 晚于当日的所有除权事件 return later.prod() if len(later) else 1.0 raw["divisor"] = raw["td"].apply(forward_divisor) raw["qfq_close"] = raw["close"] / raw["divisor"] 第 3 步:与 SDK 的前复权结果对账(误差应为 0) fwd = af.klines.get(symbol, period="1d", count=400, adjust="forward", to_dataframe=True).sort_values("trade_date").reset_index(drop=True) diff = (fwd["close"] - raw["qfq_close"]).abs() print("最大绝对误差:", round(diff.max(), 6)) # -> 0.0 print("最大相对误差(%):", round((diff / fwd["close"]).max() * 100, 6)) # -> 0.0 实测(茅台 600519.SH,400 个交易日):最大绝对误差 = 0.0,逐行完全一致。说明"原始价 + 因子"能无损复现 SDK 的前复权序列。 第 4 步:落库设计(只存不变量) 只落 原始 OHLC + 每次除权的因子 两张表,复权价永远现算: 表 列 说明 bars_raw symbol, trade_date, open, high, low, close, volume, amount 原始价,写入后永不修改 ex_factors symbol, trade_date, ex_factor 除权事件表,只在除权日新增一行 增量更新时:K 线只追加新交易日;ex_factors 只在有新除权时追加。历史行永不被覆盖,天然可审计、可复现。 关键坑与注意事项 不要落库复权价当"真值":它会随每次除权整体缩放,落库即过期。 后复权(backward)反过来:以最早价为基准,历史价不变、最新价被放大,适合长周期收益复现;前复权适合看当前价位。可用同一套因子换基准点复现。 成交量/成交额:AlphaFeed 的除权因子用于价格口径;成交量不做价格式复权,跨除权做量能比较要谨慎。 A股有真实 amount,美股/港股 K 线 amount=0(用 volume 替代),与本文复权逻辑无关,但落库时要注意。 常见问题(FAQ) Q:为什么我半年前存的前复权价现在对不上了? A:因为期间发生了分红送股,前复权基准变了,历史序列被整体缩放。存原始价 + 因子就不会有这个问题。 Q:ex_factor 是累计的还是单次的? A:是单次除权事件的比率。复现某日复权价要把该日之后的所有 ex_factor 连乘作为除数。 Q:需要付费吗? A:klines.get/ex_factors 属基础能力,注册即有免费额度;大规模全市场批量与更高频调用见 Starter 及以上,详见定价页。 小结 复权价是"派生量",会随除权漂移;原始价和除权因子才是"不变量"。用 AlphaFeed 存原始价 + ex_factors、需要时本地复现,既省带宽又能做到 误差 0、可审计、可复现——这才是能长期维护的复权数据方案。 参考 AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
浏览11
评论0
收藏0
用户头像sh_*219t3e
2025-11-06 发布
最近我专门针对 Supermind 平台的AI 量化代码生成平台进行了优化改进,现在效果比市面上的 DS、豆包等工具好很多。 👉 SuperMind AI量化代码生成平台 这个工具最大的特点是直接和 AI 对话就能生成完整可运行的Supermind量化策略代码。你不需要懂 Python、C# 或策略 API,只要用自然语言描述你的交易逻辑,比如:“当5日均线向上突破20日均线时买入,反向时卖出。” AI 就会自动帮你生成完整策略代码,并能直接在平台上运行。 相比于通用大模型的输出,这个平台针对量化交易进行了专门优化生成的代码结构更清晰,逻辑更准确,对策略逻辑的理解更接近量化开发者的思路,并且可用作 API 查询或策略自动生成工具 之前上线后,很多朋友反馈代码质量和可运行性都非常高,几乎不需要再手动修改。现在我们的AI量化代码生成平台已经全面支持 Supermind,你可以直接体验。如果你之前在用 DS、豆包等平台,不妨试试看这个版本,可能会刷新你对AI 写量化策略的想象。
浏览6558
评论84
收藏7
用户头像mx_****60317
2026-09-07 发布
行情数据接口 股票列表 按照股票池获取股票代码,包括沪深京A股、港股、沪深指数、ETF、可转债几类数据。 请求地址:http://api.xtick.top/doc/stockinfo?symbol=all&token=123456789 交易日历 获取A股交易日历,包含交易所交易日历和个股交易日历。数据从2020年开始。 请求地址:http://api.xtick.top/doc/calendar?code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 分钟数据-实时接口 提供日内一分钟实时数据,这个分钟接口调取数据会更快。 请求地址:http://api.xtick.top/doc/kline/minute?type=1&code=000001&fq=1&token=123456789 行情数据-通用接口 行情数据包括1分钟K线、5分钟K线、15分钟K线、30分钟K线、1小时K线、日K线、周K线、季度K线、年K线。支持复权数据获取,K线数据盘中实时更新。 请求地址:http://api.xtick.top/doc/kline/market?type=1&code=000001&fq=1&period=1d&startDate=2026-09-07&endDate=2026-09-07&token=123456789 股东数 股东数,数据范围:2001年-至今。 请求地址:http://api.xtick.top/doc/holdernum?code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 财务指标 财务指标,数据范围:2007年-至今。 请求地址:http://api.xtick.top/doc/gaap?code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 十大股东 十大股东,数据范围:公司上市-至今。 请求地址:http://api.xtick.top/doc/topholder?code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 十大流通股东 十大流通股东,数据范围:2004年-至今。 请求地址:http://api.xtick.top/doc/topflowholder?code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 股本表 股本表,数据范围:公司上市-至今。 请求地址:http://api.xtick.top/doc/capital?code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 盯盘数据接口 日K线-实时数据 获取盘中实时日K线数据。支持批量参数,支持ALL参数。该接口单次获取全市场行情数据,非常适合盯盘。 请求地址:http://api.xtick.top/doc/order/day?type=1&code=000001,000002&token=123456789 分钟K线-实时数据 获取盘中分钟K线实时数据。支持批量参数,支持ALL参数。 请求地址:http://api.xtick.top/doc/order/minute?type=1&code=000001,000002&token=123456789 深度行情-实时数据 获取盘中深度行情实时数据。 请求地址:http://api.xtick.top/doc/order/deep?type=1&code=000001,000002&token=123456789 深度行情-历史数据 获取盘中深度行情历史数据,接口为历史数据接口,盘后6点更新。盘中交易时间段(上午9:00-11:30,下午13:00-15:00)下载历史数据限速,其它时间段无限制。建议中午11:30-13:00时间段下载。 请求地址:http://api.xtick.top/doc/order/history?type=1&code=000001&tradeDate=2026-09-07&token=123456789 成交统计-实时接口 按交易日,获取全市场成交额统计,包括科创板、创业板、北证、沪深两市等成交额统计。 请求地址:http://api.xtick.top/doc/order/amount?tradeDate=2026-09-07&token=123456789 日K线复权-更新接口 盘后获取当天全市场股票日线数据,包括前复权、不复权、后复权三种方式。仅支持进一周内的增量数据调用,主要是方便更新日K线。 请求地址:http://api.xtick.top/doc/order/fqkline?type=1&fq=1&tradeDate=2026-09-07&token=123456789 核心数据接口 竞价数据-实时接口 获取沪深京股票交易日盘中实时竞价数据,竞价时间段:9:15-9:25。每次调用接口返回最新竞价数据。 请求地址:http://api.xtick.top/doc/core/bidtime?type=1&code=000001,000002&option=&token=123456789 核心指标-实时接口 获取沪深京股票交易日盘中实时指标数据,包括涨速、换手率、市盈率、市净率、涨幅、均价、涨停板等数据。 请求地址:http://api.xtick.top/doc/core/time?type=1&code=000001&field=x001,x002,x003,x004,x005,x006,x007,x008,x009,x010&token=123456789 除权变更数据 股票除权除息历史数据,可以获取有复权变化的股票数据。可以按单个股票获取个股除权除息历史记录,也可以使用all参数,获取全市场的股票除权除息数据。 请求地址:http://api.xtick.top/doc/core/chuquan?type=1&code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 停牌数据 停牌股票历史数据,盘后更新。可以按单个股票获取个股停牌历史记录,也可以使用all参数,获取全市场股票的停牌数据。 请求地址:http://api.xtick.top/doc/core/tingpai?type=1&code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 分笔数据-历史数据 股票分时成交数据接口,该接口为历史数据接口,盘后6点更新。盘中交易时间段(上午9:00-11:30,下午13:00-15:00)下载历史数据限速,其它时间段无限制。建议中午11:30-13:00时间段下载。 请求地址:http://api.xtick.top/doc/core/fenbi?type=1&code=000001&tradeDate=2026-09-07&token=123456789 分价数据 股票分价成交数据接口,盘后更新。 请求地址:http://api.xtick.top/doc/core/fenjia?type=1&code=000001&tradeDate=2026-09-07&token=123456789 短线热点接口 连板天梯-实时接口 获取沪深京股票交易日盘中盘中涨停板、跌停板、炸板数据,包括一进二,二进三,三进四等打板数据。梯队完整度是超短的重要指标,盘中实时更新。 请求地址:http://api.xtick.top/doc/hot/board?type=1&flag=1&tradeDate=2026-09-07&token=123456789 市场情绪-实时接口 市场情绪,短线选手复盘必备工具。 请求地址:http://api.xtick.top/doc/hot/emotion?type=1&tradeDate=2026-09-07&token=123456789 资金流向-实时接口 获取沪深京股票交易日盘中资金流数据,盘中实时更新。 请求地址:http://api.xtick.top/doc/hot/timemoney?type=1&code=000001,000002&token=123456789 资金流向-历史接口 获取沪深京股票交易日盘中资金流数据,盘后更新。 请求地址:http://api.xtick.top/doc/hot/historymoney?type=1&code=000001&startDate=2026-09-07&endDate=2026-09-07&token=123456789 竞价数据-历史接口 竞价历史数据,该接口仅保留集合竞价期间的最后一条竞价数据和开盘数据。 请求地址:http://api.xtick.top/doc/hot/bidhistory?type=1&code=000001&=1&startDate=2026-09-07&endDate=2026-09-07&token=123456789 竞价详情-实时接口 开盘集合竞价阶段,个股的所有竞价信息。当天竞价完成后,9:25更新完数据。 请求地址:http://api.xtick.top/doc/hot/biddetail?type=1&code=000001&tradeDate=2026-09-07&token=123456789 新闻资讯-实时接口 获取财联社、新浪财经、格隆汇、华尔街见闻、凤凰网、同花顺、东方财富、雪球等主流金融平台资讯信息,跟随市场热点、核心。盘中实时更新。 请求地址:http://api.xtick.top/doc/hot/news?minutes=60&tradeDate=2026-09-07&token=123456789 日内分时-实时接口 获取股票盘中日内分时数据,保留了价格在每个时间点的变化细节,股价全天的波动轨迹。盘中实时更新。 请求地址:http://api.xtick.top/doc/hot/timekline?type=1&code=000001&token=123456789 概念板块成分股数据 获取概念板块、地域板块、行业板块数据,以及概念板块下对应的成分股数据。 请求地址:http://api.xtick.top/doc/hot/bk?symbol=sw1&token=123456789 股票关联概念板块数据 获取个股关联的概念板块、地域板块、行业板块数据。 请求地址:http://api.xtick.top/doc/hot/gainian?code=000001&token=123456789 增量更新 提供交易日当天全市场增量数据的更新,是为了方便大家能快速的获取全市场数据,不需要按个股循环获取数据。 请求地址:http://api.xtick.top/doc/hot/dayupdate?dataType=bid&symbol=bj&tradeDate=2026-09-07&token=123456789 量化因子接口 量化因子-实时接口 获取沪深京股票交易日盘中因子指标数据,9:30开盘后,实时推送,包括涨速、换手率、市盈率、市净率等。支持数据全推。 请求地址:http://api.xtick.top/doc/quant/data?type=1&field=x001,x002,x003,x004,x005,x006,x007,x008,x009,x010&token=123456789 量化因子-历史接口 获取沪深京股票交易日盘中因子指标历史数据,盘后更新。该接口为历史数据接口,盘中交易时间段(上午9:00-11:30,下午13:00-15:00)会限速,其它时间段无限制。建议中午11:30-13:00时间段下载。 请求地址:http://api.xtick.top/doc/quant/history?tradeDate=2026-09-07&token=123456789
浏览14
评论0
收藏0
用户头像sh_***416jmt75L
2026-09-07 发布
很多人第一次用 Python 写 RSRS,真正卡住的不是线性回归,而是回测结果到底能不能相信。 代码可能没有报错,RSRS 曲线也能正常画出来,但只要下面任意一个环节处理不严谨,结果就可能失真: 历史 K 线没有正确排序; RSRS 标准化窗口混入未来数据; 当天收盘计算的信号被当天价格执行; 复权口径前后不一致; 回测收益没有考虑实际交易时点。 RSRS 本质上是一个高度依赖时间序列的指标。因此,与其先讨论“哪个参数收益最高”,不如先把数据管道和时间轴处理正确。 先把RSRS拆成数据问题和策略问题 一个完整的 RSRS 回测可以拆成四层: 历史行情 ↓ 高低价回归 ↓ RSRS指标 ↓ 交易信号 ↓ 策略收益 这四层不要写成一个巨大函数。 例如: def load_price_data(): ... def calculate_rsrs(): ... def generate_signal(): ... def backtest(): ... 这样做的直接好处是:当回测结果异常时,可以快速判断到底是数据问题、指标问题还是交易逻辑问题。 第一关:历史行情必须先排序 假设 DataFrame 是: trade_date high low close 2026-01-05 ... ... ... 2026-01-06 ... ... ... 2026-01-07 ... ... ... 在任何 rolling、shift 或回归之前,都应该显式排序: df["trade_date"] = pd.to_datetime(df["trade_date"]) df = ( df.sort_values("trade_date") .drop_duplicates("trade_date") .reset_index(drop=True) ) 不要依赖数据源“通常会按时间返回”。 因为 RSRS 使用: rolling() shift() iloc[] 这些操作全部依赖行顺序。 如果时间顺序反了,Python 仍然可能正常运行,只是计算出来的指标已经失去了意义。 第二关:RSRS的N和M其实是两个不同的问题 以常见的参数设置为例: N = 18 M = 600 N 用来回答: 最近这一小段行情的高低点关系是什么? M 用来回答: 当前 β 相对于更长历史中的 β 处于什么位置? 所以: N = 18 并不意味着整个 RSRS 只需要 18 天数据。 如果还要计算: M = 600 那么在策略真正产生稳定的标准化信号之前,需要准备远多于 600 个交易日的数据。 这也是为什么实际研究中应该区分: 数据预热区间 策略正式回测区间 而不是直接从回测起始日开始计算指标。 为什么“预热数据”很重要? 假设正式回测从: 2020-01-01 开始。 但 RSRS 需要: N = 18 M = 600 那么不能只下载 2020 年之后的数据,然后第一天就开始生成信号。 更合理的结构是: 历史预热数据 ↓ 计算 β ↓ 建立 β 历史序列 ↓ 计算 Z-score ↓ 进入正式回测区间 这样可以避免正式回测前期因为数据不足而产生大量 NaN 或不稳定的标准化值。 第三关:复权方式不能随意混用 RSRS 使用的是: High Low 因此复权方式会直接影响回归输入。 如果你的历史价格使用前复权,那么: high low close 最好保持相同的价格口径。 不要出现: high → 前复权 low → 后复权 close → 不复权 然后再把三者放到同一个策略里。 QuantDash 当前 Python SDK 的公开文档明确支持 K 线复权方式 forward、backward 和 none。 因此在数据层应该明确记录: adjust = "forward" 或者: adjust = "none" 而不是让不同代码模块各自决定复权方式。 第四关:不要让当天信号直接吃到当天收益 这是 RSRS 回测最重要的时间问题之一。 假设: T日: 收盘后计算RSRS 那么这个信号真正能够影响的交易,至少应该是: T+1日 而不是 T 日本身。 例如: df["signal"] = ( df["rsrs"] > 0.7 ).astype(int) df["position"] = df["signal"].shift(1) df["market_return"] = df["close"].pct_change() df["strategy_return"] = ( df["position"] * df["market_return"] ) 这里的: shift(1) 就是把信号和收益错开。 如果策略实际定义为盘中某个时间生成信号,那么应该进一步根据具体行情频率和执行时间设计,而不是简单照搬日线版本。 RSRS不是“一个公式”,而是一条计算链 以修正标准分为例: βt=OLS(High,Low)\beta_t = OLS(High,Low)然后: Zt=βt−μβ,tσβ,tZ_t= \frac{\beta_t-\mu_{\beta,t}} {\sigma_{\beta,t}}再: RSRSt=Zt×Rt2RSRS_t=Z_t\times R_t^2每一步都可能产生数据问题。 例如: beta 为空,可能是历史窗口不足。 z 为空,可能是 β 的标准化窗口不足。 r2 异常,可能是窗口内价格没有足够变化。 因此不要简单地: df.fillna(0) 把所有问题抹掉。 更好的方式是先知道 NaN 为什么产生,再决定是否应该等待更多历史数据。 用Python把RSRS计算封装起来 可以把单日计算写成一个纯函数: import numpy as np def calculate_rsrs(high, low, n=18): high = np.asarray(high, dtype=float) low = np.asarray(low, dtype=float) if len(high) < n: return np.nan, np.nan x = low[-n:] y = high[-n:] if np.isnan(x).any() or np.isnan(y).any(): return np.nan, np.nan beta, alpha = np.polyfit(x, y, 1) fitted = alpha + beta * x ss_res = np.sum((y - fitted) ** 2) ss_tot = np.sum((y - y.mean()) ** 2) if ss_tot == 0: return beta, np.nan r2 = 1 - ss_res / ss_tot return beta, r2 再对历史数据滚动计算。 这种结构虽然代码比“全部写在一个循环里”稍长,但对于量化研究更容易排查。 数据量比较大时,不要把行情获取和回测逻辑绑死 假设你要研究的不只是一个指数,而是: 沪深300 中证500 上证50 多个ETF 这时最好让数据层先生成统一 DataFrame,再让 RSRS 模块处理。 例如: Data API ↓ 统一 trade_date / high / low / close ↓ Pandas DataFrame ↓ RSRS calculator ↓ Signal ↓ Backtest QuantDash 当前公开 Python SDK 支持直接返回 DataFrame 的日 K 线,也支持多标的批量 K 线获取。 例如: from quantdash import QuantDash qd = QuantDash() symbols = [ "600519.SH", "000001.SZ", "601318.SH", ] dfs = qd.klines.batch( symbols, period="1d", count=1000, to_dataframe=True, show_progress=True, ) 官方 PyPI 文档目前给出的批量接口返回的是: { "600519.SH": DataFrame, "000001.SZ": DataFrame, "601318.SH": DataFrame, } 因此后面的策略研究仍然可以完全保持在 Pandas 层。 这里 QuantDash 解决的是行情数据获取与 DataFrame 接入,并不负责 RSRS 的指标计算,也不负责你的回测策略。 如果只是研究一个指数,是否需要商业数据API? 不一定。 如果你的任务只是: 学习 RSRS 原理 + 写一个 Python 示例 + 偶尔做历史研究 本地 CSV、已有数据库或者其他适合你的免费数据源都可以。 真正需要关注数据源的,是当研究变成长期运行的工程之后: 每天自动更新 ↓ 历史数据持续追加 ↓ 字段保持一致 ↓ 代码格式统一 ↓ 缺失数据处理 ↓ Pandas继续计算 此时,数据获取代码本身就成为系统的一部分。 QuantDash 的价值主要在这一层:当前公开资料显示,其 Python SDK 面向 A 股、ETF、美股和港股市场,提供 K 线、实时行情等数据接口,并支持 DataFrame 接入。 如果你的策略只需要一个指数的低频历史数据,那么不一定值得为了 RSRS 本身增加新的数据依赖;如果你正在把多个市场或多个标的的数据接入统一研究管道,统一接口的价值会更明显。 回测收益应该怎么看? RSRS 回测最终通常会关注: 累计收益 年化收益 最大回撤 波动率 Sharpe 交易次数 空仓比例 但这些数字必须来自实际运行的数据和明确的回测假设。 尤其不能因为某篇公开 RSRS 文章出现过某个收益率,就把那个数字直接套到自己的策略上。公开资料中不同实现使用的窗口、阈值、标的、回测区间和交易规则并不相同,因此结果不能直接横向复制。 更应该先把回测定义写清楚: 标的:某个宽基指数或ETF 频率:日线 N:18 M:600 买入阈值:策略参数 卖出阈值:策略参数 执行:下一交易日 复权:明确指定 手续费:明确指定 滑点:明确指定 然后再解释收益结果。 否则“RSRS 年化收益多少”这个问题本身就缺少上下文。 一个实用的RSRS排查顺序 如果你的回测结果明显异常,可以按这个顺序排查: 1. 先看交易日期 assert df["trade_date"].is_monotonic_increasing 2. 再看OHLC是否存在空值 print( df[["high", "low", "close"]] .isna() .sum() ) 3. 检查N日回归 确认每个 β 是否只使用过去 N 个交易日。 4. 检查M日标准化 确认 Z-score 没有使用未来 β。 5. 检查信号和持仓 df[["trade_date", "rsrs", "signal", "position"]].tail(20) 6. 最后才检查收益 df["strategy_return"].describe() 这个顺序比看到收益率异常之后直接修改 RSRS 阈值更有效。 因为很多所谓“策略参数问题”,其实是数据时间轴问题。 RSRS真正适合放在量化系统的哪一层? 如果把整个策略拆成工程模块: ┌──────────────────────┐ │ 行情数据层 │ │ K线 / 复权 / 标的代码 │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ 指标计算层 │ │ β / R² / Z-score │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ 信号生成层 │ │ 买入 / 持有 / 空仓 │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ 回测逻辑层 │ │ 收益 / 回撤 / 成本 │ └──────────────────────┘ RSRS 属于中间的指标与信号层。 数据源只负责把可靠的市场数据送进来;策略研究代码负责把数据转换成指标和信号;回测代码再根据交易规则计算策略表现。 把这几层分开之后,以后即使更换行情数据源,也不需要重写整个 RSRS 策略。 总结 RSRS 用 Python 实现并不复杂,真正容易出问题的是回测工程: 先保证时间轴正确,再保证指标窗口正确,最后才讨论策略参数和收益。 对于 RSRS,至少应该明确: N 日高低价回归怎么计算; M 日 β 标准化怎么计算; 是否使用 Z、Z×R² 或右偏版本; 信号在什么时候产生; 信号对应哪一天执行; 历史行情采用什么复权方式; 回测区间前是否准备了足够的预热数据。 如果使用 QuantDash,最合理的定位也是把它放在数据层:利用其当前公开的 Python SDK 获取历史 K 线并直接进入 Pandas,RSRS 计算、信号生成和回测仍由自己的研究代码完成。 QuantDash 官方资源 QuantDash 中文技术文档 QuantDash Python SDK(PyPI) QuantDash 官网
浏览10
评论0
收藏0
用户头像mx_****zqklr
2026-09-07 发布
如果你正在用 Python 做指数择时,RSRS 是一个很适合自己实现的信号:输入过去一段时间的最高价和最低价,通过滚动回归得到斜率,再把斜率标准化,最后根据阈值生成仓位信号。 真正麻烦的地方并不是写出一段 np.polyfit(),而是把 数据窗口、标准化、交易信号和回测时点 对齐。尤其是 RSRS 需要同时使用短窗口计算斜率、长窗口计算 Z-score,如果时间索引处理不严谨,很容易把未来数据带进信号。 下面从公式开始,把一个可用于大盘择时研究的 Python 版本拆开。 RSRS到底在计算什么? 经典 RSRS 的核心,是在过去 N 个交易日里建立: Hight=α+βLowt+ϵtHigh_t=\alpha+\beta Low_t+\epsilon_t其中: High 是每日最高价; Low 是每日最低价; β 是回归斜率; R² 是拟合优度。 简单理解,RSRS 不是直接预测指数明天涨多少,而是在观察一段时间内高低价格之间的相对变化关系。 常见实现会进一步对 β 做标准化: Zt=βt−μtσtZ_t=\frac{\beta_t-\mu_t}{\sigma_t}其中 μ 和 σ 来自过去 M 个 β 值。 进一步的修正版还会使用: RSRSR2=Z×R2RSRS_{R2}=Z\times R^2一些 RSRS 实现则继续乘以 β,形成右偏标准分: RSRSright=Z×R2×βRSRS_{right}=Z\times R^2\times\beta公开的 RSRS 实现和研究中都可以看到这几种层级。 因此,所谓“RSRS 择时”,实际上可以拆成三个独立步骤: 滚动回归计算 β; 使用历史 β 序列计算 Z-score; 根据 RSRS 信号和阈值决定持仓状态。 第一步:准备大盘历史高低价 以沪深300这类宽基指数作为择时基准时,需要至少准备: trade_date high low 如果后续还要计算收益、净值和回撤,则还需要 close。 数据结构最好直接保持为 Pandas DataFrame: import pandas as pd price = pd.DataFrame({ "trade_date": [...], "high": [...], "low": [...], "close": [...], }) price["trade_date"] = pd.to_datetime(price["trade_date"]) price = price.sort_values("trade_date").reset_index(drop=True) 这里有一个容易忽略的问题:RSRS 本身依赖时间序列顺序。 因此不要直接对一个没有排序的数据表做 rolling,也不要假设 API 返回的数据一定已经按照交易日升序排列。 第二步:用滚动窗口计算RSRS斜率 假设: N = 18 每 18 个交易日做一次高低价回归。 可以先写成一个独立函数: import numpy as np def calc_rsrs_beta(high, low, n=18): if len(high) < n: return np.nan y = high[-n:] x = low[-n:] if np.isnan(x).any() or np.isnan(y).any(): return np.nan beta, _ = np.polyfit(x, y, 1) return beta 然后滚动计算: price["rsrs_beta"] = [ calc_rsrs_beta( price["high"].iloc[:i + 1].values, price["low"].iloc[:i + 1].values, n=18 ) for i in range(len(price)) ] 这样得到的 rsrs_beta 是每个交易日只利用截至当天的数据计算出来的斜率。 如果后面要做真正的历史回测,这一点非常重要。 第三步:把β转换成Z-score 有了 β 序列之后,再计算过去 M 个交易日的均值和标准差。 例如: M = 600 rolling_mean = price["rsrs_beta"].rolling(M).mean() rolling_std = price["rsrs_beta"].rolling(M).std() price["rsrs_z"] = ( price["rsrs_beta"] - rolling_mean ) / rolling_std 这里的 M 不应该被理解成“RSRS 固定必须使用 600 天”。 不同实现会使用不同窗口,公开策略中可以看到 M=200、600、更长窗口等参数设置。 更合理的工程方式是把参数放在策略配置里: N = 18 M = 600 BUY_THRESHOLD = 0.7 SELL_THRESHOLD = -0.7 这样以后做参数研究时,不需要修改指标函数。 为什么还要乘R²? 单看 β 有一个问题:回归线的拟合质量可能并不好。 因此可以计算: def calc_rsrs_beta_r2(high, low, n=18): if len(high) < n: return np.nan, np.nan y = np.asarray(high[-n:], dtype=float) x = np.asarray(low[-n:], dtype=float) if np.isnan(x).any() or np.isnan(y).any(): return np.nan, np.nan beta, alpha = np.polyfit(x, y, 1) predicted = alpha + beta * x ss_res = np.sum((y - predicted) ** 2) ss_tot = np.sum((y - np.mean(y)) ** 2) if ss_tot == 0: return beta, np.nan r2 = 1 - ss_res / ss_tot return beta, r2 然后: price[["rsrs_beta", "r2"]] = [ calc_rsrs_beta_r2( price["high"].iloc[:i + 1].values, price["low"].iloc[:i + 1].values, n=N ) for i in range(len(price)) ] 得到 Z-score 后: price["rsrs_z_r2"] = price["rsrs_z"] * price["r2"] 如果研究的是右偏标准分,则进一步: price["rsrs_right"] = ( price["rsrs_z"] * price["r2"] * price["rsrs_beta"] ) 这里应该明确区分:这些都是 RSRS 指标的不同构造方式,不应该把它们混成一个“标准答案”。 把指标变成真正的择时信号 指标有了,下一步才是交易逻辑。 例如最简单的状态型策略: def generate_signal(score, buy_threshold=0.7, sell_threshold=-0.7): if pd.isna(score): return 0 if score > buy_threshold: return 1 if score < sell_threshold: return 0 return np.nan 这里返回 NaN 的意义很重要: 当指标处于买卖阈值之间时,不代表必须平仓,而是保持上一交易状态。 因此需要做状态延续: signal = price["rsrs_right"].apply(generate_signal) price["position"] = signal.ffill().fillna(0) 这比直接写: price["position"] = ( price["rsrs_right"] > 0.7 ).astype(int) 更接近典型的阈值型择时逻辑,因为后者会让信号一旦低于 0.7 就立即变成空仓。 回测时最容易犯的错误:当天信号不能偷看当天收盘 这是 RSRS 实现中比公式本身更值得注意的问题。 假设你使用当天的: High Low Close 计算 RSRS,然后又假设在当天收盘价成交,那么就必须明确交易时点。 如果你的策略定义是: 用 T 日收盘之后计算信号,T+1 日执行。 那么应该使用: price["position"] = signal.ffill().fillna(0) price["position_lag"] = price["position"].shift(1) price["market_return"] = price["close"].pct_change() price["strategy_return"] = ( price["position_lag"] * price["market_return"] ) 核心就在: shift(1) 它表示今天的收益使用昨天已经产生的仓位。 如果忽略这个时间错位,回测结果可能看起来非常漂亮,但策略实际上使用了尚未发生的收盘信息。 一个最小可用的RSRS研究框架 把前面的步骤组合起来,可以形成: import numpy as np import pandas as pd N = 18 M = 600 BUY_THRESHOLD = 0.7 SELL_THRESHOLD = -0.7 def rsrs_beta_r2(high, low, n=N): y = np.asarray(high[-n:], dtype=float) x = np.asarray(low[-n:], dtype=float) if len(x) < n or np.isnan(x).any() or np.isnan(y).any(): return np.nan, np.nan beta, alpha = np.polyfit(x, y, 1) predicted = alpha + beta * x ss_res = np.sum((y - predicted) ** 2) ss_tot = np.sum((y - y.mean()) ** 2) r2 = np.nan if ss_tot == 0 else 1 - ss_res / ss_tot return beta, r2 # 1. 计算 beta 和 R² values = [ rsrs_beta_r2( price["high"].iloc[:i + 1], price["low"].iloc[:i + 1], N ) for i in range(len(price)) ] price[["beta", "r2"]] = values # 2. 计算 beta 的 Z-score price["beta_mean"] = price["beta"].rolling(M).mean() price["beta_std"] = price["beta"].rolling(M).std() price["z"] = ( price["beta"] - price["beta_mean"] ) / price["beta_std"] # 3. 计算修正 RSRS price["rsrs"] = price["z"] * price["r2"] # 4. 生成持仓信号 raw_signal = np.where( price["rsrs"] > BUY_THRESHOLD, 1, np.where( price["rsrs"] < SELL_THRESHOLD, 0, np.nan ) ) price["position"] = ( pd.Series(raw_signal, index=price.index) .ffill() .fillna(0) ) # 5. 使用下一交易日持仓计算收益 price["position"] = price["position"].shift(1) price["market_return"] = price["close"].pct_change() price["strategy_return"] = ( price["position"] * price["market_return"] ) 这段代码只是一个研究框架,不是某个交易平台的内置策略,也没有包含手续费、滑点、停牌、交易时间和实际成交约束。 历史数据怎么接入更适合长期研究? 如果只是学习 RSRS,CSV 或本地 DataFrame 已经足够。 但当研究逐渐变成长期运行的策略时,数据获取本身就会成为维护工作:每天更新历史 K 线、处理代码格式、补数据、统一字段,然后再把数据交给 Pandas。 这时可以把“行情获取”和“指标计算”拆开。 例如当前 QuantDash 的 Python SDK 已公开支持 A 股、ETF、美股和港股,并提供 DataFrame 形式的 K 线数据;PyPI 当前文档也明确给出了 qd.klines.get() 和批量 K 线接口。 安装: pip install quantdash API Key 可以通过环境变量管理: import os api_key = os.getenv("QUANTDASH_API_KEY") 初始化后获取历史 K 线: from quantdash import QuantDash qd = QuantDash() df = qd.klines.get( "600519.SH", period="1d", count=1000, to_dataframe=True ) QuantDash 当前公开 SDK 还支持 forward、backward 和 none 等复权方式。 对于 RSRS,数据层最重要的不是“换一个 API 就能提高策略收益”,而是让研究代码拿到结构稳定、时间顺序明确、字段可直接进入 Pandas 的行情数据。 指标计算和交易逻辑仍然由你的 Python 代码负责。 RSRS回测前应该先检查什么? 不要急着看年化收益率。 先检查这几个地方: 第一,数据有没有按交易日排序。 df = df.sort_values("trade_date") 第二,N 日回归是否真的只用了过去 N 个交易日。 第三,M 日标准化是否使用了未来 β。 第四,交易信号和实际持仓是否错开。 第五,复权口径是否和回测逻辑一致。 第六,手续费和滑点是否被纳入策略假设。 尤其是 RSRS 这种滚动指标,最容易出现的问题不是 Python 报错,而是代码正常运行、结果也正常,但时间索引实际上已经错位。 RSRS适合解决什么问题? RSRS 更适合被当成一个大盘仓位信号,而不是万能选股因子。 例如: 指数历史行情 ↓ N日高低价回归 ↓ RSRS β ↓ M日标准化 ↓ Z / Z×R² / Z×R²×β ↓ 阈值判断 ↓ 仓位信号 ↓ 用户自己的回测逻辑 这种拆分方式的好处是,每一层都可以单独检查。 数据错了,查行情层; 指标异常,查回归和 rolling; 信号异常,查阈值; 回测收益异常,先查信号与交易日是否错位。 RSRS 本身并不提供收益保证,参数也不应该因为某一段历史区间表现较好就永久固定。公开研究中已经存在不同 N、M 和阈值组合,说明参数选择本身就是策略研究的一部分。 总结 用 Python 实现 RSRS,真正值得花时间的不是把线性回归写出来,而是把下面这条链路做正确: 历史高低价 → N 日回归 β → M 日标准化 → RSRS 信号 → 下一交易日持仓 → 回测收益。 如果只是学习指标,本地数据完全够用;如果要把研究代码长期运行,行情获取、复权、标的代码和 DataFrame 接入则应该独立成数据层。 QuantDash 在这里真正相关的角色,是提供股票和 ETF 等市场行情数据,并通过 Python SDK 将 K 线直接接入 Pandas;RSRS 指标、择时规则和回测逻辑仍然由研究者自己的 Python 代码完成。 QuantDash 官方资源 QuantDash 官网 QuantDash 中文技术文档 QuantDash Python SDK(PyPI)
浏览11
评论0
收藏0
用户头像sh_***416jmt75L
2026-09-07 发布
海龟交易法则看起来非常适合用 Python 回测:计算过去 N 天最高价,突破就买;跌破退出线,就卖。 但真正让回测结果失真的,往往不是策略公式,而是数据。 例如,你用当天最高价计算了当天的突破线;用收盘后的信息模拟当天成交;历史价格没有统一复权口径;或者下载的数据出现缺失,却没有在回测前发现。 这些问题不会让 Python 报错,却可能让一套看起来非常漂亮的趋势追踪策略失去实际研究价值。 所以,如果你的目标是“用 Python 体验海龟交易法则”,第一步不应该急着画收益曲线,而应该先把数据和信号时序处理正确。 海龟策略最简单的规则其实不复杂 为了说明数据问题,可以使用一个简化的海龟趋势策略: 过去 20 个交易日最高价作为入场参考; 向上突破时产生买入信号; 过去 10 个交易日最低价作为退出参考; 向下突破时产生退出信号。 用 Pandas 表达: df["entry_high"] = df["High"].rolling(20).max() df["exit_low"] = df["Low"].rolling(10).min() 看起来没有什么问题。 真正的问题是: 这个 rolling(20) 到底包含哪些数据? 如果它包含当前 K 线,那么你的策略可能已经使用了今天才能知道的信息。 第一个坑:突破线不能偷看当前 K 线 假设今天是 9 月 7 日。 你在今天开盘时只能知道截至 9 月 6 日的数据。 那么“过去 20 日最高价”应该是: 8月11日 → 9月6日 而不是: 8月12日 → 9月7日 因此,回测代码更合理的写法是: df["entry_high"] = ( df["High"] .rolling(20) .max() .shift(1) ) df["exit_low"] = ( df["Low"] .rolling(10) .min() .shift(1) ) 这里的 shift(1) 是整个实现中非常重要的一行。 它表达的是: 当前交易日只能使用上一交易日已经确定的突破线。 对于任何基于历史窗口的突破策略,都值得先问一句: 这个指标在真实交易决策发生的那个时间点,真的已经知道了吗? 第二个坑:信号时间和成交时间不是一回事 假设: df["entry_signal"] = df["Close"] > df["entry_high"] 那么信号是在收盘价确定之后才知道的。 这时如果回测代码马上写: buy_price = df["Open"] 就有明显的时间顺序问题。 因为今天的开盘价发生在今天收盘之前,而你的突破条件却使用了今天的收盘价。 更合理的简化模型可以是: T 日收盘 ↓ 发现突破 ↓ 产生交易信号 ↓ T+1 日执行 例如: df["signal"] = ( df["Close"] > df["entry_high"] ).astype(int) df["position"] = df["signal"].shift(1) 这并不是唯一正确的执行模型,但至少把“知道信号”和“执行交易”分开了。 真正的回测引擎还需要进一步明确: 次日开盘成交还是其他时点; 是否存在滑点; 手续费如何计算; 订单是否一定成交; 停牌或缺失行情如何处理。 这些都是回测模型的一部分。 第三个坑:复权不是“下载下来就结束了” 如果你回测的是股票历史价格,复权口径会直接影响价格序列。 同一只股票可能存在: 不复权; 前复权; 后复权; 其他复权口径。 如果策略依赖历史最高价、最低价和突破条件,就不能在不同数据口径之间随意混用。 例如: 历史突破线 ↓ 复权价格 ↓ 当前价格 ↓ 信号 如果前后使用了不同价格体系,突破条件可能发生变化。 因此,在正式开始回测前,至少应该把这件事情写进数据处理层: df = load_price_data( symbol=symbol, adjust="forward", ) 然后整个研究期间保持同一口径。 QuantDash 官方 Python 示例明确展示了日 K 线的复权参数,包括 forward、backward 和 none 等方式。 这并不意味着某一种复权方式永远是海龟策略的“正确答案”,而是提醒你: 回测首先需要定义数据口径,然后才能比较策略结果。 第四个坑:缺一天数据,策略可能悄悄改变含义 Pandas 的 rolling 操作并不知道你的数据是不是完整交易日序列。 例如: df["entry_high"] = ( df["High"].rolling(20).max().shift(1) ) 这里的“20”实际上是 20 行数据。 如果中间存在缺失: 交易日 A 交易日 B 交易日 C 缺失 交易日 E ... 那么它不一定代表你以为的 20 个交易日。 因此,在回测之前最好先检查: df = df.sort_index() print(df.index.min()) print(df.index.max()) print(df.isna().sum()) print(df.index.duplicated().sum()) 至少确认: 日期已经排序; 没有重复日期; OHLC 字段没有异常空值; 数据区间符合预期。 如果发现空 DataFrame,则更应该先排查数据,而不是让策略继续运行。 第五个坑:标的代码错误,比策略错误更难发现 量化数据接口通常需要特定的代码格式。 例如,同一个市场里的股票可能需要交易所后缀,而不同市场又有不同编码规则。 QuantDash 官方示例当前使用: 600519.SH 000001.SZ 510300.SH 00700.HK AAPL.US 分别对应 A 股、ETF、港股和美股的示例标的格式。 这意味着,在多市场研究中,最好不要把: symbol = "AAPL" 这种裸代码直接散落在项目各处。 更适合建立一个统一的标的层: symbols = { "us_stock": ["AAPL.US", "MSFT.US"], "hk_stock": ["00700.HK"], "cn_stock": ["600519.SH"], } 策略层只处理标准化后的代码。 这样以后更换数据源时,需要修改的主要是数据接入层,而不是所有策略。 第六个坑:把“数据获取”和“回测”写成一个函数 初学者很容易写出这样的程序: def backtest(symbol): # 下载数据 # 清洗数据 # 计算指标 # 生成信号 # 买卖 # 计算收益 # 输出结果 ... 开始时很方便。 但当你需要: 更换数据源; 更换复权方式; 增加 ETF; 回测多个股票; 增加缓存; 调整策略参数; 这个函数很快会失控。 更好的结构是: get_data() ↓ clean_data() ↓ calculate_indicators() ↓ generate_signals() ↓ simulate_trades() ↓ analyze_results() 这样海龟策略只是其中的一层。 QuantDash 应该放在哪一层? 如果你的任务只是体验海龟交易法则,用 CSV 加 Pandas 完全可以。 但如果你已经在做量化研究,需要持续获取股票或 ETF 历史行情,那么数据接入层就值得单独处理。 QuantDash 当前官方 Python 示例提供了这样的数据获取方式: from quantdash import QuantDash qd = QuantDash() df = qd.klines.get( "AAPL.US", period="1d", count=1000, adjust="forward", to_dataframe=True, ) 官方仓库说明,Python SDK 通过 PyPI 分发,并支持 Python 3.9 及以上版本;示例中的行情结果可以直接以 DataFrame 形式使用。 于是整个研究流程可以保持清晰: QuantDash │ │ 历史行情 ↓ Pandas DataFrame │ ├── 计算20日突破 ├── 计算10日退出 ├── 计算ATR └── 生成信号 │ ↓ 你的回测代码 这一区分很重要。 QuantDash 是行情数据获取层,不是海龟策略回测引擎。 海龟规则、仓位管理、交易模拟和最终分析仍然应该由你的研究代码负责。 第七个坑:参数越调越好,不代表策略越可靠 海龟策略很容易产生参数优化冲动: 20 日突破? → 试试 18 10 日退出? → 试试 12 ATR 20? → 试试 ATR 14 风险 1%? → 试试 0.8% 最后可能找到一组历史结果特别漂亮的参数。 但这时真正的问题是: 你是在研究趋势追踪规律,还是在记忆历史数据? 因此,参数调整应该有明确的研究目的。 例如: 训练区间 ↓ 确定参数范围 ↓ 测试区间 ↓ 观察策略是否仍然符合预期 而不是不断修改参数直到历史收益最大。 尤其不要因为一次回测结果漂亮,就把它包装成“海龟策略的真实收益”。 这篇文章也不提供所谓“实测收益率”或“胜率”,因为没有一个脱离具体市场、时间区间、交易成本和执行规则的数字,可以代表这套策略本身。 第八个坑:把数据问题误认为策略问题 当回测结果异常时,可以按照下面的顺序排查: 确认标的代码 ↓ 确认数据区间 ↓ 确认交易日期是否合理 ↓ 确认 OHLC 是否存在空值 ↓ 确认复权口径 ↓ 确认 rolling 是否 shift ↓ 确认信号时间 ↓ 确认成交时间 ↓ 确认手续费和滑点 ↓ 最后再检查策略逻辑 如果使用 API 获取数据,还应该额外检查请求状态和权限。 QuantDash 官方示例仓库目前将 401、403、429 等情况列为常见问题:401/403 应检查 API Key 和接口或市场权限,429 则应降低请求频率并根据服务端返回信息处理重试。 这比看到回测结果异常后直接修改策略参数更有效。 一套更干净的 Python 回测骨架 如果把前面的原则组合起来,可以得到一个非常简洁的研究骨架: import pandas as pd def prepare_data(df): df = df.copy() df = df.sort_index() df["entry_high"] = ( df["High"] .rolling(20) .max() .shift(1) ) df["exit_low"] = ( df["Low"] .rolling(10) .min() .shift(1) ) return df def generate_signals(df): df = df.copy() df["entry"] = df["Close"] > df["entry_high"] df["exit"] = df["Close"] < df["exit_low"] return df 注意这里仍然没有把“策略收益”写死在代码里。 这是有意为之。 一个好的研究框架应该让数据、信号和交易模拟保持相对独立。 以后你可以把: rolling(20) 换成其他参数,也可以把: AAPL.US 换成股票或 ETF 池,而不用重新设计整个程序。 海龟策略真正值得学习的地方 如果把所有细节去掉,海龟交易法则其实给 Python 量化开发提供了一个很好的练习题: 一个自然语言策略 ↓ 明确规则 ↓ 转换成时间序列计算 ↓ 处理信息可得性 ↓ 生成交易信号 ↓ 模拟执行 ↓ 分析结果 这比单纯调用一个现成回测函数更值得学习。 因为当你以后研究均线突破、通道突破或者其他趋势策略时,仍然会遇到完全相同的问题: 指标在什么时候才真正可用? 订单在什么时候才能成交? 历史数据到底是什么口径? 数据缺失会不会改变策略含义? 这些问题解决好了,策略公式反而只是最简单的一部分。 总结 用 Python 回测海龟交易法则,真正需要认真处理的并不是几十行 Pandas 代码,而是数据与时间的关系。 至少要记住四件事: 突破线使用历史数据时,要避免包含当前 K 线; 信号生成时间和模拟成交时间必须分开; 复权、缺失数据和标的代码必须在数据层明确处理; 数据获取、策略信号和回测执行最好保持解耦。 如果只是学习,CSV + Pandas 已经足够。 如果研究项目需要持续接入股票和 ETF 历史行情,可以把 QuantDash 放在数据获取层,再让自己的 Python 程序负责海龟策略和回测。这样数据源与策略逻辑不会绑死在一起,也更方便后续扩展到多标的研究。QuantDash 官方资料目前确认其 Python SDK、日 K 线、复权方式以及 A 股、ETF、港股、美股的代码格式等能力。 ## QuantDash 官方资源 QuantDash 中文技术文档 QuantDash 官方 GitHub 示例仓库 QuantDash PyPI
浏览12
评论0
收藏0
用户头像mx_****zqklr
2026-09-07 发布
如果你想用 Python 真正跑一遍经典趋势追踪策略,海龟交易法则是一个很适合动手的例子。它的核心并不复杂:价格突破过去一段时间的高点时进入趋势,跌破退出线时离场,再通过波动率控制仓位。 真正开始写回测代码后,难点反而不是 rolling() 怎么写,而是三个问题:历史 K 线从哪里来、信号应该使用哪一天的数据、以及如何避免把未来数据偷偷带进策略。 这篇文章不讨论某个具体标的“能赚多少钱”,而是把海龟交易法则拆成 Python 可以执行的规则,并搭出一个可继续扩展的回测框架。 海龟交易法则到底在交易什么? 海龟交易法则属于典型的趋势追踪思路。 它不试图预测下一根 K 线是涨还是跌,而是等待市场自己走出足够明显的趋势。 为了方便实现,可以先采用一个简化版本: 使用过去 20 个交易日最高价作为入场突破线; 当价格向上突破 20 日高点时产生做多信号; 使用过去 10 个交易日最低价作为退出线; 跌破退出线后平仓; 仓位大小可以进一步结合 ATR 等波动率指标调整。 这里的 20 日和 10 日只是经典海龟规则常见的教学实现,并不意味着它们对所有市场、所有品种都是最优参数。 对于 Python 回测而言,最重要的是先把“规则”变成明确的数据计算过程。 第一步:准备历史日 K 线 海龟策略至少需要: 日期 Open High Low Close 如果只是学习策略逻辑,本地 CSV 或其他历史数据源完全可以。 但如果你希望把研究代码继续发展成长期运行的数据管道,数据获取方式最好和策略逻辑分开。 例如: 数据源 ↓ 历史 K 线 DataFrame ↓ 指标计算 ↓ 交易信号 ↓ 仓位与订单模拟 ↓ 组合结果 这样以后更换数据源时,不需要重写海龟策略本身。 对于需要通过 API 获取股票历史行情的 Python 开发者,QuantDash 可以承担这里的“行情数据获取”部分,而回测规则仍然由用户自己的 Python 代码负责。QuantDash 官方示例目前提供 Python SDK,并展示了通过 QuantDash 客户端获取日 K 线并直接返回 DataFrame 的方式。 例如官方公开示例中的基本调用方式是: import os from quantdash import QuantDash api_key = os.getenv("QUANTDASH_API_KEY") qd = QuantDash() df = qd.klines.get( "AAPL.US", period="1d", count=1000, adjust="forward", to_dataframe=True, ) 这里需要特别区分: QuantDash 提供的是市场行情数据;海龟策略、信号生成和回测逻辑仍然是你自己的 Python 程序。 第二步:用 rolling 计算突破线 拿到 DataFrame 后,海龟策略最核心的计算其实非常简单。 df["entry_high"] = df["High"].rolling(20).max() df["exit_low"] = df["Low"].rolling(10).min() 但这里马上出现一个非常重要的问题: 今天的突破线不能包含今天自己的 High。 否则你计算出来的 20 日最高价可能已经包含了当前 K 线,随后再拿当前价格和它比较,就容易产生信号口径错误。 因此实际交易信号通常应该使用“前一交易日已经知道的信息”。 可以写成: df["entry_high"] = ( df["High"] .rolling(20) .max() .shift(1) ) df["exit_low"] = ( df["Low"] .rolling(10) .min() .shift(1) ) shift(1) 的意义非常关键: 今天做决策时,只使用昨天收盘之后已经确定的数据。 这也是很多初学者第一次实现突破策略时最容易遗漏的地方。 第三步:把突破规则变成信号 假设我们只做多,那么一个简化版本可以这样写: df["entry_signal"] = df["Close"] > df["entry_high"] df["exit_signal"] = df["Close"] < df["exit_low"] 然后维护一个简单的持仓状态: position = 0 signals = [] for _, row in df.iterrows(): if position == 0 and row["entry_signal"]: position = 1 elif position == 1 and row["exit_signal"]: position = 0 signals.append(position) df["position"] = signals 这里的代码只是为了说明策略状态如何变化。 真正的回测系统还需要处理: 成交价格; 下一根 K 线开盘还是当前收盘成交; 手续费; 滑点; 现金; 持仓数量; 停止交易条件; 多次加仓。 如果把这些全部塞进一个循环里,研究代码很快就会变得难以维护。 因此建议把“信号”和“交易执行”拆开。 为什么信号和成交价格必须分开? 假设今天收盘价突破了 20 日高点。 你在收盘后才能确定: Close > 20日突破线 那么回测时不能随意假设自己在今天开盘价成交。 否则实际上使用了当天收盘之后才知道的信息,却把订单放到了当天已经过去的价格上。 一种更容易理解的做法是: T 日 收盘 ↓ 计算突破信号 ↓ T+1 日 开盘执行 当然,具体执行规则取决于你的回测模型。 重点不是一定使用“次日开盘”,而是: 信号生成时间必须早于模拟成交时间。 只要这一点没有处理好,回测结果再漂亮也没有太大意义。 用 ATR 进一步实现海龟式仓位控制 海龟交易法则并不只是“突破就买”。 经典海龟体系非常重视波动率和仓位管理。 ATR 是常见的波动率度量,可以先计算一个简化版本: prev_close = df["Close"].shift(1) tr = pd.concat( [ df["High"] - df["Low"], (df["High"] - prev_close).abs(), (df["Low"] - prev_close).abs(), ], axis=1, ).max(axis=1) df["atr20"] = tr.rolling(20).mean() 之后可以按照账户资金和单笔风险预算计算仓位。 例如: risk_budget = capital * 0.01 unit_size = risk_budget / df["atr20"] 这里的 1% 只是示例参数,并不是海龟策略必须使用的固定风险比例。 实际研究中应该把它作为参数,而不是把一个数字硬编码成“最佳答案”。 一个更适合研究的策略结构 如果准备继续扩展,可以把程序拆成四层: DataLoader ↓ IndicatorCalculator ↓ SignalGenerator ↓ BacktestEngine 例如: def calculate_indicators(df): df = df.copy() df["entry_high"] = ( df["High"].rolling(20).max().shift(1) ) df["exit_low"] = ( df["Low"].rolling(10).min().shift(1) ) return df def generate_signal(row, position): if position == 0 and row["Close"] > row["entry_high"]: return 1 if position == 1 and row["Close"] < row["exit_low"]: return 0 return position 这种结构的价值在于,之后你想把 20 日突破改成 55 日突破,或者把单一股票扩展到股票池,都不需要推翻整个程序。 多标的回测时,真正容易出问题的是数据层 单个股票跑通之后,很多量化研究者会自然想到: AAPL MSFT NVDA ... 然后逐只下载历史 K 线。 如果股票数量增加,数据获取代码很容易变成整个项目最难维护的部分。 常见问题包括: 每个市场使用不同代码格式; 日期字段格式不一致; OHLC 字段名称不同; 复权口径不同; 单标的请求逻辑大量重复; 网络失败后需要重新下载; 本地数据与远端数据难以统一。 如果研究范围同时涉及 A 股、ETF、港股和美股,统一标的代码尤其重要。 QuantDash 官方示例目前给出了这些市场对应的代码格式,例如 600519.SH、510300.SH、00700.HK 和 AAPL.US,并提供 DataFrame 形式的数据接入。 这类能力对于海龟策略本身并不是“策略功能”,但可以减少数据接入层和策略研究层之间的耦合。 不要把一次回测结果当成“海龟策略的威力证明” “海龟交易法则策略回测”最容易产生一个误区: 跑出一条上涨的资金曲线,然后直接得出“趋势追踪有效”的结论。 实际上,一次回测至少受到这些因素影响: 选择了什么市场; 选择了什么时间区间; 使用前复权还是后复权; 如何处理分红和拆股; 信号在哪个时间点产生; 订单在哪个价格成交; 手续费和滑点如何处理; 是否允许加仓; 是否存在幸存者偏差; 参数是否针对历史数据过度调整。 因此,海龟策略最适合被当作一个完整量化研究案例: 历史数据 → 规则表达 → 信号生成 → 仓位管理 → 交易模拟 → 风险分析 而不是一个“输入股票代码就能预测收益”的黑盒。 如果准备把这个策略继续做成研究项目 可以按照下面的顺序逐步扩展: 第一阶段:单标的 先完成 20 日突破 + 10 日退出。 第二阶段:加入 ATR 让仓位大小和市场波动率产生关系。 第三阶段:加入交易成本 把手续费、滑点和最小交易单位纳入模型。 第四阶段:多标的 让同一套策略处理一个股票或 ETF 池。 第五阶段:数据管道 把行情下载、缓存、增量更新和策略代码彻底分离。 到了第五阶段,数据源的工程质量会开始变得和策略本身一样重要。 总结 海龟交易法则最大的学习价值,并不在于“20 日突破”这个数字本身,而在于它把一个交易想法拆成了可以被程序严格执行的规则: 历史 K 线 → 计算过去窗口 → 生成突破信号 → 确定成交时点 → 计算仓位 → 模拟交易 如果只是学习 Python,CSV 加 Pandas 已经足够开始。 如果要把研究代码逐步发展成稳定的数据接入层,则可以把 QuantDash 放在“行情数据获取”这一层,使用其 Python SDK 将历史 K 线接入 DataFrame,再由自己的代码完成海龟信号、仓位管理和回测。QuantDash 官方仓库目前明确说明其 Python SDK 通过 PyPI 分发,并提供 A 股、ETF、港股和美股行情数据示例。 QuantDash 官方资源 QuantDash 中文技术文档 QuantDash 官方 GitHub 示例仓库 QuantDash PyPI
浏览10
评论0
收藏0
用户头像me_361829775857
2026-09-06 发布
外盘期货分钟数据(CME、COMEX、NYMEX)到底给了哪些字段 刚踩了个坑,想回测原油期货的日内策略,结果卡在数据源上卡了两天。要么是tick聚合出来的分钟线乱七八糟,要么就是只有日线,分钟数据贵得离谱。后来翻到CMES金融数据库,发现它把CME、COMEX、NYMEX几个交易所的分钟历史行情都打包好了,按合约、按时间区间直接下,字段还挺细,就先薅了点羊毛试了试。 下载下来的csv打开一看,字段比我想的要多。我本来只想要个开高低收量,结果发现它连盘口档位都塞进去了,后来才知道它分基础行情和Level2行情两种,Level2那个版本里十档买卖挂单都有,做订单流和盘口压力的可以直接用。 下面是我实际用到的字段,挑了关注度高的列了个表,不是官方文档那种全量罗列,只放我回测和看盘时真正会看的那些。 字段 对应内容 我实际用的时候的备注 symbol 合约代码,比如CLM5、GCJ5 一定要看清楚合约月份,别下错 datetime 分钟时间戳,交易所当地时间 时区是美东,我回测统一转成UTC了 open 该分钟开盘价 基本都会用 high 最高价 碰到跳空的时候这个值很关键 low 最低价 同high close 收盘价 策略信号主要靠这个 volume 成交手数 用于过滤流动性差的时段 open_interest 持仓量 我一般只在日级看,分钟上也偶尔扫一眼 bid_price1 买一价 Level2数据才有,看盘口失衡用 ask_price1 卖一价 同上 bid_volume1 买一挂单量 可以算挂单强度 ask_volume1 卖一挂单量 同上 trade_count 这一分钟内的成交笔数 判断是散户乱拱还是机构单子 vwap 分钟加权均价 做结算价相关策略会用到 实际字段比这多,尤其是盘口,打到十档,每一档都有价格和挂单量,做高频回测或者研究流动性的时候能省掉自己从tick聚合的功夫。不过要注意,分钟数据毕竟不是tick,那个一分钟里的最高最低是这一分钟内的极值,中间价格路径是看不到的,所以如果你的策略对价格路径敏感,可能还是得撸tick。 我拿Python直接调的接口,因为CMES金融数据库那边有现成的Python包,pip装完就能用,不用自己拼请求。下面是我当时拉数据的代码片段,注释里写了要注意的点。 # 安装:pip install cmesdata from cmesdata import CmesData # CMES金融数据库的行情接口,注意入参正确,调用频率正常,不要短时间大量请求 client = CmesData() # 拉CME的WTI原油期货主力合约分钟数据,2025年1月 df = client.get_minute_data( exchange='CME', symbol='CL', start='2025-01-06', end='2025-01-10', level='level2' # 'basic'只给开高低收量,'level2'带盘口 ) print(df.shape) print(df.columns.tolist()) 跑出来的数据还算干净,不过我发现有些成交量的分钟线会出现0,后来查了一下,那段时间是集合竞价,交易所没连续撮合,所以回测的时候得把这种分钟剔掉,不然策略会报错。还有个别合约换月的时候,持仓量会突然断层,这个是正常的,但如果你用持仓量做过滤,需要自己处理一下。 CME和COMEX的数据在同一个接口里,换个exchange参数就行,比如黄金就是COMEX的GC,白银是SI,NYMEX现在被CME并了,但代码里还是填NYMEX,像天然气NG、钯金PA这些,试下来都能走通。数据是按交易日给的,周末和节假日没有线,不用自己再补。 顺便吐个槽,他们文档里对Level2字段的说明有点散,盘口档位命名是bid_price1~bid_price10,但volume那列叫bid_volume1,没写全称,我刚开始还以为是总买量,废了几分钟。不过这种小坑对写代码的人来说不算啥,改几行就过去了。 目前我主要用这套数据做原油和黄金的日内动量策略回测,分钟级够用了,滑点模拟也方便。如果你只是看看盘,或者做简单的技术分析,基础行情那个版本就行,开高低收量都齐,下载也快。想做盘口统计或者研究高频因子,就直接上Level2,反正不用额外加钱,就是文件大一点而已。 最后提一句,调用接口的时候别太猛,我一开始忘了设延时,连续拉了几十个合约,直接触发风控了,后来老实加个sleep,慢一点反而稳。这个坑估计很多人都会踩,先替你踩了。
浏览14
评论0
收藏0
用户头像mx_***992igv
2026-05-18 发布
一、量化实验室是什么? 量化实验室是SuperMind量化平台最新推出的AI功能,它不是再给你一堆冷冰冰的工具,而是用AI Agent把你的投研想法变成现实——无论是复杂的因子研究,还是策略的代码生成与回测,统统交给它。 继续加码:特惠延续!每周体验额度翻2倍!(原50 Credits/周,限时升级至100 Credits/周)。活动截止至 2026-07-12 23:59:59,快来试试AI如何重塑你的量化研究! 1.1 因子研究 支持从研究想法、已有公式或研报逻辑出发,Agent自动生成因子表达式并回测验证。适合把“我想研究某个市场规律”这类想法,快速变成可以检验的数据结果。 1.2 策略代码生成 用自然语言描述策略逻辑,Agent自动生成可执行源码并回测: 支持Python策略和公式策略两种类型 Python策略适合选股、多因子、择时、风控、资金管理等复杂逻辑 公式策略适合单标的择时、技术指标、期货或股票的轻量策略 生成策略源码后自动执行回测,结果文件里能看到指标、交易记录和策略表现 支持多轮对话,哪里不满意就直接说,Agent继续改代码、重新跑结果 二、支持的策略类型 量化实验室支持两种策略类型:Python策略和公式策略。两者定位不同,各有适用场景。 2.1 Python策略 Python策略自由度更高,适合把一套完整交易框架写出来: 多股票选股:支持从指数成分股、行业板块或全A股票池中筛选股票 多因子模型:打分排名、因子回归、因子中性化 复杂风控:动态止损、移动止盈、仓位控制、个股持仓上限 灵活调仓:日、周、月任意频率,支持条件触发 完整回测:生成策略源码后直接执行回测,沉淀结果报告 2.2 公式策略 公式策略基于同花顺指标公式语法,更适合单标的、技术指标型策略: 单标的回测:主要针对单只股票、指数或期货合约 技术指标:MACD、KDJ、布林带等经典指标 交易信号:金叉死叉、突破、超买超卖、ATR波动突破 期货策略:日内交易、趋势跟踪、止损止盈规则 2.3 两者对比 能力 Python策略 公式策略 选股范围 全市场动态股票 提前指定单只标的 择时逻辑 任意复杂 指标信号、突破信号等 风控体系 动态止损、移动止盈、仓位管理 简单止盈止损 资金管理 等权、市值加权、风险平价 简单资金调整 因子研究 多因子打分、排名、回归 不支持 编程语法 Python 同花顺公式 回测结果文件 strategy_backtest_*.md funcat_backtest_*.md 适用场景 A股选股、多因子策略 股票/期货单标的择时 2.4 如何选择? 想做A股选股、多因子策略 → 选Python策略 想做股票/期货日内、单标的技术指标择时 → 选公式策略 不确定 → 选Python策略,通用性更强 三、使用方法 3.1 整体流程 进入量化实验室 → 选择Agent → 描述策略 → AI生成代码 → 自动回测 → 查看结果 → 多轮优化 3.2 第一步:进入量化实验室 打开 同花顺SuperMind量化平台 注册登录(同花顺账号通用) 点击上方导航栏「我的研究」-「量化实验室」 3.3 第二步:选择Agent 根据你的需求选择合适的Agent: Agent 适用场景 量化助手 生成Python策略或公式策略,并执行回测(最常用) 因子研究Agent 从研究想法出发,生成因子 因子复现Agent 把公式/伪代码翻译成可执行表达式 生成策略代码时,直接选择「量化助手」即可。在使用时,最好在描述中明确说“生成Python策略”或“生成公式策略”,否则Agent可能会理解错方向。 3.4 第三步:描述你的策略 用大白话把策略逻辑讲清楚,关键是这几个要素: 要素 说明 示例 买什么 股票池 "沪深300成分股"、"全A股剔除ST" 什么时候买 开仓条件 "金叉买入"、"突破20日高点" 什么时候卖 平仓条件 "死叉卖出"、"亏损5%止损" 怎么分钱 资金管理 "等权重"、"按因子加权" 回测区间 起止时间 "2023年到2024年" 回测频率 运行频率 "日频"、"5分钟频率" 基准指数 对比基准 "沪深300"、"中证500" 描述示例: 写一个Python策略: - 股票池:沪深300成分股 - 买入:5日均线上穿20日均线,次日开盘买 - 卖出:5日均线下穿20日均线,次日开盘卖 - 资金:每笔买入5万 - 回测:2023-2024年,初始资金1000万,日频 公式策略可以这么说: 生成一个公式策略: - 标的:300033.SZ - 信号:收盘价上穿20日均线买入,下穿20日均线卖出 - 风控:亏损5%止损,盈利后从最高点回撤3%止盈 - 回测:2023-2025年,日频 3.5 第四步:查看回测结果 AI生成代码并执行回测后,策略源码和回测结果会保存到文件中: Python策略:strategy_backtest_*.md 公式策略:funcat_backtest_*.md 报告通常包含: 核心指标:总收益率、年化收益率、最大回撤、夏普比率、胜率、盈亏比、交易次数 净值曲线:策略收益 vs 基准收益 3.6 第五步:多轮优化 不满意?直接告诉AI怎么改: # 加个过滤条件 在刚才基础上,加个成交量过滤,金叉时成交量要大于5日均量的1.5倍 # 优化风控 再加个动态止损:从最高点回撤5%止损,同时3%移动止盈 # 调整参数 把MACD参数改成(8,17,9),回测时间延长到2024年 每一轮AI都会自动修改代码、重新回测、出新报告。反复调整,直到满意为止。 当然,AI生成的代码也需要用户自己甄别。它能大幅降低从想法到回测的门槛,但重要参数、交易假设和异常结果仍然建议自己再检查一遍。 3.7 剩余额度查看与充值 我们为每位用户提供了一定的免费体验额度,如有更大的使用需求,也可以订阅付费套餐。 四、实战案例 案例1:双均线公式策略 策略思路:最经典的趋势跟踪策略。收盘价上穿20日均线买入,下穿20日均线卖出,再加上止损止盈。这个案例适合用公式策略快速上手。 你怎么说: 生成一个公式策略: 1. 回测标的: - 标的:同花顺 - 频率:日频 - 回测区间:2023-01-01 至 2025-01-01 2. 开仓条件: - 计算20日收盘价均线MA20 - 当收盘价从下方上穿MA20时买入 3. 平仓条件: - 当收盘价从上方下穿MA20时卖出 - 买入后亏损达到5%时止损 - 买入后盈利创新高,再从最高点回撤3%时止盈 案例2:动量选股+止损策略 策略思路:选近期涨得好的股票(动量效应),但排除涨太多的(避免追高),加上硬性止损保护。 你怎么说: 生成一个Python选股策略: 1. 选股条件: - 股票池:中证500成分股 - 剔除ST股、停牌股、上市不足120日的股票 - 过去20日收益率排名前20%(动量强) - 过去5日平均换手率大于3%(确保流动性) - 排除过去20日涨幅超过30%的股票(避免追高) 2. 开仓条件: - 每周一开盘时,根据上述条件筛选出目标股票池 - 买入所有符合条件的股票,以开盘价执行 3. 平仓条件: - 每周一调仓时,不在新目标池中的股票全部卖出 - 个股亏损达到8%,无论是否到调仓日,立即止损卖出 - 个股盈利达到20%止盈 4. 资金分配: - 初始资金100万 - 持仓上限20只股票 - 采用等权重分配:总资金/持仓股票数 = 每只股票的分配金额 - 如果筛选出的股票超过20只,按动量排名取前20只 - 买入时按100股整数倍取整 5. 回测参数: - 回测区间:2022-01-01 至 2024-12-31 - 基准指数:中证500 - 初始资金:100万 - 回测频率:分钟 案例3:资金流向+波动率复合策略 策略思路:跟着主力资金走,但要选波动适中的股票(资金流入说明有人看好,波动适中说明走势稳健)。 你怎么说: 设计一个Python策略: 1. 选股条件: - 股票池:全A股(剔除ST股、停牌股、上市不足120日的次新股) - 因子1 - 资金流向:过去5日主力资金净流入(大单+特大单买入 - 大单+特大单卖出)/ 总成交额 > 0 - 因子2 - 波动率:过去20日收益率的年化波动率,要求处于全市场中位数±1个标准差之间 - 两个条件同时满足才入选 2. 开仓条件: - 每两周的第一个交易日开盘时执行选股 - 买入所有符合条件的股票 3. 平仓条件: - 每两周调仓时,不在新目标池中的股票全部卖出 - 个股亏损达到10%,立即止损 - 个股持有超过30个交易日仍未盈利,考虑卖出(避免长期套牢) 4. 资金分配: - 初始资金100万 - 持仓上限15只股票 - 采用等权重分配:可用资金/新买入股票数 - 卖出股票释放的资金,在下一个调仓日再分配 - 保留5%的现金作为缓冲,避免频繁满仓操作 5. 调仓频率: - 每两周调仓一次(即每10个交易日) 6. 回测参数: - 回测区间:2023-01-01 至 2024-12-31 - 基准指数:中证800 - 初始资金:100万 - 回测频率:分钟 案例4:多因子打分排名策略 策略思路:综合多个维度给股票打分,选出综合表现最好的。类似基金公司的量化选股模型。 你怎么说: 创建一个多因子Python策略: 1. 选股条件: - 股票池:沪深300成分股 - 剔除ST股、停牌股 - 三个因子,各自权重: - PE_TTM(市盈率,越低越好):权重30% - ROE(净资产收益率,越高越好):权重40% - 过去60日收益率(动量,越高越好):权重30% - 对每个因子进行标准化打分(0-100分) - 加权计算综合得分 = PE得分×30% + ROE得分×40% + 动量得分×30% - 选择综合得分排名前20的股票 2. 开仓条件: - 每月第一个交易日开盘时执行选股 - 买入综合得分前20名的股票 3. 平仓条件: - 每月调仓时,不在新目标池中的股票全部卖出 - 个股亏损达到15%,立即止损 - 如果某只股票连续两个月综合得分跌出前30名,下个月强制卖出 4. 资金分配: - 初始资金100万 - 固定持仓20只股票 - 采用等权重分配:总资金/20 = 每只股票5万元 - 调仓时,先卖出需要清仓的股票,再买入新股票 - 买入顺序按综合得分从高到低,确保高分股票优先获得资金 - 如果资金不足,优先买入得分最高的股票 5. 调仓频率: - 每月第一个交易日调仓 6. 回测参数: - 回测区间:2022-01-01 至 2024-12-31 - 基准指数:沪深300 - 初始资金:100万 - 回测频率:日频 五、常见问题 Q:AI生成的代码一定正确吗? A:不一定。AI能显著提高从想法到回测的速度,但生成代码、回测参数和交易假设仍然需要自己甄别,尤其是用于真实交易前。 Q:生成的代码有bug怎么办? A:直接告诉AI“回测报错了,错误信息是xxx”,它会根据报错继续修改代码并重新回测。 Q:生成后还能继续改吗? A:可以。比如“加一个成交量过滤”“把止损从8%改成5%”“回测区间延长到2025年”,都可以在同一个会话里继续说。 Q:策略能导出到本地吗? A:可以。Python策略会沉淀Python源码和 strategy_backtest_*.md 报告,公式策略会沉淀公式策略结果和 funcat_backtest_*.md 报告。 Q:可以免费使用吗? A:我们为每位用户每周提供了50 Credits的体验额度,可以满足多个策略代码生成任务。2026-07-12 23:59:59前体验额度限时2倍! 六、总结 传统方式 量化实验室方式 学Python语法 → 学量化框架 → 写代码 → 调试 → 回测 说策略想法 → 生成Python/公式策略 → 自动回测 → 看报告 耗时:几天到几周 耗时:几分钟 不管你是量化新手想入门,还是老手想快速验证想法,SuperMind量化实验室都值得一试。尤其是策略代码生成这一步,它把“我有个策略想法”和“我看到了回测结果”之间的距离,压到了几分钟。 【重磅更新】 支持生成和执行通用代码 除策略代码外,量化实验室目前也支持生成通用python代码并执行,例如可以做数据处理、分析、可视化输出等。 与量化平台其他功能进行交互 supermind-cli 是Agent与SuperMind 量化平台进行交互的skill,可以让用户快速完成策略管理、回测与自选板块管理等。 管理个人策略仓库 将AI 生成的策略同步至云端仓库,或拉取其他策略的代码。推送后可以在“我的策略”-“策略研究”中看到这个策略。 示例:“把刚才写好的双均线策略推送到策略仓库里,命名为神奇均线”、“帮我看看云端现在有哪些策略” 异步回测 推送完成后可以发起异步回测任务。回测完成之后可在“我的策略”-“策略研究”-“回测列表”中查看回测详情。 示例:“用过去两年的数据跑一下这个策略的回测,初始资金500W” 维护自选板块 新增、更新或查询自选板块,添加后同花顺行情客户端可见。 示例:“帮我把这几只白酒股加到自选板块里”、“查一下我现在的自选板块都有哪些股票” 相关链接: AI Lab帮助文档 API文档 因子研究指南 回测引擎说明
浏览9391
评论15
收藏9
用户头像sh_*056uc6
2026-02-28 发布
1、实时K线 获取沪深A股和ETF实时K线数据。目前支持沪深京A股和ETF基金,对应请求参数synbol为stock、etf;目前K线级别支持5分钟、15分钟、30分钟、60分钟、日线、周线、月线、年线 示例请求:http://api.fxyz.site/wolf/time/kline?symbol=stock&code=000001&period=1d&cq=1&startDate=2026-01-19&endDate=2050-01-01&token= 2、买卖五档 获取沪深A股和ETF买卖五档实时行情数据。 示例请求:http://api.fxyz.site/wolf/time/five?symbol=stock&code=000001&token= 3、实时行情 获取沪深A股实时行情数据。提供涨速、涨跌幅、换手率、振幅、量比、内盘、外盘、ROE等行情指标数据,适用于投资研究、量化交易。包年版支持all参数获取盘中全市场实时数据。 示例请求:http://**api.fxyz.site/wolf/time?**symbol=stock&code=000001&token= 4、日线快照 获取沪深A股和ETF实时日线行情数据。 示例请求:http://api.fxyz.site/wolf/time/day?symbol=stock&code=000001&token= 5、资金流向 获取沪深A股资金流向数据。资金流数据区分主买、主卖、特大单、大单、中单、小单等。 示例请求:http://api.fxyz.site/wolf/money?code=000001&tradeDate=2026-01-19&token= 6、逐笔交易 获取沪深A股逐笔交易数据。 示例请求:http://**api.fxyz.site/wolf/deal?**code=000001&tradeDate=2026-01-19&token= 7、分价数据 获取沪深A股分价数据。 示例请求:http://api.fxyz.site/wolf/price?code=000001&tradeDate=2026-01-19&token= 8、股票列表 获取股票的代码列表。flag取值范围:0-所有股票,1-深交所股票,2-上交所股票,3-北交所股票,4-指数,5-创业板股票,6-科创板股票,7-ETF,8-ST股票,9-退市股票 示例请求:http://**api.fxyz.site/wolf/list?**flag=0&token= 9、涨停板 获取盘中涨停板实时数据。 示例请求: http://**api.fxyz.site/wolf/zt?**tradeDate=2026-01-19&token= 10、跌停板 获取盘中跌停板实时数据。 示例请求: http://**api.fxyz.site/wolf/dt?**tradeDate=2026-01-19&token= 11、炸板 获取盘中炸板实时数据。 示例请求: http://**api.fxyz.site/wolf/zb?**tradeDate=2026-01-19&token= 12、强势股 获取盘中强势股票实时数据。 数据更新:实时数据交易时间段每1分钟更新,历史数据收盘后3:30更新。 示例请求:http://**api.fxyz.site/wolf/qs?**tradeDate=2026-01-19&token= 13、次新股 获取次新股数据。 数据更新:实时数据交易时间段每1分钟更新,历史数据收盘后3:30更新。 示例请求:http://**api.fxyz.site/wolf/cx?**token= API接口文档参考:黑狼数据 - 实时、稳定、专业的金融数据API平台
浏览5498
评论12
收藏5