Placing Orders

This guide shows how to place orders using the Trading API REST endpoint. You'll learn how to:

  • Submit market orders for immediate execution
  • Place limit orders at specific prices
  • Add stop loss protection to your trades

REST Endpoint

Orders are submitted via HTTP POST to the /orders endpoint:

POST http://localhost:8080/orders
Content-Type: application/json

Order Request Fields

Every order requires these fields:

FieldTypeDescription
symbolstringTrading symbol (e.g., "AAPL", "EUR/USD")
sidestringBUY or SELL
quantitystringAmount to trade
order_typestringMARKET, LIMIT, STOP, STOP_LIMIT, TRAILING_STOP

Additional fields depending on order type:

FieldTypeRequired For
limit_pricestringLIMIT, STOP_LIMIT orders
stop_pricestringSTOP, STOP_LIMIT orders
stop_lossstringBracket orders (optional)
take_profitstringBracket orders (optional)
time_in_forcestringOptional (default: GTC)
client_order_idstringOptional (for idempotency)

Market Orders

Market orders execute immediately at the best available price. They're the simplest order type - just specify what you want to trade.

Python

import requests
import json

def place_market_order(symbol: str, side: str, quantity: str) -> dict:
    url = "http://localhost:8080/orders"

    order = {
        "symbol": symbol,
        "side": side,
        "quantity": quantity,
        "order_type": "MARKET"
    }

    response = requests.post(url, json=order)
    response.raise_for_status()
    return response.json()

# Buy 100 shares of AAPL
result = place_market_order("AAPL", "BUY", "100")
print(f"Order ID: {result['id']}, Status: {result['status']}")

JavaScript

async function placeMarketOrder(symbol, side, quantity) {
  const response = await fetch('http://localhost:8080/orders', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      symbol,
      side,
      quantity,
      order_type: 'MARKET'
    })
  });

  if (!response.ok) {
    throw new Error(`Order failed: ${response.status}`);
  }

  return response.json();
}

// Buy 100 shares of AAPL
const result = await placeMarketOrder('AAPL', 'BUY', '100');
console.log(`Order ID: ${result.id}, Status: ${result.status}`);

Java

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class MarketOrder {
    private static final HttpClient client = HttpClient.newHttpClient();
    private static final String BASE_URL = "http://localhost:8080";

    public static String placeMarketOrder(String symbol, String side, String quantity)
            throws Exception {
        String json = String.format("""
            {
                "symbol": "%s",
                "side": "%s",
                "quantity": "%s",
                "order_type": "MARKET"
            }
            """, symbol, side, quantity);

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(BASE_URL + "/orders"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 201) {
            throw new RuntimeException("Order failed: " + response.statusCode());
        }

        return response.body();
    }

    public static void main(String[] args) throws Exception {
        String result = placeMarketOrder("AAPL", "BUY", "100");
        System.out.println("Order response: " + result);
    }
}

Rust

use reqwest::Client;
use serde::{Deserialize, Serialize};

#[derive(Serialize)]
struct OrderRequest {
    symbol: String,
    side: String,
    quantity: String,
    order_type: String,
}

#[derive(Deserialize, Debug)]
struct OrderHandle {
    id: String,
    status: String,
}

async fn place_market_order(
    client: &Client,
    symbol: &str,
    side: &str,
    quantity: &str,
) -> Result<OrderHandle, reqwest::Error> {
    let order = OrderRequest {
        symbol: symbol.to_string(),
        side: side.to_string(),
        quantity: quantity.to_string(),
        order_type: "MARKET".to_string(),
    };

    client
        .post("http://localhost:8080/orders")
        .json(&order)
        .send()
        .await?
        .json()
        .await
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();
    let result = place_market_order(&client, "AAPL", "BUY", "100").await?;
    println!("Order ID: {}, Status: {}", result.id, result.status);
    Ok(())
}

Go

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

type OrderRequest struct {
	Symbol    string `json:"symbol"`
	Side      string `json:"side"`
	Quantity  string `json:"quantity"`
	OrderType string `json:"order_type"`
}

type OrderHandle struct {
	ID     string `json:"id"`
	Status string `json:"status"`
}

func placeMarketOrder(symbol, side, quantity string) (*OrderHandle, error) {
	order := OrderRequest{
		Symbol:    symbol,
		Side:      side,
		Quantity:  quantity,
		OrderType: "MARKET",
	}

	body, err := json.Marshal(order)
	if err != nil {
		return nil, err
	}

	resp, err := http.Post(
		"http://localhost:8080/orders",
		"application/json",
		bytes.NewBuffer(body),
	)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusCreated {
		return nil, fmt.Errorf("order failed: %d", resp.StatusCode)
	}

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var handle OrderHandle
	if err := json.Unmarshal(respBody, &handle); err != nil {
		return nil, err
	}

	return &handle, nil
}

func main() {
	result, err := placeMarketOrder("AAPL", "BUY", "100")
	if err != nil {
		panic(err)
	}
	fmt.Printf("Order ID: %s, Status: %s\n", result.ID, result.Status)
}

Limit Orders

Limit orders let you specify the maximum price you'll pay (for buys) or minimum price you'll accept (for sells). They only execute when the market reaches your price.

Python

import requests

def place_limit_order(symbol: str, side: str, quantity: str, limit_price: str) -> dict:
    url = "http://localhost:8080/orders"

    order = {
        "symbol": symbol,
        "side": side,
        "quantity": quantity,
        "order_type": "LIMIT",
        "limit_price": limit_price,
        "time_in_force": "GTC"  # Good Till Cancelled
    }

    response = requests.post(url, json=order)
    response.raise_for_status()
    return response.json()

# Buy AAPL at $150 or better
result = place_limit_order("AAPL", "BUY", "100", "150.00")
print(f"Limit order placed: {result['id']}")

JavaScript

async function placeLimitOrder(symbol, side, quantity, limitPrice) {
  const response = await fetch('http://localhost:8080/orders', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      symbol,
      side,
      quantity,
      order_type: 'LIMIT',
      limit_price: limitPrice,
      time_in_force: 'GTC'
    })
  });

  if (!response.ok) {
    throw new Error(`Order failed: ${response.status}`);
  }

  return response.json();
}

// Buy AAPL at $150 or better
const result = await placeLimitOrder('AAPL', 'BUY', '100', '150.00');
console.log(`Limit order placed: ${result.id}`);

Java

public static String placeLimitOrder(String symbol, String side,
        String quantity, String limitPrice) throws Exception {
    String json = String.format("""
        {
            "symbol": "%s",
            "side": "%s",
            "quantity": "%s",
            "order_type": "LIMIT",
            "limit_price": "%s",
            "time_in_force": "GTC"
        }
        """, symbol, side, quantity, limitPrice);

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://localhost:8080/orders"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json))
        .build();

    HttpResponse<String> response = client.send(request,
        HttpResponse.BodyHandlers.ofString());

    return response.body();
}

Rust

#[derive(Serialize)]
struct LimitOrderRequest {
    symbol: String,
    side: String,
    quantity: String,
    order_type: String,
    limit_price: String,
    time_in_force: String,
}

async fn place_limit_order(
    client: &Client,
    symbol: &str,
    side: &str,
    quantity: &str,
    limit_price: &str,
) -> Result<OrderHandle, reqwest::Error> {
    let order = LimitOrderRequest {
        symbol: symbol.to_string(),
        side: side.to_string(),
        quantity: quantity.to_string(),
        order_type: "LIMIT".to_string(),
        limit_price: limit_price.to_string(),
        time_in_force: "GTC".to_string(),
    };

    client
        .post("http://localhost:8080/orders")
        .json(&order)
        .send()
        .await?
        .json()
        .await
}

Go

type LimitOrderRequest struct {
	Symbol      string `json:"symbol"`
	Side        string `json:"side"`
	Quantity    string `json:"quantity"`
	OrderType   string `json:"order_type"`
	LimitPrice  string `json:"limit_price"`
	TimeInForce string `json:"time_in_force"`
}

func placeLimitOrder(symbol, side, quantity, limitPrice string) (*OrderHandle, error) {
	order := LimitOrderRequest{
		Symbol:      symbol,
		Side:        side,
		Quantity:    quantity,
		OrderType:   "LIMIT",
		LimitPrice:  limitPrice,
		TimeInForce: "GTC",
	}

	body, _ := json.Marshal(order)
	resp, err := http.Post(
		"http://localhost:8080/orders",
		"application/json",
		bytes.NewBuffer(body),
	)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var handle OrderHandle
	json.NewDecoder(resp.Body).Decode(&handle)
	return &handle, nil
}

Stop Loss Orders (Bracket Orders)

Protect your positions by adding a stop loss when you enter a trade. The Trading API supports bracket orders that automatically create a stop loss order alongside your entry.

Python

import requests

def place_bracket_order(
    symbol: str,
    side: str,
    quantity: str,
    stop_loss: str,
    take_profit: str = None
) -> dict:
    url = "http://localhost:8080/orders"

    order = {
        "symbol": symbol,
        "side": side,
        "quantity": quantity,
        "order_type": "MARKET",
        "stop_loss": stop_loss,
    }

    if take_profit:
        order["take_profit"] = take_profit

    response = requests.post(url, json=order)
    response.raise_for_status()
    return response.json()

# Buy AAPL with stop loss at $145
result = place_bracket_order("AAPL", "BUY", "100", stop_loss="145.00")
print(f"Bracket order placed: {result['id']}")

# Buy with both stop loss and take profit
result = place_bracket_order(
    "AAPL", "BUY", "100",
    stop_loss="145.00",
    take_profit="165.00"
)

JavaScript

async function placeBracketOrder(symbol, side, quantity, stopLoss, takeProfit = null) {
  const order = {
    symbol,
    side,
    quantity,
    order_type: 'MARKET',
    stop_loss: stopLoss,
  };

  if (takeProfit) {
    order.take_profit = takeProfit;
  }

  const response = await fetch('http://localhost:8080/orders', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(order)
  });

  if (!response.ok) {
    throw new Error(`Order failed: ${response.status}`);
  }

  return response.json();
}

// Buy AAPL with stop loss at $145 and take profit at $165
const result = await placeBracketOrder('AAPL', 'BUY', '100', '145.00', '165.00');

Java

public static String placeBracketOrder(String symbol, String side,
        String quantity, String stopLoss, String takeProfit) throws Exception {
    StringBuilder json = new StringBuilder();
    json.append("{");
    json.append(String.format("\"symbol\": \"%s\",", symbol));
    json.append(String.format("\"side\": \"%s\",", side));
    json.append(String.format("\"quantity\": \"%s\",", quantity));
    json.append("\"order_type\": \"MARKET\",");
    json.append(String.format("\"stop_loss\": \"%s\"", stopLoss));
    if (takeProfit != null) {
        json.append(String.format(",\"take_profit\": \"%s\"", takeProfit));
    }
    json.append("}");

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://localhost:8080/orders"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json.toString()))
        .build();

    return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
}

Rust

#[derive(Serialize)]
struct BracketOrderRequest {
    symbol: String,
    side: String,
    quantity: String,
    order_type: String,
    stop_loss: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    take_profit: Option<String>,
}

async fn place_bracket_order(
    client: &Client,
    symbol: &str,
    side: &str,
    quantity: &str,
    stop_loss: &str,
    take_profit: Option<&str>,
) -> Result<OrderHandle, reqwest::Error> {
    let order = BracketOrderRequest {
        symbol: symbol.to_string(),
        side: side.to_string(),
        quantity: quantity.to_string(),
        order_type: "MARKET".to_string(),
        stop_loss: stop_loss.to_string(),
        take_profit: take_profit.map(|s| s.to_string()),
    };

    client
        .post("http://localhost:8080/orders")
        .json(&order)
        .send()
        .await?
        .json()
        .await
}

Go

type BracketOrderRequest struct {
	Symbol     string  `json:"symbol"`
	Side       string  `json:"side"`
	Quantity   string  `json:"quantity"`
	OrderType  string  `json:"order_type"`
	StopLoss   string  `json:"stop_loss"`
	TakeProfit *string `json:"take_profit,omitempty"`
}

func placeBracketOrder(symbol, side, quantity, stopLoss string, takeProfit *string) (*OrderHandle, error) {
	order := BracketOrderRequest{
		Symbol:     symbol,
		Side:       side,
		Quantity:   quantity,
		OrderType:  "MARKET",
		StopLoss:   stopLoss,
		TakeProfit: takeProfit,
	}

	body, _ := json.Marshal(order)
	resp, err := http.Post(
		"http://localhost:8080/orders",
		"application/json",
		bytes.NewBuffer(body),
	)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var handle OrderHandle
	json.NewDecoder(resp.Body).Decode(&handle)
	return &handle, nil
}

Response: OrderHandle

When you submit an order, you receive an OrderHandle response:

{
  "id": "order_abc123",
  "status": "PENDING",
  "client_order_id": "my-order-1"
}
FieldDescription
idServer-assigned order ID
statusInitial status: PENDING, OPEN, or FILLED
client_order_idYour ID if you provided one

Full order details arrive via WebSocket events or a subsequent GET request to /orders/{id}.

Error Handling

Orders can fail for various reasons. Check the HTTP status code and error response:

StatusMeaning
201Order submitted successfully
400Invalid request (bad parameters)
422Order rejected (insufficient funds, invalid symbol, etc.)
503Provider unavailable

Error response format:

{
  "code": "INSUFFICIENT_BALANCE",
  "message": "Insufficient balance to place order",
  "details": { "required": "15000.00", "available": "10000.00" }
}

Common rejection reasons:

  • INSUFFICIENT_MARGIN - Not enough margin for the trade
  • INSUFFICIENT_BALANCE - Not enough cash balance
  • INVALID_QUANTITY - Quantity below minimum or wrong step size
  • INVALID_PRICE - Price outside valid range
  • SYMBOL_NOT_TRADEABLE - Market closed or symbol not available

Next Steps