Skip to content

Place Flexi Order

create_order() places one leg-based Trading API V3 FNO strategy order when the order object sets isMultiLeg=True and provides a non-empty legs list.

Flexi orders help users build complex FNO strategies with ease by grouping multiple option or future legs into one strategy order.

With basket-level execution, users can choose strategy-level entry and/or exit configs. Both time-based and price-based entry and exits are possible, along with trailing stop-loss and other trigger configurations.

LLM guidance

Use this page for one strategy order composed from FNO legs. This shape omits top-level refId, requires isMultiLeg=True, sets the strategy-level side, and uses legs[].refId plus signed legs[].unitQty. Set executionMode based on the top-level entry and exit fields. Do not use this page for multiple independent single orders; use Place Multi Order.

Basic Usage

from datetime import datetime
from nubra_python_sdk.refdata.instruments import InstrumentData
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv
from nubra_python_sdk.trading.trading_data import NubraTrader
from nubra_python_sdk.trading.trading_enum import TradingAPIVersion

nubra = InitNubraSdk(NubraEnv.UAT, env_creds=True)
instruments = InstrumentData(nubra)
market_data = MarketData(nubra)
trader = NubraTrader(nubra, version=TradingAPIVersion.V3)

def get_ref_id(asset, strike, expiry, option_type):
    expiry = datetime.strptime(expiry, "%d-%m-%Y").strftime("%Y%m%d")
    result = instruments.get_instruments_by_pattern([{
        "exchange": "NSE",
        "asset": asset,
        "strike_price": str(strike * 100),
        "expiry": expiry,
        "option_type": option_type,
    }])
    return result[0].ref_id if result else None

def get_ltp(asset, strike, expiry, option_type):
    ref_id = get_ref_id(asset, strike, expiry, option_type)
    quote = market_data.quote(ref_id=ref_id, levels=1)
    return ref_id, quote.orderBook.last_traded_price

long_call_ref_id, long_call_ltp = get_ltp("NIFTY", 23600, "17-03-2026", "CE")
long_put_ref_id, long_put_ltp = get_ltp("NIFTY", 23600, "17-03-2026", "PE")
entry_price = long_call_ltp + long_put_ltp

result = trader.create_order({
    "isMultiLeg": True,
    "qty": 1,
    "side": "BUY",
    "deliveryType": "CNC",
    "priceType": "LIMIT",
    "validityType": "DAY",
    "executionMode": "ENTRY_AND_EXIT",
    "entryPrice": entry_price,
    "legs": [
        {"refId": long_call_ref_id, "unitQty": 65},
        {"refId": long_put_ref_id, "unitQty": 65}
    ],
    "entryConfig": {
        "entryTime": "2026-03-20T09:20:00.000Z",
        "triggers": [
            {"kind": "AT_OR_ABOVE", "value": entry_price + 10}
        ]
    },
    "exitConfig": {
        "exitTime": "2026-03-20T15:10:00.000Z",
        "stoplossParams": {
            "stoplossTriggerPrice": {"value": entry_price - 50},
            "stoplossLimitPrice": {"value": entry_price - 40}
        },
        "targetParams": {
            "targetProfitTriggerPrice": {"value": entry_price + 80},
            "targetProfitLimitPrice": {"value": entry_price + 90}
        }
    },
    "stratTags": ["python-sdk-test", "nifty-buy-straddle"],
    "echoFields": "nifty_buy_straddle_example"
})

order = result.orders[0]
print(order.intentOrderId, order.isMulti, order.status)

Example Order Patterns

These examples show common option strategy orders built with Trading API V3 multi-leg payloads.

  • each leg is passed through legs
  • strategy-level pricing and controls stay on the top-level order object
  • option refId values are resolved dynamically before order placement
  • set isMultiLeg: True, set strategy side: "BUY", omit top-level refId, and set the correct executionMode
  • use qty as the strategy multiplier and legs[].unitQty as the signed lot quantity for each leg
from datetime import datetime
from nubra_python_sdk.refdata.instruments import InstrumentData
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv
from nubra_python_sdk.trading.trading_data import NubraTrader
from nubra_python_sdk.trading.trading_enum import TradingAPIVersion

nubra = InitNubraSdk(NubraEnv.UAT, env_creds=True)
instruments = InstrumentData(nubra)
market_data = MarketData(nubra)
trader = NubraTrader(nubra, version=TradingAPIVersion.V3)

def get_ref_id(asset, strike, expiry, option_type):
    expiry = datetime.strptime(expiry, "%d-%m-%Y").strftime("%Y%m%d")
    result = instruments.get_instruments_by_pattern([{
        "exchange": "NSE",
        "asset": asset,
        "strike_price": str(strike * 100),
        "expiry": expiry,
        "option_type": option_type,
    }])
    return result[0].ref_id if result else None

def get_ltp(asset, strike, expiry, option_type):
    ref_id = get_ref_id(asset, strike, expiry, option_type)
    quote = market_data.quote(ref_id=ref_id, levels=1)
    return ref_id, quote.orderBook.last_traded_price

long_call_ref_id, long_call_ltp = get_ltp("NIFTY", 23600, "17-03-2026", "CE")
long_put_ref_id, long_put_ltp = get_ltp("NIFTY", 23600, "17-03-2026", "PE")

result = trader.create_order({
    "isMultiLeg": True,
    "qty": 1,
    "side": "BUY",
    "deliveryType": "CNC",
    "priceType": "LIMIT",
    "validityType": "DAY",
    "executionMode": "ENTRY",
    "entryPrice": long_call_ltp + long_put_ltp,
    "legs": [
        {"refId": long_call_ref_id, "unitQty": 65},
        {"refId": long_put_ref_id, "unitQty": 65}
    ],
    "stratTags": ["python-sdk-test", "nifty-buy-straddle"],
    "echoFields": "buy_straddle_example"
})

Use this pattern for a two-leg same-strike buy straddle strategy.

from datetime import datetime
from nubra_python_sdk.refdata.instruments import InstrumentData
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv
from nubra_python_sdk.trading.trading_data import NubraTrader
from nubra_python_sdk.trading.trading_enum import TradingAPIVersion

nubra = InitNubraSdk(NubraEnv.UAT, env_creds=True)
instruments = InstrumentData(nubra)
market_data = MarketData(nubra)
trader = NubraTrader(nubra, version=TradingAPIVersion.V3)

def get_ref_id(asset, strike, expiry, option_type):
    expiry = datetime.strptime(expiry, "%d-%m-%Y").strftime("%Y%m%d")
    result = instruments.get_instruments_by_pattern([{
        "exchange": "NSE",
        "asset": asset,
        "strike_price": str(strike * 100),
        "expiry": expiry,
        "option_type": option_type,
    }])
    return result[0].ref_id if result else None

def get_ltp(asset, strike, expiry, option_type):
    ref_id = get_ref_id(asset, strike, expiry, option_type)
    quote = market_data.quote(ref_id=ref_id, levels=1)
    return ref_id, quote.orderBook.last_traded_price

long_call_ref_id, long_call_ltp = get_ltp("NIFTY", 23800, "17-03-2026", "CE")
long_put_ref_id, long_put_ltp = get_ltp("NIFTY", 23400, "17-03-2026", "PE")

result = trader.create_order({
    "isMultiLeg": True,
    "qty": 1,
    "side": "BUY",
    "deliveryType": "CNC",
    "priceType": "LIMIT",
    "validityType": "DAY",
    "executionMode": "ENTRY",
    "entryPrice": long_call_ltp + long_put_ltp,
    "legs": [
        {"refId": long_call_ref_id, "unitQty": 65},
        {"refId": long_put_ref_id, "unitQty": 65}
    ],
    "stratTags": ["python-sdk-test", "nifty-buy-strangle"],
    "echoFields": "buy_strangle_example"
})

Use this pattern for a two-leg buy strangle strategy with different call and put strikes.

from datetime import datetime
from nubra_python_sdk.refdata.instruments import InstrumentData
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv
from nubra_python_sdk.trading.trading_data import NubraTrader
from nubra_python_sdk.trading.trading_enum import TradingAPIVersion

nubra = InitNubraSdk(NubraEnv.UAT, env_creds=True)
instruments = InstrumentData(nubra)
market_data = MarketData(nubra)
trader = NubraTrader(nubra, version=TradingAPIVersion.V3)

def get_ref_id(asset, strike, expiry, option_type):
    expiry = datetime.strptime(expiry, "%d-%m-%Y").strftime("%Y%m%d")
    result = instruments.get_instruments_by_pattern([{
        "exchange": "NSE",
        "asset": asset,
        "strike_price": str(strike * 100),
        "expiry": expiry,
        "option_type": option_type,
    }])
    return result[0].ref_id if result else None

def get_ltp(asset, strike, expiry, option_type):
    ref_id = get_ref_id(asset, strike, expiry, option_type)
    quote = market_data.quote(ref_id=ref_id, levels=1)
    return ref_id, quote.orderBook.last_traded_price

long_put_ref_id, long_put_ltp = get_ltp("NIFTY", 23200, "17-03-2026", "PE")
short_put_ref_id, short_put_ltp = get_ltp("NIFTY", 23400, "17-03-2026", "PE")
short_call_ref_id, short_call_ltp = get_ltp("NIFTY", 23800, "17-03-2026", "CE")
long_call_ref_id, long_call_ltp = get_ltp("NIFTY", 24000, "17-03-2026", "CE")

result = trader.create_order({
    "isMultiLeg": True,
    "qty": 1,
    "side": "BUY",
    "deliveryType": "CNC",
    "priceType": "LIMIT",
    "validityType": "DAY",
    "executionMode": "ENTRY",
    "entryPrice": long_put_ltp - short_put_ltp - short_call_ltp + long_call_ltp,
    "legs": [
        {"refId": long_put_ref_id, "unitQty": 65},
        {"refId": short_put_ref_id, "unitQty": -65},
        {"refId": short_call_ref_id, "unitQty": -65},
        {"refId": long_call_ref_id, "unitQty": 65}
    ],
    "stratTags": ["python-sdk-test", "nifty-iron-condor"],
    "echoFields": "iron_condor_example"
})

Use this pattern for a four-leg defined-risk short-volatility strategy with wider protective wings.

from datetime import datetime
from nubra_python_sdk.refdata.instruments import InstrumentData
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv
from nubra_python_sdk.trading.trading_data import NubraTrader
from nubra_python_sdk.trading.trading_enum import TradingAPIVersion

nubra = InitNubraSdk(NubraEnv.UAT, env_creds=True)
instruments = InstrumentData(nubra)
market_data = MarketData(nubra)
trader = NubraTrader(nubra, version=TradingAPIVersion.V3)

def get_ref_id(asset, strike, expiry, option_type):
    expiry = datetime.strptime(expiry, "%d-%m-%Y").strftime("%Y%m%d")
    result = instruments.get_instruments_by_pattern([{
        "exchange": "NSE",
        "asset": asset,
        "strike_price": str(strike * 100),
        "expiry": expiry,
        "option_type": option_type,
    }])
    return result[0].ref_id if result else None

def get_ltp(asset, strike, expiry, option_type):
    ref_id = get_ref_id(asset, strike, expiry, option_type)
    quote = market_data.quote(ref_id=ref_id, levels=1)
    return ref_id, quote.orderBook.last_traded_price

long_put_ref_id, long_put_ltp = get_ltp("NIFTY", 23400, "17-03-2026", "PE")
short_put_ref_id, short_put_ltp = get_ltp("NIFTY", 23600, "17-03-2026", "PE")
short_call_ref_id, short_call_ltp = get_ltp("NIFTY", 23600, "17-03-2026", "CE")
long_call_ref_id, long_call_ltp = get_ltp("NIFTY", 23800, "17-03-2026", "CE")

result = trader.create_order({
    "isMultiLeg": True,
    "qty": 1,
    "side": "BUY",
    "deliveryType": "CNC",
    "priceType": "LIMIT",
    "validityType": "DAY",
    "executionMode": "ENTRY",
    "entryPrice": long_put_ltp - short_put_ltp - short_call_ltp + long_call_ltp,
    "legs": [
        {"refId": long_put_ref_id, "unitQty": 65},
        {"refId": short_put_ref_id, "unitQty": -65},
        {"refId": short_call_ref_id, "unitQty": -65},
        {"refId": long_call_ref_id, "unitQty": 65}
    ],
    "stratTags": ["python-sdk-test", "nifty-iron-butterfly"],
    "echoFields": "iron_butterfly_example"
})

Use this pattern for a four-leg strategy with the short call and short put at the same strike.

Multi-Leg Behavior

When isMultiLeg is True, Trading API V3 treats the payload as one strategy order made from legs.

Rule Meaning
isMultiLeg: True Selects the leg-based validation path.
no top-level refId The instrument lives on each leg through legs[].refId.
top-level side is required Use side: "BUY" for the strategy order. Leg direction still lives on each leg through the sign of legs[].unitQty.
legs must be non-empty Each leg needs its own FNO refId and signed unitQty.
qty is the strategy multiplier Use qty: 1 for one strategy unit. Do not put the option lot size in qty.
legs[].unitQty is the signed lot quantity Positive values are buy legs and negative values are sell legs. For one NIFTY lot, use 65 or -65; for two strategy units, keep unitQty as the per-unit leg quantity and set qty: 2.
entry and exit controls are top-level entryPrice, entryConfig, and exitConfig apply to the strategy order, not to individual legs.

Execution Modes

Use executionMode to match the strategy lifecycle fields in the payload.

Payload shape executionMode Meaning
The strategy has entryPrice and/or entryConfig, and no exitConfig. ENTRY Entry-only multi-leg strategy order.
The strategy has no entryPrice or entryConfig, and has exitConfig. EXIT Exit-only multi-leg strategy order.
The strategy has entryPrice and/or entryConfig, and also has exitConfig. ENTRY_AND_EXIT Entry multi-leg strategy order with attached stop-loss, target, trailing stop-loss, or timed exit.

Multi-leg execution mode

executionMode is still required for the strategy order. The difference from single order is that isMultiLeg=True moves instrument direction into legs[], while executionMode still describes whether the strategy payload is defining entry, exit, or both.

Strategy side and leg direction

The top-level side is the strategy-level side required by the Trading API V3 flexi order shape. Individual leg direction is controlled by signed legs[].unitQty: positive values are buy legs and negative values are sell legs.

Python SDK Payload Shape

Pass one strategy dictionary to trader.create_order().

{
  "isMultiLeg": true,
  "qty": 1,
  "side": "BUY",
  "deliveryType": "CNC",
  "priceType": "LIMIT",
  "validityType": "DAY",
  "executionMode": "ENTRY",
  "entryPrice": 0,
  "legs": [
    {"refId": 111111, "unitQty": 65},
    {"refId": 222222, "unitQty": -65}
  ]
}

Strategy Order Fields

Field Type Required Allowed values / shape Meaning
isMultiLeg bool yes True Enables the leg-based order validation path.
legs list[LegRequest] yes non-empty list FNO legs inside this one strategy order.
legs[].refId int yes instrument ref ID FNO instrument reference ID for that leg.
legs[].unitQty int yes signed lot quantity Per-strategy-unit leg quantity. Use positive values for buy legs and negative values for sell legs, such as 65 or -65 for one NIFTY lot.
qty int yes positive integer Strategy multiplier. Use 1 for one strategy unit; do not use this field for the option lot size.
side str yes BUY Strategy-level order side required by the current flexi strategy placement path. Leg buy/sell direction is still represented by signed unitQty.
deliveryType str yes CNC Product / delivery type for the flexi FNO strategy examples. Current Trading API V3 flexi placement expects CNC for this strategy shape.
priceType str no LIMIT Price behavior for the strategy order.
validityType str no DAY, GTE Order validity.
goodTillDate str no date/time string Good-till date for supported good-till workflows.
executionMode str yes ENTRY, EXIT, ENTRY_AND_EXIT Execution mode for the strategy order. Match this to the entry and exit fields in the payload.
entryPrice int conditional price integer Strategy entry price or net price, as expected by Trading API V3. Required for price-based ENTRY and ENTRY_AND_EXIT payloads. Omit for EXIT-only payloads.
entryConfig object no see below Delayed or trigger-based strategy entry conditions.
exitConfig object no see below Strategy stop-loss, target, trailing stop, or time exit settings.
algoId str no string Algo identifier when applicable.
stratTags list[str] no strings Strategy or tracking tags.
echoFields str no string Free-form metadata echoed back by Trading API V3.
orderId int no integer Present in the SDK model but not normally sent for new create requests.
refId int no omit Must be absent when isMultiLeg=True.
icebergInfo object no omit unless Trading API V3 enables it for this strategy Iceberg fields exist on the SDK model, but are not part of the normal leg-based strategy shape.

Condition Fields

Field Type Required Allowed values / shape Meaning
entryConfig.entryTime str no date/time string Time at which the strategy entry can activate.
entryConfig.triggers list[object] no trigger objects One or more LTP trigger conditions.
entryConfig.triggers[].kind str yes for trigger ABOVE, BELOW, AT_OR_ABOVE, AT_OR_BELOW Trigger comparison.
entryConfig.triggers[].value int yes for trigger price integer Trigger threshold.
exitConfig.stoplossParams.stoplossTriggerPrice object no {"value": int} or {"disabled": true} Stop-loss trigger price wrapper.
exitConfig.stoplossParams.stoplossLimitPrice object no {"value": int} or {"disabled": true} Stop-loss limit price wrapper.
exitConfig.stoplossParams.stoplossTrailJump float no number Trailing stop jump.
exitConfig.targetParams.targetProfitTriggerPrice object no {"value": int} or {"disabled": true} Target trigger price wrapper.
exitConfig.targetParams.targetProfitLimitPrice object no {"value": int} or {"disabled": true} Target limit price wrapper.
exitConfig.exitTime str no date/time string Time-based exit.

Response Fields

Field Type Meaning
orders list[IntentOrderResponse] Created Trading API V3 strategy orders. This request normally returns one item.
orders[].intentOrderId int Trading API V3 strategy order identifier.
orders[].status str Current order status.
orders[].isMulti bool True for leg-based strategy orders.
orders[].exchange str Exchange.
orders[].legs list[IntentOrderLeg] Leg details returned by Trading API V3.
orders[].legs[].refId int Leg instrument reference ID.
orders[].legs[].unitQty int Signed leg unit quantity.
orders[].legs[].orderQty int Expanded leg order quantity.
orders[].legs[].filledQty int Filled quantity for the leg.
orders[].legs[].filledPrice int Fill price for the leg.
orders[].legs[].refData RefData Leg instrument metadata.
orders[].orderQty int Strategy quantity.
orders[].deliveryType str Delivery type.
orders[].priceType str Price type.
orders[].validityType str Validity type.
orders[].executionMode str Execution mode.
orders[].entryConfig IntentOrderEntryConfig Entry conditions as returned by Trading API V3.
orders[].exitConfig list[IntentOrderExitTrigger] Exit triggers as returned by Trading API V3.
orders[].stratTags list[str] Strategy tags.
orders[].echoFields str Echo metadata.
orders[].entryPrice int Strategy entry price.
orders[].ltp int Latest traded price.
orders[].orderPrice int Order price.
orders[].filledPrice int Fill price.
orders[].rejectionMsg str Rejection reason when rejected.
orders[].timestamps IntentOrderTimestamps Lifecycle timestamps.
orders[].positionId str Position identifier when available.
orders[].intentOrderType str Trading API V3 intent order type.

Important Rules

Important Rules

  • This is one strategy order, not multiple independent orders.
  • isMultiLeg must be True.
  • legs must be non-empty.
  • Top-level refId must be absent.
  • Top-level side should be BUY for the strategy shape; leg direction is represented by signed legs[].unitQty.
  • Use FNO refId values in legs[].
  • Use deliveryType: "CNC" for the flexi FNO strategy payload.
  • Use qty as the strategy multiplier and legs[].unitQty as the per-leg signed lot quantity.
  • Use ENTRY_AND_EXIT when the same strategy payload has both entry fields and exitConfig.
  • Use Get Margin before placement when margin impact matters.
  1. Get Orders
  2. Modify Order
  3. Cancel Order
NEO Assistant