backtesting.py icon indicating copy to clipboard operation
backtesting.py copied to clipboard

Auto-scale Y-axis for indicators graph when zooming

Open zlpatel opened this issue 4 years ago • 5 comments

Original Discussion Post: #355

There's something that I noticed which makes it difficult to view indicator graph on the chart if you're backtesting for longer period. Below is an example of an indicator view on the chart without zooming in. Notice the y axis scales. Screenshot 2021-05-21 at 4 03 16 PM

Now, when I zoom in to focus on a specific period when ttm squeeze value stayed between -5 to +5, it still shows the full scale from -15 to+20. which makes it really hard to visualize the indicator chart. See below. Screenshot 2021-05-21 at 4 09 25 PM

I know that re-scaling is allowed for the price chart/Volume. Is that something that can be implemented on the indicator charts as well?

zlpatel avatar May 22 '21 22:05 zlpatel

I fiddled around with the code and made it work :)

Here's what I did:

I have added code

indicator_max=value.df.max(axis='columns')
indicator_min=value.df.min(axis='columns')
source.add(indicator_max, f'indicator_{i}_range_max')
source.add(indicator_min,f'indicator_{i}_range_min')

right above https://github.com/kernc/backtesting.py/blob/0a76e9655f702331c4cc2a035d040d50111ce78d/backtesting/_plotting.py#L526

then,

indicator_ranges = {}
for idx,indicator in enumerate(indicator_figs):
    indicator_range_key = f'indicator_{idx}_range'
    indicator_ranges.update({indicator_range_key:indicator.y_range})
custom_js_args.update({'indicator_ranges':indicator_ranges})

right below these lines https://github.com/kernc/backtesting.py/blob/0a76e9655f702331c4cc2a035d040d50111ce78d/backtesting/_plotting.py#L610-L611

then,

if(indicator_ranges){
    let keys = Object.keys(indicator_ranges);
    for(var count=0;count<keys.length;count++){
        if(keys[count]){
            max = Math.max.apply(null, source.data[keys[count]+'_max'].slice(i, j));
            min = Math.min.apply(null, source.data[keys[count]+'_min'].slice(i, j));
            if(min && max){
                _bt_scale_range(indicator_ranges[keys[count]], min, max, true);
            }    
        }
    }
}

right below these lines https://github.com/kernc/backtesting.py/blob/0a76e9655f702331c4cc2a035d040d50111ce78d/backtesting/autoscale_cb.js#L30-L33

Here's how it looks on the graph:

Without Zooming in: Screenshot 2021-05-22 at 12 13 14 PM

When Zoomed in: Screenshot 2021-05-22 at 12 13 36 PM

zlpatel avatar May 22 '21 22:05 zlpatel

@kernc can you review my fix for this?

zlpatel avatar Jun 13 '21 20:06 zlpatel

Thank you for the great work. That is something that I was looking for and made the job. However, did you notice that it works only if the volume is plotted along (i.e. plot_volume=True)? ...or did I miss something (I'm not an experienced user).

lkfrota avatar Dec 02 '21 02:12 lkfrota

Thank you for the great work. That is something that I was looking for and made the job. However, did you notice that it works only if the volume is plotted along (i.e. plot_volume=True)? ...or did I miss something (I'm not an experienced user).

Thanks for pointing it out. I will need to figure out the dependency on volume chart and separate it from it.

zlpatel avatar Dec 13 '21 01:12 zlpatel