Synchronize charts for scroll and zoom (functional) - OLE

Hi everyone! I have two windows open that are linked to the same symbol:

Window 1 in Daily Timeframe
Window 2 in 5min Timeframe

When I click anywhere on Window 1, is there any way to have Amibroker move to the visible area of this date in Window 2? It only moves my selection and so everytime I have to scroll back or forward to find this selection in Window 2. Is there a way to move there right away?

I wrote the following code for Window 2, but SelectedValue(DateNum()) does not go outside of the visible area when it is selected in Window 1:

procedure ZoomChart( Begindate, Enddate )
{
   AB = CreateObject("Broker.Application");
   AW = AB.ActiveWindow;
   AW.ZoomToRange( Begindate, Enddate );
}

id = GuiGetEvent( 0, 0 );
event = GuiGetEvent( 0, 1 );

GuiButton( "inDaily Date", 24, 10, 60, 155, 30, 7 );
if( id == 24 && event == 1 )
{
	BeginZoom0 = DateTimeConvert( 2, SelectedValue(DateNum()), SelectedValue(TimeNum()) );
	BeginZoom = DateTimeToStr(DateTimeConvert( 2, SelectedValue(DateNum()), SelectedValue(TimeNum()) ));
	EndZoom = DateTimeToStr( DateTimeAdd( BeginZoom0, 20, inDaily ) );
	
	_TRACE(""+BeginZoom);
	_TRACE(""+EndZoom);

}

Below afl is tested and working for zoom and Synchronize charts
Here is the code that can be used to Synchronize charts and zoom.
just remeber that you have to insert the afl to ONLY one chart

@trongart Note that, also what you are asking to do can be accomplished with gfx
Study this code and I think will be fine. If you write the gfx version come here to share with us.

/*<Usage>
Here is the code that Synchronize charts and zoom.
just remeber that you have to insert the afl to ONLY one chart 
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
UseZoomer = ParamToggle( "Use Zoomer?", "No|Yes", 0 );

if ( UseZoomer )
    ZqZoomSync( False );


8 Likes

Hi
I try to delete my first reply, as some of the afl code was missing, but not luck.
Always please check the second reply.

History of the function
The first Thanks goes to BruceR for the function
Originally Function was made 10 years ago By Bruce R.
The truth is since then many other users involve and modify this Function to synchronise zoom and scrolling charts

Thank you very much for sharing this! Works great!

1 Like