Here is my script for stepping through each symbol in the list of all symbols. It could be modified in several different ways, and I would like to hear your suggestions. (email directly if you like).
By the way, posting afl code to this yahoo group is difficult. I think it would work OK using Outlook (and maybe some other email programs), and maybe if I select "Copy as HTML" in the AmiBroker Editor Preferences. But I am forced to use gmail or yahoo's awful interface, and there doesn't appear to be any option to preserve the indentation, coloring, and without adding redundant new lines. I hope the following is at least indented correctly, as it appears to me now.
// Visit each symbol in the list of All symbols.
// You can use this like a slide show.
// Written by Daniel LaLiberte (
daniel.laliberte@xxxxxxxxx), July 2008.
// You are free to use this however you want.
// Instructions for use:
// Select a symbol in your list of all symbols.
// Use the "Start" trigger parameter to begin stepping at the current symbol.
// It will stop automatically at the end of the list, or you can "Stop" at any time,
// and "Start" again to continue (not restart).
// If you start in a watchlist, or switch charts while stepping, interesting things will happen.
if ( ParamTrigger( "Start Stepping", "Step" ) )
{
StaticVarSetText( "gotoSymbol", "" );
StaticVarSetText( "stepping", "yes" );
}
if ( ParamTrigger( "Stop Stepping", "Stop" ) )
{
StaticVarSetText( "gotoSymbol", "" );
StaticVarSetText( "stepping", "" );
}
// Number of seconds to delay between each step.
delaySeconds = 5;
// Implementation note:
// You can't use a loop over all symbols like the following within one script.
// It would cause an infinite loop because the chart updates as a result of changing the symbol,
// thus executing this script again and restarting the loop.
/*
for (i=0; i<numTickers; i++)
{
ticker = tickers.getKey(i);
JS.setTicker(ticker);
}
*/
// Instead of a simple loop, we must use static vars, stepping to the next symbol
// each time the script is executed. We add a delay using a refresh loop.
// Jscript is used to get the list of all symbols, and to go to the next symbol.
AB = CreateStaticObject( "Broker.Application" );
EnableScript( "jscript" );
< %
var AB = AFL( "AB" );
function setTicker( ticker )
{
AB.ActiveDocument.Name = ticker;
}
function KeyList ( keys )
{
this.keys = keys; // ordered list of the keys
this.keyIndex = {}; // map from key to index.
for ( var i = 0; i < keys.length; i++ )
this.keyIndex[keys[i]] = i;
}
KeyList.prototype.getIndex = function( key )
{
return this.keyIndex[ key ];
}
KeyList.prototype.getKey = function( index )
{
return this.keys[ index ];
}
KeyList.prototype.getLength = function ()
{
return this.keys.length;
}
function getAllTickers ()
{
var stocks = AB.stocks;
var tickerList = stocks.getTickerList( 0 ); // 0 for list of All symbols?
var tickers = tickerList.split( ',' );
if ( !tickers[tickers.length - 1] )
delete tickers[tickers.length - 1]; // Last element is empty due to extra comma.
var tickerKeyList = new KeyList( tickers );
return tickerKeyList;
}
% >
JS = GetScriptObject();
function doneWithSymbol ()
{
// In this test, simply check if the symbol we were supposed to go to is what we see now.
// Special case: no gotoSymbol is OK.
gotoSymbol = StaticVarGetText( "gotoSymbol" );
atSymbol = ( gotoSymbol == "" ) OR ( gotoSymbol == Name() );
// Now delay for some period of time.
// One way to cause a delay is to use the IBController Sleep function, as in the following.
// But this disrupts normal processing in other windows, not completely, but enough to destroy interactivity.
/*
ibc = GetTradingInterface( "IB" );
ibc.sleep(5000);
*/
// Another slightly simpler way is to call RequestTimedRefresh( ) with the desired sleep time.
// The time will be rounded to the nearest whole multiple, so it is not exactly a delay time.
RequestTimedRefresh( delaySeconds );
// But setting the symbol also causes an immediate refresh, which we want to ignore.
refreshed = Status( "redrawaction" ) == 1;
//_Trace("doneWithSymbol refreshed: " + refreshed);
done = atSymbol and refreshed;
return done;
}
function gotoNextSymbol ()
{
// Reconstruct the list of all symbols (aka tickers). Yes, every time.
tickerKeyList = JS.getAllTickers();
// Get the index of the next symbol.
nextIndex = 1 + tickerKeyList.getIndex( Name() );
if ( tickerKeyList.getLength() - 1 > nextIndex ) // Is the index in range?
{
// OK, so get the next symbol and go to it.
nextSymbol = tickerKeyList.getKey( nextIndex );
StaticVarSetText( "gotoSymbol", nextSymbol );
JS.setTicker( nextSymbol );
}
else
{
// No more symbols, so stop stepping.
stepping = "";
StaticVarSetText( "stepping", stepping );
// RequestTimedRefresh(0); // this is not the way to stop the refresh loop.
}
}
stepping = ( "yes" == StaticVarGetText( "stepping" ) );
if ( stepping )
{
// If done with this symbol, go to next symbol.
if ( doneWithSymbol() )
{
gotoNextSymbol();
}
}
Plot( Close, "Close", colorBlack, styleCandle );