Skip to content

A long-to-short flip is charged as two orders, so a per-order commission applies twice #105

Closed

Description

@stefan-jansen

Version: ml4t-backtest 0.1.8

A single order that takes a position from long 100 to short 100 is split into a closing leg and an opening leg, and each leg is passed to the commission model separately. With a model that charges a flat amount per call (the shape of a per-order minimum or a per-ticket fee), one order is charged twice.

Repro: a commission model that records calls and returns 1.0; submit +100, later -200, constant prices, short selling allowed.

orders submitted: 2, fills: 2
commission calls: [('A', 100.0, 10.0), ('A', 200.0, 10.0), ('A', 100.0, 10.0), ('A', 100.0, 10.0)]
total commission charged: 3.0

Two things are visible:

  1. The flip is charged 1.0 + 1.0 for one order. Brokers that charge per order (fixed fee or minimum) charge one ticket for a flip.
  2. The model is called once more than it is charged (the 200 call), apparently for a pre-trade estimate. That is fine, but it is undocumented, and a stateful model (counting orders, tiered pricing by monthly volume) will be wrong.

Expected: a flip that is one order is charged as one order, or the split is documented and configurable; and the commission-model docs say when calculate is called and which calls are charged.

Activity

  1. added
    type: bugConfirmed or reported incorrect behavior
    and removed on Sep 23, 2026
  2. added
    priority: highMaterial user impact requiring prompt remediation
    compatibility: affectedHas Python, platform, dependency, or cross-library compatibility impact
    on Sep 23, 2026
  3. added 2 commits that reference this issue on Sep 23, 2026
    3f8957c
    7435694
  4. stefan-jansen commented on Sep 24, 2026

    @stefan-jansen
    ContributorAuthor

    Verified on PR #119 at commit 8343029. The focused tests in tests/test_commission_flip.py passed locally (2 passed); the remote coverage job passed. A long-to-short flip produces one commission-bearing fill, including stateful commission models.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    compatibility: affectedHas Python, platform, dependency, or cross-library compatibility impactpriority: highMaterial user impact requiring prompt remediationstatus: acceptedAccepted for implementationtype: bugConfirmed or reported incorrect behavior

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions