Sync charts for zoom and scroll


I am lloking for a way to sync 2 charts tiled horizontally such that scrolling one of them scrols the other as well, I tried zoomer ( but it slows the system down. Is there a better way?


@waverider I am not sure how to get what you want (or what you actually want) but I am picking up orphaned posts this evening.

Have you tried Symbol link and/or Interval link? Some resources for review that may help.


Imagine two chart windows one has cboe symbol selected and the other one has es symbol selected. Both are of 1 minute interval. Now tile them horizontally. I am looking for a way by which if I scroll the first chart the second chart scrolls along with it.


@waverider Maybe it is not exactly what you have asked for, but there is a very simple way in which you can achieve similar result without any hassle or drop in performance.

Instead of opening two (or more) separate charts and tiling them horizontally, you can display the second, third etc. chart in the first chart’s pane - like this:


Use SetForeign() or PlotForeign() to plot the chart of another Symbol(s). You should use the most liquid (most traded) Issue as the base symbol, to avoid data holes.

Perfect syncing of all charts guarenteed without any drop of performance!


Thanks for suggesting that. I am using that in my charts with the index instrument as foreign. Although i have only one scale on the right.


That’s because you probably use only one chart pane, not two or more as I suggested. Take a look at these two short videos:


This is very usefull. Thank you.


I have the same need, that I am guessing @Jefforey may be requesting.
Essentially, a synchronized zoom and scroll across multiple chart WINDOWS, (not panes).
Amibroker already supports syncing Symbol and Intervals across charts. Why not Zoom?

So for example, the date ranges displayed across all displayed charts would remain in sync.


Thanks to @PanoS and a somewhat ancient piece of Amibroker code, I discovered the AFL formula that enables a user to Synchronize Charts for Zoom and Scroll. The formula has been included in the Sync charts +zoom posting.


Here is the code that can be used to Synchronize charts and zoom.

Put this AFL in the Include Folder.
Add below 2 lines into your AFL
  UseZoomer = ParamToggle("Use Zoomer?", "No|Yes", 0);
  #include_once <>
  Sourcecode downloaded from:

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