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
Cancel All Orders
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
erron every REST call - Monitor position limits and margin with
GetMargin/GetLimits - Use
Remarksfor order identification in bulk operations (max 16 characters)