NexusFi: Find Your Edge


Home Menu

 





Help exporting NT8 data to csv via indicator


Discussion in NinjaTrader

Updated
    1. trending_up 569 views
    2. thumb_up 1 thanks given
    3. group 3 followers
    1. forum 3 posts
    2. attach_file 1 attachments




 
Search this Thread

Help exporting NT8 data to csv via indicator

  #1 (permalink)
 
stoicbuddha's Avatar
 stoicbuddha 
Seattle, WA
 
Experience: Intermediate
Platform: NinjaTrader 8
Broker: AMP/CQG
Trading: Indices
Frequency: Every few days
Duration: Minutes
Posts: 96 since Feb 2012
Thanks Given: 1,047
Thanks Received: 96

Has anyone created a Ninjatrader 8 indicator that exports live tick data to a .csv? I want to export time, Price, OHLC, Volume and a few custom indicator values. I just need a starting point in terms of C#. I haven't worked in C# in many years and am hoping somoene else has started or created a version of this that I can use as a template. Be grateful for any help.

Our life is our own today. Tomorrow you will be dust, a shade, a tale that is told. Live mindful of death, the hour flies.
Visit my NexusFi Trade Journal Started this thread Reply With Quote

Can you help answer these questions
from other members on NexusFi?
Exit Strategy
NinjaTrader
REcommedations for programming help
Sierra Chart
NT7 Indicator Script Troubleshooting - Camarilla Pivots
NinjaTrader
How to apply profiles
Traders Hideout
Pivot Indicator like the old SwingTemp by Big Mike
NinjaTrader
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Spoo-nalysis ES e-mini futures S&P 500
29 thanks
Just another trading journal: PA, Wyckoff & Trends
25 thanks
Tao te Trade: way of the WLD
24 thanks
Bigger Wins or Fewer Losses?
21 thanks
GFIs1 1 DAX trade per day journal
17 thanks
  #2 (permalink)
benJephunneh
Huntsville, AL
 
Posts: 13 since Feb 2022
Thanks Given: 9
Thanks Received: 5

It's been over a year since I've played with this code, but I believe it still works with the latest NT8 update. That is, I haven't seen any write errors. Please don't be shy with suggestions, as well, since this was my first go in C# to write to CSV.

Here is a routine for recording prices of a day's open, market open, high, and low prices. I'll throw in something for reading these values from CSV just for completeness, such as for painting historical data. I'm leaving some of the regular items out (e.g. some SetDefaults items) and the algorithm for actually finding these values since this isn't what I've ever used it for:
 
Code
#region Fields
private double _open = 0, _marketOpen = 0, _low = 0, _high = 0;
private DateTime _currentDate, _previousDate;
private Data.SessionIterator _sessionIterator;
private static ReaderWriterLockSlim _readWriteLock;
private const int _retries 3;
private const int _delay = 1000;
private string _filepath = Path.Combine(new string[] { NinjaTrader.Core.Globals.UserDataDir, "bin", "Custom", "Indicators" });
private bool _fileExists;
#endregion

#region Properties
[NinjaScriptProperty]
[Display(Order = 1800, ResourceType = typeof(Custom.Resource), Name = "Filename", GroupName = "NinjaScriptParameters")]
public string Filename
{ get; set; }
#endregion

#region Methods
protected override void OnStateChange()
{
  base.OnStateChange();

  switch (State)
  {
    case State.SetDefaults:
      ...
      Filename = @"OMoHL.csv";
      break;
    case State.Configure:
      _currentDate = _previousDate = Core.Globals.MinDate;
      break;
    case State.DataLoaded:
      _sessionIterator = new SessionIterator(Bars);
      _fileExists = File.Exists(Path.Combine(_filepath, Filename);
      _readWriteLock = new ReaderWriterLockSlim();
      break;
  }
}

protected override void OnBarUpdate()
{
  base.OnBarUpdate();

  _previousDate = _currentDate;
  _currentDate = _sessionIterator.GetTradingDay(Time[0]);

  if (_currentDate != _previousDate)
  {
    // Routine for getting old values:
    if (State == State.Historical)
    {
      var entry = GetEntry();

      if (entry.Item5)
      {
        _open = entry.Item1;
        _marketOpen = entry.Item2;
        ...
      }
    }
    else
    {
      // Algo for getting new values:
      ...

      AddEntry(_currentDate, _open, _marketOpen, _high, _low, _filepath, _Filename);  // Given that all these arguments are fields in the class, I would imagine you could just change this to AddEntry().
    }
}

private void AddEntry(DateTime date, double open, double marketOpen, double high, double low, string path, string filename)
{
  StringBuilder newEntry = new StringBuilder();
  string[] instrumentName = Instrument.FullName.Split(' ');

  newEntry.Append(Environment.NewLine);
  newEntry.Append(date.ToString("yyyyMMdd") + ",");
  newEntry.Append(instrumentName[0].ToLowerInvariant() + ",");
  newEntry.Append(open.ToString(), ",");
  newEntry.Append(marketOpen.ToString(), ",");
  ...

  _readWriteLock.EnterWriteLock();
  try
  {
    for (var ii = 1; i <= _retries; ii++)
    {
      try
      {
        using (StreamWriter sw = new StreamWriter(Path.Combine(path, filename), true))
        {
          var t = Task.Run(() => sw.Write(newEntry.ToString()));
          t.Wait();
          t.Close();
          break;
        }
      }
      catch (IOException e)
      {
        Thread.Sleep(_delay);
      }
    }
  }
  finally
  {
    _readWriteLock.ExitWriteLock();
  }
}

private Tuple<double, double, double, double, bool> GetEntry()
{
  double open = 0, marketOpen = 0, high = 0, low = 0;
  bool entryFound = false;

  if (!_fileExists)
    return Tuple.Create(open, marketOpen, high, low, entryFound);

  using (TextFieldParser parser = new TextFieldParser(Path.Combine(_filepath, Filename)))
  {
    parser.Delimiters = new string[] { "," };
    string[] parts;
    DateTime entryDate;

    do
    {
      parts = parser.ReadFields();

      if (parts != null)
      {
        if (DateTime.TryParseExact(parts[0], "yyyyMMdd", null, System.Globalization.DateTimeStyles.AllowWhiteSpaces |
                                                               System.Globalization.DateTimeStyles.AdjustToUniversal, out entryDate))
        {
          if (_currentDate == entryDate)
          {
            string[] chartInstrument = Instrument.FullName.Split(' ');
            if (parts[1].Equals(chartInstrument[0], StringComparison.OrdinalIgnoreCase))
            {
              open = Convert.ToDouble(parts[2]);
              marketOpen = Convert.ToDouble(parts[3]);
              ...

              entryFound = true;
              break;
            }
          }
        }
      }
    } while (!entryFound && !parser.EndOfData);
  }

  return Tuple.Create(open, marketOpen, high, low, entryFound);
}
#endregion

Reply With Quote
Thanked by:
  #3 (permalink)
 
stoicbuddha's Avatar
 stoicbuddha 
Seattle, WA
 
Experience: Intermediate
Platform: NinjaTrader 8
Broker: AMP/CQG
Trading: Indices
Frequency: Every few days
Duration: Minutes
Posts: 96 since Feb 2012
Thanks Given: 1,047
Thanks Received: 96



benJephunneh View Post
It's been over a year since I've played with this code, but I believe it still works with the latest NT8 update. That is, I haven't seen any write errors. Please don't be shy with suggestions, as well, since this was my first go in C# to write to CSV.

Here is a routine for recording prices of a day's open, market open, high, and low prices. I'll throw in something for reading these values from CSV just for completeness, such as for painting historical data. I'm leaving some of the regular items out (e.g. some SetDefaults items) and the algorithm for actually finding these values since this isn't what I've ever used it for:
 
Code
#region Fields
private double _open = 0, _marketOpen = 0, _low = 0, _high = 0;
private DateTime _currentDate, _previousDate;
private Data.SessionIterator _sessionIterator;
private static ReaderWriterLockSlim _readWriteLock;
private const int _retries 3;
private const int _delay = 1000;
private string _filepath = Path.Combine(new string[] { NinjaTrader.Core.Globals.UserDataDir, "bin", "Custom", "Indicators" });
private bool _fileExists;
#endregion

#region Properties
[NinjaScriptProperty]
[Display(Order = 1800, ResourceType = typeof(Custom.Resource), Name = "Filename", GroupName = "NinjaScriptParameters")]
public string Filename
{ get; set; }
#endregion

#region Methods
protected override void OnStateChange()
{
  base.OnStateChange();

  switch (State)
  {
    case State.SetDefaults:
      ...
      Filename = @"OMoHL.csv";
      break;
    case State.Configure:
      _currentDate = _previousDate = Core.Globals.MinDate;
      break;
    case State.DataLoaded:
      _sessionIterator = new SessionIterator(Bars);
      _fileExists = File.Exists(Path.Combine(_filepath, Filename);
      _readWriteLock = new ReaderWriterLockSlim();
      break;
  }
}

protected override void OnBarUpdate()
{
  base.OnBarUpdate();

  _previousDate = _currentDate;
  _currentDate = _sessionIterator.GetTradingDay(Time[0]);

  if (_currentDate != _previousDate)
  {
    // Routine for getting old values:
    if (State == State.Historical)
    {
      var entry = GetEntry();

      if (entry.Item5)
      {
        _open = entry.Item1;
        _marketOpen = entry.Item2;
        ...
      }
    }
    else
    {
      // Algo for getting new values:
      ...

      AddEntry(_currentDate, _open, _marketOpen, _high, _low, _filepath, _Filename);  // Given that all these arguments are fields in the class, I would imagine you could just change this to AddEntry().
    }
}

private void AddEntry(DateTime date, double open, double marketOpen, double high, double low, string path, string filename)
{
  StringBuilder newEntry = new StringBuilder();
  string[] instrumentName = Instrument.FullName.Split(' ');

  newEntry.Append(Environment.NewLine);
  newEntry.Append(date.ToString("yyyyMMdd") + ",");
  newEntry.Append(instrumentName[0].ToLowerInvariant() + ",");
  newEntry.Append(open.ToString(), ",");
  newEntry.Append(marketOpen.ToString(), ",");
  ...

  _readWriteLock.EnterWriteLock();
  try
  {
    for (var ii = 1; i <= _retries; ii++)
    {
      try
      {
        using (StreamWriter sw = new StreamWriter(Path.Combine(path, filename), true))
        {
          var t = Task.Run(() => sw.Write(newEntry.ToString()));
          t.Wait();
          t.Close();
          break;
        }
      }
      catch (IOException e)
      {
        Thread.Sleep(_delay);
      }
    }
  }
  finally
  {
    _readWriteLock.ExitWriteLock();
  }
}

private Tuple<double, double, double, double, bool> GetEntry()
{
  double open = 0, marketOpen = 0, high = 0, low = 0;
  bool entryFound = false;

  if (!_fileExists)
    return Tuple.Create(open, marketOpen, high, low, entryFound);

  using (TextFieldParser parser = new TextFieldParser(Path.Combine(_filepath, Filename)))
  {
    parser.Delimiters = new string[] { "," };
    string[] parts;
    DateTime entryDate;

    do
    {
      parts = parser.ReadFields();

      if (parts != null)
      {
        if (DateTime.TryParseExact(parts[0], "yyyyMMdd", null, System.Globalization.DateTimeStyles.AllowWhiteSpaces |
                                                               System.Globalization.DateTimeStyles.AdjustToUniversal, out entryDate))
        {
          if (_currentDate == entryDate)
          {
            string[] chartInstrument = Instrument.FullName.Split(' ');
            if (parts[1].Equals(chartInstrument[0], StringComparison.OrdinalIgnoreCase))
            {
              open = Convert.ToDouble(parts[2]);
              marketOpen = Convert.ToDouble(parts[3]);
              ...

              entryFound = true;
              break;
            }
          }
        }
      }
    } while (!entryFound && !parser.EndOfData);
  }

  return Tuple.Create(open, marketOpen, high, low, entryFound);
}
#endregion

Thanks, I'll give it a try!

Our life is our own today. Tomorrow you will be dust, a shade, a tale that is told. Live mindful of death, the hour flies.
Visit my NexusFi Trade Journal Started this thread Reply With Quote
  #4 (permalink)
 
stoicbuddha's Avatar
 stoicbuddha 
Seattle, WA
 
Experience: Intermediate
Platform: NinjaTrader 8
Broker: AMP/CQG
Trading: Indices
Frequency: Every few days
Duration: Minutes
Posts: 96 since Feb 2012
Thanks Given: 1,047
Thanks Received: 96

I used the streamwriter to create a indicator that gets me the information I need. I included a 'Datetime.Now' to correlate market time with PC local time. It also helps me to know when past data was added. I'm uploading it in case it helps someone else. I'll be updating and making edits to suit my needs.

Our life is our own today. Tomorrow you will be dust, a shade, a tale that is told. Live mindful of death, the hour flies.
Attached Files
Elite Membership required to download: Samplecsvwriter.zip
Visit my NexusFi Trade Journal Started this thread Reply With Quote




Last Updated on June 20, 2023


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts