Table of Contents


Example (code and executable here)

Here's an example of printing out all Options of Futures


#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>

#include <map>
#include <string>

#include <NxCoreAPI.h>
#include <NxCoreAPI_class.h>

#include "NxCoreTableHelper.h"

static NxCoreClass nxCoreClass;

typedef std::map<std::string, std::string> String2StringMap;

String2StringMap map;

struct UserData2
{
    std::string underlying;
    UserData2(const std::string &s) : underlying(s) {}
};

bool makeUserData2(const NxCoreHeader &ch, const char *p)
{
    char symbol[64];

    sprintf(symbol, "%.*s_%d_%d", p - ch.pnxStringSymbol->String, ch.pnxStringSymbol->String, ch.ListedExg, ch.SessionID);

    std::string s(symbol);

    String2StringMap::const_iterator itr = map.find(s);
    if (itr != map.end())
    {
        ch.pnxStringSymbol->UserData2 = (int) new UserData2(itr->second);
        return false;
    }

    ch.pnxStringSymbol->UserData2 = 1;
    return true;
}

inline const char *toFutOptRootSym(const NxCoreCategory &cat, int index, const char *otherwise)
{
    const char *s = cat.pnxFields[index].data.StringZ;

    if (!cat.pnxFields[index].Set || *s == '*' || *s == ' ')
    {
        return otherwise;
    }

    return s;
}

static int __stdcall nxCoreCallback(const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMessage)
{
    switch (pNxCoreMessage->MessageType)
    {
        case NxMSG_EXGQUOTE:
        {
            const NxCoreHeader &ch = pNxCoreMessage->coreHeader;

            if (*ch.pnxStringSymbol->String != 'p')
            {
                break;
            }

            char *p = strchr(ch.pnxStringSymbol->String, '.');
            if (p == 0)
            {
                break;
            }

            if (ch.pnxStringSymbol->UserData2 == 1)
            {
                break;
            }

            if (ch.pnxStringSymbol->UserData2 == 0)
            {
                if (makeUserData2(ch, p))
                {
                    break;
                }
            }

            const char *und = ((UserData2*) ch.pnxStringSymbol->UserData2)->underlying.c_str();

            const NxTime &t = pNxCoreSys->nxTime;

            printf("%.2d:%.2d:%.2d.%.3d Symbol(%s) ListedExg(%d) Underlying(%s) SessionID(%d) ExgQuote\n",
                (int) t.Hour, (int) t.Minute, (int) t.Second, (int) t.Millisecond,
                ch.pnxStringSymbol->String,
                ch.ListedExg,
                und,
                ch.SessionID);

            break;
        }

       case NxMSG_TRADE:
        {
            const NxCoreHeader &ch = pNxCoreMessage->coreHeader;
            const NxCoreTrade  &nt = pNxCoreMessage->coreData.Trade;

#if 0
            if (nt.BATECode == 'B' || nt.BATECode == 'A')
            {
                break;
            }
#endif

            if (*ch.pnxStringSymbol->String != 'p')
            {
                break;
            }

            char *p = strchr(ch.pnxStringSymbol->String, '.');
            if (p == 0)
            {
                break;
            }

            if (ch.pnxStringSymbol->UserData2 == 1)
            {
                break;
            }

            if (ch.pnxStringSymbol->UserData2 == 0)
            {
                if (makeUserData2(ch, p))
                {
                    break;
                }
            }

            const char *und = ((UserData2*) ch.pnxStringSymbol->UserData2)->underlying.c_str();

            const NxTime &t = pNxCoreSys->nxTime;

            printf("%.2d:%.2d:%.2d.%.3d Symbol(%s) ListedExg(%d) Underlying(%s) SessionID(%d) BATE(%c) Price(%ld@%.2lf)\n",
                (int) t.Hour, (int) t.Minute, (int) t.Second, (int) t.Millisecond,
                ch.pnxStringSymbol->String,
                ch.ListedExg,
                und,
                ch.SessionID,
                nt.BATECode == 0 ? '0' : nt.BATECode,
                nt.Size,
                nxCoreClass.PriceToDouble(nt.Price, nt.PriceType));

            break;
        }
    }

    return NxCALLBACKRETURN_CONTINUE;
}


static int __stdcall getFutureOptionRootCallback(const NxCoreSystem* pNxCoreSystem,const NxCoreMessage* pNxCoreMessage)
{
    switch (pNxCoreMessage->MessageType)
    {
        case NxMSG_STATUS:
        {
            if (pNxCoreSystem->nxTime.MsOfDay > 60*1000) // Category 70 should come within the first minute
            {
                // now that we have saved off the Root info, flip to the normal callback and restart the tape
                nxCoreClass.SetCallback(nxCoreCallback);
                return NxCALLBACKRETURN_RESTART;
            }

            break;
        }
        case NxMSG_CATEGORY:
        {
            switch (pNxCoreMessage->coreData.Category.pnxStringCategory->Atom)
            {
                case nxST_CATEGORY::RootSymbolInfo:
                {
                    const NxCoreHeader&   ch  = pNxCoreMessage->coreHeader;
                    const NxCoreCategory &cat = pNxCoreMessage->coreData.Category;

                    const char *pUnderlying = "";
                    const char *callSymbol  = "";
                    const char *putSymbol   = "";

                    char symbol[64];
                    char underlying[64];
                    std::string s;

                    if (ch.pnxStringSymbol->String[1] == 'p')
                    {
                        pUnderlying = toFutOptRootSym(cat, 3, ch.pnxStringSymbol->String + 1);
                        callSymbol  = ch.pnxStringSymbol->String + 1;
                    }
                    else if (ch.pnxStringSymbol->String[1] == 'f')
                    {
                        pUnderlying = ch.pnxStringSymbol->String + 1;
                        callSymbol  = toFutOptRootSym(cat, 4, ch.pnxStringSymbol->String + 1);
                        putSymbol   = toFutOptRootSym(cat, 5, callSymbol);
                    }
                    else
                    {
                        break;
                    }

                    strcpy(underlying, pUnderlying);
                    if (*underlying == 'p')
                        *underlying = 'f';

                    printf("%-5s %ld %ld Underlying: %-5s Call:%-5s Put:%-5s\n",
                        ch.pnxStringSymbol->String,
                        ch.ListedExg,
                        ch.SessionID,
                        underlying,
                        callSymbol,
                        putSymbol);

                    if (*callSymbol)
                    {
                        sprintf(symbol, "%s_%d_%d", callSymbol, ch.ListedExg, ch.SessionID);
                        s.assign(symbol);
                        map.insert(std::make_pair(s, underlying));
                    }

                    if (*putSymbol && strcmp(callSymbol, putSymbol))
                    {
                        sprintf(symbol, "%s_%d_%d", putSymbol, ch.ListedExg, ch.SessionID);
                        s.assign(symbol);
                        map.insert(std::make_pair(s, underlying));
                    }

                    break;
                }
            }
            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;
    }

    int rc = nxCoreClass.ProcessTape(argv[1], 0, NxCF_EXCLUDE_CRC_CHECK, 0, getFutureOptionRootCallback);

    return rc;
}