问题描述
解决方案
在PTrade中进行期货回测时,设置特定品种(如沪铜)的手续费和保证金,需要在 initialize 函数中使用 set_future_commission 和 set_margin_rate 这两个API接口。
以下是详细的设置方法和代码示例。
1. 设置保证金比例 (set_margin_rate)
该函数用于设置期货合约的保证金比例。
- 语法:
set_margin_rate(transaction_code, margin_rate) - 参数说明:
transaction_code(str):交易品种代码(注意不是具体合约代码)。例如沪铜2112合约代码为CU2112.XSGE,这里只需要填'CU'。margin_rate(float):保证金比例。例如 10% 的保证金,应填0.10。
2. 设置手续费 (set_future_commission)
该函数用于设置期货合约的手续费。PTrade根据传入数值的大小自动判断是“按手收取”还是“按金额收取”。
- 语法:
set_future_commission(transaction_code, commission) - 参数说明:
transaction_code(str):交易品种代码,如'CU'。commission(float):手续费数值。- 按金额收取(费率):如果数值 小于 1,系统视为按成交额的比例收取。例如万分之零点五,应填
0.00005。 - 按手收取(固定值):如果数值 大于等于 1,系统视为按手数收取固定金额。例如每手 5 元,应填
5.0。
- 按金额收取(费率):如果数值 小于 1,系统视为按成交额的比例收取。例如万分之零点五,应填
完整策略代码示例
以下代码展示了如何将沪铜(CU)的保证金设置为 10%,并将手续费设置为成交额的万分之零点五。
def initialize(context):
# 1. 设置回测标的:沪铜2112
g.security = 'CU2112.XSGE'
set_universe(g.security)
# 2. 设置保证金比例
# 将沪铜(CU)品种的保证金设置为 10%
set_margin_rate('CU', 0.10)
# 3. 设置手续费
# 情况A:按成交额比例收取(数值 < 1)
# 将沪铜(CU)的手续费设置为万分之0.5 (0.5/10000 = 0.00005)
set_future_commission('CU', 0.00005)
# 情况B:按手数固定收取(数值 >= 1)
# 如果是黄金(AU)等按手收费的品种,例如每手10元,则如下设置:
# set_future_commission('AU', 10.0)
def handle_data(context, data):
# 简单的下单测试:买入开仓1手
# 注意:实际回测中请添加逻辑控制,避免每个bar都下单
if not context.portfolio.positions[g.security].amount:
buy_open(g.security, 1)
log.info("买入开仓沪铜,当前保证金比例与手续费已生效")
注意事项
- 品种代码 vs 合约代码:设置费率时,第一个参数必须是品种代码(如
'CU','IF','RB'),而不是具体的合约代码(如'CU2112.XSGE')。 - 生效范围:该设置仅在回测模块中生效。实盘交易中,手续费和保证金由柜台实际数据决定,策略中的设置不会覆盖柜台数据。
- 默认值:如果不调用这两个函数,PTrade回测引擎会使用系统默认的费率和保证金比例(通常是交易所标准)。
Q&A
Q: 如何确认我设置的保证金比例是否生效?
A: 在回测的 before_trading_start 或 handle_data 中,可以使用 get_margin_rate('CU') 函数来获取当前该品种的保证金比例并打印到日志中进行核对。
Q: set_future_commission 能否同时设置开仓和平仓的不同费率?
A: PTrade 的 set_future_commission 接口设置的是统一费率标准。如果需要模拟极其复杂的差异化费率(如平今仓免费),可能需要通过调整滑点 (set_slippage) 或在回测结果中进行后处理估算,标准接口暂不支持区分开平仓费率设置。
Q: 为什么我设置了手续费为 0.0001,但回测结果里手续费还是很高?
A: 请检查合约的合约乘数。按金额收取的手续费计算公式为:价格 * 合约乘数 * 手数 * 费率。沪铜的合约乘数较大(5吨/手),因此即便费率很低,单手绝对金额也会相对较高。