Metadata-Version: 2.5
Name: nautilus-ctp-fee-model
Version: 0.1.1
Summary: Deterministic CTP futures commission schedules and NautilusTrader fee model
License: MIT License
        
        Copyright (c) 2026 nautilus-ctp-fee-model contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Requires-Python: <3.15,>=3.14
Requires-Dist: nautilus-trader==1.230.0
Description-Content-Type: text/markdown

# nautilus-ctp-fee-model

`nautilus-ctp-fee-model` provides a small, deterministic commission domain for
Chinese CTP futures and a strict NautilusTrader backtest `FeeModel` adapter.
It is an independent, unofficial project and is not affiliated with Nautech
Systems, NautilusTrader, any Chinese futures exchange, or a CTP vendor.

The package deliberately has no knowledge of any upstream data provider, account
query mechanism, execution lifecycle, or position lifecycle model. It only
consumes versioned `FeeSchedule` inputs and applies a deterministic Decimal
commission calculation.

## Public API

```python
from nautilus_ctp_fee_model import (
    MODEL_ID,
    CtpFeeModel,
    CtpFeeModelConfig,
    FeeRates,
    FeeSchedule,
    PositionEffect,
    calculate_commission,
    format_position_effect_tag,
    parse_position_effect,
)
```

The persisted schema is intentionally minimal:

```json
{
  "schema_version": 1,
  "currency": "CNY",
  "instruments": {
    "a2607.DCE": {
      "open": {"by_money": "0", "by_volume": "2"},
      "close": {"by_money": "0.00005", "by_volume": "0"},
      "close_today": {"by_money": null, "by_volume": null}
    }
  }
}
```

`by_money` is a fraction of fill notional and `by_volume` is CNY per lot.
Explicit zero is known zero; `null` is unknown and causes calculation to fail.

The codec API lives in `nautilus_ctp_fee_model.codec`:

```python
from nautilus_ctp_fee_model.codec import decode_fee_schedule
from nautilus_ctp_fee_model.codec import encode_fee_schedule
from nautilus_ctp_fee_model.codec import load_fee_schedule
```

## Nautilus configuration

NautilusTrader creates the model through its native factory:

```python
from nautilus_trader.backtest.config import FeeModelFactory
from nautilus_trader.backtest.config import ImportableFeeModelConfig

config = ImportableFeeModelConfig(
    fee_model_path="nautilus_ctp_fee_model.nautilus:CtpFeeModel",
    config_path="nautilus_ctp_fee_model.nautilus:CtpFeeModelConfig",
    config={"fee_schedule_path": "/explicit/path/to/dce.json"},
)
model = FeeModelFactory.create(config)
```

The strict model requires exactly one canonical order tag:

```text
ctp.position_effect=OPEN
ctp.position_effect=CLOSE_YESTERDAY
ctp.position_effect=CLOSE_TODAY
```

Applications must use `format_position_effect_tag` and
`parse_position_effect`; they must not implement a second string codec.

## Decimal contract

Commission is calculated without `Instrument.notional_value()` and without a
binary floating-point conversion:

```text
notional = lots * fill_price * contract_multiplier
commission = lots * by_volume + notional * by_money
```

The Nautilus fixed-point extraction, all candidate calculations, and the one
final `Money.from_decimal` call execute inside a new package-owned Decimal
context with precision 128. Tests pin NautilusTrader's high-precision mode and
the fixed-point precision used by the boundary proof.

## Development

```bash
cd ctp_fee_model
uv sync --locked --exact --dev
bash ci/check.sh fast
```

Release tags are project-qualified, for example
`ctp-fee-model-v0.1.0`. A release pipeline must publish the exact wheel bytes
which passed isolated producer/consumer qualification; rebuilding in the
publish job is not acceptable.
