问题描述
解决方案
在PTrade量化交易平台中,获取期货的多空仓位及计算浮动盈亏,主要通过调用 get_position(security) 函数获取 Position 对象,然后访问该对象的特定属性来实现。
核心概念说明
- 获取持仓对象:使用
get_position(security)获取指定合约的持仓详情。 - 多头信息:
- 仓位:
long_amount(多头总持仓量) - 盈亏:
long_pnl(多头浮动盈亏)
- 仓位:
- 空头信息:
- 仓位:
short_amount(空头总持仓量) - 盈亏:
short_pnl(空头浮动盈亏)
- 仓位:
PTrade系统会自动根据当前的最新价、持仓成本(long_cost_basis / short_cost_basis)以及合约乘数(contract_multiplier)来计算浮动盈亏,通常不需要用户手动编写公式计算。
策略代码示例
以下是一个完整的策略示例,展示了如何在交易过程中获取当前的多头和空头持仓量,以及对应的浮动盈亏,并将其打印在日志中。
def initialize(context):
"""
初始化函数
"""
# 设置我们要操作的期货合约,这里以中金所沪深300股指期货为例
# 注意:实际回测或交易时请确保合约代码在有效期内
g.security = 'IF2309.CCFX'
set_universe(g.security)
# 设置一个标志位,用于演示开仓
g.has_ordered = False
def handle_data(context, data):
"""
盘中运行函数
"""
# ---------------------------------------------------
# 1. 演示下单(为了让账户有持仓,方便展示查询结果)
# ---------------------------------------------------
if not g.has_ordered:
# 买入开仓 1手 (多头)
buy_open(g.security, 1)
# 卖出开仓 1手 (空头 - 锁仓演示)
sell_open(g.security, 1)
g.has_ordered = True
log.info("已执行开仓操作:多头1手,空头1手")
return # 开仓当次循环先跳过查询,等待下一tick或分钟更新持仓状态
# ---------------------------------------------------
# 2. 获取持仓对象
# ---------------------------------------------------
# 获取指定合约的持仓详情
position = get_position(g.security)
# 如果没有持仓对象(通常不会发生,除非代码错误),则返回
if position is None:
log.info("当前无持仓信息")
return
# ---------------------------------------------------
# 3. 获取多头和空头仓位及盈亏
# ---------------------------------------------------
# --- 多头数据 ---
# 多头总持仓量
long_amount = position.long_amount
# 多头可用数量 (平仓时使用)
long_enable = position.long_enable_amount
# 多头浮动盈亏
long_pnl = position.long_pnl
# 多头持仓成本
long_cost = position.long_cost_basis
# --- 空头数据 ---
# 空头总持仓量
short_amount = position.short_amount
# 空头可用数量
short_enable = position.short_enable_amount
# 空头浮动盈亏
short_pnl = position.short_pnl
# 空头持仓成本
short_cost = position.short_cost_basis
# ---------------------------------------------------
# 4. 打印日志信息
# ---------------------------------------------------
log.info("====== 合约: %s 持仓详情 ======" % g.security)
log.info("[多头] 持仓量: %s, 可用: %s, 成本: %.2f, 浮动盈亏: %.2f" % (
long_amount, long_enable, long_cost, long_pnl
))
log.info("[空头] 持仓量: %s, 可用: %s, 成本: %.2f, 浮动盈亏: %.2f" % (
short_amount, short_enable, short_cost, short_pnl
))
# 计算总盈亏
total_pnl = long_pnl + short_pnl
log.info("[汇总] 净浮动盈亏: %.2f" % total_pnl)
关键字段详解
在 Position 对象中,期货交易相关的关键字段如下:
| 属性名 | 类型 | 说明 |
|---|---|---|
| long_amount | int | 多头总持仓量。包含今仓和昨仓。 |
| short_amount | int | 空头总持仓量。包含今仓和昨仓。 |
| long_pnl | float | 多头浮动盈亏。计算逻辑大致为:(最新价 - 多头持仓成本) * 合约乘数 * 多头数量。 |
| short_pnl | float | 空头浮动盈亏。计算逻辑大致为:(空头持仓成本 - 最新价) * 合约乘数 * 空头数量。 |
| long_cost_basis | float | 多头持仓均价(成本)。 |
| short_cost_basis | float | 空头持仓均价(成本)。 |
| today_long_amount | int | 多头今仓数量(仅回测有效,实盘中通常不区分今昨仓字段,需通过柜台规则判断)。 |
| today_short_amount | int | 空头今仓数量(仅回测有效)。 |
| contract_multiplier | int | 合约乘数(例如沪深300是300,螺纹钢是10)。 |
常见问题 (Q&A)
Q: 为什么 get_position 返回的 amount 属性在期货中通常是 0?
A: 在PTrade的期货模式下,amount 属性通常用于股票等单向交易品种。对于期货,必须明确区分方向,因此请务必使用 long_amount 和 short_amount,不要使用 amount。
Q: long_pnl 是基于结算价计算的还是基于最新价计算的?
A: 在盘中(handle_data 或 tick_data),long_pnl 和 short_pnl 通常是基于最新成交价(Last Price)计算的浮动盈亏。如果是盘后结算数据,则取决于券商柜台的返回逻辑。
Q: 如何获取合约乘数来手动计算盈亏?
A: 可以通过 position.contract_multiplier 获取该合约的乘数。
手动计算多头盈亏公式示例:(current_price - position.long_cost_basis) * position.long_amount * position.contract_multiplier。
Q: 回测时 today_long_amount 和 long_amount 有什么区别?
A: long_amount 是总持仓(今仓 + 昨仓)。today_long_amount 仅指当日新开的仓位。这在处理“平今仓”手续费较高的品种(如股指期货)时非常有用,可以用来判断优先平昨仓还是平今仓。