-
-
Notifications
You must be signed in to change notification settings - Fork 78
Alpaca Streaming API
All WebSocket-based streaming messages described here and here is available for you via events of Alpaca.Markets.AlpacaStreamingClient
and Alpaca.Markets.AlpacaDataStreamingClient
classes respectively. All these events provide you read-only interfaces for related JSON objects.
For creating an instance of each client class we recommend using special extension methods of the IEnvironment
interface designed for this task.
For Alpaca.Markets.AlpacaStreamingClient
class:
var client = Environments.Paper.GetAlpacaStreamingClient(new SecretKey(KEY_ID, SECRET_KEY));
For Alpaca.Markets.AlpacaDataStreamingClient
class:
var client = Environments.Paper.AlpacaDataStreamingClient(new SecretKey(KEY_ID, SECRET_KEY));
You can read more about these extension methods on this Wiki page.
You have to call the ConnectAsync
method for connecting the stream and the DisconnectAsync
method for disconnecting. It also would be very helpful to free resources used by the instance of Alpaca.Markets.AlpacaStreamingClient
or Alpaca.Markets.AlpacaDataStreamingClient
objects using standard .NET IDisposable
pattern. Another helpful method is ConnectAndAuthenticateAsync
- you can use it if you do not want to track connected and authenticated states separately.
The Alpaca.Markets.AlpacaStreamingClient
class provides two events:
- The
OnAccountUpdate
event occurred when a new account update received from the stream. - The
OnTradeUpdate
event occurred when a new trade (order) update received from the stream.
As soon as a client will connect and successfully authenticate you will receive these events. You do not need to call any special methods for enabling/disabling these events - just subscribe to them as usual .NET events.
The Alpaca.Markets.AlpacaDataStreamingClient
class uses another approach for active subscriptions management. Each active subscription represented as an instance of IAlpacaDataSubscription<T>
generic interface, instantiated with a specific update type.
- You have to obtain such a subscription object using the
GetTradeSubscription
,GetQuoteSubscription
, orGetMinuteAggSubscription
method. - Each subscription object exposes the
Received
event with a specific update type (IStreamTrade
for trade subscription,IStreamQuote
for quote subscription,IStreamAgg
for minute aggregates subscription) - you should subscribe to this .NET event for receiving notifications from the streaming client. - All subscription objects for newly created
Alpaca.Markets.AlpacaDataStreamingClient
class is in the unsubscribed state regardless of .NET event invocations list size. - You can change the state of a single subscription object or a list of different subscriptions using the
Subscribe
andUnsubscribe
methods of theAlpaca.Markets.AlpacaDataStreamingClient
class respectively.
The next code snippet demonstrates this process in detail - create client, create subscriptions, subscribe events, wait for events, close connection:
using var client = Environments.Live
.GetAlpacaDataStreamingClient(new SecretKey(KEY_ID, SECRET_KEY));
await client.ConnectAndAuthenticateAsync();
var waitObjects = new []
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};
var tradeSubscription = client.GetTradeSubscription("AAPL");
tradeSubscription.Received += (trade) =>
{
Console.WriteLine($"Trade received for the {trade.Symbol} contract");
waitObjects[0].Set();
};
var quoteSubscription = client.GetQuoteSubscription("AAPL");
quoteSubscription.Received += (quote) =>
{
Console.WriteLine($"Quote received for the {quote.Symbol} contract");
waitObjects[1].Set();
};
client.Subscribe(tradeSubscription, quoteSubscription);
WaitHandle.WaitAll(waitObjects, TimeSpan.FromSeconds(10));
client.Unsubscribe(tradeSubscription, quoteSubscription);
await client.DisconnectAsync();
The Alpaca.Markets.Extensions package contains helper interfaces (and related implementations) and methods for more simple real-time data events consuming in the asynchronous code:
- The
AsAsyncEnumerable
extension method of theIAlpacaDataSubscription<T>
interface converts the instance of this interface into the instance ofIAsyncEnumerable<T>
interface for consuming it with C#await foreach
statement. - The
IDisposableAlpacaDataSubscription<T>
interface and internal implementation that combinesIAlpacaDataSubscription<IStreamQuote>
,IAsyncDisposable
, andIDisposable
interfaces and allows you to consume subscription events in the scope of C#using
orawait using
statements.
The next code snippet demonstrates both features in action:
using var client = Environments.Live
.GetAlpacaDataStreamingClient(new SecretKey(KEY_ID, SECRET_KEY));
await client.ConnectAndAuthenticateAsync();
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(15));
await using var subscription = client.SubscribeTrade(Symbol);
await foreach (var trade in subscription
.AsAsyncEnumerable(cancellationTokenSource.Token)
.ConfigureAwait(false))
{
Console.WriteLine($"Trade received for the {trade.Symbol} contract");
}
await client.DisconnectAsync();
You shouldn't call Subscribe
and Unsubscribe
methods manually - they will be called for you (in the implementation class constructor and inside the IDisposeAsync
method) automatically. And keep in mind that C# await foreach
statement will not execute any code behind the loop body until enumerable completion - in this example, it will happen after 15 seconds, but you can use the cancellation token received from the outer code.