问题描述
解决方案
在PTrade中,查询历史资金变动记录(包括股票买卖结算、银证转账、利息归本等流水)主要使用 get_fundjour 函数。
该函数专门用于获取账户的历史资金流水信息。
核心代码实现
以下是一个完整的策略示例,展示如何在每日盘前(before_trading_start)查询过去30天的资金流水并打印到日志中。
import datetime
def initialize(context):
# 初始化函数,这里不需要做特殊设置
pass
def before_trading_start(context, data):
"""
盘前处理函数
get_fundjour 仅支持在 before_trading_start 和 after_trading_end 阶段调用
"""
# 1. 获取当前日期
# context.blotter.current_dt 获取的是当前策略运行的时间
current_date = context.blotter.current_dt.date()
# 2. 计算查询的时间范围
# 结束日期设为昨天(因为该接口通常查询历史数据,不包含当日实时流水)
end_date = current_date - datetime.timedelta(days=1)
# 开始日期设为结束日期往前推30天
start_date = end_date - datetime.timedelta(days=30)
# 3. 转换日期格式为字符串 'YYYYmmdd'
start_str = start_date.strftime('%Y%m%d')
end_str = end_date.strftime('%Y%m%d')
log.info("开始查询资金流水,时间范围: %s 到 %s" % (start_str, end_str))
# 4. 调用接口获取资金流水
# 注意:该函数仅在【交易模式】下有效,回测模式下通常无数据或不支持
fund_records = get_fundjour(start_str, end_str)
# 5. 处理并打印数据
if fund_records:
for record in fund_records:
# 打印关键字段:日期、业务名称、发生金额、后资金额、备注
log.info("日期: %s, 业务: %s, 发生金额: %s, 账户余额: %s, 备注: %s" % (
record.get('business_date'),
record.get('business_name'),
record.get('occur_balance'),
record.get('post_balance'),
record.get('remark')
))
else:
log.info("该时间段内未查询到资金流水记录。")
def handle_data(context, data):
pass
def after_trading_end(context, data):
pass
关键说明
-
适用场景:
get_fundjour函数仅在交易模块(实盘/仿真)中使用。- 它仅支持在
before_trading_start(盘前)和after_trading_end(盘后)阶段调用,不能在handle_data(盘中)中调用。
-
参数格式:
start_date和end_date必须是字符串格式'YYYYmmdd'(例如'20231001')。
-
返回数据解析:
函数返回的是一个字典列表,其中包含的关键字段如下:business_name: 业务名称(如“证券买入”、“证券卖出”、“银行转存”、“银行转取”等)。occur_balance: 发生金额(负数通常代表资金流出或买入扣款,正数代表资金流入或卖出回款)。post_balance: 变动后的资金余额。remark: 备注信息(通常包含具体的股票名称、代码、成交价格等细节)。business_date: 业务发生日期。
-
数据时效性:
- 该接口主要用于查询历史流水(上一个交易日及之前)。当日实时的资金变动通常不通过此接口查询,而是通过
context.portfolio.cash查看当前可用资金,或通过get_trades()查看当日成交。
- 该接口主要用于查询历史流水(上一个交易日及之前)。当日实时的资金变动通常不通过此接口查询,而是通过
Q&A
Q: 为什么我在回测模式下调用 get_fundjour 返回是空的?
A: get_fundjour 是专门用于对接柜台查询账户实际历史流水的接口。在回测环境中,资金变动是模拟计算的,并没有真实的柜台流水记录,因此该函数仅在交易(实盘或仿真交易)模式下可用。
Q: 如何区分是“买卖股票”还是“银证转账”?
A: 您可以通过返回字典中的 business_name(业务名称)字段来判断。
- 如果是 银证转账,
business_name通常显示为“银行转存”(转入证券账户)或“银行转取”(转出到银行卡)。 - 如果是 股票交易,
business_name通常显示为“证券买入”或“证券卖出”。
Q: 我可以查询超过一个月的记录吗?
A: 可以。只要修改代码中的 datetime.timedelta(days=30) 为您需要的天数即可。不过请注意,查询跨度过大可能会导致接口返回数据较慢,建议根据实际需求分段查询。