Here is the code that can be used to Synchronize charts and zoom.
/*<Usage>
Put this AFL in the Include Folder.
Add below 2 lines into your AFL
UseZoomer = ParamToggle("Use Zoomer?", "No|Yes", 0);
#include_once <iZoomer.afl>
Sourcecode downloaded from: http://zaqimon.blogspot.co.uk/2012/09/synchronous-scrolling-in-amibroker.html
*/
function ZqZoomSync( force )
{
// All variables are made local to guarantee naming collisions or side effects
local LastBarIndex, FirstBarIndex, prevLastBarIndex, prevFirstBarIndex, prevFirstDateTime, DT, BI, LastDateTime, FirstDateTime, LastDateTimestr, FirstDateTimestr;
local OAB, OAD, dcount, i, OADoc, OAW, OADocWin, res;
// Get a count of the number of documents
OAB = CreateObject( "Broker.Application" );
OAD = OAB.Documents;
dcount = OAD.Count;
// Process multiple windows (documents)
res = False;
if ( dcount > 1 )
{
// Get current and last start and end DateTimes's
LastBarIndex = Status( "LastVisibleBarIndex" );
FirstBarIndex = Status( "FirstVisibleBarIndex" );
//Nblankbar = Status( "LastVisibleBarIndex" ) - BarCount; // [zq] not used !!
// [zq] BarIndex may always be the same due to QuickAFL, check prevFirstDateTime in addition
prevLastBarIndex = Nz( StaticVarGet( "_prevLastVisibleBarIndex" ) );
prevFirstBarIndex = Nz( StaticVarGet( "_prevFirstVisibleBarIndex" ) );
prevFirstDateTime = Nz( StaticVarGet( "_prevFirstDateTime" ) );
// [zq] move outside if() statement for checking prevFirstDateTime
DT = DateTime();
BI = BarIndex();
LastDateTime = LastValue( ValueWhen( LastBarIndex == BI, DT ) ); // [zq] LastDateTime could be empty
FirstDateTime = LastValue( ValueWhen( FirstBarIndex == BI, DT ) );
// Check for a new date/time range
// _TRACE(""+FirstBarIndex+", "+LastBarIndex);
if ( LastBarIndex != prevLastBarIndex OR FirstBarIndex != prevFirstBarIndex OR FirstDateTime != prevFirstDateTime OR force )
{
// Set the new last values
StaticVarSet( "_prevLastVisibleBarIndex", LastBarIndex );
StaticVarSet( "_prevFirstVisibleBarIndex", FirstBarIndex );
StaticVarSet( "_prevFirstDateTime", FirstDateTime );
LastDateTimestr = DateTimeToStr( LastDateTime );
FirstDateTimestr = DateTimeToStr( FirstDateTime );
// _TRACE(""+FirstDateTimestr+", "+LastDateTimestr);
// Loop through the document collection
for ( i = 0; i < dcount; i++ )
{
// If it is not the active document -
OADoc = OAD.Item( i );
// NOTE - it doesn't hurt to sync the current window and it makes all
// windows have no blank bars on the right so they look the same
// [zq] I think it's reasonable for not syncing ActiveDocument.
// [zq] Something not belong to the ActiveDocument was shown when not syncing ActiveDocument with multi-threaded charts options disabled.
if ( OADoc != OAB.ActiveDocument )
{
// Get the document window and zoom to range
//_TRACE( " Zoom to range document - " + i + " , " + Curststr + " - " + Curendstr );
OADW = OADoc.Windows;
// Document window count assumed to be 1
OADocWin = OADW.Item( 0 );
OADocWin.ZoomToRange( FirstDateTimestr, LastDateTimestr ); // [zq] this function failed to update chart at the right most margin with empty LastDateTimestr. Just minor issue, don't care.
}
}
res = True;
}
}
return res;
}
// Call for synchronization
If (UseZoomer)
ZqZoomSync( False ); // [zq] set True will enter infinite loop if we also update ActiveDocument