API Documentation

Language: C++ Java Python C C#
Basic: Intro/Trade Quote Category Status Symbol Options
Detailed: Trade Quote

Detailed Trades

This guide assumes you have already read the "Getting Started and Introduction to Trades" guide. This guide will cover more detailed processing of trade messages.

Code

#include "stdio.h"
#include "NxCoreAPI_Wrapper_C.h"


int OnNxCoreCallback(const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg) {
    if(pNxCoreMsg->MessageType == NxMSG_TRADE) {
        
        const NxCoreHeader* pHeader = &pNxCoreMsg->coreHeader;
        char* symbol = pHeader->pnxStringSymbol->String;
        const NxTime* pTs = &pHeader->nxExgTimestamp;
        
        const char* exchangeLong = pfNxCoreGetDefinedString(NxST_EXCHANGE, pHeader->ReportingExg);
        char exchange[64];
        char *quotPtr = strchr(exchangeLong, '|');
        if (quotPtr) {
            memcpy(exchange, exchangeLong, quotPtr - exchangeLong);
            exchange[quotPtr - exchangeLong] = 0;
        }
        else
            strcpy(exchange, exchangeLong);
        
        const NxCoreTrade* pTrade = &pNxCoreMsg->coreData.Trade;
        double price = pfNxCorePriceToDouble(pTrade->Price, pTrade->PriceType);
        int size = pTrade->Size;
        unsigned int sequence = pTrade->ExgSequence;

        char conditions[64] = "";
        char* p = conditions;
        for (int i = 0; i < 4; i++) {
            char condition = pTrade->ExtTradeConditions[i];
            const char* conditionName = pfNxCoreGetDefinedString(NxST_TRADECONDITION, condition);
            p += sprintf(p,"%s|", (conditionName ? conditionName :""));
        }

        char eligibility[64] = "";
        p = eligibility;
        if (pTrade->ConditionFlags) {
            p += sprintf(p,"(Doesn't set");
            if (pTrade->ConditionFlags & NxTCF_NOHIGH)
                p += sprintf(p, " high");
            if (pTrade->ConditionFlags & NxTCF_NOLOW)
                p += sprintf(p, " low");
            if (pTrade->ConditionFlags & NxTCF_NOLAST)
                p += sprintf(p, " last");
            p += sprintf(p, ")");
        }

        if(pTrade->PriceFlags & NxTPF_EXGCANCEL)
            printf("Cancel for %s at sequence %u on %s %d shares at $%.02f\n",
                symbol, sequence, exchange, size, price);
        else
            printf("Trade for %s at %02d:%02d:%02d sequence %u on %s for %d shares at $%.02f %s%s\n", 
                symbol, pTs->Hour, pTs->Minute, pTs->Second, sequence, exchange, size, price, conditions, eligibility);
    }
    return NxCALLBACKRETURN_CONTINUE;  
}

int main(int argc, char* argv[]) {
    if (argc < 3)
        return 1;

    if (LoadNxCore(argv[1])){
        int returnValue = pfNxCoreProcessTape(argv[2], 0, 0, 0, OnNxCoreCallback);
        processReturnValue(returnValue);
    }
    else
        printf("loading library failed\n");

    return 0;
}

Trade Message

Trades are identified by combination of sequence and reporting exchange. This can be used in conjunction with cancels to determine which trade was canceled. Note that some feeds use non-sequential 64-bit sequences which may cause sequence number to not be unique. pfNxCoreGetDefinedString returns the both a short and full name of the exchange split by a pipe. We get the short exchange name by taking the part of the string before the pipe.

const char* exchangeLong = pfNxCoreGetDefinedString(
    NxST_EXCHANGE, pHeader->ReportingExg);
char exchange[64];
char *quotPtr = strchr(exchangeLong, '|');
if (quotPtr) {
    memcpy(exchange, exchangeLong, quotPtr - exchangeLong);
    exchange[quotPtr - exchangeLong] = 0;
}
else
    strcpy(exchange, exchangeLong);

const NxCoreTrade* pTrade = &pNxCoreMsg->coreData.Trade;
double price = pfNxCorePriceToDouble(
    pTrade->Price, pTrade->PriceType);
int size = pTrade->Size;
unsigned int sequence = pTrade->ExgSequence;

Trade Conditions

The type of trade is indicated by up to 4 conditions. The full list of possible trade conditions can be found in the Trade Condition Table. For example, trades with less than 100 shares will have the OddLot(115) condition. pfNxCoreGetDefinedString can be used to find the string name of the condition using NxST_TRADECONDITION as ixTable. pfNxCoreGetDefinedString returns a nullptr if there is no valid condition.

char conditions[64] = "";
char* p = conditions;
for (int i = 0; i < 4; i++) {
    char condition = pTrade->ExtTradeConditions[i];
    const char* conditionName = pfNxCoreGetDefinedString(
    NxST_TRADECONDITION, condition);
    p += sprintf(p,"%s|", (conditionName ? conditionName :""));
}

Trade Eligiblity

Not all trades are permitted to set the daily high, low, and last. Whether or not a trade can set daily prices is determined by the aforementioned trade conditions. ConditionFlags is a bitmap of which daily prices the trade can not set. A value of zero means the trade can set all Daily prices.

char eligibility[64] = "";
p = eligibility;
if (pTrade->ConditionFlags) {
    p += sprintf(p,"(Doesn't set");
    if (pTrade->ConditionFlags & NxTCF_NOHIGH)
        p += sprintf(p, " high");
    if (pTrade->ConditionFlags & NxTCF_NOLOW)
        p += sprintf(p, " low");
    if (pTrade->ConditionFlags & NxTCF_NOLAST)
        p += sprintf(p, " last");
    p += sprintf(p, ")");
}

Cancels

Sometimes past trades are canceled or modified. In this case, PriceFlags will have the NxTPF_EXGCANCEL(0x20) bit set. When avaiable the sequence and reporting exchange will match the trade being canceled.

if(pTrade->PriceFlags & NxTPF_EXGCANCEL)
    ...

Next:
Quote