API Documentation

NxMSG_EXGQUOTE message

The second parameter to the NxCoreCallback function, NxCoreMessage, holds the symbol and session information in pNxCoreMessage->coreHeader, and data information in pNxCoreMessage->coreData.ExgQuote, which is a NxCoreExgQuote data structure.

Sent for every exchange quote (regular quote) and BBO (Exchange-determined Best Bid/Offer). Each quote update includes the bid and ask prices, sizes and condition codes, plus price/size changes. Also for symbols trading on multiple exchanges, each ExgQuote also contains fields with the current values of the best bid/best ask prices, sizes and condition codes. This message type is by far the most active of all messages your callback will receive (depending of course on the exchanges you subscribe to). A typical trading day will have 700+ million option quotes!

Simplest example

Here's the simplest example.

#include "NxCoreAPI.h"
int processNxCoreExgQuote(const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg)
{
    return NxCALLBACKRETURN_CONTINUE;
}
int __stdcall OnNxCoreCallback(const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg)
{
    switch( pNxCoreMsg->MessageType ) {
        case NxMSG_STATUS:       break;
        case NxMSG_EXGQUOTE:     return processNxCoreExgQuote(pNxCoreSys, pNxCoreMsg);
        case NxMSG_MMQUOTE:      break;
        case NxMSG_TRADE:        break;
        case NxMSG_CATEGORY:     break;
        case NxMSG_SYMBOLCHANGE: break;
        case NxMSG_SYMBOLSPIN:   break;
    }
    return NxCALLBACKRETURN_CONTINUE;
}

Example

Here's an example of printing out every quote that happens

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "NxCoreAPI.h"
#include "NxCoreAPI_Wrapper_C++.h"              
              
NxCoreClass NxCore;              

const char* getSymbol(char* sym, NxString* nx, NxOptionHdr* oh)
{
    // If an option
    if (oh)
    {
        // If pnxsDateAndStrike->String[1] == ' ', then this symbol is in new OSI format.     
        if (oh->pnxsDateAndStrike->String[1]==' ')    
        {
            sprintf(sym,"%s%02d%02d%02d%c%08d",
                    nx->String,
                    oh->nxExpirationDate.Year-2000,
                    oh->nxExpirationDate.Month,
                    oh->nxExpirationDate.Day,
                    (oh->PutCall == 0) ? 'C' : 'P',
                    oh->strikePrice);
        }
        // Otherwise the symbol is in old OPRA format.
        else
        {
            sprintf(sym,"%s%c%c",
                    nx->String,
                    oh->pnxsDateAndStrike->String[0],
                    oh->pnxsDateAndStrike->String[1]);
        }
    }
    // otherwise a non-option
    else
    {
        sprintf(sym, "%s", nx->String);
    }    
 
    return sym;
} 
  
int __stdcall nxCoreCallback(const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMessage)
{
    switch (pNxCoreMessage->MessageType) {
        case NxMSG_EXGQUOTE:
            const NxCoreHeader&   ch = pNxCoreMessage->coreHeader;
            const NxCoreExgQuote& eq = pNxCoreMessage->coreData.ExgQuote;
            const NxCoreQuote&    cq = eq.coreQuote;
            const NxTime& t = pNxCoreSys->nxTime;    
    
            char symbol[23];  
    
            char buf[1024] = {0};
            char* p = buf;    
    
            if (cq.BidPriceChange || cq.BidSizeChange)
            {
                p += sprintf(p, "RGN_bid(%d @ %.2lf)[%ld] ",
                            cq.BidSize,
                            NxCore.PriceToDouble(cq.BidPrice, cq.PriceType),
                            ch.ReportingExg);
            }
            if (cq.AskPriceChange || cq.AskSizeChange)
            {
                p += sprintf(p, "RGN_ask(%d @ %.2f)[%ld] ",
                            cq.AskSize,
                            NxCore.PriceToDouble(cq.AskPrice, cq.PriceType),
                            ch.ReportingExg);
            }
            if ((eq.BBOChangeFlags & (NxBBOCHANGE_BIDPRICE | NxBBOCHANGE_BIDSIZE)) && eq.BestBidPrice > 0)
            {
                p += sprintf(p, "BBO_bid(%d @ %.2f) ",
                            eq.BestBidSize,
                            NxCore.PriceToDouble(eq.BestBidPrice, cq.PriceType));
            }
            if ((eq.BBOChangeFlags & (NxBBOCHANGE_ASKPRICE | NxBBOCHANGE_ASKSIZE)) && eq.BestAskPrice > 0)
            {
                p += sprintf(p, "BBO_ask(%d @ %.2f) ",
                            eq.BestAskSize,
                            NxCore.PriceToDouble(eq.BestAskPrice, cq.PriceType));
            }
            if (p > buf)
            {
                printf("%02d:%02d:%02d.%03d %s %s\n",
                    (int) t.Hour, (int) t.Minute, (int) t.Second, (int) t.Millisecond,
                    getSymbol(symbol, ch.pnxStringSymbol, ch.pnxOptionHdr), buf);
            }    
    
            break;
    }
    return NxCALLBACKRETURN_CONTINUE;
}

int main(int argc, char** argv)
{
    if (!NxCore.LoadNxCore("NxCoreAPI64.dll") &&
        !NxCore.LoadNxCore("NxCoreAPI.dll"))
    {
        printf("loading library failed\n");
        return -1;
    }
    NxCore.ProcessTape(argv[1], 0, NxCF_EXCLUDE_CRC_CHECK, 0, nxCoreCallback);
    return 0;
}
import net.nanex.NxCoreClass;
class ExgQuoteSample extends NxCoreClass{
    
    String getSymbol( NxString nx, NxOptionHdr oh) {
        // If an option
        if (oh != null) {
            // If oh.pnxsDateAndStrike.String.charAt(1) == ' ', then this symbol is in new OSI format.     
            if (oh.pnxsDateAndStrike.String.charAt(1) == ' ') {
                return String.format("%s%02d%02d%02d%c%08d",
                        nx.String,
                        oh.nxExpirationDate.Year-2000,
                        oh.nxExpirationDate.Month,
                        oh.nxExpirationDate.Day,
                        (oh.PutCall == 0) ? 'C' : 'P',
                        oh.strikePrice);
            }
            // Otherwise the symbol is in old OPRA format.
            else {
                return String.format("%s%c%c",
                        nx.String,
                        oh.pnxsDateAndStrike.String.charAt(0),
                        oh.pnxsDateAndStrike.String.charAt(1));
            }
        }
        // otherwise a non-option
        return String.format("%s", nx.String);
    }
    
    @Override
    public int OnNxCoreCallback(NxCoreSystem nxCoreSys, NxCoreMessage nxCoreMsg) {
        switch (nxCoreMsg.MessageType) {
            case defines.NxMSG_EXGQUOTE:
                NxCoreHeader   ch = nxCoreMsg.coreHeader;
                NxCoreExgQuote eq = nxCoreMsg.coreData.ExgQuote;
                NxCoreQuote    cq = eq.coreQuote;
                NxTime t = ch.nxExgTimestamp;    
                
                String buf = "";    
                
                if (cq.BidPriceChange != 0 || cq.BidSizeChange != 0) {
                    buf += String.format("RGN_bid(%d @ %.2f)[%d] ",
                                cq.BidSize,
                                PriceToDouble(cq.BidPrice, cq.PriceType),
                                ch.ReportingExg);
                }
                if (cq.AskPriceChange != 0 || cq.AskSizeChange != 0) {
                    buf += String.format("RGN_ask(%d @ %.2f)[%d] ",
                                cq.AskSize,
                                PriceToDouble(cq.AskPrice, cq.PriceType),
                                ch.ReportingExg);
                }
                if ((eq.BBOChangeFlags & (defines.NxBBOCHANGE_BIDPRICE | defines.NxBBOCHANGE_BIDSIZE)) != 0 && eq.BestBidPrice > 0) {
                    buf += String.format("BBO_bid(%d @ %.2f) ",
                                eq.BestBidSize,
                                PriceToDouble(eq.BestBidPrice, cq.PriceType));
                }
                if ((eq.BBOChangeFlags & (defines.NxBBOCHANGE_ASKPRICE | defines.NxBBOCHANGE_ASKSIZE)) != 0 && eq.BestAskPrice > 0) {
                    buf += String.format("BBO_ask(%d @ %.2f) ",
                                eq.BestAskSize,
                                PriceToDouble(eq.BestAskPrice, cq.PriceType));
                }
                
                if (buf.length() > 0) {
                    System.out.println(String.format("%02d:%02d:%02d.%03d %s %s",
                        t.Hour, t.Minute, t.Second, t.Millisecond,
                        getSymbol(ch.pnxStringSymbol, ch.pnxOptionHdr), buf));
                }
                break;
        }
        return defines.NxCALLBACKRETURN_CONTINUE;
    }

    public static void main(String args[]) {
        ExgQuoteSample nxCore = new ExgQuoteSample();

        if (nxCore.LoadNxCore("NxCoreAPI64.dll") != 0){
            nxCore.ProcessTape(args[0], 0, defines.NxCF_EXCLUDE_CRC_CHECK, 0);
        }
        else
            System.out.println("loading library failed");
    }
}
import NxCore

tapePath = ""

def getSymbol(nx, oh):
    # If an option
    if oh:
        # If oh.pnxsDateAndStrike.String[1] == ' ', then this symbol is in new OSI format.     
        if oh.pnxsDateAndStrike.String[1] == ' ':    
            return "{}{:02d}{:02d}{:02d}{}{:08d}".format(
                nx.String,
                oh.nxExpirationDate.Year-2000,
                oh.nxExpirationDate.Month,
                oh.nxExpirationDate.Day,
                'C' if oh.PutCall == 0 else 'P',
                oh.strikePrice)
        # Otherwise the symbol is in old OPRA format.
        else:
            return "{}{}{}".format(
                nx.String,
                oh.pnxsDateAndStrike.String[0],
                oh.pnxsDateAndStrike.String[1])
    # otherwise a non-option
    return nx.String

def OnNxCoreCallback(NxCoreSys, NxCoreMsg):
    if NxCoreMsg.MessageType == NxCore.NxMSG_EXGQUOTE:
        ch = NxCoreMsg.coreHeader;
        eq = NxCoreMsg.coreData.ExgQuote
        cq = eq.coreQuote
        t = ch.nxExgTimestamp    
        
        buf = "" 
        
        if cq.BidPriceChange or cq.BidSizeChange:
            buf += "RGN_bid({} @ {:.2f})[{}] ".format(
                cq.BidSize,
                NxCore.PriceToDouble(cq.BidPrice, cq.PriceType),
                ch.ReportingExg)
        
        if cq.AskPriceChange or cq.AskSizeChange:
            buf += "RGN_ask({} @ {:.2f})[{}] ".format(
                cq.AskSize,
                NxCore.PriceToDouble(cq.AskPrice, cq.PriceType),
                ch.ReportingExg)
        
        if eq.BBOChangeFlags & (NxCore.NxBBOCHANGE_BIDPRICE | NxCore.NxBBOCHANGE_BIDSIZE) and eq.BestBidPrice:
            buf += "BBO_bid({} @ {:.2f}) ".format(
                eq.BestBidSize,
                NxCore.PriceToDouble(eq.BestBidPrice, cq.PriceType))
        
        if eq.BBOChangeFlags & (NxCore.NxBBOCHANGE_ASKPRICE | NxCore.NxBBOCHANGE_ASKSIZE) and eq.BestAskPrice:
            buf += "BBO_ask({} @ {:.2f}) ".format(
                eq.BestAskSize,
                NxCore.PriceToDouble(eq.BestAskPrice, cq.PriceType))
        
        if len(buf) > 0:
            print("{:02d}:{:02d}:{:02d}.{:03d} {} {}".format(
                t.Hour, t.Minute, t.Second, t.Millisecond,
                getSymbol(ch.pnxStringSymbol, ch.pnxOptionHdr), buf))
    return NxCore.NxCALLBACKRETURN_CONTINUE

if NxCore.LoadNxCore("NxCoreAPI64.dll"):
    returnValue = NxCore.ProcessTape(tapePath, 0, NxCore.NxCF_EXCLUDE_CRC_CHECK, 0, OnNxCoreCallback)
else:
    print("loading library failed")