Order Appendix

The Order Appendix is a powerful feature in the Nado Protocol that allows you to specify advanced order parameters through a compact bit-packed integer. This appendix encodes various order properties including execution types, isolated positions, TWAP parameters, and trigger types.

Overview

The appendix is a 128-bit integer with the following bit layout (from MSB to LSB):

| 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 (bits 0-7): Protocol version for future compatibility (currently version 1)

  • Isolated (bit 8): Whether the order is for an isolated position

  • Order Type (bits 9-10): Execution type (DEFAULT, IOC, FOK, POST_ONLY)

  • Reduce Only (bit 11): Whether the order can only reduce existing positions

  • Trigger Type (bits 12-13): Type of trigger order (NONE, PRICE, TWAP, TWAP_CUSTOM_AMOUNTS)

  • Reserved (bits 14-63): Reserved for future use

  • Value (bits 64-127): Additional data (isolated margin or TWAP parameters)

Building an Appendix

Use the build_appendix() function to create an appendix with the desired parameters:

from nado_protocol.utils.order import build_appendix
from nado_protocol.utils.expiration import OrderType

# Basic order with IOC execution type
appendix = build_appendix(order_type=OrderType.IOC)

# Reduce-only order
appendix = build_appendix(
    order_type=OrderType.POST_ONLY,
    reduce_only=True
)

Order Execution Types

The appendix supports four execution types:

DEFAULT

Standard limit order behavior

IOC (Immediate or Cancel)

Execute immediately, cancel any unfilled portion

FOK (Fill or Kill)

Execute completely or cancel the entire order

POST_ONLY

Only add liquidity to the order book, never take liquidity

Example:

from nado_protocol.utils.order import build_appendix
from nado_protocol.utils.expiration import OrderType

# Create different order types
ioc_appendix = build_appendix(order_type=OrderType.IOC)
fok_appendix = build_appendix(order_type=OrderType.FOK)
post_only_appendix = build_appendix(order_type=OrderType.POST_ONLY)

Isolated Positions

Isolated positions allow you to allocate specific margin to a trade, limiting your risk:

from nado_protocol.utils.order import build_appendix
from nado_protocol.utils.expiration import OrderType
from nado_protocol.utils.math import to_x6

# Create isolated position with 1000 USDC margin
# Note: isolated margin uses x6 precision and is limited to 64-bit values
isolated_appendix = build_appendix(
    isolated=True,
    isolated_margin=to_x6(1000),
    order_type=OrderType.POST_ONLY
)

Note

Isolated positions and TWAP orders are mutually exclusive - you cannot have both in the same order.

TWAP Orders

Time-Weighted Average Price (TWAP) orders split large orders into smaller chunks executed over time:

from nado_protocol.utils.order import build_appendix, OrderAppendixTriggerType

# Create TWAP order with 10 child orders and 0.5% slippage tolerance
twap_appendix = build_appendix(
    trigger_type=OrderAppendixTriggerType.TWAP,
    twap_times=10,
    twap_slippage_frac=0.005
)

# TWAP with custom amounts and reduce-only
twap_custom_appendix = build_appendix(
    trigger_type=OrderAppendixTriggerType.TWAP_CUSTOM_AMOUNTS,
    twap_times=5,
    twap_slippage_frac=0.01,
    reduce_only=True
)

Trigger Orders

Trigger orders can be configured with different trigger types:

from nado_protocol.utils.order import build_appendix, OrderAppendixTriggerType
from nado_protocol.utils.expiration import OrderType

# Price-based trigger order
price_trigger_appendix = build_appendix(
    trigger_type=OrderAppendixTriggerType.PRICE,
    order_type=OrderType.IOC,
    reduce_only=True
)

Extracting Appendix Information

You can extract information from an existing appendix:

from nado_protocol.utils.order import (
    order_version,
    order_execution_type,
    order_reduce_only,
    order_is_isolated,
    order_isolated_margin,
    order_is_trigger_order,
    order_trigger_type,
    order_twap_data
)

from nado_protocol.utils.math import to_x6

appendix = build_appendix(
    isolated=True,
    isolated_margin=to_x6(500),
    order_type=OrderType.IOC,
    reduce_only=True
)

# Extract information
version = order_version(appendix)
execution_type = order_execution_type(appendix)
is_reduce_only = order_reduce_only(appendix)
is_isolated = order_is_isolated(appendix)
margin = order_isolated_margin(appendix)
is_trigger = order_is_trigger_order(appendix)
trigger_type = order_trigger_type(appendix)

print(f"Order Type: {execution_type.name}")
print(f"Reduce Only: {is_reduce_only}")
print(f"Isolated: {is_isolated}")
if margin:
    print(f"Isolated Margin: {margin}")

Using Appendix with Orders

When placing orders, include the appendix in your order parameters:

from nado_protocol.engine_client.types import OrderParams, PlaceOrderParams
from nado_protocol.utils.order import build_appendix
from nado_protocol.utils.expiration import OrderType
from nado_protocol.utils.subaccount import SubaccountParams
import time

# Create appendix for a reduce-only IOC order
appendix = build_appendix(
    order_type=OrderType.IOC,
    reduce_only=True
)

# Create order with appendix
order = OrderParams(
    sender=SubaccountParams(subaccount_owner="0x...", subaccount_name="default"),
    priceX18=28898000000000000000000,
    amount=-10000000000000000,  # Sell to close position
    expiration=int(time.time()) + 3600,  # 1 hour from now
    appendix=appendix
)

# Place the order
client.market.place_order(PlaceOrderParams(product_id=1, order=order))

Complex Trading Scenarios

Here are examples of complex trading scenarios using appendix:

Stop Loss Order

# Stop loss: reduce-only IOC order that executes immediately when triggered
stop_loss_appendix = build_appendix(
    order_type=OrderType.IOC,
    reduce_only=True,
    trigger_type=OrderAppendixTriggerType.PRICE
)

Take Profit Order

# Take profit: reduce-only post-only order to avoid paying taker fees
take_profit_appendix = build_appendix(
    order_type=OrderType.POST_ONLY,
    reduce_only=True,
    trigger_type=OrderAppendixTriggerType.PRICE
)

Breakout Strategy with Isolated Position

from nado_protocol.utils.math import to_x6

# Enter position on breakout with dedicated margin
# Note: isolated margin uses x6 precision and is limited to 64-bit values
breakout_appendix = build_appendix(
    isolated=True,
    isolated_margin=to_x6(5000),  # 5000 USDC dedicated margin
    order_type=OrderType.IOC
)

Large Order with TWAP

# Split large order into 20 smaller orders with 0.1% slippage tolerance
twap_appendix = build_appendix(
    trigger_type=OrderAppendixTriggerType.TWAP,
    twap_times=20,
    twap_slippage_frac=0.001
)

Validation Rules

The appendix system enforces several validation rules:

  • Isolated + TWAP Exclusion: An order cannot be both isolated and a TWAP order

  • TWAP Parameters: TWAP orders require both twap_times and twap_slippage_frac

  • Isolated Margin: isolated_margin can only be set when isolated=True

  • Margin Limits: Isolated margin uses x6 precision and must be between 0 and 2^64 - 1

Error Handling

The appendix functions will raise ValueError for invalid configurations:

from nado_protocol.utils.math import to_x6

# This will raise ValueError: isolated_margin can only be set when isolated=True
try:
    build_appendix(isolated=False, isolated_margin=to_x6(1000))
except ValueError as e:
    print(f"Error: {e}")

# This will raise ValueError: TWAP parameters required
try:
    build_appendix(trigger_type=OrderAppendixTriggerType.TWAP)
except ValueError as e:
    print(f"Error: {e}")

# This will raise ValueError: Isolated and TWAP are mutually exclusive
try:
    build_appendix(
        isolated=True,
        isolated_margin=to_x6(1000),
        trigger_type=OrderAppendixTriggerType.TWAP,
        twap_times=5,
        twap_slippage_frac=0.01
    )
except ValueError as e:
    print(f"Error: {e}")

API Reference

For detailed API documentation, see:

  • nado_protocol.utils.order.build_appendix()

  • nado_protocol.utils.order.order_version()

  • nado_protocol.utils.order.order_execution_type()

  • nado_protocol.utils.order.order_reduce_only()

  • nado_protocol.utils.order.order_is_isolated()

  • nado_protocol.utils.order.order_isolated_margin()

  • nado_protocol.utils.order.order_is_trigger_order()

  • nado_protocol.utils.order.order_trigger_type()

  • nado_protocol.utils.order.order_twap_data()

  • nado_protocol.utils.order.OrderAppendixTriggerType