Brokers

An AbstractBroker signifies the interface between the local Trader and an external party that supplies data, and potentially executes orders and holds the user's portfolio. The current brokers are:

Data

Historical

A slew of historical data can be requested through a broker e.g

broker = AlpacaBroker(ENV["ALPACA_KEY_ID"], ENV["ALPACA_SECRET"])
bars(broker, Stock("AAPL"), DateTime("2023-04-05T00:00:00"), DateTime("2023-04-05T22:00:00"), timeframe=Minute(1))
628×7 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2023-04-05T00:00:00 to 2023-04-05T22:00:00
│                     │ o        │ h        │ l        │ c        │ v          │
├─────────────────────┼──────────┼──────────┼──────────┼──────────┼────────────┤
│ 2023-04-05T00:00:00 │ 165.57   │ 165.68   │ 165.57   │ 165.68   │ 3878.0     │
│ 2023-04-05T00:07:00 │ 165.6    │ 165.6    │ 165.6    │ 165.6    │ 275.0      │
│ 2023-04-05T00:09:00 │ 165.6    │ 165.6    │ 165.6    │ 165.6    │ 728.0      │
│ 2023-04-05T00:10:00 │ 165.6    │ 165.6    │ 165.6    │ 165.6    │ 468.0      │
│ 2023-04-05T00:13:00 │ 165.57   │ 165.57   │ 165.57   │ 165.57   │ 267.0      │
│ 2023-04-05T00:16:00 │ 165.55   │ 165.55   │ 165.55   │ 165.55   │ 369.0      │
│ 2023-04-05T00:19:00 │ 165.56   │ 165.56   │ 165.56   │ 165.56   │ 1936.0     │
│ 2023-04-05T00:23:00 │ 165.5301 │ 165.5301 │ 165.5301 │ 165.5301 │ 346.0      │
│ 2023-04-05T00:25:00 │ 165.54   │ 165.54   │ 165.53   │ 165.53   │ 355.0      │
   ⋮
│ 2023-04-05T21:53:00 │ 163.59   │ 163.725  │ 163.585  │ 163.72   │ 219434.0   │
│ 2023-04-05T21:54:00 │ 163.72   │ 163.84   │ 163.72   │ 163.79   │ 292333.0   │
│ 2023-04-05T21:55:00 │ 163.79   │ 163.89   │ 163.76   │ 163.8799 │ 317012.0   │
│ 2023-04-05T21:56:00 │ 163.8877 │ 163.89   │ 163.8    │ 163.8331 │ 365009.0   │
│ 2023-04-05T21:57:00 │ 163.84   │ 163.91   │ 163.8    │ 163.88   │ 326652.0   │
│ 2023-04-05T21:58:00 │ 163.885  │ 163.895  │ 163.83   │ 163.8645 │ 343050.0   │
│ 2023-04-05T21:59:00 │ 163.87   │ 163.95   │ 163.73   │ 163.76   │ 756617.0   │
│ 2023-04-05T22:00:00 │ 163.76   │ 163.82   │ 163.71   │ 163.76   │ 5.554997e6 │

│                     │ n      │ vw       │
├─────────────────────┼────────┼──────────┤
│ 2023-04-05T00:00:00 │ 95.0   │ 165.6294 │
│ 2023-04-05T00:07:00 │ 15.0   │ 165.5986 │
│ 2023-04-05T00:09:00 │ 14.0   │ 165.6012 │
│ 2023-04-05T00:10:00 │ 8.0    │ 165.5966 │
│ 2023-04-05T00:13:00 │ 15.0   │ 165.5764 │
│ 2023-04-05T00:16:00 │ 22.0   │ 165.5584 │
│ 2023-04-05T00:19:00 │ 12.0   │ 165.5586 │
│ 2023-04-05T00:23:00 │ 11.0   │ 165.531  │
│ 2023-04-05T00:25:00 │ 24.0   │ 165.5406 │
   ⋮
│ 2023-04-05T21:53:00 │ 1970.0 │ 163.662  │
│ 2023-04-05T21:54:00 │ 2470.0 │ 163.7587 │
│ 2023-04-05T21:55:00 │ 2720.0 │ 163.8309 │
│ 2023-04-05T21:56:00 │ 2750.0 │ 163.8559 │
│ 2023-04-05T21:57:00 │ 2759.0 │ 163.8556 │
│ 2023-04-05T21:58:00 │ 2873.0 │ 163.8634 │
│ 2023-04-05T21:59:00 │ 5296.0 │ 163.8585 │
│ 2023-04-05T22:00:00 │ 210.0  │ 163.7601 │

There are so far three such functions:

  • bars: retrieve historical bar data
  • trades: retrieve historical data on trades
  • quotes: retrieve historical data on quotes

Realtime

The Broker can be queried for the current_price of an asset, and bar data can be streamed in by calling data_stream, either in realtime from a realtime broker (e.g. AlpacaBroker), or faked realtime when using a HistoricalBroker.

For example, internally start_data essentially looks like:

data_stream(trader.broker) do stream
    for (asset, q) in trader.asset_ledgers
        register!(stream, asset)
    end
    while !trader.stop_data
        bars = receive(stream)
        # distribute bars to asset ledgers
    end
end

See register! and receive for further information.

Orders

Orders can be submitted with submit_order and updates to them can be streamed in with trading_stream. Similarly to start_data, start_trading opens an order stream so order updates can be passed along to the Order Component:

trading_stream(trader.broker) do stream
    while !trader.stop_trading
        order = receive(stream)
        # update Order component
    end
end

In general, however, these functions should not be used and one should rely on the core systems of the Trader to submit and handle orders through Purchase and Sale Components. See Portfolio for more info.

References

Trading.HistoricalBrokerType
HistoricalBroker(broker)

Stores and provides data from historical datasets. Data can be streamed fashion by assigning a Clock to the clock constructor kwarg, which will be used to determine the next bar to stream when calling receive on this broker.

source
Trading.barsFunction
bars(broker, asset, start, stop; timeframe, kwargs...)

Retrieve the bar data for asset from start to stop and with an interval of timeframe. When using AlpacaBroker see the Bar Object documentation for further reference.

Example

broker = AlpacaBroker(<key_id>, <secret_key>)

bars(broker, "AAPL",
     DateTime("2022-01-01T00:00:00"),
     DateTime("2023-01-01T00:00:00"),
     timeframe = Minute(1))

The above will retrieve 2022 bar data "AAPL" on a Minute resolution.

source
Trading.tradesFunction
trades(broker, asset, start, stop)

Returns the trades made for asset between start and stop. When using AlpacaBroker see the Trade Object documentation for further reference.

Example

broker = AlpacaBroker(<key_id>, <secret_key>)

trades(broker, "AAPL", DateTime("2022-01-01T14:30:00"), DateTime("2022-01-01T14:31:00"))
source
Trading.quotesFunction
quotes(broker, asset, start, stop)

Returns the quotes made for asset between start and stop. When using AlpacaBroker see the Quote Object documentation for further reference.

Example

broker = AlpacaBroker(<key_id>, <secret_key>)

quotes(broker, "AAPL", DateTime("2022-01-01T14:30:00"), DateTime("2022-01-01T14:31:00"))
source
Trading.submit_orderFunction
submit_order(broker, order::Union{Purchase,Sale})

Submits the order to a broker for execution.

source
Trading.trading_streamFunction
trading_stream(f::Function, broker::AbstractBroker)

Creates an TradingStream to stream order data. Uses the same semantics as a standard HTTP.WebSocket.

Example

broker = AlpacaBroker(<key_id>, <secret_key>)

trading_stream(broker) do stream
    order = receive(stream)
end
source