问题描述
/
解决方案
在 ptrade 量化交易平台中,查询资金和持仓信息是策略编写的基础。理解其与柜台的同步逻辑对于避免重复下单、计算可用资金至关重要。以下是详细的逻辑解析:
一、 资金信息查询逻辑
资金信息主要通过上下文对象 context.portfolio 获取。引擎会在后台自动与柜台进行同步。
- 获取当前可用资金:
context.portfolio.cash(不包含冻结资金) - 获取账户总资产:
context.portfolio.portfolio_value(持仓市值 + 现金) - 获取持仓总市值:
context.portfolio.positions_value
二、 持仓信息查询逻辑
持仓信息可以通过 context 对象或专门的 API 函数获取:
- 通过 context 获取:
context.portfolio.positions返回一个字典,key 是标的代码,value 是Position对象。可以遍历获取所有持仓。 - 获取单个标的持仓:
使用get_position(security)函数,返回指定标的的Position对象。包含amount(总持仓)、enable_amount(可用数量) 等属性。 - 获取多个标的持仓详情:
使用get_positions(security_list)函数,返回包含多个标的持仓信息的字典。
三、 柜台同步逻辑与时滞(核心注意点)
ptrade 引擎的资金和持仓数据是与券商柜台进行同步的,但并非绝对的实时无延迟。这主要受限于券商柜台的配置和网络通信:
- 同步时滞:在交易场景中,持仓和资金信息的同步通常存在时滞,一般在 6 秒左右。这意味着当你下达一笔买入委托并成交后,
context.portfolio.cash和get_position返回的数据可能需要几秒钟才会更新。 - 券商配置差异:
- 体现当日变化:大多数柜台配置为体现当日变化,即盘中会不断同步。但由于上述的 6 秒时滞,如果在短时间内(如 1 秒内)连续调用
order_target或order_target_value,由于持仓未及时更新,极易导致重复下单。 - 不体现当日变化:极少数情况下,柜台配置为不体现当日变化(一天只同步一次)。这种情况下,绝对不能依赖持仓查询接口来进行目标数量的调仓。
- 体现当日变化:大多数柜台配置为体现当日变化,即盘中会不断同步。但由于上述的 6 秒时滞,如果在短时间内(如 1 秒内)连续调用
四、 最佳实践与代码示例
为了避免同步时滞带来的问题,建议在策略中自行维护订单状态,或者避免在极短时间内对同一标的进行基于持仓的目标调仓。
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 1. 查询资金
available_cash = context.portfolio.cash
log.info(f"当前可用资金: {available_cash}")
# 2. 查询持仓
pos = get_position(g.security)
log.info(f"{g.security} 总持仓: {pos.amount}, 可用持仓: {pos.enable_amount}")
# 3. 安全的下单逻辑示例
# 假设我们要买入,先判断资金是否充足
current_price = data[g.security]['close']
if available_cash > current_price * 100:
order(g.security, 100)
# 注意:下单后,available_cash 和 pos.amount 不会立即改变,需等待柜台同步
总结:ptrade 的资金和持仓查询非常便捷,但开发者必须牢记**“柜台同步存在约 6 秒时滞”**这一关键逻辑,在编写高频或依赖精确持仓的策略时做好状态管理。