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:
AlpacaBroker: the main "real" brokerMockBroker: behaves similarly to a real broker but with random dataHistoricalBroker: wraps another broker to supply historical data whenBackTesting
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 datatrades: retrieve historical data on tradesquotes: 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
endSee 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
endIn 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.AbstractBroker — TypeAbstractBrokerInterface for external brokers.
Trading.AlpacaBroker — TypeAlpacaBroker(key_id, secret_key)Broker to communicate with Alpaca. Can be constructed with your key_id and secret_key (see connect-to-alpaca-api).
Trading.HistoricalBroker — TypeHistoricalBroker(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.
Trading.MockBroker — TypeMockBrokerMimics all function of a normal broker but with random data.
Trading.bars — Functionbars(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.
Trading.trades — Functiontrades(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"))Trading.quotes — Functionquotes(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"))Trading.current_price — Functioncurrent_price(broker, asset)
current_price(trader, asset)Return the current price of an asset.
Trading.DataStream — TypeDataStreamSupplies a stream of bars from a broker. Can be created by calling data_stream on an AbstractBroker. See receive and register! for more information.
Trading.data_stream — Functiondata_stream(f::Function, broker, a)Open a bar stream, calls function f with a DataStream object. Call receive on the DataStream to get new bars streamed in, and register! to register assets for which to receive bar updates for.
HTTP.WebSockets.receive — Methodreceive(barstream)Blocking function which will return new bars as soon as they are available.
Trading.register! — Methodregister!(barstream, asset)Register a asset to the DataStream so that receive will also return updates with new bars for asset.
Trading.submit_order — Functionsubmit_order(broker, order::Union{Purchase,Sale})Submits the order to a broker for execution.
Trading.TradingStream — TypeInterface to support executing trades and retrieving account updates. Opened with trading_stream
Trading.trading_stream — Functiontrading_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