Using a batch to start Shell_execute, which run batch every 1 minute

Hi guys,

I am trying to run a batch call My_batch.abb every 1 minute on my End of Day data. Ideally, I want to run it only during certain period (9AM - 3PM)
I have read this forum thread: How-to-run-batch-for-exploration-and-writing-csv-file-15-minutes
However, the code provided by @fxshrat in that thread would only work on intraday chart I assume.
I have also read this thread:
Automate batch every 5 minute
The solution provided mainly is to create 12 schedule of every 5 minute. But what about for 1 minute? I don't want to create 60 of them @beppe. I would do that as a last resort though.
I have also read this thread:
Backtest every 1 minute

After researching these many threads and article in Amibroker forum, I come up with this method, which I thought would be the solution, but it is not:

  1. I create a batch file call Shell_starter.abb to load an apx file called Shell_execute.apx, which contain a the Shell_execute.afl. Here is the code for Shell_execute.afl:
_SECTION_BEGIN("Batch_Start");
if ( Status( "stocknum" ) == 0 ) 
{
	ShellExecute( "runbatch", "path-to-batch-file\\My_batch.abb", "" );
}
_SECTION_END();

Now I put the setting exactly like @fxshrat recommended in the previous thread to only run Shell_execute.apx for only the current ticker to avoid multiple batch run at the same time, and set the repeat function to run automatic scan every 1 minute.

image

It does run wonderfully every 1 minute just like I expect, BUT ONLY WHEN I HIT THE SCAN BUTTON once in the beginning of the day. If I did not hit the scan button, it would not run.
Also, I don't know how to stop this Shell_execute.apx automatically according to my prefered schedule

Now 3 problems with this process:

  1. I could just insert the step "Scan" in the Shell_starter.abb. However, doing so would cause 2 batch file to run simultainously: the Shell_starter.abb and My_batch.abb
  2. I must click the Scan button at the beginning of the day for Shell_execute.apx to run every 1 minute. Someday I won't be able to click this button before 9AM, which means My_batch.abb will run behind my schedule.
  3. I don't know how to stop this Shell_execute.apx automatically according to my schedule 9AM - 3PM. It keeps running forever until I turn it off by hand.

I read in the old threads that we can use OLE automation. I have no idea how to use OLE to create this automate process. I wonder if that is the only possible solution, or is there any simpler solution to the problems I post above.

Much thanks everyone!

No, that's not correct.
Now function gets system time not bar time.

If you want to run only from 9:00 to 15:00 then e.g.:

batch_file = "path_to_batch_file.abb";// batch file location

run_every = 15;// run every n-minutes of hour
start_time = 90000;
end_time = 150000;

//RequestTimedRefresh(1);// if local DB

tn = Now(4);
printf( "current time: %g", tn);

x = (tn/100)%100;
_TRACEF("Now (minutes):%g", x);

is_session = tn >= start_time AND tn <= end_time;

if ( x % run_every == 0 AND is_session ) {
	_TRACE("Batch run");
	ShellExecute("runbatch", batch_file, "" ); 
}
1 Like

You don't need "old threads" in the forum, you don't need batch or anything else other than just reading the manual.

  1. Open AmiBroker Object Model

  2. Scroll down to the very end of the document

  3. Ready to use automation code is there (Example 1: Running simple backtest)

You can add a loop that will repeat that every minute in specified times of the day.

1 Like

Dear @fxshrat,

You are and will always be a legend of the Amibroker forum :wink: It works amazingly!

Here is my code solution base on your code:

batch_file = "My_batch.abb";// batch file location
RequestTimedRefresh(1);// if local DB

tn = Now(4);
printf( "current time: %g", tn);

x = (tn/100)%100;
_TRACEF("Now (minutes):%g", x);

run_every = 1;// run every n-minutes of hour

is_session = tn >= 90000 AND tn <= 150000;

if ( x % run_every == 0 AND is_session ) 
{
	_TRACE("Batch run");
	ShellExecute( "runbatch", batch_file, "");
}

Plot(tn,"time",colorPaleGreen, styleLine);

As I put it in the chart with the RequestTimedRefresh(1) code, the time plot run automatically every second, and along with it, running my batch file within the time limit without me scaning or doing anything. Simple and sweet solution.

Dear Dr. @Tomasz,
You inspired me to learn more about OLE automation! I would definitely look into it to create more automatic process. Thank you so much.

For what it is worth, using OLE is much cleaner solution than triggering batch from constantly refreshing chart.

2 Likes

I am definitely aware of that. I am just not that familiar with OLE and is in an urgent need of a solution.
Do you mind shed some light for me on how I could write the time loop so that it will only repeat every minute in specified times of day?

I must make it clear here for future reference:

I encounter this error when I put the above afl on my normal chartview.
image
It will not happen if I open a new default chart and put the code on in that separate screen chart like below

image

The message is clear you are trying to run TWO batches at the same time. You should not do that. You have to wait until one batch finishes before starting another run of same batch. Batches need to be run sequentially. The Scheduler does that automatically (sequence batches).

As I wrote: the "solution" of starting batch periodically from chart window is bad/unreliable.

If you don't know how to use (provided) OLE automation code, you can use Batch Scheduler. It can be setup so to run every minute (60 runs spaced by 1minute repeated hourly)

1 Like

Save the OLE code from manual to Scripts folder of AmiBroker directory.

// This is NOT AFL but jscript
// Source: https://www.amibroker.com/guide/objects.html
var AB = new ActiveXObject( "Broker.Application" ); // creates AmiBroker object
var apx_file = "C:\\Analysis1.apx"; //insert your path to project file 

try 
{ 
	var NewA = AB.AnalysisDocs.Open( apx_file  ); // opens previously saved analysis project file 
	// NewA represents the instance of New Analysis document/window 

	if ( NewA ) 
	{ 
		NewA.Run( 2 ); // start backtest asynchronously

		while ( NewA.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 

		NewA.Export( "test.html" ); // export result list to HTML file

		//WScript.echo( "Completed" ); 

		NewA.Close(); // close new Analysis 
	} 
} 
catch ( err ) 
{ 
	WScript.echo( "Exception: " + err.message ); // display error that may occur
}

Then instead of batch file insert that OLE file location into ShellExecute:

js_file = "Scripts\\YOUR_FILE_NAME.js";// js file location

run_every = 15;// run every n-minutes of hour
start_time = 90000;
end_time = 150000;

//RequestTimedRefresh(1);// if local DB

tn = Now(4);
printf( "current time: %g", tn);

x = (tn/100)%100;
_TRACEF("Now (minutes):%g", x);

is_session = tn >= start_time AND tn <= end_time;

if ( x % run_every == 0 AND is_session ) {
	_TRACE("OLE run");
	ShellExecute(js_file, "", "" ); 
}
2 Likes

Dear @fxshrat ,

I see your solution. I guess I will still have to put it on the chart for it to work. I have recently try to operate auto-batch with your previous method of applying the Shell-execute code on my chart, and it indeed cost a lot of memory for my computer. I wonder if the new method you propose would save me some memory?

Also, The Ole code that you share only work on 1 apx file right? However, I usually run batch that would perform EXPLORE along with backtest on some of the 5 apx and then export to csv, not html. How should I rewrite the Ole file to accomplish that?

Thank you very much.

So I have come up with this js code to explore and backtest multiple apx, and then export them to CSV. I have no idea if it will work correctly. I set it on the chart just like you said, @fxshrat, and when it is the moment to execute my js, nothing show up beside my code editor pop-up.
Can someone please take a look and let me know if there might be any problem?
Credit the idea to this forum post:

// This is NOT AFL but jscript
// Source: https://www.amibroker.com/guide/objects.html
var AB = new ActiveXObject( "Broker.Application" ); // creates AmiBroker object
var apx_52week 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\52 week HiLO.apx"; //insert your path to project file 
var apx_50ma   		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\50MA index.apx"; //insert your path to project file 
var apx_vn30bnh 	= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\VN30 BnH.apx"; //insert your path to project file 
var apx_vn30csv 	= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\VN30 to CSV.apx"; //insert your path to project file 
var apx_vnibnh 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\VNINDEX BnH.apx"; //insert your path to project file 
var apx_vnicsv 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\VNINDEX to CSV.apx"; //insert your path to project file 
var apx_ew100m 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\EW100M.apx"; //insert your path to project file 
var apx_ew500m 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\EW500M.apx"; //insert your path to project file 
var apx_ew1b 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\EW1B.apx"; //insert your path to project file
var apx_ew1b5 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\EW1.5B.apx"; //insert your path to project file
var apx_ew2b 		= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\EW2B.apx"; //insert your path to project file
var apx_explore 	= "D:\\AmiBroker\\Formulas\\Custom\\$$ HEIKEN SEPA BATCH PRO $$\\Apx\\EXPLORER.apx"; //insert your path to project file

try 
{ 
	// NewA represents the instance of New Analysis document/window 
	var NewA1  = AB.AnalysisDocs.Open( apx_52week  ); // opens previously saved analysis project file
	if ( NewA1 ) 
	{ 
		NewA1.Run( 1 ); // start exploration
		NewA1.Close(); // close new Analysis 
	}

	var NewA2  = AB.AnalysisDocs.Open( apx_50ma  ); // opens previously saved analysis project file 
	if ( NewA2 ) 
	{ 
		NewA2.Run( 1 ); // start exploration
		NewA2.Close(); // close new Analysis 
	}

	var NewA3  = AB.AnalysisDocs.Open( apx_vn30bnh  ); // opens previously saved analysis project file 
	if ( NewA3 ) 
	{ 
		NewA3.Run( 2 );  // start backtest asynchronously
		NewA3.Close(); // close new Analysis 
	}

	var NewA4  = AB.AnalysisDocs.Open( apx_vn30csv  ); // opens previously saved analysis project file 
	if ( NewA4 ) 
	{ 
		NewA4.Run( 1 );  // start exploration
		while ( NewA4.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		//NewA.Export( "test.html" ); // export result list to HTML file
		NewA4.Export( "D:\\Amibroker\\Ha Sepa\\VN30 eq.csv" ); // export result list to CSV file
		NewA4.Close(); // close new Analysis 
	}

	var NewA5  = AB.AnalysisDocs.Open( apx_vnibnh  ); // opens previously saved analysis project file 
	if ( NewA5 ) 
	{ 
		NewA5.Run( 2 );  // start backtest asynchronously
		NewA5.Close(); // close new Analysis 
	}

	var NewA6  = AB.AnalysisDocs.Open( apx_vnicsv  ); // opens previously saved analysis project file
	if ( NewA6 ) 
	{ 
		NewA6.Run( 1 );  // start exploration
		while ( NewA6.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA6.Export( "D:\\Amibroker\\Ha Sepa\\VNINDEX eq.csv" ); // export result list to CSV file
		NewA6.Close(); // close new Analysis 
	}

	var NewA7  = AB.AnalysisDocs.Open( apx_ew100m  ); // opens previously saved analysis project file 
	if ( NewA7 ) 
	{ 
		NewA7.Run( 2 );  // start backtest
		while ( NewA7.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA7.Export( "D:\\Amibroker\\Ha Sepa\\EW 100M.csv" ); // export result list to CSV file
		NewA7.Close(); // close new Analysis 
	}	

	var NewA8  = AB.AnalysisDocs.Open( apx_ew500m  ); // opens previously saved analysis project file 
	if ( NewA8 ) 
	{ 
		NewA8.Run( 2 );  // start backtest
		while ( NewA8.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA8.Export( "D:\\Amibroker\\Ha Sepa\\EW 500M.csv" ); // export result list to CSV file
		NewA8.Close(); // close new Analysis 
	}	

	var NewA9  = AB.AnalysisDocs.Open( apx_ew1b  ); // opens previously saved analysis project file 
	if ( NewA9 ) 
	{ 
		NewA9.Run( 2 );  // start backtest
		while ( NewA9.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA9.Export( "D:\\Amibroker\\Ha Sepa\\EW 1B.csv" ); // export result list to CSV file
		NewA9.Close(); // close new Analysis 
	}	

	var NewA10 = AB.AnalysisDocs.Open( apx_ew1b5  ); // opens previously saved analysis project file 
	if ( NewA10 ) 
	{ 
		NewA10.Run( 2 );  // start backtest
		while ( NewA10.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA10.Export( "D:\\Amibroker\\Ha Sepa\\EW 1.5B.csv" ); // export result list to CSV file
		NewA10.Close(); // close new Analysis 
	}	

	var NewA11 = AB.AnalysisDocs.Open( apx_ew2b  ); // opens previously saved analysis project file 
	if ( NewA11 ) 
	{ 
		NewA11.Run( 2 );  // start backtest
		while ( NewA11.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA11.Export( "D:\\Amibroker\\Ha Sepa\\EW 2B.csv" ); // export result list to CSV file
		NewA11.Close(); // close new Analysis 
	}	

	var NewA12 = AB.AnalysisDocs.Open( apx_explore  ); // opens previously saved analysis project file 
	if ( NewA12 ) 
	{ 
		NewA12.Run( 1 );  // start exploration
		while ( NewA12.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 
		NewA12.Export( "D:\\Amibroker\\Ha Sepa\\Explore_Signal HA Sepa.csv" ); // export result list to CSV file
		NewA12.Close(); // close new Analysis 
	}	

} 
catch ( err ) 
{ 
	WScript.echo( "Exception: " + err.message ); // display error that may occur
}