Scan and write text files

Amibroker 6.22 / WIN 7

I am using a program to process (scan) a watch list and write a text disk file.

The program performs a backtest (max open positions = 1), the writes to disk profit / loss for each symbol.
Problem:

  • Output to disk is inconsistennt. Watchlist has 1212 symbols. Disk file has fewer symbols (1202 to 1210)
    Missing symbols seem to be OK when tested individually.
  • One case disk file has blank lines or skips a line return. See below:

    AFL code below
//File: UTIL - Create Performance ASCII file - Single
// May 2015
//
//Use AK-Tradable Equities as source file - backtest
//
//do a backtest in Individual backtest mode
//get equity for all trades for single equity backtest from Equity()
//write one line to an ASCII file with profit info.
//
//
//
//
CCI1		= CCI(13);
CCI1_slope 	= CCI1 - Ref(CCI1,-1);
//
Buy			= CCI1 < 0 AND CCI1_slope > 0;
Sell		= 0;
//
ApplyStop( Stoptypenbar, stopmodebars, 16, 0, False, 0 );			// nbar stop
//
//Set backtest paramenters
StartEquity = 100000;

SetOption( "InitialEquity", StartEquity );
//
Max_Pos     = 1;													// Test single issue
PositionSize = -50 / Max_Pos;
//
SetTradeDelays( 1, 1, 1, 1 );
SetOption( "PriceBoundChecking", False ) ;
SetChartOptions( 0, chartShowArrows );
SetOption( "futuresmode", False );
SetOption( "MinShares", 1 );
SetOption( "MaxOpenPositions", Max_Pos );
//

//
//
//Write backtest summary report for individual Backtest
function backtestsummary( count, symbol, profit, perc_profit )
{
	Date_string = StrReplace(NumToStr(DateNum(),1.0),",","");
    Filepath  	= "G:/DataFiles/Daily Backtest Summary/";
    Filename  	= "TradableEquities - " + Date_string + "-" + "Single" ;              
    //
    _TRACE( "fh - 0 - Filename " + FilePath + Filename);
//
//Remove "," from date string
	//Date_string = StrReplace( NumToStr(DateNum(),1.0), ",", "" );
		
	//
   strprofit = ""; 
//Verify that file exists
    fhread = fopen( Filepath + filename + ".txt", "r" );	// Test if file exists
    _TRACE( "fh - 1 - fhread " + fhread );
	

	
    if ( fhread == 0 )   // file does not exist 
    {
	     _TRACE( "fh - 2 - Inside file write process - Symbol "  + Symbol  );
        fhw = fopen( Filepath + filename + ".txt", "w" );	// Open file in Write Mode
        //
	//fputs( "Program: Create Performance ASCII file - Single Issue test" + "\n\n"  , fhw );
        //fputs( symbol + "   " + Date_string + " - "  + writeval(perc_profit,1.2) + "\n"  , fhw );
        fputs( NumToStr(Count,1.0) + "  " + symbol + "   " + Date_string + " - "  + writeval(perc_profit,1.2) + "\n"  , fhw );
        fclose( fhw );
	}
	else
	{
	//
	fclose(fhread);											// CLose file in Read Mode
	
	//
	//
	fha = fopen( Filepath + filename + ".txt", "a" );		// Open file in amend mode
	
        if ( fha )
        {
        
            fputs(  NumToStr(Count,1.0) + "  " + symbol + "   " +  Date_string + " - "  +  writeval(perc_profit,1.2) + "\n", fha );
            fclose( fha );
             _TRACE( "fh - 3 - Inside file amend proceess - Symbol "  + Symbol);
        } // end if (fha)
	}
_TRACE( "fh - 4 - ----------------------------------------------------------------------------------------- " );

//
    
}
//

//
// Run program
profit 			= Equity() - StartEquity;
perc_profit		= profit / startequity * 100;
//
count			= Status("stocknum");
_TRACE( "fh - 4 - Symbol " + Name() + "  Equity " + WriteVal(Equity(),1.0) + "  Profit " + WriteVal(profit,1.0) );
backtestsummary( count, Name(), profit, perc_profit);
//

You really need to start your adventure with reading the manual:
http://www.amibroker.com/guide/h_multithreading.html
and the Knowledge Base:
http://www.amibroker.com/kb/2016/01/27/how-to-write-to-single-shared-file-in-multi-threaded-scenario/

BTW: When submitting AFL use proper code tags. I corrected your post already.

1 Like

I crrected the fopen statements to handle multi-threading and problem got corrected.

A new but similar issue with another program READING an ASCII file … already corrected fopen issue, but still have problems.

This program reads an extra non-existing line returning a value of, I think, return character only. I does not miss any lines. For a file with 1200 lines, it ends up reading 1202 lines, with 2 blank lines.
The problem appears to happen at linr 98 when VarSet(Symbol,Value_Num) has a Symbol with null value.

AFL ode below . Using amibriker 6.22 woth WIN 7.

[code] //File: Create Performance Watch List - 2
//version 1.0
//November 2016
//
//This program reads specified ASCII file with performance data from prior backtest,
// - Prior backtest data created from “UTIL - Scan - Create Performance ASCII file”
// - ASCII filename is shown below as “SourceName”
//
//Use Dummy watchlist (contains 1 symbol) as source in order to process data only once

//Specify Source File
Date_string = StrReplace( NumToStr( DateNum(), 1.0 ), “,”, “” );
Filepath = “G:/DataFiles/Daily Backtest Summary/”;
Filename = "TradableEquities - " + Date_string + “-Single.txt”;
//
SourceName = Filepath + Filename;
Num_symbols = 0;
//
_TRACE( "WL_Utilities-x0 - SourceName " + SourceName );

//
if( status( “action” ) == actionScan AND Status( “stocknum” ) == 0 )
{
//
files = fdir( filepath + “.”, 1 ); // ZZZZZZ???
_TRACE( "WL_Utilities-xdir - " + files );

line			= "startline";
len 			= 0;

//
fh = fopen( Sourcename, “r”, True ); // Open file from disk
_TRACE( "WL_Utilities-x1 - fhread " + fh );
//

if( fh )
{
    do
    {


        if( Num_symbols == 0 )											     // Forces to read first line of file
            line	= fgets( fh );											// Read first line from from disk file. Subsequent lines are read later in program

        num_symbols++;													// Count symbols read
        _TRACE( "WL_Utilities-7A - start of do loop - Num_sumbols " + WriteVal( num_symbols, 1.0 ) );

        len		= StrLen( line ) - 1;										// one based. Count new line character

        _TRACE( "WL_Utilities-7B - line " + line + "  len " + numtostr( len, 1.0 ));

        char			= "X";												// Dummy character filler
        count       	= 0;

        while( char != " " AND len > 0)										// Find space before value
        {
            char	= StrMid( line, len - 1, 1 );							// zero based - get last character
            len--;
            count++;
            _TRACE( "WL_Utilities-7C - len " + WriteVal( len, 1.0 ) + "  count " + WriteVal( count, 1.0 ) + "  ASCchar " + Asc( line, len ) + "  char " + char );
        } // end while char

        //_TRACE( "WL_Utilities-8A - count " + WriteVal(count,1.0));
        //_TRACE( "WL_Utilities-8B - len " + numtostr(len,1.0));

//

        Value		= StrMid( line, len + 1, count - 1 );					// Extract value from line

        Value_len   = StrLen( value );

//
charpos = StrFind( line, " " ); // Find first blank after symbol

        symbol		= StrMid( line, 0, charpos - 1 );						// get symbol

        symlen		= StrLen( symbol );
        //
		_TRACE( "WL_Utilities-8A - Symbol " + Symbol + "  Val len " +  Value_len + "  Value " +  value );

//
for( j = 0; j <= Value_len - 1; j++ ) // Verify ASCII codes for Value string
{
_TRACE( "WL_Utilities-8B - Symbol " + Symbol + " Val len " + WriteVal( Value_len, 1.0 ) + " j " + WriteVal( j, 1.0 ) + " char " + StrMid( value, j, 1 ) + " ASC " + Asc( StrMid( value, j, 1 ) ) );
}

        //
        _TRACE( "WL_Utilities-9A - Vallen " + WriteVal( Value_len, 1.0 ) );
        _TRACE( "WL_Utilities-9B - symlen " + WriteVal( symlen, 1.0 ) );
        _TRACE( "WL_Utilities-9C - symnum " + WriteVal( num_symbols, 1.0 ) );
        _TRACE( "WL_Utilities-9D - symbol " + symbol );
        _TRACE( "WL_Utilities-9E - value  " + value );
        _TRACE( "WL_Utilities-9F - value  " + value  + "  symbol " + symbol + "  numsym " + WriteVal( num_symbols, 1.0 ) );

//Assign values to dynamic variables
Num_symbols_str = numtostr( Num_symbols, 1.0 );
Value_Num = StrToNum( Value );
VarSet( symbol, Value_Num );
VarSetText( Num_symbols_str, symbol );
_TRACE( "WL_Utilities-9G - value_Num " + WriteVal(value_num,1.0) + " Num_symbols_str " + Num_symbols_str + " symbol " + symbol + " numsym " + WriteVal( num_symbols, 1.0 ) );
//
Get_Value = VarGet( symbol );
Get_Symbol = VarGetText( Num_symbols_str );
_TRACE( "WL_Utilities-9H - Sym Num " + Num_symbols_str + " Get value " + WriteVal(Get_Value,1.0) + " Get_Symbol " + Get_Symbol );
//
// Read file from disk. Reads line + newline character. First read is done at start of loop. This allows check for empty line
line = fgets( fh ); // PROBLEM LINE. OCCASIONALLY IT READS AN EXTRA LINE AND RETURNS A BLANK ZZZZZZZZZZZZZZZZZZZZ
_TRACE( "WL_Utilities-7 - Read New Line - len " + StrLen(line) + " " + Line);

    }
    while( ! feof( fh ) AND line != "" );  // not oef

    //
    fclose( fh );

	_TRACE( "WL_Utilities-9J - file closed - out of loop " );
    //
} // end if (fh)
else
    _TRACE( "WL_Utilities-9K - fh " + WriteVal( fh, 1.0 ) + "  File " + SourceName + " Not found" );

//
}// end if status
[/code]

If it reads 1202 lines it means that there are 1202 new line characters in your file. As simple as that.

You may be misguided by the fact that some external editors use just \n (code 13) and some use \r (code 10) and some use \n\r sequence for new lines depending if they use “Unix” or “Windows” style.

Tomasz,

You are correct n that there is an ASCII character 10 in the line that
appears empty

How can I determine where it is coming from?

Below is the code segment I use to write that file (different program)

     fha = fopen( Filepath + filename + ".txt", "a" );        // Open file in amend mode

         if ( fha )
         {

             fputs( symbol + "   " +  Date_string + " - "  + 
writeval(perc_profit,1.2) + "\n", fha );
             fclose( fha );
              _TRACE( "fh - 3 - Inside file amend proceess - Symbol "  + 
Symbol);
         } // end if (fha)

Moderator comment: USE THE CODE TAGS for formula pieces. I really have better things to do than correcting each and every incorrectly formatted message. If you fail to respect forum rules your posts will be deleted

New line is just new line. If you for example open the file with Notepad or any other text editor in Windows it will convert \n into \r\n (codes 10 and 13) because that is what Windows does.
Your “reading” code should ignore lines that are empty. (You can use StrTrim() to trim whitespaces)

1 Like