Skip to content

Commit

Permalink
Release 1.207.0
Browse files Browse the repository at this point in the history
See release notes.
  • Loading branch information
cjdsellers authored Nov 29, 2024
2 parents 230b42f + f80d47f commit 02a9ef1
Show file tree
Hide file tree
Showing 186 changed files with 9,778 additions and 2,348 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel msgspec
run: python -m pip install --upgrade pip setuptools wheel

- name: Set poetry cache-dir
run: echo "POETRY_CACHE_DIR=$(poetry config cache-dir)" >> $GITHUB_ENV
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

# ta-lib Python install currently broken
# https://github.com/TA-Lib/ta-lib-python/issues/655
Expand Down Expand Up @@ -221,7 +221,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

- name: Cached pre-commit
id: cached-pre-commit
Expand Down Expand Up @@ -324,7 +324,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

- name: Cached pre-commit
id: cached-pre-commit
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

# ta-lib Python install currently broken
# https://github.com/TA-Lib/ta-lib-python/issues/655
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

- name: Test pip installation
run: pip install .
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

- name: Set poetry cache-dir
run: echo "POETRY_CACHE_DIR=$(poetry config cache-dir)" >> $GITHUB_ENV
Expand Down Expand Up @@ -217,7 +217,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

- name: Set poetry cache-dir
run: echo "POETRY_CACHE_DIR=$(poetry config cache-dir)" >> $GITHUB_ENV
Expand Down Expand Up @@ -324,7 +324,7 @@ jobs:
version: ${{ env.POETRY_VERSION }}

- name: Install build dependencies
run: python -m pip install --upgrade pip setuptools wheel pre-commit msgspec
run: python -m pip install --upgrade pip setuptools wheel pre-commit

- name: Set poetry cache-dir
run: echo "POETRY_CACHE_DIR=$(poetry config cache-dir)" >> $GITHUB_ENV
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ repos:
exclude: "docs/_pygments/monokai.py"

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.4
rev: v0.8.1
hooks:
- id: ruff
args: ["--fix"]
Expand Down Expand Up @@ -129,6 +129,6 @@ repos:
]

- repo: https://github.com/kynan/nbstripout
rev: 0.8.0
rev: 0.8.1
hooks:
- id: nbstripout
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ build-wheel-debug:

.PHONY: clean
clean:
git clean -fxd
git clean -fxd -e tests/test_data/large/

.PHONY: format
format:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

| Platform | Rust | Python |
| :----------------- | :------ | :----- |
| `Linux (x86_64)` | 1.82.0+ | 3.11+ |
| `macOS (arm64)` | 1.82.0+ | 3.11+ |
| `Windows (x86_64)` | 1.82.0+ | 3.11+ |
| `Linux (x86_64)` | 1.83.0+ | 3.11+ |
| `macOS (arm64)` | 1.83.0+ | 3.11+ |
| `Windows (x86_64)` | 1.83.0+ | 3.11+ |

[![](https://dcbadge.limes.pink/api/server/AUWVs3XaCS)](https://discord.gg/AUWVs3XaCS)

Expand Down
44 changes: 42 additions & 2 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
# NautilusTrader 1.207.0 Beta

Released on 29th November 2024 (UTC).

### Enhancements
- Implemented mixed catalog data requests with catalog update (#2043), thanks @faysou
- Added Databento symbology support for Interactive Brokers (#2073), thanks @rsmb7z
- Added `metadata` parameter for data requests (#2043), thanks @faysou
- Added `STOP_MARKET` and `STOP_LIMIT` order support for dYdX (#2066), thanks @davidsblom
- Added `max_reconnection_tries` to data client config for dYdX (#2066), thanks @davidsblom
- Added wallet subscription for Bybit (#2076), thanks @sunlei
- Added docs clarity on loading historical bars (#2078), thanks @dodofarm
- Added `price_precision` optional parameter for `DatabentoDataLoader` methods
- Improved `Cache` behavior when adding more recent quotes, trades, or bars (now adds to cache)

### Internal Improvements
- Ported `Portfolio` and `AccountManager` to Rust (#2058), thanks @Pushkarm029
- Implemented `AsRef<str>` for `Price`, `Money`, and `Currency`
- Improved expired timer cleanup in clocks (#2064), thanks @twitu
- Improved live engines error logging (will now log all exceptions rather than just `RuntimeError`)
- Improved symbol normalization for Tardis
- Improved historical bar request performance for Tardis
- Improved `TradeId` Debug implementation to display value as proper UTF-8 string
- Refined `HttpClient` for use directly from Rust
- Refined Databento decoder (removed currency hard coding and use of `unsafe`)
- Upgraded `datafusion` crate to v43.0.0 (#2056), thanks @twitu

### Breaking Changes
- Renamed `TriggerType.LAST_TRADE` to `LAST_PRICE` (more conventional terminology)

### Fixes
- Fixed missing venue -> exchange mappings for Tardis integration
- Fixed account balance and order status parsing for dYdX (#2067), thanks @davidsblom
- Fixed parsing best effort opened order status for dYdX (#2068), thanks @davidsblom
- Fixed occasionally incorrect `price_precision`, `multiplier` and `lot_size` decoding for Databento instruments
- Fixed missing Arrow schemas for instrument deserialization
- Reconcile order book for dYdX when inconsistent (#2077), thanks @davidsblom

---

# NautilusTrader 1.206.0 Beta

Released on 17th November 2024 (UTC).

### Enhancements
- Added `TardisDataClient` providing live data streams from a Tardis Machine WebSocket server
- Added `TardisInstrumentProvider` providing instrument definitions from Tardis through the HTTP instrument metadata API
- Added `Portfolio.realized_pnl(...)` method for per instrument realized PnL (based on positions)
- Added `Portfolio.realized_pnls(...)` method for per venue realized PnL (based on positions)
- Added `TardisInstrumentProvider`
- Added `PolymarketExecClientConfig.generate_order_history_from_trades` config setting (default False and not currently recommended)
- Added configuration warning for `InstrumentProvider` (to warn when node starts with no instrument loading)
- Implemented Tardis optional [symbol normalization](https://nautilustrader.io/docs/nightly/integrations/tardis/#symbology-and-normalization)
- Implemented `WebSocketClient` reconnection retries (#2044), thanks @davidsblom
Expand Down
10 changes: 5 additions & 5 deletions docs/concepts/orders.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ order: StopMarketOrder = self.order_factory.stop_market(
order_side=OrderSide.SELL,
quantity=Quantity.from_int(1),
trigger_price=Price.from_int(100_000),
trigger_type=TriggerType.LAST_TRADE, # <-- optional (default DEFAULT)
trigger_type=TriggerType.LAST_PRICE, # <-- optional (default DEFAULT)
time_in_force=TimeInForce.GTC, # <-- optional (default GTC)
expire_time=None, # <-- optional (default None)
reduce_only=False, # <-- optional (default False)
Expand Down Expand Up @@ -328,7 +328,7 @@ See the `MarketToLimitOrder` [API Reference](../api_reference/model/orders.md#cl
### Market-If-Touched

A _Market-If-Touched_ order is a conditional order which once triggered will immediately
place a _Market_ order. This order type is often used to enter a new position on a stop price in the market orders direction,
place a _Market_ order. This order type is often used to enter a new position on a stop price,
or to take profits for an existing position, either as a SELL order against LONG positions,
or as a BUY order against SHORT positions.

Expand All @@ -349,7 +349,7 @@ order: MarketIfTouchedOrder = self.order_factory.market_if_touched(
order_side=OrderSide.SELL,
quantity=Quantity.from_int(10),
trigger_price=Price.from_str("10_000.00"),
trigger_type=TriggerType.LAST_TRADE, # <-- optional (default DEFAULT)
trigger_type=TriggerType.LAST_PRICE, # <-- optional (default DEFAULT)
time_in_force=TimeInForce.GTC, # <-- optional (default GTC)
expire_time=None, # <-- optional (default None)
reduce_only=False, # <-- optional (default False)
Expand Down Expand Up @@ -386,7 +386,7 @@ order: StopLimitOrder = self.order_factory.limit_if_touched(
quantity=Quantity.from_int(5),
price=Price.from_str("30_100"),
trigger_price=Price.from_str("30_150"),
trigger_type=TriggerType.LAST_TRADE, # <-- optional (default DEFAULT)
trigger_type=TriggerType.LAST_PRICE, # <-- optional (default DEFAULT)
time_in_force=TimeInForce.GTD, # <-- optional (default GTC)
expire_time=pd.Timestamp("2022-06-06T12:00"),
post_only=True, # <-- optional (default False)
Expand Down Expand Up @@ -425,7 +425,7 @@ order: TrailingStopMarketOrder = self.order_factory.trailing_stop_market(
order_side=OrderSide.SELL,
quantity=Quantity.from_int(10),
trigger_price=Price.from_str("5_000"),
trigger_type=TriggerType.LAST_TRADE, # <-- optional (default DEFAULT)
trigger_type=TriggerType.LAST_PRICE, # <-- optional (default DEFAULT)
trailing_offset=Decimal(100),
trailing_offset_type=TrailingOffsetType.BASIS_POINTS,
time_in_force=TimeInForce.GTC, # <-- optional (default GTC)
Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ def buy(self) -> None:
order_side=OrderSide.BUY,
quantity=self.instrument.make_qty(self.trade_size),
price=self.instrument.make_price(5000.00),
emulation_trigger=TriggerType.LAST_TRADE,
emulation_trigger=TriggerType.LAST_PRICE,
)

self.submit_order(order)
Expand Down
29 changes: 24 additions & 5 deletions docs/integrations/ib.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,35 +101,42 @@ To troubleshoot TWS API incoming message issues, consider starting at the `Inter

## Symbology

The InteractiveBrokersInstrumentProvider supports two methods for constructing InstrumentId instances, which can be configured via the strict_symbology flag in InteractiveBrokersInstrumentProviderConfig.
The InteractiveBrokersInstrumentProvider supports three methods for constructing InstrumentId instances, which can be configured via the `symbology_method` enum in `InteractiveBrokersInstrumentProviderConfig`.

### Simplified Symbology

When strict_symbology is set to False (the default setting), the system utilizes the following parsing rules for symbology:
When symbology_method is set to `IB_SIMPLIFIED` (the default setting), the system utilizes the following parsing rules for symbology:

- Forex: The format is `{symbol}/{currency}.{exchange}`, where the currency pair is constructed as `EUR/USD.IDEALPRO`.
- Stocks: The format is `{localSymbol}.{primaryExchange}`. Any spaces in localSymbol are replaced with -, e.g., `BF-B.NYSE`.
- Futures: The format is `{localSymbol}.{exchange}`. Single digit years are expanded to two digits, e.g., `ESM24.CME`.
- Options: The format is `{localSymbol}.{exchange}`, with all spaces removed from localSymbol, e.g., `AAPL230217P00155000.SMART`.
- Index: The format is `^{localSymbol}.{exchange}`, e.g., `^SPX.CBOE`.

### Strict Symbology
### Raw Symbology

Setting strict_symbology to True enforces stricter parsing rules that align directly with the fields defined in the ibapi. The format for each security type is as follows:
Setting symbology_method to `IB_RAW` enforces stricter parsing rules that align directly with the fields defined in the ibapi. The format for each security type is as follows:

- CFDs: `{localSymbol}={secType}.IBCFD`
- Commodities: `{localSymbol}={secType}.IBCMDTY`
- Default for Other Types: `{localSymbol}={secType}.{exchange}`

This configuration ensures that the symbology is explicitly defined and matched with the Interactive Brokers API requirements, providing clear and consistent instrument identification.
While this format may lack visual clarity, it is robust and supports instruments from any region,
especially those with non-standard symbology where simplified parsing may fail.

### Databento Symbology

Setting symbology_method to `DATABENTO`, the system utilized the symbology rules defined by `DatabentoInstrumentProvider`.
Note that this symbology is only compatible with venues supported by Databento and there is not automatic fall-back to other symbology methods to avoid any conflicts.

## Instruments & Contracts

In IB, a NautilusTrader `Instrument` is equivalent to a [Contract](https://ibkrcampus.com/ibkr-api-page/trader-workstation-api/#contracts). Contracts can be either a [basic contract](https://ibkrcampus.com/ibkr-api-page/trader-workstation-api/#contract-object) or a more [detailed](https://ibkrcampus.com/ibkr-api-page/trader-workstation-api/#contract-details) version (ContractDetails). The adapter models these using `IBContract` and `IBContractDetails` classes. The latter includes critical data like order types and trading hours, which are absent in the basic contract. As a result, `IBContractDetails` can be converted to an `Instrument` while `IBContract` cannot.

To search for contract information, use the [IB Contract Information Center](https://pennies.interactivebrokers.com/cstools/contract_info/).

It's typically suggested to utilize `strict_symbology=False` (which is the default setting). This provides a cleaner and more intuitive use of `InstrumentId` by employing `load_ids` in the `InteractiveBrokersInstrumentProviderConfig`, following the guidelines established in the Simplified Symbology section.
It's typically suggested to utilize `symbology_method=SymbologyMethod.IB_SIMPLIFIED` (which is the default setting). This provides a cleaner and more intuitive use of `InstrumentId` by employing `load_ids` in the `InteractiveBrokersInstrumentProviderConfig`, following the guidelines established in the Simplified Symbology section.
In order to load multiple Instruments, such as Options Instrument without having to specify each strike explicitly, you would need to utilize `load_contracts` with provided instances of `IBContract`.

```python
Expand Down Expand Up @@ -232,9 +239,11 @@ Additionally, this provider offers specialized methods to build and retrieve the

```python
from nautilus_trader.adapters.interactive_brokers.config import InteractiveBrokersInstrumentProviderConfig
from nautilus_trader.adapters.interactive_brokers.config import SymbologyMethod


instrument_provider_config = InteractiveBrokersInstrumentProviderConfig(
symbology_method=SymbologyMethod.IB_SIMPLIFIED,
build_futures_chain=False, # Set to True if fetching futures
build_options_chain=False, # Set to True if fetching options
min_expiry_days=10, # Relevant for futures/options with expiration
Expand All @@ -259,6 +268,16 @@ instrument_provider_config = InteractiveBrokersInstrumentProviderConfig(
)
```

### Integration with Databento Data Client
To integrate with `DatabentoDataClient`, set the `symbology_method` in `InteractiveBrokersInstrumentProviderConfig`
to `SymbologyMethod.DATABENTO`. This ensures seamless compatibility with Databento symbology, eliminating the need
for manual translations or mappings within your strategy.

When using this configuration:
- `InteractiveBrokersInstrumentProvider` will not publish instruments to the cache to prevent conflicts.
- Instruments Cache management must be handled exclusively by `DatabentoDataClient`.


### Data Client

`InteractiveBrokersDataClient` interfaces with IB for streaming and retrieving market data. Upon
Expand Down
8 changes: 6 additions & 2 deletions docs/integrations/tardis.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ This includes the following:

## Symbology and normalization

The Tardis integration seamlessly integrates with NautilusTrader's crypto exchange adapters through consistent symbol normalization.
Each exchange's raw symbols are normalized to follow Nautilus symbology conventions as detailed below:
The Tardis integration ensures seamless compatibility with NautilusTrader’s crypto exchange adapters
by consistently normalizing symbols. Typically, NautilusTrader uses the native exchange naming conventions
provided by Tardis. However, for certain exchanges, raw symbols are adjusted to adhere to the Nautilus symbology normalization, as outlined below:

### Common rules

Expand All @@ -91,6 +92,7 @@ Each exchange's raw symbols are normalized to follow Nautilus symbology conventi
- **Binance**: Nautilus appends the suffix `-PERP` to all perpetual symbols.
- **Bybit**: Nautilus uses specific product category suffixes, including `-SPOT`, `-LINEAR`, `-INVERSE`, `-OPTION`.
- **dYdX**: Nautilus appends the suffix `-PERP` to all perpetual symbols.
- **Gate.io**: Nautilus appends the suffix `-PERP` to all perpetual symbols.

For detailed symbology documentation per exchange:

Expand Down Expand Up @@ -425,6 +427,8 @@ you must filter for the desired venues using an `InstrumentProviderConfig`:
```python
from nautilus_trader.config import InstrumentProviderConfig

# See supported venues https://nautilustrader.io/docs/nightly/integrations/tardis#venues
venues = {"BINANCE", "BYBIT"}
filters = {"venues": frozenset(venues)}
instrument_provider_config = InstrumentProviderConfig(load_all=True, filters=filters)
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
atr_period=20,
trailing_atr_multiple=3.0,
trailing_offset_type="PRICE",
trigger_type="LAST_TRADE",
trigger_type="LAST_PRICE",
)
# Instantiate and add your strategy
strategy = EMACrossTrailingStop(config=config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ async def create_provider():
atr_period=20,
trailing_atr_multiple=3.0,
trailing_offset_type="PRICE",
trigger_type="LAST_TRADE",
trigger_type="LAST_PRICE",
)
# Instantiate and add your strategy
strategy = EMACrossTrailingStop(config=config)
Expand Down
11 changes: 7 additions & 4 deletions examples/backtest/databento_option_greeks.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
# %%
# import nautilus_trader.adapters.databento.data_utils as db_data_utils
# from nautilus_trader.adapters.databento.data_utils import init_databento_client
# from option_trader import DATA_PATH, DATABENTO_API_KEY # personal library, use your own values especially for DATABENTO_API_KEY
# from option_trader import DATA_PATH # personal library, use your own value here
# db_data_utils.DATA_PATH = DATA_PATH

catalog_folder = "options_catalog"
Expand All @@ -69,9 +69,9 @@
start_time = "2024-05-09T10:00"
end_time = "2024-05-09T10:05"

# a valid databento key can be entered here, the example below runs with already saved test data
# db_data_utils.DATABENTO_API_KEY = DATABENTO_API_KEY
# init_databento_client()
# a valid databento key can be entered here (or as an env variable of the same name)
# DATABENTO_API_KEY = None
# init_databento_client(DATABENTO_API_KEY)

# https://databento.com/docs/schemas-and-data-formats/whats-a-schema
futures_data = databento_data(
Expand Down Expand Up @@ -322,3 +322,6 @@ def user_log(self, msg):

# %%
engine.trader.generate_account_report(Venue("GLBX"))

# %%
node.dispose()
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
atr_period=20,
trailing_atr_multiple=3.0,
trailing_offset_type="BASIS_POINTS",
trigger_type="LAST_TRADE",
trigger_type="LAST_PRICE",
trade_size=Decimal("0.010"),
)
# Instantiate your strategy
Expand Down
2 changes: 1 addition & 1 deletion examples/live/bybit/bybit_ema_cross_stop_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
trailing_atr_multiple=3.0,
trailing_offset=Decimal("0.010"),
trailing_offset_type="BASIS_POINTS",
trigger_type="LAST_TRADE",
trigger_type="LAST_PRICE",
trade_size=trade_size,
)
# Instantiate your strategy
Expand Down
Loading

0 comments on commit 02a9ef1

Please sign in to comment.