Force bar array update after ticker change via OLE

AB 6.1

Hi,

My AFL changes a chart’s ticker with OLE. No backtest will be run after the change so the normal precautions about changing tickers from AFL don’t appear to apply.

To adjust the visible bar range of the chart to display a given trade, the values in the bar array returned by the DateTime() function must represent the values for the ticker displayed on the chart.

However, the DateTime() values are not updating to match the new ticker’s series. RefreshAll() doesn’t seem to help.

How can I force a refresh of the bar arrays after the ticker has been changed?

Reproducible example follows.

Many thanks!!


Step 1) Choose 2 tickers from your database. Ideally they will have different date ranges and have unequal record (bar) counts. Open up DebugView and run the AFL below while each ticker is chosen as the active chart’s current ticker (I press the “start debugging” button to accomplish this). Now you have baseline stats for the start & end dates and the number of bars in each series.

bi = BarIndex();
dt = DateTime();

_TRACE( "AmiBroker - **** " + Name() + " STATS ****" );
_TRACE( "AmiBroker - chart  " + Name() );

_TRACE( "AmiBroker - first date " + DateTimeToStr( dt[0], 0 ) );
_TRACE( "AmiBroker - last date  " + DateTimeToStr( dt[BarCount-1], 0 ) );

_TRACE( "AmiBroker - lowest bi  " + Lowest( bi ) );
_TRACE( "AmiBroker - highest bi " + Highest( bi ) );
  1. In the AFL below, enter the 2 tickers from (1) into the “symbol1” and “symbol2” variables. Hit “Apply” to create a chart with the formula. Manually set the current chart ticker to 1 of the 2 tickers chosen.

Now right-click on the formula’s chart to open the “Parameters” window and once opened, press “GO” to toggle the chart’s ticker. The chart series should now display the other ticker and the drop down box will display the other ticker as the current ticker.

When you look at the DebugView print you’ll notice the “BEFORE” and “AFTER” stats are exactly the same. The chart’s series ( retrieved by Name() ) and the bar arrays were not updated with the ticker change.


//    need all bars

SetBarsRequired( sbrAll, sbrAll );

//    set symbols for toggle

symbol1 = "Your first ticker here";
symbol2 = "Your second ticker here";

//    change chart tickers on button press
//    ( right click chart to bring up parameters window )

GO = ParamTrigger( "Change chart ticker", "GO" );

if( GO )
{
    //    toggle tickers
    
    if( Name() == symbol1 )
        ticker = symbol2;
    else
        ticker = symbol1;
        
    //    BEFORE stats
    
    bi = BarIndex();
    dt = DateTime();
    
    _TRACE( "AmiBroker - **** BEFORE ****" );
    _TRACE( "AmiBroker - ticker " + ticker );
    _TRACE( "AmiBroker - chart  " + Name() );

    _TRACE( "AmiBroker - first date " + DateTimeToStr( dt[0], 0 ) );
    _TRACE( "AmiBroker - last date  " + DateTimeToStr( dt[BarCount-1], 0 ) );

    _TRACE( "AmiBroker - lowest bi  " + Lowest( bi ) );
    _TRACE( "AmiBroker - highest bi " + Highest( bi ) );

    //    use 'ActiveDocument' to change the chart ticker

    //AB = CreateObject( "Broker.Application" );
    //AD = AB.ActiveDocument;
    //AD.Name = ticker;
    
    //    use 'ActiveWindow' to change the chart ticker
    
    AB = CreateObject( "Broker.Application" );
    AW = AB.ActiveWindow;
    AD = AW.Document;
    AD.Name = ticker;
    
    //    nothing below seems to help
    
    //AB.RefreshAll();
    //ThreadSleep( 100 );
    //WSHShell = CreateObject( "WScript.Shell" );
    //WSHShell.Sleep(500);
    //WSHShell = CreateObject( "WScript.Shell" );
    //WSHShell.AppActivate( "AmiBroker" );
    //WSHShell.Sendkeys( "{F5}" );

    //    AFTER stats
    
    bi = BarIndex();    // <-- Doesn't update after the ticker change
    dt = DateTime();    // <-- Doesn't update after the ticker change
    
    _TRACE( "AmiBroker - **** AFTER ****" );
    _TRACE( "AmiBroker - ticker " + ticker );
    _TRACE( "AmiBroker - chart  " + Name() );

    _TRACE( "AmiBroker - first date " + DateTimeToStr( dt[0], 0 ) );
    _TRACE( "AmiBroker - last date  " + DateTimeToStr( dt[BarCount-1], 0 ) );

    _TRACE( "AmiBroker - lowest bi  " + Lowest( bi ) );
    _TRACE( "AmiBroker - highest bi " + Highest( bi ) );
}

Plot( C, "", colorDefault, styleCandle );
1 Like

First of ALL: you doing big NO-NO - you should NEVER EVER use OLE calls that trigger re-execution of running AFL from the same AFL formula. It can be compared with cutting the tree branch you are sitting on. That is crazy idea to start from.

OLE is supposed to be called from the OUTSIDE only. I.e. from the outside .js or .vbs file that you run using Windows Explorer for example!

And if you change the ticker from the outside all you need to call AB.RefreshAll() from your OLE script once (not more than once per second). That is all what is really needed.

If you try to call it from the inside (people always try things that are forbidden) AmiBroker will PROTECT itself from infinite loops that such actions would cause by ignoring certain calls (like looping RefreshAll() that would cause another RefreshAll() and another and another).

1 Like

Hi @Tomasz,

Thank you. That explains it. Using RefreshAll() from external scripts has always worked in the past and I couldn’t figure out why it wasn’t working in this case…until now.

My original plan was to do this from an external script. Other things in the external script version were getting messy so I thought I’d try to do it from within AFL, where if it worked life would be much simpler.

Back to the drawing board…or IDE in this case.

David