} //InstrumentCatalog_InstrumentsUpdated() // // private void InstrumentLookup_InstrumentUpdated(object sender, InstrumentLookupSubscriptionEventArgs eventArgs) { if (eventArgs.Instrument != null && eventArgs.Error == null) { UVProd.InstrumentName instrName; Instrument ttInstrument = eventArgs.Instrument; if (TTConvertNew.TryConvert(ttInstrument, out instrName)) { // Success in converting to our internal naming scheme. InstrumentDetails details; if (m_InstrumentDetails.TryGetValue(instrName, out details)) { // This instrument was already added! if (!ttInstrument.Key.Equals(details.Key)) { Log.NewEntry(LogLevel.Warning, "{0}: Instrument {1} found before with non-unique key {2}!", this.Name, instrName.FullName, instrName.SeriesName); } else { Log.NewEntry(LogLevel.Warning, "{0}: Instrument {1} found before and keys match! Good.", this.Name, instrName.FullName); } } else { // Add new InstrumentDetails m_KeyToInstruments.Add(ttInstrument.Key, instrName); m_InstrumentDetails.Add(instrName, ttInstrument.InstrumentDetails); Log.NewEntry(LogLevel.Minor, "{0}: Instruments found {1} <---> {2}.", this.Name, instrName, ttInstrument.Key.ToString()); if (sender is InstrumentLookupSubscription) { InstrumentLookupSubscription instSubscription = (InstrumentLookupSubscription)sender; if (!m_InstrumentLookups.ContainsValue(instSubscription)) { // If user called for instr info using only a series name, and not key, we couldn't store subscription object then. // Store it now! m_InstrumentLookups.Add(ttInstrument.Key, instSubscription); Log.NewEntry(LogLevel.Minor, "{0}: Adding new Instrument Subscription found {1}.", this.Name, instrName); } } } } else { // Failed to convert TT instrument to a UV Instrument. // This happens because either their name is too confusing to know what it is. // Or, more likely, we are set to ignore the product type (options, equity, swaps). Log.NewEntry(LogLevel.Warning, "{0}: Instrument creation failed for {1}.", this.Name, ttInstrument.Key.ToString()); } OnInstrumentsFound(); } else if (eventArgs.IsFinal) { // Instrument was not found and TTAPI has given up on looking. if (eventArgs.Instrument != null) { Log.NewEntry(LogLevel.Warning, "{0}: TTAPI gave up looking for {1}.", this.Name, eventArgs.Instrument.Key.ToString()); } else { Log.NewEntry(LogLevel.Warning, "{0}: TTAPI gave up looking for something. ", this.Name, eventArgs.RequestInfo.ToString()); } } }//InstrumentLookup_Callback()
public void SetAttributes(Dictionary <string, string> attributes) { InstrumentName name; InstrumentKey ttkey; foreach (string key in attributes.Keys) { if (key.Equals("Name") && InstrumentName.TryDeserialize(attributes["Name"], out name)) { this.Name = name; } else if (key.Equals("Key") && TTConvertNew.TryCreateInstrumentKey(attributes["Key"], out ttkey)) { this.Key = ttkey; } } }
} //ProcessAJob() // // #endregion// private methods #region TT Callback Event Handlers // ***************************************************************************** // **** TT Callback Event Handlers **** // ***************************************************************************** /// <summary> /// Using TT's dispatcher model, the thread in these methods is my local thread. /// </summary> private void InstrumentCatalog_InstrumentsUpdated(object sender, InstrumentCatalogUpdatedEventArgs eventArgs) { if (m_isDisposing) { return; } if (eventArgs.Error != null) { Log.NewEntry(LogLevel.Warning, "{0}: Error in instrument catalog {1}.", this.Name, eventArgs.Error.Message); return; } // foreach (Instrument ttInstrument in eventArgs.Added) { UVProd.InstrumentName instrName; if (TTConvertNew.TryConvert(ttInstrument, out instrName)) { // Success in converting to our internal type. InstrumentDetails details; if (m_InstrumentDetails.TryGetValue(instrName, out details)) { // This instrument was already added! if (!ttInstrument.Key.Equals(details.Key)) { Log.NewEntry(LogLevel.Warning, "{0}: Instrument {1} found before with non-unique key {2}!", this.Name, instrName.FullName, instrName.SeriesName); } else { Log.NewEntry(LogLevel.Warning, "{0}: Instrument {1} found before and keys match! Good.", this.Name, instrName.FullName); } } else { m_KeyToInstruments.Add(ttInstrument.Key, instrName); m_InstrumentDetails.Add(instrName, ttInstrument.InstrumentDetails); Log.NewEntry(LogLevel.Minor, "{0}: Instruments found {1} <---> {2}.", this.Name, instrName, ttInstrument.Key.ToString()); } } else { // Failed to convert TT instrument to a UV Instrument. // This happens because either their name is too confusing to know what it is. // Or, more likely, we are set to ignore the product type (options, equity, swaps). Log.NewEntry(LogLevel.Warning, "{0}: Instrument creation failed for {1}.", ttInstrument.Key.ToString()); } } // next instr added OnInstrumentsFound(); // Trigger event for subscribers } //InstrumentCatalog_InstrumentsUpdated()
// // //****************************************************************** // **** TimeAndSalesSubscription_Updated() **** //****************************************************************** // /// <summary> /// Time and Sales data is uncoalesced trade data. This allows us to a better job /// of diffrentiating sides volume traded on while recording data for analysis. /// This update Volume on all sides but last. The price subscription has a good last traded volume /// field, this is used only for more in depth analysis when needed /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> private void TimeAndSalesSubscription_Updated(object sender, TimeAndSalesEventArgs eventArgs) { if (m_isDisposing) { return; } if (eventArgs.Error == null) { UVProd.InstrumentName instrumentName; InstrumentKey key = eventArgs.Instrument.Key; if (m_KeyToInstruments.TryGetValue(key, out instrumentName)) { if (eventArgs.Data.Count != 0) { // is any data packed with this event m_NewEvents.Clear(); MarketBase newEvent = m_Market.m_MarketBaseFactory.Get(); // Get an event arg. newEvent.ClearVolume(); // make sure our event is clean. newEvent.Name = instrumentName; int[] instrumentVolumeArray = m_InstrKeyToVolume[key]; foreach (TimeAndSalesData timeAndSalesData in eventArgs.Data) { // for each trade if (!timeAndSalesData.IsOverTheCounter) { // this trade was not OTC int tradeSide = TTConvertNew.ToUVMarketSide(timeAndSalesData.Direction); //long, short or unknown if (timeAndSalesData.TradeQuantity.IsValid) { // qty is valid so aggregate all qty's by the direction of the trade instrumentVolumeArray[tradeSide] += timeAndSalesData.TradeQuantity.ToInt(); } } } for (int side = 0; side < newEvent.Volume.Length; side++) { // update all sides newEvent.Volume[side] = instrumentVolumeArray[side]; } newEvent.IsIncludesTimeAndSales = true; m_NewEvents.Add(newEvent); ProcessPriceChangeEvents(ref m_NewEvents); } } } }