Working with price subscriptions
Process for creating price subscriptions
To create a price subscription and start receiving updates, you:
- Create a PriceSubscription object for a specific Instrument.
- Specify the price subscription type.
- Create an event handler method to be called when market data updates for the Instrument are available.
- Register the event handler with the PriceSubscription instance.
- Call the Start method of the PriceSubscription instance.
Warning : TT strongly recommends users maintain their price subscriptions. To prevent issues, users must avoid unsubscribing and immediately resubscribing to market updates.
Subscribing for market data
Typically, you start a price subscription for an Instrument when TT .NET SDK fires the Update event for the InstrumentLookup object you created to find the Instrument.
The following snippet modifies the OnData event handler to start a price subscription for market depth data.
void m_instrLookupRequest_OnData(object sender, InstrumentLookupEventArgs e)
{
if (e.Event == ProductDataEvent.Found)
{
// Instrument was found
Instrument instrument = e.InstrumentLookup.Instrument;
Console.WriteLine("Found: {0}", instrument);
// Subscribe for market Data
m_priceSubsciption = new PriceSubscription(instrument, tt_net_sdk.Dispatcher.Current);
m_priceSubsciption.Settings = new PriceSubscriptionSettings(PriceSubscriptionType.MarketDepth);
m_priceSubsciption.FieldsUpdated += m_priceSubscription_FieldsUpdated;
m_priceSubsciption.Start();
}
else if (e.Event == ProductDataEvent.NotAllowed)
{
Console.WriteLine("Not Allowed : Please check your Token access");
}
else
{
// Instrument was not found and TT API has given up looking for it
Console.WriteLine("Cannot find instrument: {0}", e.Message);
}
}
Creating the subscription event handler
After the subscription starts, TT .NET SDK retrieves all of the market data for the Instrument and invokes the event handler method you registered with the subscription. TT .NET SDK fires the FieldsUpdated event with the FieldsUpdatedEventArgs.UpdateType property set to UpdateType.Snapshot for the initial market data snapshot. You can use the PriceSubscriptionFields.GetFieldIds method to process all of market data. Subsequently, when any of the market data fields change, TT .NET SDK sets the FieldsUpdatedEventArgs.UpdateType property to UpdateType.Incremental to indicate that only some of the market data changed. In this case, you can use the PriceSubscriptionFields.GetChangedFieldIds method to retrieve the ids of only the fields whose values changed.
The following code snippet shows the structure of a sample price subscription event handler method.
void m_priceSubscription_FieldsUpdated(object sender, FieldsUpdatedEventArgs e)
{
// Inside market fields
foreach (FieldId id in e.Fields.GetFieldIds())
{
Field f = e.Fields[id];
// Put code to process the field here
}
Console.WriteLine("Ask Depth Snapshot");
int askDepthLevels = e.Fields.GetLargestCurrentDepthLevel(FieldId.BestAskPrice);
for (int i = askDepthLevels - 1; i >= 0; i--)
{
Quantity q = e.Fields.GetBestAskQuantityField(i).Value;
if (Quantity.IsEmpty(q))
continue;
Console.WriteLine(" Level=" + i + " Qty=" + q + " Price=" + e.Fields.GetBestAskPriceField(i).Value.ToString());
int askDetailedDepthLevels = e.Fields.GetLargestCurrentDetailedDepthLevel(FieldId.AskDetailedDepthQuantity, i);
for (int j = 0; j < askDetailedDepthLevels; j++)
{
Quantity qu = e.Fields.GetAskDetailedDepthQuantityField(i, j).Value;
if (Quantity.IsEmpty(qu))
continue;
Console.WriteLine(" DETAILED DEPTH Level=" + j + " Detailed Depth Qty=" + qu + " Price=" + e.Fields.GetBestAskPriceField(i).Value.ToString());
}
}
Console.WriteLine("Bid Depth Snapshot");
int bidDepthLevels = e.Fields.GetLargestCurrentDepthLevel(FieldId.BestBidPrice);
for (int i = 0; i < bidDepthLevels; i++)
{
Quantity q = e.Fields.GetBestBidQuantityField(i).Value;
if (Quantity.IsEmpty(q))
continue;
Console.WriteLine(" Level=" + i + " Qty=" + q + " Price=" + e.Fields.GetBestBidPriceField(i).Value.ToString());
int bidDetailedDepthLevels = e.Fields.GetLargestCurrentDetailedDepthLevel(FieldId.BidDetailedDepthQuantity, i);
for (int j = 0; j < bidDetailedDepthLevels; j++)
{
Quantity qu = e.Fields.GetBidDetailedDepthQuantityField(i, j).Value;
if (Quantity.IsEmpty(qu))
continue;
Console.WriteLine(" DETAILED DEPTH Level=" + j + " Detailed Depth Qty=" + qu + " Price=" + e.Fields.GetBestBidPriceField(i).Value.ToString());
}
}
}
Extracting market data values
FieldId is an enumerated type defining the set of valid market data fields, such as DirectBidPrice, DirectBidQuantity, etc. When used as an index to extract market data fields from the Fields property of the FieldsUpdatedEventArgs object, it returns a Field object.
To extract the actual value, you can call the FormattedValue property of the tt_net_sdk.Field object, for example:
Field f = e.Fields[id];
string s = f.FormattedValue;
You can also use the FormattedValue property of the tt_net_sdk.Field object object to reference to the Object storing the value. You can then cast it to its real type. For example:
foreach (FieldId id in e.Fields.GetFieldIds())
{
Field field = e.Fields[id];
if (field is PriceField pf)
{
Price p = pf.Value;
}
else if (field is QuantityField qf)
{
Quantity q = qf.Value;
}
}
Alternatively, you can access specific tt_net_sdk.Field values directly without needing to cast the return value, as follows:
Price bid = e.Fields.GetDirectBidPriceField().Value;
Quantity bidQty = e.Fields.GetBidMarketQuantityField().Value;