Table of Contents


Price and PriceType in NxCore

NxCore uses integer prices internally. When combined with a PriceType descriptor, these integer prices can be converted to a floating or a double-precision value. But for absolute performance critical code, they allow integer math to be performed on prices.

Price

A signed integer, it is used for such things as Ask/Bid price, Last Sale, Net Change, Ask/Bid price changes, and so on.

PriceType

A number between 0 and 39 which indicates how to convert between an implied decimal number and a floating point number. PriceTypes are arranged in 2 groups, one for base 10 (PriceType 0-19) and one for base 2 (PriceType 20-39). The table below shows the multiplication factor for each PriceType which will convert a integer price to a floating point number.

NxPriceType Factor NxPriceType Factor
0 Not defined 20 0.0009765625
1 0.000000001 21 0.001953125
2 0.00000001 22 0.00390625
3 0.0000001 23 0.0078125
4 0.000001 24 0.015625
5 0.00001 25 0.03125
6 0.0001 26 0.0625
7 0.001 27 0.125
8 0.01 28 0.25
9 0.1 29 0.50
10 1.0 30 1.0
11 10.0 31 2.0
12 100.0 32 4.0
13 1000.0 33 8.0
14 10000.0 34 16.0
15 100000.0 35 32.0
16 1000000.0 36 64.0
17 10000000.0 37 128.0
18 100000000.0 38 256.0
19 1000000000.0 39 512.0

For example, to convert the number 1234 with a NxPriceType of 8, multiply 1234 by 0.01 to get 12.34. Converting between NxPriceTypes within the same base can be performed strictly as an integer operation -- for example, from a NxPriceType between 0-19 with another NxPriceType between 0-19 can be performed as an interger operation by multiplying or dividing by a multiple of 10. Converting within base 2, NxPriceTypes (20-39), you would multiply or divide by a multiple of 2.

Two NxPriceTypes are mathematically equivalent: NxPriceType(10) and NxPriceType(30). The former is used for prices that normally appear in base 10, the later is used for prices normally appearing in base 2. Very rarely will prices in the Nanex Financial Stream alter between base 10 and base 2; however, converting from one base to another is simply a matter of multiplying by the source type and dividing by the destitation type.

The integer value 0 is equivalent in any NxPriceType, but convention is for 0 to use the same NxPriceType common to the Quote, Trade, or Category message for a particular symbol.

Rounding issues

When converting from one NxPriceType to another within integer format, where the number being converted loses precision, positive numbers are first incremented by 1/2 the multiplication factor, and negative numbers are incremented by - 1/2 the multiplcation factor. For example, converting the number 150 from NxPriceType(7) to NxPriceType(9):

Convert 150 from NxPriceType(7) to NxPriceType(9)
7-9 = -2. Multiply by 10^-2, which is the same as Divide by 10^2, which is the same as Divide by 100.
Rounding = 100/2 = 50;
result = (150 + 50)/100;
result == 2.
Converting 140, the result would be 1.
For negative numbers, rounding = -50 (-divisor/2)
Converting -150.
result = (-150 + -50)/100
result == -2.
Converting -140, the result would be -1.

Several exchanges transmit quotes more precision than is necessary; however, the Nanex Financial Stream does not round prices, rather it changes to a NxPriceType with more precision. You may find it useful to round prices in your application to a common NxPriceType. For example, you might decide to value all North American Equities trading over $5 with a NxPriceType of 8 (2 decimal places), and those under $5 with a NxPriceType of 7 (3 decimal places). Or perhaps you value all North American Equities with a NxPriceType of 7.

NOTE: NxPriceType of a specific symbol's NxPrice may change during the day. Do not assume that because MSFT traded at PriceType=8, it won't trade at PriceType=7 a second later.

Combined Price and PriceType structure

Some NxCore structures use the NxPrice struct that combines both the integer Price with PriceType.

struct NxPrice {
    int           Price;
    unsigned char PriceType;
};

Standalone Price and PriceType

Many other NxCore structures use a single PriceType and multiple Price fields.

Converting Price and PriceType into a double

int __stdcall nxCoreCallback(const NxCoreSystem* pNxCoreSys,const NxCoreMessage* pNxCoreMessage)
{ 
  switch (pNxCoreMessage->MessageType)
  {
    case NxMSG_TRADE:
         {
         const NxCoreTrade& nt = pNxCoreMessage->coreData.Trade; 			 
 			 
         char buf[256];
         char* p = buf; 			 
 			 
     // Use PriceFormat function to print as a float
         p += sprintf(p, "LastTrade(");
         p += pfNxCorePriceFormat(p, nt.Price, nt.PriceType,0,false);
         p += sprintf(p, ")"); 			 
 			 
         printf("buf = %s\n", buf); 			 
 			 
         break;
         } 			 
 			 
    case NxMSG_EXGQUOTE:
         {
         const NxCoreQuote&    cq = pNxCoreMessage->coreData.ExgQuote.coreQuote; 			 
 			 
     // Use PriceToDouble function to convert prices         
         double Bid = (float) pfNxCorePriceToDouble(cq.BidPrice,     cq.PriceType);
         double Ask = (float) pfNxCorePriceToDouble(cq.AskPrice,     cq.PriceType); 			 
 			 
         char buf[256];			
         sprintf(buf, "Bid(%0.2f) Ask(%0.2f)",Bid,Ask);         
         printf("buf = %s\n", buf);
         break;
         }  
  } 			 
 			 
  return NxCALLBACKRETURN_CONTINUE;  
}