API Documentation

States in NxCore

NxCore uses a concept of a State to allow the persisting of snapshot of the memory, and a subsequent loading of the memory to return to the exact spot in the processing.

A very key point to understand is that the "state" is just a starting point

If the state is from a real-time processing, and it's still the same day It will pick up from the timestamp of the state, but will switch to real-time when it catches up
If the state is from a real-time processing, and it's a different day It will pick up from the timestamp of the state, and continue with the tape
If the state is from a tape It will pick up from the timestamp of the state, and continue with the tape

Notes

  • While taking a state snapshot is fast, it's not free, and you have to balance your performance requirements against your need to be able to recover from a crash without having the replay the entire tape.
  • The memory saved includes the UserData1 and UserData2 fields of every NxString.
    • If these fields contain primitive values, they save and load without any issues. This includes pointer values, but not the pointed-to-areas
    • If these fields contain pointers, the saving will NOT also save the pointed-to areas, as NxCore has no idea of their size and contents. The example below gives one solution to persisting your own data successfully.
  • Easy way to tell if you are running a state or realtime or tape, is if the very first callback you get is:
    • pNxCoreSys->Status==NxCORESTATUS_LOADED_STATE, you're processing a state
    • pNxCoreSys->Status==NxCORESTATUS_INITIALIZING, you're running real-time or processing a tape

Saving States

You can save a state anytime within your callback by calling the nxCoreClass.SaveState() method and passing in the file name to save into and a flag telling it how you want the data for saving collected and written out.

#define Value Comments
NxSAVESTATE_GRADUALLY 0 Save completes in multiple passes - NxCore writes out memory block to file in 1MB increments.
NxSAVESTATE_ONEPASS 1 Save completes in one pass - NxCore writes out entire memory block to file at one time.
NxSAVESTATE_CANCEL 2 Abort a scheduled Save State -- can be done at NxCSSAVESTATE_CAPTURE time

For example, nxCoreClass.SaveState(stateFileName, NxSAVESTATE_ONEPASS) triggers a number of subsequent calls into your callback with pNxCoreSys->Status==NxCORESTATUS_SAVING_STATE with pNxCoreSys->StatusData one of:

If Status: StatusData:
NxCORESTATUS_SAVING_STATE
#define Value Comments
NxCSSAVESTATE_CAPTURE 0 the core state will be captured after you return from this callback
NxCSSAVESTATE_COMPLETE 1 the save core state operation is complete
NxCSSAVESTATE_ERR_CREATEFILE -1 failed to open the specified tape filename
NxCSSAVESTATE_ERR_DISKSPACE -2 not enough disk space to complete the operation
NxCSSAVESTATE_ERR_MEMORY -3 insufficient memory to complete the operation

Loading States

To load a state, you'd just pass the file name in to the nxCoreClass.ProcessTape, just as you would pass in "" for real-time, or a tape.

The example below shows how to pre-allocate a specific, unused, memory address to ensure that the state can load in the same memory it was saved in.

Unlike processing a real-time feed or a tape, the first call to your callback function will be with pNxCoreSys->Status==NxCORESTATUS_LOADED_STATE, and pNxCoreSys->StatusData will contain the size of the tape inside the file. The example below shows how to use that "size" to persist and retrieve additional data to the end of the file.

Example

This example assigns a unique value to each symbol in Userdata1 on the initial symbol spin and processes trades until 9:00 AM EST, when it will save the current state to a state tape file and exit the ProcessTape thread. Next it will start the ProcessTape thread again, this time starting it with the newly saved state tape and continue to process trades. Note that the UserData1 values have persisted in the saved state tape.

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

NxCoreClass NxCore;

char StateFileFilename[255];

// OnNxCoreStatus: Function to handle NxCore Status messages
//----------------------------------------------------------
int OnNxCoreStatus(const NxCoreSystem* pNxCoreSys,const NxCoreMessage* pNxCoreMsg)
{

    // On minute
    if ((pNxCoreSys->ClockUpdateInterval >= NxCLOCK_MINUTE) &&
        (pNxCoreSys->nxTime.Hour < 24))
    {
        printf("NxCore Time: %02d/%02d/%d  %02d:%02d:%02d\n",
            pNxCoreSys->nxDate.Month,pNxCoreSys->nxDate.Day,pNxCoreSys->nxDate.Year,
            pNxCoreSys->nxTime.Hour,pNxCoreSys->nxTime.Minute,pNxCoreSys->nxTime.Second);


        // LOOK! If it's 9:00:00 AM SAVE THE CURRENT STATE TO A STATE FILE!
        if (pNxCoreSys->nxTime.Hour==9 && pNxCoreSys->nxTime.Minute==0)
        {
            printf("\nNxCore Will Save the State Now!\nPress [Enter] to Continue.\n");
            getchar();
            NxCore.SaveState(StateFileFilename,NxSAVESTATE_ONEPASS);
        }
    }

    switch( pNxCoreSys->Status )
    {
    case NxCORESTATUS_SAVING_STATE:
        // If state has been saved, exit processing by returning NxCALLBACKRETURN_STOP in the callback
        if(pNxCoreSys->StatusData == NxCSSAVESTATE_COMPLETE)
            return NxCALLBACKRETURN_STOP;
        break;

    // NxCore Has been loaded from a state tape. Tell user and wait for keypress
    case NxCORESTATUS_LOADED_STATE:
        printf("NxCore Has Been Loaded From A State!\nPress [Enter] to continue.\n");
        getchar();
    break;
    }
    // Continue processing
    return NxCALLBACKRETURN_CONTINUE;
}

// The NXCore Callback Function    
//-----------------------------
int __stdcall OnNxCoreCallback(const NxCoreSystem* pNxCoreSys,const NxCoreMessage* pNxCoreMsg)
{

    switch (pNxCoreMsg->MessageType)
    {
    // NxCore Status Message
    case NxMSG_STATUS:
        return OnNxCoreStatus(pNxCoreSys, pNxCoreMsg);
    }
    return NxCALLBACKRETURN_CONTINUE;
}

// Main Entry Point for app.
//-------------------------    
int main(int argc, char* argv[])
{
      if (!NxCore.LoadNxCore("NxCoreAPI64.dll") &&
        !NxCore.LoadNxCore("NxCoreAPI.dll"))
    {
        fprintf(stderr, "loading library failed\n");
        return -1;
    }

    printf("NxCore SampleApp Start.\n");

    // Set the state tape filename
    strcpy(StateFileFilename,"STATESAVE.TMP");

    printf("\nThe application will process trades until 9:00 AM and then save the state,\n exit and reload from the state tape.\n\nPress [Enter] to continue.\n");
    getchar();

    // A tape filename shoul be passed in command line argument,
    // call ProcessTape with that argument. 
    NxCore.ProcessTape(argv[1], NULL, NxCF_EXCLUDE_CRC_CHECK, 0, OnNxCoreCallback);

    // The current process has exited and the state tape has been saved!
    printf("Tape state saved and process exited.\nPress [Enter] to Load the state and continue.\n");
    getchar();

    // Process the tape from a state file
    NxCore.ProcessTape(StateFileFilename, NULL, NxCF_EXCLUDE_CRC_CHECK, 0, OnNxCoreCallback);

    printf("NxCore SampleApp Stop.\n");

    return 0;
}
import net.nanex.NxCoreClass;
import java.io.*;

class StateSample extends NxCoreClass{
    String StateFileFilename;
    // OnNxCoreStatus: Function to handle NxCore Status messages
    //----------------------------------------------------------
    int OnNxCoreStatus(NxCoreSystem nxCoreSys, NxCoreMessage nxCoreMsg)
    {       
        // On minute
        if (nxCoreSys.ClockUpdateInterval >= defines.NxCLOCK_MINUTE &&
            nxCoreSys.nxTime.Hour < 24)
        {
            System.out.println(String.format("NxCore Time: %02d/%02d/%d  %02d:%02d:%02d",
                nxCoreSys.nxDate.Month, nxCoreSys.nxDate.Day, nxCoreSys.nxDate.Year,
                nxCoreSys.nxTime.Hour, nxCoreSys.nxTime.Minute, nxCoreSys.nxTime.Second));
        
            // LOOK! If it's 9:00:00 AM SAVE THE CURRENT STATE TO A STATE FILE!
            if (nxCoreSys.nxTime.Hour==9 && nxCoreSys.nxTime.Minute==0)
            {
                System.out.println("\nNxCore Will Save the State Now!");    
                SaveState(StateFileFilename, defines.NxSAVESTATE_ONEPASS);
            }
        }       
        
        switch( nxCoreSys.Status ) 
        {
        case defines.NxCORESTATUS_SAVING_STATE:
            // If state has been saved, exit processing by returning NxCALLBACKRETURN_STOP in the callback
            if(nxCoreSys.StatusData == defines.NxCSSAVESTATE_COMPLETE)
                return defines.NxCALLBACKRETURN_STOP;
            break;       
        
        // NxCore Has been loaded from a state tape. Tell user and wait for keypress
        case defines.NxCORESTATUS_LOADED_STATE:
            System.out.println("NxCore Has Been Loaded From A State!");    
        break;
        }
        // Continue processing
        return defines.NxCALLBACKRETURN_CONTINUE;
    }
    
    @Override
    public int OnNxCoreCallback(NxCoreSystem nxCoreSys, NxCoreMessage nxCoreMsg) {
        switch (nxCoreMsg.MessageType)
        {
            case defines.NxMSG_STATUS:
                return OnNxCoreStatus(nxCoreSys,nxCoreMsg);
        }
        return defines.NxCALLBACKRETURN_CONTINUE;
    }
    
    public static void main(String args[]) throws IOException {
        StateSample nxCore = new StateSample();

        if (nxCore.LoadNxCore("NxCoreAPI64.dll") != 0){
            nxCore.StateFileFilename = "STATESAVE.TMP";
            
            System.out.println("\nThe application will process trades until 9:00 AM and then save the state,\n exit and reload from the state tape.\n\nPress [Enter] to continue.");
            System.in.read();    
            
            // A tape filename shoul be passed in command line argument,
            // call ProcessTape with that argument. 
            nxCore.ProcessTape(args[0], 0, defines.NxCF_EXCLUDE_CRC_CHECK, 0);
            
            // The current process has exited and the state tape has been saved!
            System.out.println("Tape state saved and process exited.\nPress [Enter] to Load the state and continue.");
            System.in.read();
            
            // Process the tape from a state file
            nxCore.ProcessTape(nxCore.StateFileFilename, 0, defines.NxCF_EXCLUDE_CRC_CHECK, 0);
            
            System.out.println("NxCore SampleApp Stop.");
        }
        else
            System.out.println("loading library failed");
    }
}
import NxCore

tapePath = ""
StateFileFilename = "STATESAVE.TMP"

def OnNxCoreStatus(NxCoreSys, NxCoreMsg):
    # On minute
    if NxCoreSys.ClockUpdateInterval >= NxCore.NxCLOCK_MINUTE and NxCoreSys.nxTime.Hour < 24:
        print("NxCore Time: {:02d}/{}/{}  {:02d}:{:02d}:{:02d}".format(
            NxCoreSys.nxDate.Month, NxCoreSys.nxDate.Day, NxCoreSys.nxDate.Year,
            NxCoreSys.nxTime.Hour, NxCoreSys.nxTime.Minute, NxCoreSys.nxTime.Second))
    
        # LOOK! If it's 9:00:00 AM SAVE THE CURRENT STATE TO A STATE FILE!
        if NxCoreSys.nxTime.Hour==9 and NxCoreSys.nxTime.Minute == 0:
            print("\nNxCore Will Save the State Now!\nPress [Enter] to continue.")    
            input()
            NxCore.SaveState(StateFileFilename, NxCore.NxSAVESTATE_ONEPASS)
    
    if NxCoreSys.Status == NxCore.NxCORESTATUS_SAVING_STATE:
        # If state has been saved, exit processing by returning NxCALLBACKRETURN_STOP in the callback
        if NxCoreSys.StatusData == NxCore.NxCSSAVESTATE_COMPLETE:
            return NxCore.NxCALLBACKRETURN_STOP;
    
        # NxCore Has been loaded from a state tape. Tell user and wait for keypress
    if NxCoreSys.Status ==  NxCore.NxCORESTATUS_LOADED_STATE:
        print("NxCore Has Been Loaded From A State!\nPress [Enter] to continue.");    
        input()
    # Continue processing
    return NxCore.NxCALLBACKRETURN_CONTINUE
def OnNxCoreCallback(NxCoreSys, NxCoreMsg):
    if NxCoreMsg.MessageType == NxCore.NxMSG_STATUS:
        return OnNxCoreStatus(NxCoreSys, NxCoreMsg);
    return NxCore.NxCALLBACKRETURN_CONTINUE

if NxCore.LoadNxCore("NxCoreAPI64.dll"):
    print("\nThe application will process trades until 9:00 AM and then save the state,\n exit and reload from the state tape.\nPress [Enter] to continue.")
    input()  
    
    # A tape filename shoul be passed in command line argument,
    # call ProcessTape with that argument. 
    NxCore.ProcessTape(tapePath, 0, NxCore.NxCF_EXCLUDE_CRC_CHECK, 0, OnNxCoreCallback)
    
    # The current process has exited and the state tape has been saved!
    print("Tape state saved and process exited.\nPress [Enter] to Load the state and continue.")
    input()
    
    # Process the tape from a state file
    NxCore.ProcessTape(StateFileFilename, 0, NxCore.NxCF_EXCLUDE_CRC_CHECK, 0, OnNxCoreCallback)
    
    print("NxCore SampleApp Stop.")
else:
    print("loading library failed")