问题描述
解决方案
在PTrade中,获取历史成交明细(即交割单)需要使用 get_deliver 函数。
关键注意事项
- 仅限实盘交易:该函数仅在交易模块(实盘)可用,回测环境中无法使用。
- 调用时机限制:仅支持在
before_trading_start(盘前)和after_trading_end(盘后)阶段调用。 - 账户限制:仅支持查询普通股票账户,不支持两融账户。
- 时间范围:仅支持查询上一个交易日(包含)之前的数据,无法查询当日实时的交割单。
策略代码实现
以下代码展示了如何自动计算“上个季度”的起始和结束日期,并调用接口获取交割单数据。
import datetime
def initialize(context):
# 初始化函数,实盘中必须存在
pass
def before_trading_start(context, data):
"""
盘前处理函数,在此处调用get_deliver
"""
# 1. 获取当前日期
current_date = context.blotter.current_dt.date()
# 2. 计算上个季度的起始和结束日期
start_date, end_date = get_last_quarter_dates(current_date)
log.info("正在查询上个季度的交割单,时间范围: %s 到 %s" % (start_date, end_date))
# 3. 调用 get_deliver 接口
# 注意:日期格式必须为 'YYYYmmdd' 字符串
start_str = start_date.strftime('%Y%m%d')
end_str = end_date.strftime('%Y%m%d')
delivery_records = get_deliver(start_str, end_str)
# 4. 打印或处理数据
if delivery_records:
log.info("查询成功,共获取到 %d 条交割记录" % len(delivery_records))
for record in delivery_records:
# 打印每一条交割单详情
log.info(record)
# 示例:获取成交金额和股票名称
# log.info("股票: %s, 操作: %s, 成交金额: %s" % (record.get('stock_name'), record.get('business_name'), record.get('business_balance')))
else:
log.info("该时间段内无交割单记录或查询失败。")
def handle_data(context, data):
pass
def get_last_quarter_dates(current_date):
"""
辅助函数:根据当前日期计算上个季度的第一天和最后一天
返回: (start_date, end_date) datetime.date对象
"""
current_month = current_date.month
current_year = current_date.year
# 确定上个季度的年份和月份范围
if 1 <= current_month <= 3:
# 当前是1季度,上季度是去年的4季度 (10月-12月)
prev_q_year = current_year - 1
prev_q_start_month = 10
prev_q_end_month = 12
prev_q_end_day = 31
elif 4 <= current_month <= 6:
# 当前是2季度,上季度是今年的1季度 (1月-3月)
prev_q_year = current_year
prev_q_start_month = 1
prev_q_end_month = 3
prev_q_end_day = 31
elif 7 <= current_month <= 9:
# 当前是3季度,上季度是今年的2季度 (4月-6月)
prev_q_year = current_year
prev_q_start_month = 4
prev_q_end_month = 6
prev_q_end_day = 30
else:
# 当前是4季度,上季度是今年的3季度 (7月-9月)
prev_q_year = current_year
prev_q_start_month = 7
prev_q_end_month = 9
prev_q_end_day = 30
start_date = datetime.date(prev_q_year, prev_q_start_month, 1)
end_date = datetime.date(prev_q_year, prev_q_end_month, prev_q_end_day)
return start_date, end_date
返回数据说明
get_deliver 返回的是一个列表,列表中的每个元素是一个字典(dict),代表一条交割记录。由于不同券商柜台返回的字段可能存在差异,以下是常见的字段示例:
business_date/init_date: 交易日期stock_code: 证券代码stock_name: 证券名称business_name: 业务名称(如“证券买入”、“证券卖出”)business_price: 成交价格business_amount: 成交数量business_balance: 成交金额occur_balance: 发生金额(包含费用的最终变动金额)commission: 佣金(字段名可能因柜台而异,如fare0等)stamp_tax: 印花税(字段名可能因柜台而异,如fare1等)
建议您先运行一次代码,查看 log.info(record) 打印出的具体字段名称,再根据实际需求提取数据。
Q&A
Q: 为什么我在回测里调用 get_deliver 返回是空的或者报错?
A: get_deliver 是交易专用接口,用于获取真实的柜台交割数据。回测环境是模拟的,没有真实的柜台交割单,因此无法使用。回测中如果需要查看成交,请使用 get_trades()。
Q: 我可以查询今天的交割单吗?
A: 不可以。get_deliver 通常只能查询上一个交易日及之前的历史数据。当日的成交情况请使用 get_trades() 或 get_all_orders()。
Q: 如何导出这些数据到CSV文件?
A: PTrade策略运行在云端,直接导出文件比较困难。您可以在 log.info 中按CSV格式打印数据(例如用逗号分隔),然后复制日志内容到本地保存为CSV文件。或者使用Python的 pandas 库在策略中处理数据,但保存文件路径受限于 get_research_path() 权限。