Table of Contents

Performance Magic
pnxStringSymbol, pnxOptionHdr, UserData1 and UserData2


Many new NxCore share a common problem when first beginning to use NxCore. As an example one user shared the following comment:

"I only look at a subset of 100 stocks on any given day, but since NxCore streams every message for every issue through the main callback I run into performance problems processing all the additional messages I am not interested in. I have tried to filter only the issues I am interested in with string compares on the symbols, but that also causes performance problems as I receive all equities (which equates to about 30,000 symbols), all with trade and quote messages that need filtered in real time."

This (or similar situations) is the most common performance related issue we hear about. If this relates to an issue you are experiencing please continue reading!


For every message type sent through the NxCore callback function, a NxCoreMessage structure is passed. Within this structure is another structure, NxCoreHeader. Within that structure you will find a pointer (pnxStringSymbol) to an NxString structure, which contains:

struct NxString {
  int UserData1;
  int UserData2;
  unsigned short Atom;
  char String[1];

};
There are 3 very important facts worth emphasizing here:
  1. The NxString pointer value contained in the NxCoreHeader structure (pnxStringSymbol) is an address that will not change for the duration of processing an NxCore Tape.

  2. UserData1 and UserData 2 are both 32-bit integers you can assign values to that will be preserved and returned in all future callback functions for each NxString, for the duration of processing an NxCore Tape.

  3. UserData1 and UserData2 are always initialized to zero when ProcessTape is started, providing an easy mechanism to determine if one has been set (testing against zero).
The importance of these three items cannot be overstated. Understanding them use is the key to unlocking unprecedented performance in your application.

Once the concepts of using the pnxStringSymbol pointer and the UserData1 and UserData2 elements is understood, the next question is usually when to set and/or capture this data. While there are numerous caveats depending on the exact application, you will generally want to set/capture these items in the initial symbol spin, which is a primary NxCore message NxMSG_SYMBOLSPIN.


Options

While other equity types (futures, indexes, currencies, etc) operate the same way as equities, Options are handled slightly differently. With options, pnxStringSymbol will only point to the root symbol. To set option data for an individual contract, use the pnxOptionHdr pointer (contained in the NxCoreHeader structure). This points to a NxOptionHdr structure which contains another NxString pointer, pnxsDateAndStrike. For options, set/check UserData1 and UserData2 with pnxsDateAndStrike (pnxsDateAndStrike->UserData1, pnxsDateAndStrike->UserData2).


Because an example is always the easiest way to demonstrate a concept, we provide 2 very simple console applications that demonstrate the use of these elements. With a little imagination these two examples should provide the insight needed for complex filtering at blazingly fast speeds.

Please note that the examples use the standard console ( "printf" ) to display the data and in the first example will print every trade for the symbols with interest set. This is not an efficient GUI by any stretch and is in fact quite slow. However, we wanted to keep the samples as simple as possible to demonstrate the concept without the need to understand pages of GUI code first. We leave it to you to improve upon these mechanisms in your own applications.

UserDataSample1

In this example, we suppose the user would like to look at only 3 symbols throughout the course of the day, and process every trade message for those symbols only.

The symbols in this example will be hard-coded to "IBM, AAPL and GE". Click HERE to view the source.



UserDataSample2

In this example, we again suppose the user would like to look at only 3 symbols throughout the course of the day, and process every trade message for those symbols only. However in this sample, data is also indexed and referenced into a user defined composite record, and data from the composite records are printed every minute for the symbols.

The symbols in this example will be hard-coded to "IBM, AAPL and GE". Click HERE to view the source.



As you can see, in both examples we have only used UserData1 and in UserDataSample2, we used it to perform 2 tasks (interest set check and a reference into a custom structure array). Using both UserData1 and UserData2, the possibilities are endless.