收益最高但换手太大:按换手预算筛选策略参数
测得利润最高的参数,可能超过研究协议允许的交易活动预算。应先从完整成交计算换手,执行事先门槛,再比较可行候选。信号次数不能替代成交:一次信号可能拆成多笔执行,拒单没有成交,不同再平衡的交易金额也可能差很多。
本文用合成闭合往返账计算换手和利润,再构建预算内候选前沿。方法为外部筛选,不说明CoTrading能自动约束任意策略。一次只研究同一市场、币种和共同期间,虚构结果不是历史股票绩效,也不提供实际投资参数建议。
先声明换手口径
本文度量是固定研究期间内,全部买入和卖出实际成交绝对金额之和,除以期初组合净值。它是总成交额相对初始资本,不除二,不用平均净值,也不年化。其他定义可以服务其他问题,但分母或单双边改变后,预算数字的含义也改变。
例如初始一千,先买四百、再卖四百,本文口径换手为零点八,而不是零点四。不能未经检查,就把它等同于基金法定报告换手率或券商账户活动指标。报告应把公式放在预算旁边,避免同样写百分之八十,实际数的却是不同活动。
期间边界和费用也要固定。SEC费用公告区分交易与持续成本。换手描述活动,不是费用金额,也不是完整市场冲击模型。本文零费用账只隔离预算记账;真实净表现必须包含约定费用,不能因为换手低就默认成本已经可接受。
获取完整候选成交账
每组冻结配置保留运行状态、计分会话覆盖、期初净值、证券币种、成交编号、数量、价格和方向,并连接配置与输入版本。实际成交应与目标仓位、未成交委托分开。若仅有策略希望买多少,尚不能计算已经执行的交易额。
只有运行完整,才能把空成交表解释为零活动。失败线程没有生成可用行,状态是未知,不是成功空仓。也可能运行完成但导出缺失,同样应保留缺口,不能制造空表。判断依据应来自任务完成与产物完整性,而不是文件行数恰好为零。
检查成交编号唯一,以及金额因子为正。重复导出行会让换手翻倍,即使实际引擎只执行一次。费用按订单计提时保留订单分组,但成交名义金额仍来自真实执行行;价格和股数恰好相同的两次合法部分成交,不应因为看起来重复就删掉。
从交易计算主例
所有有效候选同期间初始净值一千,期初期末均平仓,费用为零。A买卖十股,价格九十九点六和一百点四,总成交额二千,利润八。B买卖四股,价格九十九点三七五和一百点六二五,总成交额八百,利润五。
C买卖两股,价格一百四十九和一百五十一,总成交额六百,利润四。G买卖四股,价格九十九点六二五和一百点三七五,总成交额八百,利润三。F完整运行没有成交,利润零。D缺失成交输出,E虽然空表但运行失败,两者均保持未知。
| 候选 | 换手 | 零费用假设下净利润 | 预算0.8 |
|---|---|---|---|
| A | 2.0 | 8 | 超限 |
| B | 0.8 | 5 | 内部 |
| C | 0.6 | 4 | 内部 |
| F | 0 | 0 | 内部 |
| G | 0.8 | 3 | 内部 |
| D、E | 不可用 | 不可用 | 待解决 |
有效账户都在边界平仓、零费用,因此卖出所得减买入支出就是净利润,程序实际从成交推导,并非随意给收益赋值。表内是金额,不是百分比;期初资金和期间相同,才可直接排名。若期末有证券,还必须估值,不能只对现金流求和当作利润。
先过预算,再选赢家
预算为零点八,边界包含等号,因此B、C、F、G进入,A超限。A虽然利润最高,也不满足声明的活动约束。不能看完A成绩就把预算放宽到二,仍称自己执行了原定预算优化。预算变化需要新的研究记录和选择解释。
超限候选与超出数量都保留。真实搜索可能只在运行后筛选,而没有把约束嵌入候选生成;要明确属于哪一种。筛选完成结果,不证明优化器能在执行中阻止任意策略超限,更不能推断实盘委托通道已有同样限制。
计算使用从字符串构造价格的Python Decimal,核心如下:
traded = sum(fill['qty'] * fill['price'] for fill in fills)
turnover = traded / opening_nav
profit = sum(fill['qty'] * fill['price'] * fill['side']
for fill in fills)
方向在买入时为负,卖出为正。最后现金桥只在本例边界平仓、零费用条件下等于净利润。未平仓、股息或外部流入存在时,需要额外勾稽,不能直接复用这个公式,再宣称已计算完整组合回报。
构建预算内非支配前沿
如果另一候选换手不更高、净利润不更低,并且至少一项严格改善,当前点被支配。G与B同为零点八换手,但B利润五高于三,因此G被B支配。预算内剩余前沿是B、C和F,代码按这个定义计算,不靠图形目测。
C比B换手低、利润也低,互不支配。F不交易也不盈利,在这两个目标下可以保留;若研究另有最低活动或证据门槛,可能排除F,但应先定义。不能因为不喜欢前沿含一个空仓点,就在看图后静默删掉,然后声称原规则自然得到相同结果。
最终政策是在预算内选最高利润,因此选B。前沿仍显示取舍:预算更严格时可能选C。连接观测点的曲线只是视觉辅助,不证明未经运行的中间参数具有插值结果,也不代表每个预算都存在刚好合适的可执行配置。
反例:缺失填零与重复执行
第一种错误把D或E没有可用成交行解释为零换手,未知或失败运行就会错误进入预算。程序将二者放进unknown清单,只有完整且真空表的F得到合法零。三种记录表面都缺少交易,但证据状态截然不同,必须先判状态再计算。
另一种错误是重复导出B成交。重复编号在加总前被拒绝,避免换手和利润同时翻倍。真实部分成交要有不同执行身份;相同价格与数量并不能证明重复。去重依据应是稳定执行键,而不是任意删掉金额一样的行。
拆股等公司行动造成股数变化,不应在没有执行证据时被记为交易。撤单、信号和目标也各自保存。账户可能有很多非成交状态变化,正确换手只计算实际执行金额;如果输入来源只提供合并持仓差额,通常不足以恢复双边成交额,需要明确资料限制。
固定期间和分母再交接
报告每个点的起止会话、初始净值和完整性状态,确保没有把短期间候选与长期间候选直接比较。少一天的数据可能降低成交额,不能因此显得更符合预算。真实数据有停牌或缺报价时,先按统一政策处理,并解释计分覆盖是否仍然可比。
还应检查期初净值必须为正,以及成交数量与价格的单位。初始资本缩放后,整股取整、最低费用和现金限制可能改变交易,不能假定换手比例天然不变。本文所有有效例子初始一千且无整股外约束,仅验证同一分母下的明确比较。
本例B恰好落在零点八边界,检查时应直接核对精确金额八百除一千,而不是看已舍入标签决定资格。若真实计算需要容差,提前说明单位与大小,不能因为喜欢某候选而临时扩大。边界政策与后面的利润平局规则分列,能够避免两个不同判断共享一个含义不明的误差阈值。
运行与验收
下载完整示例。使用Python 3.12或更新版本,运行python R615.py。标准库十进制程序从成交得出表内金额,筛出B/C/F/G,前沿B/C/F,选择B,并把D/E保留未知,还实际拒绝重复成交编号。没有连接券商或真实回测引擎。
验收要求期间和分母固定,每个可行点追到完整成交,未知状态分离,前沿可从记录重算。保存预算边界、利润定义与全部被拒候选。不能只发布选中的B而丢掉A超限证据,否则看不出为什么没有选最高利润。
成交、费用、本金、期间覆盖或换手定义改变后重新计算,保留旧结果。预算筛选只是有条件研究决定,不证明所选参数未来盈利或可执行;真实成本与市场限制仍需在对应运行中核实,不能借用本例零费用结果作产品或投资承诺。
常见问题
信号次数可以估算本文换手吗?
不可以。这里依赖实际执行数量和价格。
失败运行空表能记为零换手吗?
不能。活动未知,只有完整且核实无成交的运行才有零状态。