Skip to content

Orders

The Go SDK covers placing, modifying, and canceling orders across all supported exchanges.

The first argument to PlaceOrder, ModifyOrder, and CancelOrder is the variety string. Use "regular" for standard orders.

Order Parameters

Exchanges

Exchange Code Description
NSE arrow.ExchangeNSE National Stock Exchange - Equity
BSE arrow.ExchangeBSE Bombay Stock Exchange - Equity
NFO arrow.ExchangeNFO NSE Futures & Options
BFO arrow.ExchangeBFO BSE Futures & Options
MCX arrow.ExchangeMCX Multi Commodity Exchange (permissions / instrument segment)
MCXFO arrow.ExchangeMCXFO MCX Futures & Options (orders, quotes, margin)
INDEX arrow.ExchangeINDEX Index segment (utility / option-chain APIs)
NCD arrow.ExchangeNCD NSE Currency Derivatives
BCD arrow.ExchangeBCD BSE Currency Derivatives
NSESLBM arrow.ExchangeNSESLBM NSE SLBM

MCX vs MCXFO

Use ExchangeMCXFO for place/modify order, quotes, and margin. ExchangeMCX is for permission checks and the /mcx instrument download segment. Position and trade responses return "MCXFO".

Order Types

Type Code Description
Limit arrow.OrderTypeLimit (LMT) Execute at specified price or better
Market arrow.OrderTypeMarket (MKT) Plain market orders are disabled by default. Set MarketProtection: true (mpp) to mimic a market order
Stop Loss Limit arrow.OrderTypeSLLMT (SL-LMT) Limit order activated at trigger
Stop Loss Market arrow.OrderTypeSLMKT (SL-MKT) Market order activated at trigger
Stop Loss (legacy) arrow.OrderTypeSL (SL) Legacy alias
Stop Loss Market (legacy) arrow.OrderTypeSLM (SL-M) Legacy alias

Product Types

Product Code Description Settlement
Intraday arrow.ProductMIS (I) Same-day position closure Auto-squared off at 3:15 PM
Cash & Carry arrow.ProductCNC (C) Equity delivery orders T+1 settlement
Normal arrow.ProductNRML (M) F&O margin orders Standard margin

Order Validity

Validity Code Description
Day arrow.ValidityDAY Valid until market close
IOC arrow.ValidityIOC Immediate or Cancel
GTC arrow.ValidityGTC Good Till Cancelled

Transaction Types

Type Code Description
Buy arrow.TransactionTypeBuy (B) Buy transaction
Sell arrow.TransactionTypeSell (S) Sell transaction

Market orders and mpp

Under current regulations, plain MKT orders are disabled by default on the API. Set MarketProtection: true on OrderRequest (json:"mpp") to send a LIMIT order at the Upper Limit or DPR, depending on instrument type, and mimic market-style execution. In rare cases of extreme volatility or sharp price movement, this can still leave the order open (fully or partially unfilled).

Variety

There is no Variety type in Go. Pass "regular" as the first argument. Modify and cancel also take an explicit variety (Python hardcodes /order/regular/{id}).

Place Order

PlaceOrder returns *OrderResponse. The order number is order.Data.OrderNo. All quantity and price fields on OrderRequest are strings.

Basic Example

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeNSE),
    Symbol:          "RELIANCE-EQ",
    Quantity:        "1",
    DisclosedQty:    "0",
    Product:         string(arrow.ProductCNC),
    OrderType:       string(arrow.OrderTypeLimit),
    TransactionType: string(arrow.TransactionTypeBuy),
    Price:           "1450.0",
    Validity:        string(arrow.ValidityDAY),
})
if err != nil {
    log.Fatal(err)
}
fmt.Println("Order placed:", order.Data.OrderNo)

Market-style order (mpp)

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:         string(arrow.ExchangeNSE),
    Symbol:           "RELIANCE-EQ",
    Quantity:         "10",
    DisclosedQty:     "0",
    Product:          string(arrow.ProductMIS),
    OrderType:        string(arrow.OrderTypeMarket),
    TransactionType:  string(arrow.TransactionTypeBuy),
    Price:            "0",
    Validity:         string(arrow.ValidityDAY),
    MarketProtection: true,
})

Limit Order

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeNSE),
    Symbol:          "INFY-EQ",
    Quantity:        "5",
    Product:         string(arrow.ProductCNC),
    OrderType:       string(arrow.OrderTypeLimit),
    TransactionType: string(arrow.TransactionTypeBuy),
    Price:           "1500.50",
    Validity:        string(arrow.ValidityDAY),
})

Stop Loss Order

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeNSE),
    Symbol:          "TCS-EQ",
    Quantity:        "2",
    Product:         string(arrow.ProductCNC),
    OrderType:       string(arrow.OrderTypeSLLMT),
    TransactionType: string(arrow.TransactionTypeSell),
    Price:           "3400.0",
    TriggerPrice:    "3410.0",
    Validity:        string(arrow.ValidityDAY),
})

F&O Order

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeNFO),
    Symbol:          "NIFTY02JAN25C26000",
    Quantity:        "75",
    Product:         string(arrow.ProductNRML),
    OrderType:       string(arrow.OrderTypeLimit),
    TransactionType: string(arrow.TransactionTypeBuy),
    Price:           "150.0",
    Validity:        string(arrow.ValidityDAY),
})

MCXFO Order

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeMCXFO),
    Symbol:          "GOLDPETAL31JUL26F",
    Quantity:        "1",
    DisclosedQty:    "0",
    Product:         string(arrow.ProductMIS),
    OrderType:       string(arrow.OrderTypeLimit),
    TransactionType: string(arrow.TransactionTypeBuy),
    Price:           "14300.0",
    Validity:        string(arrow.ValidityDAY),
    Remarks:         "strategy_1",
    TriggerPrice:    "0",
})
if err != nil {
    log.Fatal(err)
}

_, err = client.ModifyOrder("regular", order.Data.OrderNo, arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeMCXFO),
    Symbol:          "GOLDPETAL31JUL26F",
    Quantity:        "1",
    DisclosedQty:    "0",
    Product:         string(arrow.ProductMIS),
    OrderType:       string(arrow.OrderTypeLimit),
    TransactionType: string(arrow.TransactionTypeBuy),
    Price:           "14320.0",
    Validity:        string(arrow.ValidityDAY),
    TriggerPrice:    "0",
})

Iceberg Order (Disclosed Quantity)

order, err := client.PlaceOrder("regular", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeNSE),
    Symbol:          "RELIANCE-EQ",
    Quantity:        "1000",
    DisclosedQty:    "100",
    Product:         string(arrow.ProductCNC),
    OrderType:       string(arrow.OrderTypeLimit),
    TransactionType: string(arrow.TransactionTypeBuy),
    Price:           "1450.0",
    Validity:        string(arrow.ValidityDAY),
})

Modify Order

resp, err := client.ModifyOrder("regular", "24012400000321", arrow.OrderRequest{
    Exchange:        string(arrow.ExchangeNSE),
    Symbol:          "RELIANCE-EQ",
    Quantity:        "2",
    Price:           "1500.0",
    DisclosedQty:    "0",
    Product:         string(arrow.ProductCNC),
    TransactionType: string(arrow.TransactionTypeBuy),
    OrderType:       string(arrow.OrderTypeLimit),
    Validity:        string(arrow.ValidityDAY),
    Remarks:         "Modified order",
    TriggerPrice:    "1480.0",
})
if err != nil {
    log.Fatal(err)
}
fmt.Println(resp.Message)

Modification Restrictions

  • Cannot modify executed orders
  • Cannot change exchange or symbol
  • Cannot change transaction type (Buy/Sell)

Cancel Order

Cancel Single Order

if err := client.CancelOrder("regular", "24012400000321"); err != nil {
    log.Fatal(err)
}

Cancel All Orders

if err := client.CancelAllOrders(); err != nil {
    log.Fatal(err)
}

Bulk Cancel

CancelAllOrders is an SDK convenience wrapper (not a single REST route). It fetches the order book and cancels OPEN, TRIGGER_PENDING, and PARTIALLY_FILLED orders sequentially using variety "regular".

Orders still in PENDING / PENDINGNEW / PENDING_NEW are skipped. If any remain pending, the method returns an error (exchange connectivity binary is down). The first cancel failure is also returned.

Margin helpers

margin, err := client.GetMargin(arrow.MarginRequest{
    Exchange:         arrow.ExchangeNSE,
    Symbol:           "RELIANCE-EQ",
    Quantity:         "1",
    Price:            "1450.0",
    Product:          arrow.ProductCNC,
    TransactionType:  arrow.TransactionTypeBuy,
    Order:            arrow.OrderTypeLimit,
    IncludePositions: true,
})
if err != nil {
    log.Fatal(err)
}
fmt.Println("Required margin:", margin.Data.RequiredMargin)

basket, err := client.GetBasketMargin(arrow.BasketMarginRequest{
    Orders: []arrow.MarginRequest{{
        Exchange:        arrow.ExchangeMCXFO,
        Symbol:          "GOLDPETAL31JUL26F",
        Quantity:        "1",
        Price:           "14300.0",
        Product:         arrow.ProductMIS,
        TransactionType: arrow.TransactionTypeBuy,
        Order:           arrow.OrderTypeLimit,
    }},
    IncludePositions: false,
})

The SDK sends symbol (trading symbol) in margin requests. Basket margin is { "orders": [...], "includePositions": bool }, not a bare JSON array.

Live GetMargin response: requiredMargin, minimumCashRequired, marginUsedAfterTrade, charge.

Live GetBasketMargin response: final_margin, initial_margin, orders (each with margin, symid, charge).

Order Tracking

Get Order Details

details, err := client.GetOrder("24012400000321")
if err != nil {
    log.Fatal(err)
}
for _, d := range details.Data {
    fmt.Println(d.OrderStatus, d.ReportType, d.FillShares, d.AveragePrice)
}

Order Status Types

Status Description Next Action
PENDING Order submitted, awaiting confirmation Monitor; CancelAllOrders will not cancel these
OPEN Order active in the market Can modify or cancel
COMPLETE Order fully executed Review execution details
CANCELLED Order cancelled by user/system No further action
REJECTED Order rejected by exchange Check rejection reason

Get Order Book

orders, err := client.GetOrderBook()
if err != nil {
    log.Fatal(err)
}
for _, o := range orders {
    fmt.Printf("%s %s %s %s @ %s status=%s\n",
        o.ID, o.Symbol, o.TransactionType, o.Quantity, o.Price, o.OrderStatus)
}

Get Trade Book

trades, err := client.GetTradeBook()
if err != nil {
    log.Fatal(err)
}
for _, t := range trades {
    fmt.Printf("%s %s fill %s @ %s time=%s\n",
        t.OrderID, t.Symbol, t.Quantity, t.FillPrice, t.FillTime)
}

Note

Trade rows use OrderID, not orderNo.

Order Book Fields

Field Type Description
ID string Order ID
Exchange string Exchange code
Symbol string Trading symbol
Price string Order price
Quantity string Order quantity
Product string Product type (I / C / M)
OrderStatus string Current status
TransactionType string Buy (B) / Sell (S)
Order string Order type
FillShares string Quantity filled in this update
AveragePrice string Average fill price
ExchangeOrderID string Exchange order number
OrderTime string Order timestamp
RejectReason string Rejection reason (if any)

Complete Example

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/arrow-trade/go-arrow/arrow"
)

func main() {
    client := arrow.NewClient(os.Getenv("ARROW_APP_ID"), os.Getenv("ARROW_APP_SECRET"))
    if err := client.AutoLogin(
        os.Getenv("ARROW_USER_ID"),
        os.Getenv("ARROW_PASSWORD"),
        os.Getenv("ARROW_TOTP_SECRET"),
    ); err != nil {
        log.Fatal(err)
    }

    order, err := client.PlaceOrder("regular", arrow.OrderRequest{
        Exchange:        string(arrow.ExchangeNSE),
        Symbol:          "RELIANCE-EQ",
        Quantity:        "1",
        DisclosedQty:    "0",
        Product:         string(arrow.ProductCNC),
        OrderType:       string(arrow.OrderTypeLimit),
        TransactionType: string(arrow.TransactionTypeBuy),
        Price:           "1450.0",
        Validity:        string(arrow.ValidityDAY),
    })
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Order placed:", order.Data.OrderNo)

    details, err := client.GetOrder(order.Data.OrderNo)
    if err != nil {
        log.Fatal(err)
    }
    if len(details.Data) > 0 && details.Data[0].OrderStatus == "OPEN" {
        _, err = client.ModifyOrder("regular", order.Data.OrderNo, arrow.OrderRequest{
            Exchange:        string(arrow.ExchangeNSE),
            Symbol:          "RELIANCE-EQ",
            Quantity:        "1",
            Price:           "1455.0",
            Product:         string(arrow.ProductCNC),
            TransactionType: string(arrow.TransactionTypeBuy),
            OrderType:       string(arrow.OrderTypeLimit),
            Validity:        string(arrow.ValidityDAY),
        })
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("Order modified")
    }

    book, _ := client.GetOrderBook()
    trades, _ := client.GetTradeBook()
    fmt.Println("Orders today:", len(book), "trades:", len(trades))
}

Error Handling

order, err := client.PlaceOrder("regular", req)
if err != nil {
    log.Printf("Order failed: %v", err)
    return
}

Common Order Errors

Error Cause Solution
Insufficient margin Not enough funds Add funds or reduce quantity
Price outside DPR Price beyond daily range Adjust price within limits
Invalid symbol Symbol not found Verify symbol format
Market closed Outside trading hours Wait for market hours
Quantity not in lot F&O lot size mismatch Use correct lot multiples

Best Practices

  • Always validate order parameters before submission
  • Check err on every REST call
  • Monitor position limits and margin with GetMargin / GetLimits
  • Use Remarks for order identification in bulk operations (max 16 characters)