# Order Appendix The **Order Appendix** is a 128-bit integer that encodes extra order parameters like execution type, isolated margin, and trigger configurations. ## Bit Layout ```json | value | reserved | trigger | reduce only | order type | isolated | version | | 64 bits | 50 bits | 2 bits | 1 bit | 2 bits | 1 bit | 8 bits | | 127..64 | 63..14 | 13..12 | 11 | 10..9 | 8 | 7..0 | ``` ## Fields (from LSB to MSB) ### Version **8-bits (0-7)**. Protocol version identifier. Currently `1`. May increment when encoding structure updates. ### Isolated **1-bit (8)**. Indicates whether the order uses isolated margin. Isolated positions have dedicated margin for a specific product, creating a separate isolated subaccount. The original account becomes the "parent subaccount" that can manage the isolated position. *Key Properties:* * Creates isolated subaccount with dedicated margin * Only quote transfers allowed between isolated and parent subaccounts * Parent account can sign orders for isolated subaccount * Cannot be combined with TWAP orders *Example:* ```python from nado_protocol.utils.appendix import build_appendix from nado_protocol.utils.math import to_x6 # Create isolated order with 1000 USDT0 margin appendix = build_appendix( order_type=OrderType.DEFAULT, isolated=True, isolated_margin=to_x6(1000) # 1000 USDT0 (x6 precision) ) ``` ### Order Type **2-bits (9-10)**. Execution behavior for the order. *Values:* * `0` - `DEFAULT`: Standard limit order behavior. * `1` - `IOC (Immediate or Cancel)`: Execute immediately, cancel unfilled portion. * `2` - `FOK (Fill or Kill)`: Execute completely or cancel entire order. * `3` - `POST_ONLY`: Only add liquidity, reject if would take liquidity. *Example:* ```python from nado_protocol.utils.appendix import build_appendix # Post-only order that only provides liquidity appendix = build_appendix( order_type=OrderType.POST_ONLY ) ``` ### Reduce Only **1-bit (11)**. Restricts order to only decrease existing positions. Prevent accidentally increasing position size. Order will be rejected if it would increase the position in the same direction. *Use Cases:* * Risk management when closing positions. * Taking profits without adding exposure. * Automated position reduction strategies. *Example:* ```python from nado_protocol.utils.appendix import build_appendix # Reduce-only order to close part of existing position appendix = build_appendix( order_type=OrderType.DEFAULT, reduce_only=True ) ``` ### Trigger Type **2-bits (12-13)**. Conditional execution behavior. *Values:* * `0` - `NONE`: Execute immediately (regular order). * `1` - `PRICE`: Price-based conditional order. * `2` - `TWAP`: Time-Weighted Average Price execution. * `3` - `TWAP_CUSTOM_AMOUNTS`: TWAP with randomized amounts. *Example:* ```python from nado_protocol.utils.appendix import build_appendix # TWAP order executing 5 times with 0.5% max slippage appendix = build_appendix( order_type=OrderType.DEFAULT, trigger_type=OrderAppendixTriggerType.TWAP, twap_times=5, twap_slippage_frac=0.005 # 0.5% ) ``` ### Reserved **50-bits (14-63)**. Reserved for future protocol extensions. Must be set to `0`. ### Value **64-bits (64-127)**. Context-dependent data based on other flags. #### **TWAP Configuration (when trigger = 2 or 3)** Encodes TWAP execution parameters in the 64-bit value field: ```json | times | slippage_x6 | | 32 bits| 32 bits | ``` **Fields:** * `times`: Number of TWAP executions. * `slippage_x6`: Maximum slippage × 1\_000\_000 (6 decimal precision). **Example:** ```python from nado_protocol.utils.appendix import build_appendix, order_twap_data # TWAP: 10 executions, 1% max slippage appendix = build_appendix( order_type=OrderType.DEFAULT, trigger_type=OrderAppendixTriggerType.TWAP, twap_times=10, twap_slippage_frac=0.01 # 1% ) # Extract TWAP data times, slippage = order_twap_data(appendix) # times = 10, slippage = 0.01 ``` #### **Isolated Margin (when isolated = 1)** Amount of quote (margin\_x6) to transfer to isolated subaccount on first fill, stored in the 64-bit value field. {% hint style="warning" %} **Important:** Isolated margin is stored in **x6 precision** (6 decimals) in the appendix value field. * Stored as `margin_x6` (6 decimal places) * Takes up 64 bits (bits 64-127 of the appendix) {% endhint %} *Example:* ```python from nado_protocol.utils.appendix import build_appendix, order_isolated_margin from nado_protocol.utils.math import to_x6 # Isolated order with 500 USDT0 margin appendix = build_appendix( order_type=OrderType.DEFAULT, isolated=True, isolated_margin=to_x6(500) # 500 USDT0 (x6 precision) ) # Extract isolated margin margin = order_isolated_margin(appendix) # Returns: 500000000 (500 * 10^6 in x6 precision) ``` ## Constraints * **Isolated + TWAP**: Cannot combine isolated orders with TWAP (trigger types 2 or 3). * **TWAP Requirements**: TWAP orders must specify both `twap_times` and `twap_slippage_frac` . * **Isolated Margin**: Can only set `isolated_margin` when `isolated=True` . ## Migration from Legacy Format **Before (deprecated):** * Order type encoded in `expiration` field. * Reduce-only flag encoded in `nonce` field. * Limited trigger functionality. **After (current):** * All flags consolidated in 128-bit `appendix` . * `expiration` is pure timestamp. * `nonce` encodes `recv_time` only. * Enhanced trigger and isolated margin support. ## Building Appendix Values #### Using Python SDK (Recommended) ```python from nado_protocol.utils.expiration import OrderType from nado_protocol.utils.appendix import build_appendix, OrderAppendixTriggerType # Simple market order appendix = build_appendix(order_type=OrderType.DEFAULT) # Post-only reduce order appendix = build_appendix( order_type=OrderType.POST_ONLY, reduce_only=True ) # Isolated order with margin appendix = build_appendix( order_type=OrderType.DEFAULT, isolated=True, isolated_margin=to_x6(1000) # 1000 USDT0 (x6 precision) ) # TWAP order appendix = build_appendix( order_type=OrderType.DEFAULT, trigger_type=OrderAppendixTriggerType.TWAP, twap_times=5, twap_slippage_frac=0.01 # 1% ) ``` #### Manual Bit Manipulation (Advanced) {% hint style="info" %} Refer to [nado\_protocol.utils.order](https://nadohq.github.io/nado-python-sdk/_modules/nado_protocol/utils/order.html) for a detailed implementation. {% endhint %} ```python # Build appendix manually def build_manual_appendix(order_type=0, isolated=False, reduce_only=False, trigger_type=0, value=0): appendix = 0 # Version (bits 0-7) appendix |= 1 # Version 1 # Isolated (bit 8) if isolated: appendix |= 1 << 8 # Order type (bits 9-10) appendix |= (order_type & 0b11) << 9 # Reduce only (bit 11) if reduce_only: appendix |= 1 << 11 # Trigger type (bits 12-13) appendix |= (trigger_type & 0b11) << 12 # Reserved bits 14-63 (set to 0) # Value (bits 64-127) # Note: Value is stored in x6 precision for isolated margin appendix |= (value & ((1 << 64) - 1)) << 64 return appendix # Example: Post-only reduce order appendix = build_manual_appendix( order_type=3, # POST_ONLY reduce_only=True ) ``` ### Utility Functions ```python # Check order properties is_reduce_only = order_reduce_only(appendix) is_trigger = order_is_trigger_order(appendix) is_isolated = order_is_isolated(appendix) version = order_version(appendix) order_type = order_execution_type(appendix) trigger_type = order_trigger_type(appendix) # Extract context data twap_data = order_twap_data(appendix) # Returns (times, slippage) or None isolated_margin = order_isolated_margin(appendix) # Returns margin or None ```