Como interpretar custos de backtest quando campos de configuração não têm efeito
Resumo
Esta nota de configuração distingue parâmetros que aparecem na identidade de um backtest daqueles que realmente afetam os custos de negociação simulados. No estudo de caso descrito, todas as execuções registradas usam uma trajetória vetorizada de retorno até o vencimento. Os campos configurados de preço de execução, taxa de comissão e taxa de slippage não são passados para essa trajetória, e as execuções pelo lado da cotação pertencem a uma corretora orientada a eventos que as execuções vetorizadas não instanciam. Os parâmetros permanecem na configuração porque removê-los alteraria a identidade hash das execuções existentes.
Os custos efetivamente aplicados são lidos separadamente de um arquivo de configuração: spreads de entrada e saída de opções, spreads estimados de hedge em cada rebalanceamento e comissões por contrato ou ação. A nota relata que o campo de slippage total registrado é nulo em toda a população indicada, embora custos sejam cobrados, porque esse fluxo não registra os totais de custos. A lição para auditoria é que um valor de configuração ou uma métrica de custo ausente, por si só, não estabelece quanto um backtest pagou. As conclusões se aplicam à implementação especificada e devem ser verificadas novamente se o executor ou o fluxo de custos mudar.
Ideias principais
- Campos de configuração podem afetar a identidade hash de uma execução mesmo quando o caminho de execução não os utiliza.
- A trajetória vetorizada de retorno até o vencimento descrita aqui não usa os campos configurados de comissão e slippage baseados em taxas.
- Os custos simulados vêm de componentes separados de opções, hedge e liquidação.
- Um campo agregado de slippage nulo não prova que nenhum custo foi cobrado.
- A interpretação dos custos depende de rastrear o executor específico e seu fluxo de dados.
Tags
Texto completo
# base.yaml ```yaml # Three fields below are inert on the path this case study runs: `execution.execution_price`, # `commission.rate` and `slippage.rate`. Every registered backtest here is `ret_to_expiry`, # which `case_studies/utils/backtest_runner.py` routes to `_run_htm_daily_mtm`, and that call # is not passed `cost_spec` - the only thing that carries these rates into a run. The # `quote_side` fill is read by the event-driven broker, which a `rebalance.mode: vectorized` # case study never constructs. They still reach the registered `backtest_config` and so the # hashed identity, which is why they stay: removing them would re-key 879 backtests to delete # values nothing reads. # # The costs this case study actually pays come from `_htm_backtest.py`, which reads # `config/setup.yaml::costs.components` directly - per-leg entry spread from the real option # quotes, `hedge_spread.estimate_bps_of_notional` on every hedge rebalance, # `commission.option_per_contract` and `commission.equity_per_share`, plus an exit spread on # liquidation. Verified 2026-09-12; `total_slippage` is NULL on all 879 rows because the # vectorized path records no cost totals, not because nothing was charged. account: allow_short_selling: true execution: execution_price: quote_side mark_price: price execution_mode: next_bar commission: model: percentage rate: 0.0005 slippage: model: percentage rate: 0.0002 calendar: calendar: NYSE timezone: UTC data_frequency: daily feed: timestamp_col: timestamp entity_col: symbol price_col: instr_mid close_col: close bid_col: instr_bid ask_col: instr_ask mid_col: instr_mid metadata: case_study: sp500_options ```
Exibido na íntegra, com atribuição conforme a licença da fonte. Licença: MIT
Este resumo foi escrito pelo agente de pesquisa da Stratmill com base no original; não é uma cópia da fonte.