手续费一加参数排名就变:如何选成本后参数
毛收益最高的参数,扣除可比交易成本后可能失去领先。应把每个候选连接到实际成交,建立候选乘费用情景矩阵。只数信号,或者给所有策略统一减一个金额,不能衡量不同参数真正交易了多少资金。
本文对两组冻结的合成往返交易做外部重算,求出排名翻转点。它不是引擎重新撮合,也不是真实股票绩效研究。两候选假设使用相同研究期间、初始资金和币种;CoTrading相关功能仍为规划或待核实,不能从算例推断产品已支持成本优化。
先取得成交层证据
导出候选编号、冻结参数、运行引用、证券、方向、数量、成交价、币种和原已收费用。再核对期初期末持仓与估值口径,独立勾稽毛损益。漏记卖出或未估值持仓,会造成并非费用导致的差异,不能直接归因成本。
先决定情景是替换原费用,还是增加独立的边际费用。如果输出已经是净收益,再减一次完整费率会重复扣除。需要恢复有依据的毛口径,或者明确只计算新增部分。原费用和情景费用分列,不能覆盖原运行记录,让后来检查者无法还原最初结果。
SEC费用投资者公告区分交易收费与持续费用,并提示从披露、成交确认和对账单确认真实成本。本文基点仅为假设,不是当前券商收费表,也不代表任何市场完整税费。
定义单位与简化边界
一个基点等于成交金额的万分之一。本文对每笔买入、卖出都按绝对股数乘成交价乘费率基点再除一万计提,然后加总两腿。相同的买卖次数,如果交易股数不同,总成本也可能相差很大,不能把次数当作金额替代。
名义成交额使用正的绝对股数,现金方向另设符号。混币种或非正价格应拒绝,不得直接相加。Python Decimal官方文档说明十进制计算与舍入控制。样例从字符串构造价格和费率,保留中间精度,只在展示时舍入。真实收费若逐笔四舍五入到分,应把这一政策写进计算,不能最后统一舍入冒充逐笔收费。
单一比例费用省略了固定佣金、最低收费、买卖不对称税款、点差变化和市场冲击。应列出这些缺项,不能无依据地称作全包成本。只要明确适用范围,这种线性情景仍可用于敏感性检查;局限不意味着可以隐藏模型假设。
主例:相同次数,不同成交金额
候选A以一百买六百股,以一百点二卖出,买入金额六万、卖出六万零一百二十,毛利润一百二十,双边成交额十二万零一百二十。候选B以一百买一百股,以一百零一卖出,金额分别一万和一万零一百,毛利润一百,双边成交额二万零一百。
两者都视作同一合成期间、初始研究资金十万的实验,各有一次买入和一次卖出。因此高敏感性的原因并不是成交次数更多,而是A交易金额更大。算例只隔离这个机制,没有选择真实证券,也没有声称十万资金产生了实际历史收益。
| 每一边成交费率 | A净利润 | B净利润 | 较高者 |
|---|---|---|---|
| 0基点 | 120 | 100 | A |
| 1基点 | 107.988 | 97.990 | A |
| 4基点 | 71.952 | 91.960 | B |
表内为利润金额,不是年化百分比。由于初始资本与期间相同,可以直接比较。若报告收益率,应分别除以相同约定资本基数,年化另行处理。不同初始本金的候选,不能用绝对利润直接排名,必须先建立可比归一化口径。
计算情景矩阵和翻转点
每个情景逐笔计算成本,按候选汇总,再从已经勾稽的毛损益扣除。核心公式如下,完整程序从成交行计算毛利润和名义金额,不是直接写入预设答案:
def net(candidate, bps):
return gross[candidate] - traded_notional[candidate] * bps / 10000
令两个净利润相等,得到120 - 120120*c/10000 = 100 - 20100*c/10000,因此c=20*10000/100020,约为一点九九九六〇〇基点。它略低于二基点,因为卖出实际所得也进入双边成交额。若偷懒用两倍买入金额,翻转位置就会移动。
完整脚本检查该阈值下两个净额的差接近零。只跑零、一、四三个情景,最多知道翻转发生在一到四之间;代数给出的是这个线性模型的精确位置,不适用于包含最低费用或复杂滑点的非线性政策。复杂政策应逐笔重算,并说明求阈值时的区间与数值精度。
保留平局、失败和单位变化
采用预先声明的平局容差,或者十进制精确比较。两个净额显示后恰好相同,不应凭隐藏小数随意宣布赢家。模型翻转点处记录平局;真实费率假设区间跨过阈值时,应报告排名依赖假设,而不是强行选出一个确定最优参数。
缺失成交不等于零费用。运行失败时保留不可用情景结果和错误,不能把缺失填零参加排名。候选确实没有交易时,需要确认运行完整且成交表真实为空,才可认定交易费用为零;持续账户费用仍可能存在,不能一概省略。
费用只在卖出侧变化时,应显式对卖出行建模,不能机械把买入费率乘二。导出金额的分、元以及费率的百分比、基点都应标注。尤其不能把数值二读成百分之二,再放入要求二基点的函数;代码通过单位字段拒绝这种混用,防止差一百倍仍输出看似整齐的表格。
不同机制反例:费用改变了成交可行性
假设现金一千,以一百买十股,未计费用时恰好用完资金。新增一元费用后需要一千零一,原成交已经不再可行。事后从余额减一,会保留一笔新执行政策下本应拒绝或缩量的交易,所以算术正确也不能说明实验有效。
把这类情景标为需要重跑,再完整执行资金和订单流程。费用改变后续仓位、杠杆资格或第二张订单的可下数量,也会产生同类问题。外部重算仅在冻结成交假设成立时有效,不能因为扣费容易,就把所有参数情景都包装成独立引擎回测。
backtesting.py API文档说明了该参考实现的佣金入口、进出双边应用及执行影响。接入已有引擎时,要查实际字段语义,不应因为名称同为commission就默认行为一致。参考库文档更不能证明CoTrading适配器已经完成相同规则。
交付可追溯的排名决定
矩阵每格附方法标签:独立完整重跑,或冻结成交外部重算。本文属于后者。再附成交导出、毛净定义、费率公式、单位、舍入和计算版本,以及参数到运行的引用。四基点下A失去领先,也仍保留在结果表中,不能删除这个高成交额候选后声称所有参数对费用都稳定。
检查者应能从任一格下钻到两笔成交与各自费用,重算情景净额,再重建排名。列出是否存在未平仓、费用能否改变下单数量和是否发生资金缺口。对这些条件未知的真实数据,应把方法适用性标为待核实,而不是假定满足;同时说明下一步需要哪些账户或执行字段才能解除限制。
每格还应保存两笔单独费用,而不仅是汇总金额。这样能定位漏收卖出费用、误乘额外往返次数或对净结果重复扣费。若同一次成交分成多笔撮合,最低收费究竟按订单还是按撮合计提也要明确,否则分笔方式改变就可能移动翻转阈值,不能继续沿用当前简单比例公式。
实际运行和更新条件
下载完整示例。使用Python 3.12或更新版本,运行python R609.py。标准库十进制计算得到毛利润一百二十与一百、成交额十二万零一百二十与二万零一百、阈值一点九九九六〇〇基点,以及四基点净额七十一点九五二与九十一点九六。断言拒绝单位不符,并标出现金可行性边界。
成交、价格、费用组件、舍入或账户限制修订时重新计算。新费用改变执行时,用有引用的重跑替换相关情景,不要混用方法却不标注。成本后排名是有条件的候选决定,不证明未来盈利,也不能覆盖账本未包含的费用。更新后保留旧矩阵,说明哪项输入改变导致排名翻转,便于继续研究。
常见问题
买入侧费用乘二就够了吗?
只有政策真正对称且金额处理正确才可能成立。真实买卖金额和收费都可能不同。
外部扣费就是重新回测吗?
不是。它固定了成交,费用影响资金和股数时需要重新执行订单流程。