Market Data Streaming API

Servers

Establishing a connection

A connection must be established first in order to subscribe to any updates. To do this, you may use any ASP.NET Core SignalR client of your choice.

				
HubConnection connection = new HubConnectionBuilder()
	.WithUrl("{{API URL HERE}}/streams", options =>
	{
		options.AccessTokenProvider = GetBearerToken;
	})
	.AddMessagePackProtocol()
	.Build();

await connection.StartAsync();
				
				

Implement an access token provider

You need the md-streams-api scope claim in order to be authorized to use the streaming hub. Learn from our Auth API documentation on how to get an authorization token.

				
private async Task<string> GetBearerToken()
{
	// TODO: Implement access token provider here.
}
					
				

Subscribing to Quote Updates

In order to subscribe to pricing quote updates for securities, you first need to setup the event handler for incoming data. You need a handler for QuotesUpdated event.

				
private async Task HandleQuotesUpdates()
{
	this.connection.On("QuotesUpdated", quotes =>
	{
		// Do something with the data
	});
}
					
				

Below is the schema of the data, in JSON, coming from the hub.

									
{
	"securityCode": {
		"type": "string"
	},
	"exchange": {
		"type": "string"
	},
	"dataSource": {
		"type": "string"
	},
	"askCount": {
		"type": "number"
	},
	"askPrice": {
		"type": "number"
	},
	"askVolume": {
		"type": "number"
	},
	"bidCount": {
		"type": "number"
	},
	"bidPrice": {
		"type": "number"
	},
	"bidVolume": {
		"type": "number"
	},
	"totalVolume": {
		"type": "number"
	},
	"totalValue": {
		"type": "number"
	},
	"highPrice": {
		"type": "number"
	},
	"lastPrice": {
		"type": "number"
	},
	"lowPrice": {
		"type": "number"
	},
	"matchPrice": {
		"type": "number"
	},
	"matchVolume": {
		"type": "number"
	},
	"marketValue": {
		"type": "number"
	},
	"marketVolume": {
		"type": "number"
	},
	"movement": {
		"type": "number"
	},
	"openPrice": {
		"type": "number"
	},
	"quotationBasisCode": {
		"type": "string"
	},
	"companyReportCode": {
		"type": "string"
	},
	"tradingStatus": {
		"type": "string"
	},
	"tradeCount": {
		"type": "number"
	},
	"tradeDateTime": {
		"type": "datetime"
	},
	"updateDateTime": {
		"type": "datetime"
	},
	"previousClosePrice": {
		"type": "number"
	}
}
							
						

You may setup the handler before starting the connection.

					
...

this.HandleQuotesUpdates();
await connection.StartAsync();
						
					

Now, all you need to do is invoke the SubscribeToQuoteUpdates hub method. This will subscribe your client to security quote updates channel depending on the parameters supplied.

					
private async Task SubscribeToQuoteUpdates()
{
	string dataSource = "TM"; // The dataSource to subscribe to
	await connection.InvokeAsync("SubscribeToQuoteUpdates", dataSource);
}
						
					
Parameter Name Required Data Type Description
dataSource yes string The datasource to receive data from.

Then call it after the connection has been started.

					
...
await connection.StartAsync();
this.SubscribeToQuoteUpdates();
					
				

Subscribing to Trade Updates

In order to subscribe to trade updates, you first need to setup the event handler for incoming data. You need a handler for TradesUpdated event.

				
private async Task HandleTradeUpdates()
{
	this.connection.On("TradesUpdated", trades =>
	{
		// Do something with the data
	});
}
					
				

Below is the schema of the data, in JSON, coming from the hub.

									
{
	{
	"tradeNumber": {
		"type":"number"
	},
	"securityCode": {
		"type":"string"
	},
	"exchange": {
		"type":"string"
	},
	"dataSource": {
		"type":"string"
	},
	"price": {
		"type":"number"
	},
	"tradeVolume": {
		"type":"number"
	},
	"tradeValue": {
		"type":"number"
	},
	"tradeDateTime": {
		"type":"datetime"
	},
	"conditionCodes": {
		"type":"string"
	},
	"reason": {
		"type":"string"
	}
}
							
						

You may setup the handler before starting the connection.

					
...

this.HandleQuotesUpdates();
await connection.StartAsync();
						
					

Now, all you need to do is invoke the SubscribeToTradeUpdates hub method. This will subscribe your client to trade updates channel depending on the parameters supplied.

					
private async Task SubscribeToTradeUpdates()
{
	string dataSource = "TM"; // The dataSource to subscribe to
	await connection.InvokeAsync("SubscribeToTradeUpdates", dataSource);
}
						
					
Parameter Name Required Data Type Description
dataSource yes string The datasource to receive data from.

Then call it after the connection has been started.

					
...
await connection.StartAsync();
this.SubscribeToTradeUpdates();
					
				

Automatic Reconnect

Dropped connections due to network issues can be automatically reconnected by certain clients. Consult your client's documentation for more details. An example for the .NET Client is shown below:

				
HubConnection connection = new HubConnectionBuilder()
	.WithUrl("{{API URL HERE}}/streams", options =>
	{
		options.AccessTokenProvider = GetBearerToken;
	})
	.WithAutomaticReconnect() // this will enable automatic reconnect
	.AddMessagePackProtocol()
	.Build();
				
				

Handling Reconnects

Clients that were successfully reconnected need to resubscribe to the channels they were subscribed prior to disconnecting. A Reconnected event handler should be implemented to resubscribe a client.

				
connection.Reconnected += async (connectionId) =>
{
	Console.WriteLine("Reconnected.");

	// Resubscribe to the channels
	await SubscribeToTradeUpdates();
	await SubscribeToQuoteUpdates();
};
				
				

Additional Resources