Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Strategy for "Save OHLC" throws error

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Strategy for "Save OHLC" throws error

    I am not sure how to properly credit the original authors of the following code. How can I fix the "KNOWN ISSUE" described as "Throws errors: "Error on Calling 'OnStateChange' method: Object reference not set to an instance of an object.""? I have removed some of the code to fit the character limit here.

    Here is the code, which is intended to Save OHLC values to a text or csv file:

    Code:
    #region Versioning and Usage Notes
    /// ExportData8: Exports time-stamped OHLCV data of the selected instrument(s) to a text/csv file in Ninja Trader 8
    
    // (C) By the following authors in Change Log. License granted only under GNU GENERAL PUBLIC LICENSE (Latest Version)
    
    // NOTE: Make sure that historical data exists first. To do so, connect to your Data Source and then
    // Go to Tools -> Historical Data,
    // then click Load tab,
    // then under Download section, select Instrument(s), Intervals, Start/End Dates, Data Type,
    // then click Download
    
    // Change Log:
    // 30 January 2010 ver 1.0 Released by MXASJ.
    // ...
    // 23 February 2017 ver 4.3 MURTY ROMPALLI: Fixed non-working default properties, Added NOSEC formats
    
    // TO DO: Remove date/time formats and datetime separater and add input fields such as MM/dd/yyyy, separater, HH:MM etc
    
    // KNOWN PROBLEMS:
    // Throws errors: "Error on calling OnStateChange method: Object reference not set to an instance of an object
    #endregion
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.Indicators;
    using NinjaTrader.NinjaScript.DrawingTools;
    using System.IO; //For StreamWriter
    using System.Windows.Forms; //For the pop up warning
    
    //This namespace holds Strategies in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class ExportData8 : Strategy
    {
    #region Variables
    private string dest;
    private bool pathException = false;
    private System.IO.StreamWriter sw;
    private char dataSeparator = ',';
    #endregion
    
    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Strategy to Export data";
    Name = "ExportData8";
    Calculate = Calculate.OnBarClose;
    IsExitOnSessionCloseStrategy = true;
    ExitOnSessionCloseSeconds = 30;
    
    /*
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 0;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = false;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.PerEntryExecution;
    BarsRequiredToTrade = 20;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    */
    
    path = @"C:\Data"; // Path where file(s) will be written
    useDefaultFilename = true; // Use default file name
    filename = @"<Default>"; // Default: Instrument_BarType_Periodicity.fileExtn
    fileExtension = ExtType.csv; // Enum for File Extension
    dateTimeFormat = MyDateTime.USTimeFormatNOSEC; // Enum for DateTime output
    delimiter = SepType.comma; // Enum for data delimiter
    splitDateTime = true; // Splits DateTime into Date and Time fields
    firstRowIsColumnName = true; // Set for standard DateTime OHLC formats. Matlab, R, and CustomCode will be incorrect
    }
    else if (State == State.DataLoaded)
    {
    if (useDefaultFilename == true || filename == "<Default>")
    switch(Instrument.MasterInstrument.InstrumentType)
    {
    case InstrumentType.Stock:
    case InstrumentType.Forex:
    dest = @"\" + Instrument.MasterInstrument.Name + "_" + BarsPeriod.Value + "_" + BarsPeriod.BarsPeriodType + "." + fileExtension;
    break;
    
    case InstrumentType.Future:
    dest = @"\" + Instrument.FullName + "_" + BarsPeriod.Value + "_" + BarsPeriod.BarsPeriodType + "." + fileExtension;
    dest = dest.Replace(' ','_'); // Replaces illegal filename characters in Futures names
    dest = dest.Replace('-','_'); // Replaces illegal filename characters in Futures names
    break;
    
    case InstrumentType.Index:
    dest = @"\" + Instrument.MasterInstrument.Name + "_" + BarsPeriod.Value + "_" + BarsPeriod.BarsPeriodType + "." + fileExtension;
    dest = dest.Replace('^','i'); // Replaces illegal filename characters in Index names
    break;
    
    default:
    MessageBox.Show("Unsupported Type: " + Instrument.MasterInstrument.InstrumentType, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Stop);
    SetState(State.Terminated);
    return;
    }
    else
    dest = @"\" + filename + "." + fileExtension;
    
    dest = path + dest;
    
    switch(delimiter)
    {
    case SepType.tab:
    dataSeparator = '\t';
    break;
    
    case SepType.comma:
    dataSeparator = ',';
    break;
    
    case SepType.semicolon:
    dataSeparator = ';';
    break;
    
    case SepType.space:
    dataSeparator = ' ';
    break;
    }
    
    // NOTE: If file at 'path' doesn't exist it will create the file. If it does exist, it will append the file.
    
    try
    {
    sw = File.AppendText(dest);
    }
    catch (Exception e)
    {
    Print(DateTime.Now + " Exception caught in path and file variables");
    Print("Path " + dest + " is invalid");
    Print("Please check your path and file name and try again");
    Print ("Exception Details: " + e.ToString());
    MessageBox.Show("Invalid Path/Filename, Exception: " + e.ToString(), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Stop);
    sw.Close();
    pathException = true;
    sw.Dispose(); //Not sure if this is necessary here.
    SetState(State.Terminated);
    }
    
    Print("Writing to file: " + dest);
    
    //FirstRowIsColumnName logic
    if (firstRowIsColumnName && dateTimeFormat != MyDateTime.CustomCode)
    {
    if (splitDateTime)
    sw.WriteLine("Date" + dataSeparator + "Time" + dataSeparator + "Open" + dataSeparator + "High" + dataSeparator + "Low" + dataSeparator + "Close" + dataSeparator + "Volume");
    else
    sw.WriteLine("DateTime" + dataSeparator + "Open" + dataSeparator + "High" + dataSeparator + "Low" + dataSeparator + "Close" + dataSeparator + "Volume");
    }
    
    Print(DateTime.Now + " Running Export Data [Disable to close the file and allow access by other programs]");
    }
    else if (State == State.Terminated)
    {
    sw.Close();
    Print(DateTime.Now + " Terminating ExportData on " + Instrument.FullName + " " + BarsPeriod.Value + " " + BarsPeriod.BarsPeriodType + " Data");
    
    if (pathException)
    Print("Path exception!");
    else
    Print("File written to: " + dest);
    
    sw.Dispose();
    }
    }
    
    protected override void OnBarUpdate()
    {
    // This is the output of all lines. The output format is: DateTime Open High Low Close Volume
    // If you wanted to output indicator data you could add that to string "data" as well, for example
    // the line below would output DateTime Close EMA(14):
    // string data = (Time[0] + dataSeparator + Close[0] + dataSeparator + EMA(14)[0]);
    // The case CustomCode below is set up specifically for this.
    
    string data = string.Empty;
    
    switch(dateTimeFormat)
    {
    case MyDateTime.USTimeFormatNOSEC:
    data = Time[0].ToString("MM/dd/yyyy HH:mm") + dataSeparator + Open[0] + dataSeparator + High[0] + dataSeparator + Low[0] + dataSeparator + Close[0] + dataSeparator + Volume[0];
    break;
    
    case MyDateTime.USTimeFormat:
    data = Time[0].ToString("MM/dd/yyyy HH:mm:ss") + dataSeparator + Open[0] + dataSeparator + High[0] + dataSeparator + Low[0] + dataSeparator + Close[0] + dataSeparator + Volume[0];
    break;
    }
    
    if (splitDateTime == true)
    //Replace the space in DateTime with the DataSeparator
    data = data.Replace(' ',dataSeparator);
    
    sw.WriteLine(data);
    }
    
    public enum ExtType
    {
    txt,
    csv,
    }
    
    public enum MyDateTime
    {
    USTimeFormatNOSEC,
    USTimeFormat,
    EUTimeFormatNOSEC,
    EUTimeFormat,
    ISO8601Basic,
    ISO8601Extended,
    ISO8601BasicT,
    ISO8601ExtendedT,
    Matlab,
    R,
    CustomCode,
    }
    
    public enum SepType
    {
    comma,
    semicolon,
    tab,
    space,
    }
    
    #region Properties
    
    [Display(Name="Path", GroupName="Output File Properties", Description="Path name for the text file output. NOTE: If the file exists data will be appended to it.")]
    public string path { get; set; }
    
    [Display(Name="File Extension", GroupName="Output File Properties", Description="Output file extension. Currently supports txt and csv.")]
    public ExtType fileExtension { get; set; }
    
    [Display(Name="Filename", GroupName="Output File Properties", Description="If UseDefaultFileName is FALSE, the file name for the text file output. NOTE: If the file exists data will be appended to it.")]
    public string filename { get; set; }
    
    [Display(Name="Use Default Filename", GroupName="Output File Properties", Description="Use Default Filename? True/False. Default Filename is Instrument_Bars Type_Periodicity.")]
    public bool useDefaultFilename { get; set; }
    
    [Display(Name="Delimiter", GroupName="Output Data Format", Description="Column delimiter. Default is a comma.")]
    public SepType delimiter { get; set; }
    
    [Display(Name="DateTime Format", GroupName="Output Data Format", Description="DateTime Output. Various options are listed. CustomCode can be used if you need to output indicator values. It is currently coded to output Close and EMA(14).")]
    public MyDateTime dateTimeFormat { get; set; }
    
    [Display(Name="Split DateTime", GroupName="Output Data Format", Description="Splits Date and Time into two fields.")]
    public bool splitDateTime { get; set; }
    
    [Display(Name="First Row is Header", GroupName="Output Data Format", Description="If TRUE, first row of output is column names for standard DateTime OHLCV formats. CustomCode will ignore this setting.")]
    public bool firstRowIsColumnName { get; set; }
    
    #endregion
    }
    }

    #2
    Here is a zipped archive which contains what I assume is the original, complete, and unedited code:
    Attached Files
    Last edited by karl_model; 03-20-2022, 05:36 PM.

    Comment


      #3
      Hello karl_model,

      Note, that this is a custom script and cannot start with the @ symbol. These are reserved for system scripts that are distributed with NinjaTrader.

      To export a NinjaTrader 8 NinjaScript so this can be shared and imported by the recipient do the following:
      1. Click Tools -> Export -> NinjaScript...
      2. Click the 'add' link -> check the box(es) for the script(s) and reference(s) you want to include
      3. Click the 'Export' button
      4. Enter a unique name for the file in the value for 'File name:'
      5. Choose a save location -> click Save
      6. Click OK to clear the export location message
      By default your exported file will be in the following location:
      • (My) Documents/NinjaTrader 8/bin/Custom/ExportNinjaScript/<export_file_name.zip>
      Below is a link to the help guide on Exporting NinjaScripts.
      http://ninjatrader.com/support/helpG...-us/export.htm

      The error is indicating you have a null reference with a variable (or method call) in OnStateChange().

      When in the error occurring? Is this occurring when opening the Strategies window? (this would be when State is State.SetDefaults).
      Is this occurring only when enabling the Strategy? (this would be State.Configure, State.DataLoaded, or State.Historical)

      Add a print above each line to determine which line is causing the error. The last print to appear will be above the line causing the error.
      Below is a link to a forum post that demonstrates using prints to understand behavior.
      https://ninjatrader.com/support/foru...121#post791121

      What is the specific line causing the error?
      Chelsea B.NinjaTrader Customer Service

      Comment


        #4
        Thank you for your generous and helpful advice. I have attached a new version of the script in which I have added the print statements which you have requested. My discussion about line numbers will now refer to the new version of the script. The script seems to stop somewhere after it reaches line 205 which issues the print statement "State: Terminated". Since there is only one line before another print statement at line 207 which never appears, I might assume that the error occurs exactly at line 206 which calls "sw.close", where an attempt is made to close the streamwriter object. Given a 1-minute OHLC chart of ES-06-22, when the strategy is added to the chart then the output is as follows:

        Code:
        State.SetDefaults
        State.Terminated
        Strategy 'ExportData8': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.
        State.SetDefaults
        State.SetDefaults
        State.SetDefaults
        State.Terminated
        Strategy 'ExportData8': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.
        State.SetDefaults
        State.Configure
        State.Terminated
        Strategy 'ExportData8': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.
        State.SetDefaults
        State.Terminated
        Strategy 'ExportData8': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.
        State.Terminated
        Strategy 'ExportData8': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.
        State.Terminated
        Strategy 'ExportData8': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.

        Comment


          #5
          After reading the link about how to export NinjaScript, I did not see that specific option in my version of NinjaTrader. Therefore I have used the built-in Windows 7 "Send to > Compressed Zip File" in order to create my archives. Here is the new script in both compiled form and also as a .txt file:
          Attached Files

          Comment


            #6
            Hello karl_model,

            A print would be added above every line that has an assignment or method call (an action).

            If the print is appearing, the error is below that line.
            Chelsea B.NinjaTrader Customer Service

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by NullPointStrategies, Today, 05:17 AM
            0 responses
            51 views
            0 likes
            Last Post NullPointStrategies  
            Started by argusthome, 03-08-2026, 10:06 AM
            0 responses
            129 views
            0 likes
            Last Post argusthome  
            Started by NabilKhattabi, 03-06-2026, 11:18 AM
            0 responses
            69 views
            0 likes
            Last Post NabilKhattabi  
            Started by Deep42, 03-06-2026, 12:28 AM
            0 responses
            42 views
            0 likes
            Last Post Deep42
            by Deep42
             
            Started by TheRealMorford, 03-05-2026, 06:15 PM
            0 responses
            46 views
            0 likes
            Last Post TheRealMorford  
            Working...
            X