问题描述
目前使用 get_dominant_future 获取纯碱的主力合约是 SA2501 ,但是实际上应该是 SA2405 了,是我理解错误了嘛
解决方案
您好!这通常不是 get_dominant_future 函数的错误,而是由于 JoinQuant 平台对“主力合约”的定义规则 与您参考的其他行情软件(如文华财经、博易大师等)的规则不一致导致的。
JoinQuant 主力合约的定义规则
根据 JoinQuant 的官方 API 文档,主力合约的切换遵循以下严格规则:
- 基于持仓量(非成交量):JoinQuant 是根据**持仓量(open_interest)**来判断主力的,而不是成交量。
- 连续两天最大:某合约的持仓量必须连续2天为同一个品种中最大的。
- 必须是远期合约:该合约相对于当前主力合约必须为远期合约,才会自动变成主力合约。这意味着主力合约只会向后滚动,不会往回切(例如从 2409 切回 2405 是不允许的)。
- 切换时间:主力合约根据 T-2 和 T-1 的持仓量生成,在 T-1 的晚上(即 T 日的夜盘开始前)切换到新的主力合约。不会在日内进行切换。
为什么会出现 SA2501 而不是 SA2405?
基于上述规则,出现这种情况可能有以下原因:
- 持仓量差异:在您查询的那个时间点,
SA2501的持仓量可能确实已经连续两天超过了SA2405。其他平台可能是综合了成交量和持仓量,或者仅看成交量来定义主力。 - 远期合约限制:如果之前的主力合约已经是比
SA2405更远的合约(虽然这种情况较少见,但规则上限制了只能向远期切换),那么它就不会再切回SA2405。
如何验证?
您可以通过编写一段简单的代码,拉取这两个合约在对应日期的持仓量(open_interest)来进行验证:
from jqdata import *
def initialize(context):
# 设定要查询的日期
query_date = '2024-03-01' # 请替换为您查询的具体日期
# 获取纯碱的所有合约
contracts = get_future_contracts('SA', date=query_date)
print(f"{query_date} 纯碱可交易合约: {contracts}")
# 获取 SA2405 和 SA2501 的持仓量进行对比
# 注意:需要查询 query_date 前几天的持仓量来验证切换逻辑
df_2405 = get_price('SA2405.XZCE', end_date=query_date, count=3, fields=['open_interest'])
df_2501 = get_price('SA2501.XZCE', end_date=query_date, count=3, fields=['open_interest'])
print("\nSA2405 近期持仓量:")
print(df_2405)
print("\nSA2501 近期持仓量:")
print(df_2501)
# 查看 JoinQuant 认定的主力
dominant = get_dominant_future('SA', date=query_date)
print(f"\n{query_date} JoinQuant 认定的主力合约是: {dominant}")
总结:不同量化平台和行情软件对“主力合约”的定义没有统一的国家标准。在 JoinQuant 平台上做回测和实盘,必须遵循其“连续两天持仓量最大且为远期合约”的规则。如果您策略的逻辑强依赖于特定软件的主力切换规则,建议您自己编写逻辑,通过 get_future_contracts 获取所有合约,然后根据您自己的规则(如成交量最大)来动态选择合约进行交易的合约,而不是直接使用 get_dominant_future。