Skip to content

Commit e656c9c

Browse files
committed
Refine margins and fees docs
1 parent 35002bb commit e656c9c

File tree

1 file changed

+44
-33
lines changed

1 file changed

+44
-33
lines changed

docs/concepts/instruments.md

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -142,39 +142,47 @@ such as when passing them to the order factory to create an order.
142142

143143
## Margins and fees
144144

145-
Margin calculations are handled by the `MarginAccount` class. Let's explore how margins work in our trading system and understand all the key concepts.
145+
Margin calculations are handled by the `MarginAccount` class. This section explains how margins work and introduces key concepts you need to know.
146146

147147
### When margins apply?
148148

149-
Each exchange (like CME or Binance) operates with a specific account type that determines whether margin calculations are relevant for your trading. When setting up an exchange connection, you'll specify one of these account types:
150-
- `AccountType.MARGIN`: Uses margin calculations we'll discuss below
151-
- `AccountType.CASH`: Simple accounts where margins don't apply
152-
- `AccountType.BETTING`: Also doesn't use margin calculations
149+
Each exchange (e.g., CME or Binance) operates with a specific account types that determine whether margin calculations are applicable.
150+
When setting up an exchange venue, you'll specify one of these account types:
151+
152+
- `AccountType.MARGIN`: Accounts that use margin calculations, which are explained below.
153+
- `AccountType.CASH`: Simple accounts where margin calculations do not apply.
154+
- `AccountType.BETTING`: Accounts designed for betting, which also do not involve margin calculations.
153155

154156
### Vocabulary
155157

156-
Let's start with the key terms you'll need to understand trading on margin:
158+
To understand trading on margin, let’s start with some key terms:
157159

158-
**Notional Value** is the full contract value in base currency. The instrument's notional value represents the total market value of your position. For example, with EUR/USD futures on CME (symbol 6E):
159-
- Each contract represents 125,000 EUR (EUR is quote currency, USD is base currency)
160-
- When the current market price is 1.1000, then the notional value equals 125,000 EUR × `1.1000` (price of EUR/USD) = 137,500 USD
160+
**Notional Value**: The total contract value in the quote currency. It represents the full market value of your position. For example, with EUR/USD futures on CME (symbol 6E).
161+
- Each contract represents 125,000 EUR (EUR is base currency, USD is quote currency).
162+
- If the current market price is 1.1000, the notional value equals 125,000 EUR × 1.1000 (price of EUR/USD) = 137,500 USD.
161163

162-
**Leverage** (`leverage`) is an attribute of your trading account that defines how much market exposure you can control with your account deposit. For example, with 10× leverage, you can control 10,000 USD worth of positions with just 1,000 USD in your account.
164+
**Leverage** (`leverage`): The ratio that determines how much market exposure you can control relative to your account deposit. For example, with 10× leverage, you can control 10,000 USD worth of positions with just 1,000 USD in your account.
163165

164-
**Initial Margin** (`margin_init`) is the initial margin rate required to open positions. It represents the amount of money that must be available in your account to open new positions. This is just an entry check requirement - no money is actually locked in your account.
166+
**Initial Margin** (`margin_init`): The margin rate required to open a position. It represents the minimum amount of funds that must be available in your account to open new positions. This is only a pre-check no funds are actually locked.
165167

166-
**Maintenance Margin** (`margin_maint`) is the maintenance margin rate to keep positions open. This is the amount of money that gets locked and must remain in your account to keep positions open. It's always lower than the initial margin, and you can view all blocked funds (sum of maintenance margins) from open positions using `self.portfolio.balances_locked(venue)` in your strategy.
168+
**Maintenance Margin** (`margin_maint`): The margin rate required to keep a position open. This amount is locked in your account to maintain the position. It is always lower than the initial margin. You can view the total blocked funds (sum of maintenance margins for open positions) using the following in your strategy:
167169

168-
**Maker/Taker Fees** describe how exchanges charge trading fees based on how you interact with the market. When you place an order, you're either a "maker" or a "taker" of liquidity:
170+
```python
171+
self.portfolio.balances_locked(venue)
172+
```
169173

170-
- **Maker Fee** (`maker_fee`): This is the lower fee you pay when you "make" liquidity by placing orders that sit on the order book. For example, if you place a limit buy order below the current market price, you're adding liquidity to the market and will pay the maker fee when your order eventually fills.
171-
- **Taker Fee** (`taker_fee`): This is typically a higher fee charged when you "take" liquidity by placing orders that execute immediately against existing orders. For instance, if you place a market buy order or a limit buy above the current price, you're removing liquidity from the market and will pay the taker fee.
174+
**Maker/Taker Fees**: The fees charged by exchanges based on your order's interaction with the market:
172175

173-
Not all exchanges / instruments implement maker/taker fees. In these cases, both `maker_fee` and `taker_fee` should be set to 0 in `Instrument` and all its subclasses (such as `FuturesContract`, `Equity`, `CurrencyPair`, `Commodity`, `Cfd`, `BinaryOption`, `BettingInstrument`, and others).
176+
- Maker Fee (`maker_fee`): A fee (typically lower) charged when you "make" liquidity by placing an order that remains on the order book. For example, a limit buy order below the current price adds liquidity, and the *maker* fee applies when it fills.
177+
- Taker Fee (`taker_fee`): A fee (typically higher) charged when you "take" liquidity by placing an order that executes immediately. For instance, a market buy order or a limit buy above the current price removes liquidity, and the *taker* fee applies.
178+
179+
:::tip
180+
Not all exchanges or instruments implement maker/taker fees. If absent, set both `maker_fee` and `taker_fee` to 0 for the `Instrument` (e.g., `FuturesContract`, `Equity`, `CurrencyPair`, `Commodity`, `Cfd`, `BinaryOption`, `BettingInstrument`).
181+
:::
174182

175183
### Margin calculation formula
176184

177-
When examining the code in `MarginAccount`, you'll find the margin calculations follow these formulas:
185+
The `MarginAccount` class calculates margins using the following formulas:
178186

179187
```python
180188
# Initial margin calculation
@@ -184,26 +192,30 @@ margin_init = (notional_value / leverage * margin_init) + (notional_value / leve
184192
margin_maint = (notional_value / leverage * margin_maint) + (notional_value / leverage * taker_fee)
185193
```
186194

187-
Notes:
188-
- Notice that both formulas follow the same structure but use their respective margin rates (`margin_init` / `margin_maint`).
189-
- Each formula consists of two parts: First is the main margin calculation ; Second is an addition for maker/taker fees
195+
**Key Points**:
196+
197+
- Both formulas follow the same structure but use their respective margin rates (`margin_init` and `margin_maint`).
198+
- Each formula consists of two parts:
199+
- **Primary margin calculation**: Based on notional value, leverage, and margin rate.
200+
- **Fee Adjustment**: Accounts for the maker/taker fee.
190201

191202
### Implementation details
192203

193204
For those interested in exploring the technical implementation:
194-
- File location: `nautilus_trader/accounting/accounts/margin.pyx`
205+
206+
- [nautilus_trader/accounting/accounts/margin.pyx](https://github.com/nautechsystems/nautilus_trader/blob/develop/nautilus_trader/accounting/accounts/margin.pyx)
195207
- Key methods: `calculate_margin_init(self, ...)` and `calculate_margin_maint(self, ...)`
196208

197209
## Commissions
198210

199-
Trading commissions represent the fees charged by exchanges or brokers for executing trades. While maker/taker fees
200-
are common in cryptocurrency markets, traditional exchanges like CME often use different fee structures,
201-
such as per-contract commissions. Nautilus Trader supports multiple commission models to accommodate various
202-
fee structures across different markets.
211+
Trading commissions represent the fees charged by exchanges or brokers for executing trades.
212+
While maker/taker fees are common in cryptocurrency markets, traditional exchanges like CME often
213+
employ other fee structures, such as per-contract commissions.
214+
NautilusTrader supports multiple commission models to accommodate diverse fee structures across different markets.
203215

204216
### Built-in Fee Models
205217

206-
The framework provides two official fee model implementations:
218+
The framework provides two built-in fee model implementations:
207219

208220
1. `MakerTakerFeeModel`: Implements the maker/taker fee structure common in cryptocurrency exchanges, where fees are
209221
calculated as a percentage of the trade value.
@@ -212,7 +224,7 @@ The framework provides two official fee model implementations:
212224
### Creating Custom Fee Models
213225

214226
While the built-in fee models cover common scenarios, you might encounter situations requiring specific commission structures.
215-
Nautilus Trader's flexible architecture allows you to implement custom fee models by inheriting from the base `FeeModel` class.
227+
NautilusTrader's flexible architecture allows you to implement custom fee models by inheriting from the base `FeeModel` class.
216228

217229
For example, if you're trading futures on exchanges that charge per-contract commissions (like CME), you can implement
218230
a custom fee model. When creating custom fee models, we inherit from the `FeeModel` base class, which is implemented
@@ -240,12 +252,12 @@ and instrument, allowing for flexible commission calculations based on these par
240252
Our new class `PerContractFeeModel` inherits class `FeeModel`, which is implemented in Cython,
241253
so notice the Cython-style parameter names in the method signature:
242254

243-
- `Order_order`: The order object, with type prefix `Order_`
244-
- `Quantity_fill_qty`: The fill quantity, with type prefix `Quantity_`
245-
- `Price_fill_px`: The fill price, with type prefix `Price_`
246-
- `Instrument_instrument`: The instrument object, with type prefix `Instrument_`
255+
- `Order_order`: The order object, with type prefix `Order_`.
256+
- `Quantity_fill_qty`: The fill quantity, with type prefix `Quantity_`.
257+
- `Price_fill_px`: The fill price, with type prefix `Price_`.
258+
- `Instrument_instrument`: The instrument object, with type prefix `Instrument_`.
247259

248-
These parameter names follow Nautilus Trader's Cython naming conventions, where the prefix indicates the expected type.
260+
These parameter names follow NautilusTrader's Cython naming conventions, where the prefix indicates the expected type.
249261
While this might seem verbose compared to typical Python naming conventions, it ensures type safety and consistency
250262
with the framework's Cython codebase.
251263

@@ -270,7 +282,6 @@ When implementing custom fee models, ensure they accurately reflect the fee stru
270282
Even small discrepancies in commission calculations can significantly impact strategy performance metrics during backtesting.
271283
:::
272284

273-
274285
## Additional info
275286
The raw instrument definition as provided by the exchange (typically from JSON serialized data) is also
276287
included as a generic Python dictionary. This is to retain all information

0 commit comments

Comments
 (0)