问题描述
解决方案
在 PTrade 量化交易平台中,600570.SS 和 600570.XSHG 指代的都是同一只股票(恒生电子),区别在于尾缀的格式标准不同。
以下是详细的区别说明及使用建议:
1. 核心区别
.SS(尾缀简称): 代表上海证券交易所(Shanghai Stock Exchange)。这是 PTrade 中常用的简写形式。.XSHG(尾缀全称): 同样代表上海证券交易所。这是更正式的交易所代码标准,通常用于系统底层数据存储和返回。
对应深圳市场的代码如下:
.SZ(简称) <-->.XSHE(全称)
2. 使用场景指南
A. 作为“输入”参数(调用函数时)
建议使用:.SS / .SZ (简称)
在调用 PTrade 的大部分 API 函数时(如 order, get_price, get_history, set_universe 等),系统做了兼容处理,两者均可使用。
但为了代码简洁和书写方便,官方文档示例和大多数策略通常使用简称。
# 都可以正常工作
order('600570.SS', 100) # 推荐,更简洁
order('600570.XSHG', 100) # 可行
B. 处理“输出”数据(获取返回值时)
必须注意:系统返回的对象通常使用 .XSHG / .XSHE (全称)
这是最容易产生 Bug 的地方。当你调用获取订单、成交或持仓的接口时,返回的数据对象中,股票代码字段通常是四位尾缀(全称)。
如果你在代码中做字符串匹配(例如 if code == '600570.SS'),而系统返回的是 '600570.XSHG',判断就会失败。
涉及全称尾缀的常见接口:
get_orders()/get_order(): 返回的 Order 对象中symbol字段。get_trades(): 返回的成交记录。get_positions(): 返回字典的键(Key)。
3. 代码示例
以下代码展示了输入使用简称,但输出需要处理全称的情况:
def initialize(context):
# 输入时:习惯使用简称 .SS
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 下单:使用简称 .SS,完全没问题
order(g.security, 100)
# 获取所有订单
orders = get_orders()
for o in orders:
# 【注意】这里打印出来的 symbol 通常是 600570.XSHG
log.info("订单中的代码: " + o.symbol)
# 错误示范:直接对比字符串,可能会失败
if o.symbol == g.security:
log.info("字符串直接匹配成功") # 可能不会执行,因为 '600570.XSHG' != '600570.SS'
# 正确示范 1:做尾缀兼容处理(只比对前6位代码)
if o.symbol[:6] == g.security[:6]:
log.info("代码匹配成功(忽略尾缀)")
# 正确示范 2:或者在比较前进行转换
# 比如将 g.security 转换为四位尾缀再比较,或者将 o.symbol 转换为两位尾缀
4. 总结
| 比较项 | .SS / .SZ | .XSHG / .XSHE |
|---|---|---|
| 全称 | 尾缀简称 | 尾缀全称 |
| 主要用途 | 输入参数(写策略时手写) | 返回值(系统返回的数据结构) |
| API 兼容性 | 绝大多数 API 支持 | 绝大多数 API 支持 |
| 建议 | 推荐用于 order, get_price 等入参 |
处理 Order, Position 对象时需留意 |
最佳实践建议:
在策略逻辑中进行股票代码比对时,建议统一格式或者仅比对前6位数字代码,以避免因尾缀不同导致的逻辑错误。
Q&A
Q: 如果我在 get_positions() 中使用 .SS 作为 Key 能取到数据吗?
A: PTrade 的 get_positions 返回的是一个字典。根据文档,返回的 Key 通常是四位尾缀(如 600570.XSHG)。但是,为了方便用户,PTrade 在某些版本或特定接口的字典取值中做了兼容,允许你用 .SS 去 get。为了保险起见,建议先打印一下 get_positions().keys() 确认当前环境的返回格式,或者遍历字典时只比对股票代码的前6位。
Q: 期货代码的尾缀是什么?
A: 期货也有对应的尾缀,例如中金所期货是 .CCFX,上海期货交易所是 .XSGE。在使用期货相关 API 时,同样需要注意输入和返回值的尾缀格式。
Q: 如何将 .SS 转换为 .XSHG?
A: 可以编写一个简单的辅助函数:
def get_full_code(code):
if code.endswith('.SS'):
return code.replace('.SS', '.XSHG')
elif code.endswith('.SZ'):
return code.replace('.SZ', '.XSHE')
return code