问题描述
解决方案
获取订单与获取成交的区别及交易成本分析
在 JoinQuant 聚宽平台中,订单 (Order) 和 成交 (Trade) 是两个不同阶段的概念。理解它们的区别对于编写精确的策略和进行盘后分析至关重要。
1. 核心区别
简单来说,订单是你的“请求”,成交是市场的“结果”。
-
获取订单 (
get_orders):- 定义:代表你向交易所发送的委托指令。
- 包含信息:包含你希望买卖的标的、数量、价格(限价单)、订单状态(如已委托、全部成交、已撤单等)以及该订单产生的总费用。
- 关系:一个订单可能对应零个、一个或多个成交记录(例如一个大单分多次撮合成交)。
-
获取成交 (
get_trades):- 定义:代表订单在市场上实际撮合成功的记录。
- 包含信息:包含具体的成交时间、成交价格、成交数量。
- 关系:它是订单执行的明细。如果一个订单没有成交(如限价单价格未触发),则不会有对应的成交记录。
2. 应该用哪个函数分析交易成本?
推荐使用 get_orders() 来分析交易成本。
原因:
根据 JoinQuant API 文档,Order 对象直接包含了一个 commission 属性,该属性记录了该笔订单产生的交易费用总和(包含佣金、印花税等)。
虽然 get_trades() 反映了撮合细节,但在 API 的 Trade 对象定义中,主要关注的是价格 (price) 和数量 (amount) 以及时间 (time),而 Order 对象则帮您汇总了这笔委托最终产生的总成本。
3. 代码示例
以下代码展示了如何获取当天的订单信息并打印每笔订单的交易成本:
# -*- coding: utf-8 -*-
def after_trading_end(context):
# 获取当天的所有订单
orders = get_orders()
total_cost = 0.0
print("今日交易成本分析:")
for order_id, order_obj in orders.items():
# 仅统计已成交或部分成交的订单
if order_obj.filled > 0:
# order_obj.commission 包含了该订单的佣金和税费
cost = order_obj.commission
total_cost += cost
print(f"订单ID: {order_id}")
print(f"标的: {order_obj.security}")
print(f"状态: {order_obj.status}")
print(f"成交数量: {order_obj.filled}")
print(f"交易费用: {cost}")
print("-" * 20)
print(f"今日总交易成本: {total_cost}")
4. 详细对比表
| 特性 | 订单 (Order) | 成交 (Trade) |
|---|---|---|
| API 函数 | get_orders() / get_open_orders() |
get_trades() |
| 代表含义 | 策略发出的委托指令 | 交易所撮合成功的记录 |
| 数量关系 | 1 个订单 | 对应 N 个成交记录 (N >= 0) |
| 关键属性 | status (状态), commission (费用), avg_cost (均价) |
price (具体成交价), time (具体成交时间) |
| 主要用途 | 检查委托状态、撤单、统计成本 | 分析滑点、查看具体成交时间点 |
总结
- 如果您需要统计花了多少手续费,请使用
get_orders()并查看commission属性。 - 如果您需要分析具体的成交时间点或分笔成交的价格分布(例如分析大单对市场的冲击或滑点),请使用
get_trades()。
Q&A
Q: 为什么我的订单状态是 filled,但 get_trades() 返回了多条记录?
A: 这很正常。如果您的订单数量较大,或者市场流动性不足,交易所可能会将您的一个订单拆分成多笔交易与不同的对手盘撮合。get_trades() 会返回所有这些具体的撮合记录,而 Order 对象则显示汇总后的结果。
Q: Order.price 和 Trade.price 有什么区别?
A: Order.price 通常指该订单已成交部分的平均成交价格。而 Trade.price 是某一笔具体撮合的实际成交价格。
Q: 未成交的订单会有交易成本吗?
A: 不会。如果订单状态为 open(未成交)或 rejected(被拒绝),其 filled 数量为 0,commission 通常也为 0。只有发生实际成交(filled > 0)才会产生费用。