question

Upvotes
Accepted
5 3 1 9

Getting near-zero for off hours price requests

I'm snapshotting a long list of stocks throughout the day. (I can't subscribe with interest because my list is over our 1000 RIC limit and it doesn't seem like we can increase that.) Some of those stocks are being requested at off hours for the exchange. For example, I requested ANZ.AX (Australian stock) at 20:00 UTC. The bid (22) and ask (25) fields return values similar to what I see for the previous days close on Google.

However, the last price (6) value will have some bizarre value like 6.95313380659942E-310. Can anyone provide any insight as to how this value is being created or what's happening here?

treprfarfa-apipricing
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvote
Accepted
1.5k 5 6 7

How are you decoding the REAL value in Fid #6 ?

  • Are you checking for blank?
  • Are you checking for decimal value vs fractional value ? (don't think the Australian exchange is quoting in fractions .. very few exchanges do that .. but you never know)
  • Are you converting the REAL value to a native type such as float/double ? (not good)

Update:

Thank you for sharing your code. As pointed out by others I cannot see that you are checking for blank on the field value, only on the field list. In any case you are converting to a native type, double, and such a type cannot represent "blank". Don't be tempted to use the value 0 for this as zero is a perfectly legal value for the price of a financial instrument, although if your code is only ever meant to be used for Equities prices then go ahead, because specifically for that asset class zero is never a valid price. Bottom line, you need to figure out how your code should deal with blank values.

A REAL value is essentially what in computing is called a bignum, i.e. a type that supports exact precision (unlike native float/double) and one that supports a very high number of decimals. In Java that would be BigInteger and BigDecimal. In C# you have the BigInteger class, but BigDecimal strangely(?) isn't there unless you bring in third party packages. Such classes are the only ones which can represent a REAL without any loss of information. Personally I like to keep my REAL values in the format of a long and an exponent (both of which are integers), until such time where I actually need to do some calculation on the value. At that point in time it may of course be required to convert to say double for the specific calculation, but then it is a conscious choice.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
5 3 1 9
Here's loosely what I'm doing now. I do check for blank. I don't check for decimal or fractional value. I DO convert to to a double. 99% of the prices I gethere are valid. How should should I be reading the FieldEntry? Do you believe doing that incorrectly is somehow corrupting the original input? 

public void DecodeFieldList(FieldList input)
{
     if (null == input || input.IsBlank) return;
     using (var it = new FieldListReadIterator())
     {
          it.Start(input);
          while (!it.Off())
          {
              switch (it.Value.FieldID)
              {
                   case 6:
                   double itPrice = DecodeFieldEntry(it.Value, _ => _.Double);
                   //Do stuff with price
                   //Continue parsing other fields
              }      
          }
          it.Forth();
     }
}

      private T DecodeFieldEntry<T>(FieldEntry input, Func<DataBuffer, T> bufferFunc)
        {
            if ((input.ContentMask & FieldEntry.ContentMaskFlag.DefinedData) != 0)
            {
                // DecodeData(input.Data);
            }
            else
            {
                bool validFID = false;
                try
                {
                    var currentFidDef = _rdmFieldDict.GetFidDef(input.FieldID);
                    if (currentFidDef != null)
                    {
                        validFID = true;
                        if (currentFidDef.FieldId == 0)
                        {
                            //DecodeData(input.GetData(DataBuffer.DataBufferEnum.Int));
                        }
                        else
                        {
                            return bufferFunc(input.GetData(currentFidDef.OMMType) as DataBuffer);
                            //DecodeData( input.GetData( currentFidDef.OMMType));
                        }
                    }
                }
                catch (InvalidUsageException)
                {
                    var test = 1;
                }


                if (!validFID)
                {
                    var test = 1;
                    //AppUtil.Log(AppUtil.LEVEL.WARN,
                    //    string.Format("Decoder.DecodeFieldEntry() - Field ID {0} does not exist in data dictionary\r\n", input.FieldID));
                }
            }
            throw new NotImplementedException();
        }


icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

You should verify IsBlank inside Func<DataBuffer, T> bufferFunc function with the DataBuffer.IsBlank property.


Have updated my answer.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.