Bracket Order Code Example with alpaca-py Library

I struggled to find adequate documentation on bracket orders with the new and updated alpaca-py library, so I figured I’d post the below example for someone struggling to find an example in the future.

Imports

from alpaca.trading.client import TradingClient
from alpaca.trading.requests import MarketOrderRequest, TakeProfitRequest, StopLossRequest
from alpaca.trading.enums import OrderSide, TimeInForce, QueryOrderStatus, OrderClass

Keys

API_KEY = "<YOUR KEY>"
SECRET_KEY = "<YOUR SECRET>"

Variables

trading_client = TradingClient(API_KEY, SECRET_KEY, paper=True)

Functions

def main():

Request a Bracket market order (calling Bracket market order function)

market_order_data = bracket_order(
        "AAPL", 1, 100, 200, OrderSide.BUY, TimeInForce.GTC
    )

Submit market order

submit_order(market_order_data)

Bracket market order function

def bracket_order(ticker, size, stop, take_profit, order_side, tif):
    stop_loss_request = StopLossRequest(
    stop_price=stop
    )
    take_profit_request = TakeProfitRequest(
    limit_price=take_profit
    )
    market_order_data = MarketOrderRequest(
        symbol=ticker,
        qty=size,
        side=order_side,
        time_in_force=tif,
        order_class = OrderClass.BRACKET,
        stop_loss=stop_loss_request,
        take_profit=take_profit_request
    )
    return market_order_data

Submit an order and print the returned object function

def submit_order(order_data):
    order = trading_client.submit_order(order_data)
    for property_name, value in order:
        print(f'"{property_name}": {value}')

Calling main() when running script directly

if __name__ == "__main__":
    main()

Happy trading!
P

1 Like

Thank you! Do you think it is possible to have a limit order and when this is filled a market on close order is submitted to exit on the close?

Yes, and if you simply wanted to close everything before close end of week, you could do something like this. To close it each day just remove and next_open() >= 63:

from alpaca.trading.client import TradingClient
from alpaca.trading.requests import (
    MarketOrderRequest,
    StopOrderRequest,
    LimitOrderRequest,
    StopLimitOrderRequest,
    TrailingStopOrderRequest,
    GetOrdersRequest,
    GetOrderByIdRequest,
    ReplaceOrderRequest,
    TakeProfitRequest,
    StopLossRequest,
    ClosePositionRequest,
    GetAssetsRequest,
    GetPortfolioHistoryRequest,
    CancelOrderResponse,
    GetCalendarRequest
)
from alpaca.trading.enums import (
    OrderSide,
    TimeInForce,
    AssetClass,
    QueryOrderStatus,
    OrderClass,
)
from alpaca.data.historical import StockHistoricalDataClient
from datetime import datetime
import time
from pytz import timezone
import sys
import os
tz = timezone("EST")

def main():

def main():

while not trading_client.get_clock().is_open:  # Set to not
        print(f"{datetime.now(tz)} - Market Closed, keep checking")
        time.sleep(60) #60
        continue
    else:
        print(f"{datetime.now(tz)} - Closing any unwanted open orders and positions")
        print(trading_client.close_all_positions(cancel_orders=True))
        time.sleep(5)
        print(f"{datetime.now(tz)} - Executing trades")
        market_order_data = bracket_order("AAPL", 1, 100, 200, OrderSide.BUY, TimeInForce.GTC)
        print(submit_order(market_order_data))
        while trading_client.get_clock().is_open and market_closing() > 12 and next_open() >= 63:
            print(f"{datetime.now(tz)} - Market not closing soon and week not ending")
            time.sleep(60) #60
            continue
        else:
            print(f"{datetime.now(tz)} - Closing all open orders and trades to end the week")
            trading_client.close_all_positions(cancel_orders=True)
            while trading_client.get_clock().is_open:
                print(f"{datetime.now(tz)} - Waiting for market to close for the week to exit program")
                time.sleep(60) #60
                continue
            else:
                sys.exit(f"{datetime.now(tz)} - Exiting to restart program")
# Market order function
def market_order(ticker, size, order_side, tif):
    market_order_data = MarketOrderRequest(
        symbol=ticker,
        qty=size,
        side=order_side,
        time_in_force=tif,
    )
    return market_order_data
# Stop order function
def stop_order(ticker, size, order_side, tif, stop):
    stop_order_data = StopOrderRequest(
        symbol=ticker, qty=size, side=order_side, time_in_force=tif, stop_price=stop
    )
    return stop_order_data
# Submit an order and print the returned object function
def submit_order(order_data):
    order = trading_client.submit_order(order_data)
    for property_name, value in order:
        print(f'"{property_name}": {value}')
# Cancel_all open orders and print each of them function
def cancel_all():
    positions = trading_client.cancel_orders()
    for position in positions:
        for property_name, value in position:
            print(f'"{property_name}": {value}')
def market_closing():
    est = datetime.now(tz).timestamp()
    market_close = trading_client.get_clock().next_close.timestamp()
    time_to_close = int((market_close - est) / 60)  # Minutes to next close
    return time_to_close
    


def next_open():
    market_close = trading_client.get_clock().next_close.timestamp()
    market_open = trading_client.get_clock().next_open.timestamp()
    time_to_next_open = int((market_open - market_close) / 3600)  # Hours to next open
    return time_to_next_open
if __name__ == "__main__":
    main()
1 Like

Wow thank you! I am hoping they could include some trigger mechanism in the future like IBKR has it in their order logic.

The documentation is faulty and not updated. Wondering if I should put more money into Alpaca.

Yes, the docs on the website are outdated, and they do have updated docs, it’s just not full of context or examples. I’ve been successful using this: Alpaca-py