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
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.AbstractBroker
— TypeAbstractBroker
Interface 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
— TypeMockBroker
Mimics 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
— TypeDataStream
Supplies 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