PDA

View Full Version : Writing information to a file


NinjaTrader_Ray
01-19-2007, 01:57 AM
NinjaScript does not provide convenience methods for reading and writing files. You must use classes within .NET framework for File IO.

The System.IO name space provides types for reading and writing to files.

http://msdn2.microsoft.com/en-us/library/system.io.aspx

Following is a conceptual sample of using the System.IO.StreamWriter class.

Create a method:

private void WriteFile(string fileName, string line)
{
// Creates the file path
string file = NinjaTrader.Cbi.Core.UserDataDir + @"log" + fileName;

// Writes out a line to the specified file name
try
{
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(file))
{
writer.WriteLine(line);
}
}
catch (System.Exception exp)
{
Log("File write error for file name '" + fileName + "' Error '" + exp.Message + "'", LogLevel.Warning);
}
}



Then call this method from within OnBarUpdate():

protected override void OnBarUpdate()
{
if (condition == true)
WriteFile("myFile", "The condition is true");
}


Ray

KBJ
03-30-2007, 10:56 AM
I got the following error when I tried to compile this:

'NinjaTrader.Cbi.Globals' does not contain a definition for 'InstallDir' Strategy\Strategy12.cs 421 33
Any ideas on what to do about this?

Also, I need a way to flush and close the file at the end of back testing.

Is it possible that there is another method that would only be called when the Strategy Analyzer completes running backtesting, where someone clould put close commands and stuff like that so one doesn't have to restart NinjaTrader to close a file?

Thanks.

KBJ

NinjaTrader_Dierk
03-30-2007, 04:05 PM
To fix the compile issue, please try
NinjaTrader.Cbi.Core.UserDataDir

KBJ
03-31-2007, 01:45 AM
Is this, perhaps, version dependent? I am using the field test (6.0.0.9).

Applying your recommendation, I now get the following message:

The type or namespace name 'Core' does not exist in the namespace 'NinjaTrader' (are you missing an assembly reference?)
Also, I need a way to flush and close the file at the end of back testing.

Does NinjaTrader have any method that could be defined in my application that would be called when the Strategy Analyzer completes a backtest, so that I may places code in that method that would close a file?

I have coded a work-around for problem I was experiencing, but I still need a way to close a file at the end of backtesting. My current method is to stop NinjaTrader and restart it after every test. This is slow and boring. Can you offer a faster way of doing this?

NinjaTrader_Ray
03-31-2007, 03:29 AM
Sorry. Try

NinjaTrader.Cbi.Core.UserDataDir

Regarding flush and close the file...Could you eloborate on what you want to do? Not sure what you mean by stop NT, restart after every test.

Thanks

KBJ
03-31-2007, 10:53 AM
That worked.... thanks.

You edited your original posting, so now all my earlier comments look like they're imaginary. I'll have to be more careful what I complain about!

What I'm talking about with "closing" is this...

When I couldn't get the code snippet you have below to work, I went to MSDN and found a cose sample to write into a file using FileInto and CreateText to open the file and then WriteLine to do the output.

When using this approach, what I've found is that after running a back test from the Strategy Analyzer, if I try to do another backtest, I get this error message:

3/31/2007 6:25:05 PM Strategy Error on calling 'OnBarUpdate' method for strategy 'Strategy12': The process cannot access the file 'C:Documents and SettingsNew UserMy DocumentsNinjaTrader 6trace.txt' because it is being used by another process.
The only way I've found to prevent this error is to close the file by exiting NinjaTrader after each and every backtest, which as you might imagine gets a little tedious.

So, I was thinking that if there were a way for my application to get control back one final time AFTER all of the backtest data has been processed by OnBarUpdate, perhaps by defining another method just for this purpose, then it could contain some code to close the file that was created.

Or, if on the very last call to OnBarUpdate, there were some indicator to signify that it was the last of the backtest data, then I could do the close before exiting (although this approach does not handle closing the file if the script aborts before its completely run.)

And as far as a "flush" goes, I guess that would be done implicitly by the close. I was just uncertain as to whether all of the data was being written to the file, thinking that perhaps some was still left in a buffer.

Anyway, those were my thoughts on it. Since I don't understand NinjaTrader's internals, I may have suggested a less than optimum solution.

Nevertheless, I feel that there should be functionality of this type available, and I'd hope that it wouldn't be something difficult to implement.

Thanks,

KBJ

NinjaTrader_Ray
04-02-2007, 03:27 AM
You could override the Dispose() method to close the file. This should get called when a backtest is complete.

See the Help Guide Dispose() method for additional information.

Ray

ATI user
12-14-2009, 05:05 PM
Ray

I am trying to write an OIF, in NT7beta5, to the 'incoming' folder and have the wrong path...i.e. it is writing...somewhere....no errors in the Log

BTW your code is missing a space between 'private' and 'void'

code:


private void WriteFile(string fileName, string line )
{
// Creates the file path
string file = NinjaTrader.Cbi.Core.UserDataDir + @"incoming" + fileName;

// Writes out a line to the specified file name
try
{
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(file))
{
writer.WriteLine(line);
}
}
catch (System.Exception exp)
{
Log("File write error for file name '" + fileName + "' Error '" + exp.Message + "'", LogLevel.Warning);
}
}

ATI user
12-14-2009, 05:18 PM
actually I tried in 7 and 6.5 and in both cases it wrote the file to the NinjaTrader folder

and named if first 'logoif.txt' and then with the above code 'incomingoif.txt' and now 'oif.txt

so clearly that code appends a suffix

tried several iterations for path....no luck

please specify path to NinjaTrader7/incoming..

thanks

NinjaTrader_Josh
12-15-2009, 07:20 AM
ATI user,

What you can do is print the string of the path to see what exactly it is coming out as. Then you can make amends/changes however you see fit to match your directory.

ATI user
12-15-2009, 08:36 AM
thanks Josh

this code prints...
string file = NinjaTrader.Cbi.Core.UserDataDir + @"" + fileName;
Print (" string file = "+file);

C:\Users\Scott\Documents\NinjaTrader 7\oif.txt

I want it to print....to get the file in the 'incoming' folder

C:\Users\Scott\Documents\NinjaTrader 7\incoming\oif.txt

however, everything I try to change NinjaTrader.Cbi.Core.UserDataDir will not compile

and this code


string file = "C:\Users\Scott\Documents\NinjaTrader 7\incoming\oif.txt";

gets error 'unrecognized escape sequence'

NinjaTrader_Josh
12-15-2009, 08:40 AM
It is just a matter of you manipulating the string. Before fileName part of your string concatenation, just add another for the \incoming directory.

ATI user
12-15-2009, 09:01 AM
that just adds it to the front of the filename

string file = C:\Users\Scott\Documents\NinjaTrader 7\incomingoif.txt

this code won't compile

string file = NinjaTrader.Cbi.Core.UserDataDir + "\incoming\"+ fileName;


I need something other than

NinjaTrader.Cbi.Core.UserDataDir

could you please try this and tell me the path/code I need...I have wasted hours on this

thanks

NinjaTrader_Josh
12-15-2009, 09:16 AM
You need to use string literals for \. Please see this reference sample: http://www.ninjatrader-support2.com/vb/showthread.php?t=19174

ATI user
12-15-2009, 09:53 AM
right

this code works fine

string file = NinjaTrader.Cbi.Core.UserDataDir + @"\incoming\"+ fileName;

KBJ
12-15-2009, 12:56 PM
this code

string file = "C:\Users\Scott\Documents\NinjaTrader 7\incoming\oif.txt";

gets error 'unrecognized escape sequence'Try using a single quote instead, or a double backslash. For instance,

string file = 'C:\Users\Scott\Documents\NinjaTrader 7\incoming\oif.txt';

-- or --

string file = "C:\\Users\\Scott\\Documents\\NinjaTrader 7\\incoming\\oif.txt";

ATI user
12-15-2009, 01:38 PM
thanks KBJ

ATI user
12-15-2009, 01:58 PM
KBJ

please see this thread and let me know if you have had the same problem wherein oif.txt only executes once after NT restart

thanks

http://www.ninjatrader-support2.com/vb/showthread.php?t=23712

KBJ
12-19-2009, 01:36 PM
KBJ

please see this thread and let me know if you have had the same problem wherein oif.txt only executes once after NT restart

thanks

http://www.ninjatrader-support2.com/vb/showthread.php?t=23712
ATI User: I looked at the thread. However, this is an area that I don't know much about, as I've never tried using an OIF/Order-Instruction-File.

Good luck.

Mindset
02-08-2010, 05:00 AM
ATIuser - I assume you solved your once only error?
I declare a variable like so
string incomingpath = Cbi.Core.UserDataDir.ToString() + "\\incoming\\oif"

It works for me in Vista - the double slashes are important.

Could I add a suggestion / ask for a hint... I would like to place a stop with a negative limit order . I can do this by manipulating chart trader but is there a hint as to how to do it programmatically?
Obviously it's a synthetic order but is it possible and if it isn't can I ask for it to be added?

ATI user
02-08-2010, 06:28 AM
Mindset

yes...sorry...thought I had posted a final solution to once only issue:

you must not have the 'Ignore duplicate OIF files' checked at Tools/Options/ATI...see pic

I originally thought this option was to avoid race conditions...i.e. executing more than once per instance. In fact it stops duplicate files (same name) for the entire session

re code: as mentioned this code works fine for me..in Vista...did not need double slashes

string file = NinjaTrader.Cbi.Core.UserDataDir + @"\incoming\"+ fileName;

re negative order, if asking me, I would try to place via AtmStrategyCreate code...have not tested this though

J_o_s
11-15-2010, 09:34 AM
How can I write a file to the following location?

I:\Backtests\november-2010\SampleStrategyForTesting\MSFT_15-11-10[17:27].txt

I’ve tried to format this in a string in the following way:

string currentTime = DateTime.Now.ToString("dd-MM-yy[HH:mm]");
string fileLocation = string.Format(@"I:\Backtests\{0}\{1}\{2}_{3}.txt",
DateTime.Now.ToString("MMMM-yy"),
Name.ToString(),
Instrument.FullName.ToString(),
currentTime);
However, when I try to write to this file location using SteamWriter, I get the following error:
“The given path directories aren’t supported” (translated from Dutch)

However, I can create these directories through the use of “System.IO.Directory.CreateDirectory()”. Besides that, when I write to a file location which is hardcoded in the strategy, the file does gets written. But that won’t be feasible with backtests on multiple instruments.

So, I can create the directory in NinjaScript, however when I try to write a .txt file (to the same directory) I get an error saying that the directories aren’t supported. :confused:Anyone with a suggestion?

Regards,

Mindset
11-15-2010, 09:39 AM
have you tried \\ ie double backslashes or @?

NinjaTrader_Josh
11-15-2010, 09:43 AM
J_o_s,

Your file string output is this with your current code:

I:\Backtests\November-10\SampleStrategyForTesting\ES 12-10_15-11-10[09:41].txt

Highlighted in red is the difference area between what you wanted and what you have.

J_o_s
11-15-2010, 11:40 PM
have you tried \\ ie double backslashes or @?
Thanks for your comment Mindset. Yes, I’ve tried that to no avail. (Thanks for your comment though :) )

J_o_s,
Your file string output is this with your current code:
I:\Backtests\November-10\SampleStrategyForTesting\ES 12-10_15-11-10[09:41].txt
Highlighted in red is the difference area between what you wanted and what you have.
Thanks Josh, you’re right, I’ve copied & pasted the wrong line from the Output Window. However, that wasn’t related to the error of the strategy, just my wrong copy & paste. ;)

Because the comments of you both pointed to the basics, I’ve started this morning from scratch, and uncovered the part which made the error:

// The statement below returns the error
string currentTime = DateTime.Now.ToString("dd-MM-yy[HH:mm]");
// Removing the “:” in the string does make it work
string currentTime = DateTime.Now.ToString("dd-MM-yy[HHmm]");
Woops, not that smart because a “:” isn’t an allowed character :o (see also http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx ). So all in all it was a little mistake which rendered the (abstractly formulated) error.

For what’s it’s worth, this is the C# code at the moment:

private System.IO.StreamWriter sw;
public void WriteStrategyToFile()
{
// Generate the string with the date and time
string currentTime = DateTime.Now.ToString("dd-MM-yy[HHmm]");

// Generate the target directory path
string filePath = string.Format(@"C:\Temp\{0}\{1}\",
DateTime.Now.ToString("MMMM-yy"), Name.ToString());

// Generate the file name
string fileName = string.Format("{0}_{1}.txt", Instrument.FullName.ToString(), currentTime);

// Combine both strings in the complete path
string fileLocation = System.IO.Path.Combine(filePath, fileName);

Print("Current file location: " + fileLocation);

// Make the directory if it's not yet existing
if (!System.IO.Directory.Exists(filePath))
{
System.IO.Directory.CreateDirectory(filePath);
}

// Start writing to file
try
{
sw = System.IO.File.AppendText(fileLocation);

sw.WriteLine("Current time is " + currentTime);
sw.WriteLine("StrategyName: " + Name);
}
// Catch the exceptions
catch (Exception e)
{
// Outputs the error to the log
Log("You cannot write and read from the same file at the same time. Please remove SampleStreamReader.", NinjaTrader.Cbi.LogLevel.Error);
throw;
}

// Close SteamWriter
sw.Close();
}
Regards,