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