Table of Contents


NxMSG_TRADE message

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

NxTrade messages are the most heavily processed and analyzed within the Nanex Financial Servers. Many members in NxTrade are the result of this processing and are therefore unique to NxCore. Other members are updated from exchanges but rarely found in other financial feeds.

Trade messages are sent for last sale reports and corrections to last sale reports. Less than 10% of the Nanex Financial Feed contains Trade messages, mostly due to the heavy volume of quotes. When processing a tape, you can set a filter to exclude ExgQuote and MMQuotes, which will dramatically speed up the processing of trades. The relationship between the last sale and the most recent quote has been added to the Trade message members to make it easier to exclude quotes in certain analysis situations.

There is an abundance of information included with each trade message you won't find, or will rarely find in other feeds, such as original Exchange Sequence numbers, trade condition processing flags (is the trade elgible to update last, high, low, open?), NxCore QuoteMatch (matches each trade to the recent regional and BBO quotes), NxCore Realtime Trade Filter analysis results, and NxCore Significant High/Low data on each trade message. A typical trading day will have 10+ million of these message types.

Simplest example

Here's the simplest example.

#include "NxCoreAPI.h"
int processNxCoreTrade(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:     break;
        case NxMSG_MMQUOTE:      break;
        case NxMSG_TRADE:        return processNxCoreTrade(pNxCoreSys, pNxCoreMsg);
        case NxMSG_CATEGORY:     break;
        case NxMSG_SYMBOLCHANGE: break;
        case NxMSG_SYMBOLSPIN:   break;
    }
    return NxCALLBACKRETURN_CONTINUE;
}

Example

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

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include "NxCoreAPI.h"
#include "NxCoreAPI_class.h"

NxCoreClass nxCoreClass;

void getSymbol(const NxCoreMessage* pNxCoreMsg,char *Symbol)
{
    // Is this a valid option?
    if ((pNxCoreMsg->coreHeader.pnxStringSymbol->String[0]=='o')&&(pNxCoreMsg->coreHeader.pnxOptionHdr))
    {
        // If pnxsDateAndStrike->String[1] == ' ', then this symbol is in new OSI format.
        if (pNxCoreMsg->coreHeader.pnxOptionHdr->pnxsDateAndStrike->String[1]==' ')
        {
            sprintf(Symbol,"%s%02d%02d%02d%c%08d",
                    pNxCoreMsg->coreHeader.pnxStringSymbol->String,
                    pNxCoreMsg->coreHeader.pnxOptionHdr->nxExpirationDate.Year-2000,
                    pNxCoreMsg->coreHeader.pnxOptionHdr->nxExpirationDate.Month,
                    pNxCoreMsg->coreHeader.pnxOptionHdr->nxExpirationDate.Day,
                    (pNxCoreMsg->coreHeader.pnxOptionHdr->PutCall == 0) ? 'C' : 'P',
                    pNxCoreMsg->coreHeader.pnxOptionHdr->strikePrice);
        }
        // Otherwise the symbol is in old OPRA format.
        else
        {
            sprintf(Symbol,"%s%c%c",
                    pNxCoreMsg->coreHeader.pnxStringSymbol->String,
                    pNxCoreMsg->coreHeader.pnxOptionHdr->pnxsDateAndStrike->String[0],
                    pNxCoreMsg->coreHeader.pnxOptionHdr->pnxsDateAndStrike->String[1]);
        }
    }
    // Not an option, just copy the symbol
    else
    {
        strcpy(Symbol,pNxCoreMsg->coreHeader.pnxStringSymbol->String);
    }
}

int __stdcall nxCoreCallback(const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMessage)
{
    switch (pNxCoreMessage->MessageType)
    {
        case NxMSG_TRADE:
        {
            const NxCoreTrade& nt = pNxCoreMessage->coreData.Trade;
            const NxCoreHeader& ch = pNxCoreMessage->coreHeader;
            const NxTime&       t  = pNxCoreSys->nxTime;

            char symbol[23];
            getSymbol(pNxCoreMessage,symbol);

            printf("%.2d:%.2d:%.2d.%.3d %s Price(%ld@%.2lf) O(%.2lf) H(%.2lf) L(%.2lf) C(%.2lf) V(%I64d) Net(%.2lf)\n",
                (int) t.Hour, (int) t.Minute, (int) t.Second, (int) t.Millisecond,
                symbol,
                nt.Size,
                nxCoreClass.PriceToDouble(nt.Price,     nt.PriceType),
                nxCoreClass.PriceToDouble(nt.Open,      nt.PriceType),
                nxCoreClass.PriceToDouble(nt.High,      nt.PriceType),
                nxCoreClass.PriceToDouble(nt.Low,       nt.PriceType),
                nxCoreClass.PriceToDouble(nt.Last,      nt.PriceType),
                nt.TotalVolume,
                nxCoreClass.PriceToDouble(nt.NetChange, nt.PriceType));

             break;
        }
    }
    return NxCALLBACKRETURN_CONTINUE;
}

int main(int argc, char** argv)
{
    if (!nxCoreClass.LoadNxCore("NxCoreAPI.dll") &&
        !nxCoreClass.LoadNxCore("C:\\Program Files\\Nanex\\NxCoreAPI\\NxCoreAPI.dll"))
    {
        fprintf(stderr, "Can't find NxCoreAPI.dll\n");
        return -1;
    }
    nxCoreClass.ProcessTape(argv[1], 0, NxCF_EXCLUDE_CRC_CHECK, 0, nxCoreCallback);
    return 0;
}