Additionally, I found that self.datas[0]._name does not exist with Oanda, but there is self.datas[0]._dataname. And vice versa, so depending on my data source, I have to use different code. Would it be possible to have an attribute for all data sources (IB, VC, Oanda, Pandas etc.) with the same name, holding the name of the instrument?

The only other way is for me to write a getname() method that returns either _name or _dataname based on the data source, right?

The canonical name was getcash (and also getvalue) but along the way the simulation broker got the aliases get_cash and get_value. The latest commit in the development branch supports always filling in a _name if none was provided by the user and adding the get_cash and get_value aliases if missing in broker subclasses.

Do you maybe have plans to tune the performance for subscribing to 100 instruments? Or should I try to take care of it and feed my data to my strategy?

100 or 1000 instruments in backtesting mode should be no problem because the data feeds are (there could be exceptions) taken from frozen data and provide prices when requested to.

Without knowing what the actual json decoder error above is (and what causes it) there is not an actual performance to be tuned. The explanation:

Many platforms choose a 100% event oriented approach. A tick comes in, a tick is delivered. If you have 70 instruments, there will be 70 ticks.

To overcome this, some platforms add this constraint:

Only deliver ticks every x milliseconds. This buffers some of the ticks and reduces the number of calls, but obviously delays some of the ticks. But the delivery is not tied to the resampling target

backtrader takes another approach which favors working with (so to say) resampled data rather than ticks. Considering a 1-minute timeframe, backtrader resamples all data feeds to the 1-minute timeframe and delivers all of them at the same time, because it is synchronizing the data feeds.