An extra fix has been pushed to the development branch, because @randyt also checked it out and found a typo in the part which services historical data downloads between 2 dates (the part initially tested, downloads as much as possible and not between two given dates, which may happend during a disconnection/reconnection cycle)
Since you have subclassed Sizer (or SizerBase, which is the same), you control any extra interfaces/methods which may help you in the querying.
With that in mind, the Sizer concept was developed with the other direction in mind and that's why inside the Sizer there is a strategy member attribute, which allows the sizer to query whatever interfaces the strategy may have. The rationale behind that: abstracting the Strategy from any logic related to position sizing, allowing it to concentrate on the logic of entering/exiting the market.
That would mean that there are actually no transactions happening during those seconds. With 2 possibilities in mind:
You have joined the data feed during a not so active market phase
You are testing against the demo account setup of TWS
Take into account that the data feed provided by IB for Forex is not like the data feed for equities, for example. Appearances of the BID price will be recorded as the indication for price oscillation. This is what also others do.
In any case you may also run the sample with --debug and you will have the chance to see all messages delivered by TWS to your client (literally all), which may help you follow the details of the price formation in Forex
You may change BID to ASK or MID (check the IB documentation for possible values) by manipulating the what parameter during the creation of an IBData data feed in backtrader.
As mentioned by @ab_trader orders are executed on the same bar if you set coc=True in the broker. If not the bar is considered closed and order execution is deferred until the next bar. Two orders issued on the same bar with Market execution policy should be executed also on the same bar (be it the next or the current bar)
The system does a check of submitted orders before accepting them. To avoid for example having 2 consecutive orders which would go over the actual cash reserves on the same bar. If tries to take into account that if a long position is closed cash will be re-injected into the system to let you operate with another buy.
Deactivation of the check can be achieved in the broker with checksubmit=False
Sizers are called internally by buy and sell (close uses the actual existing position) but a Sizer can be subclassed to provide complex functionality.
It's not fool proof. Use safediv offers you an option to still use the Stochastic on data which is not probable meant for.
The safediv parameter plays together with safezero which has a default value of 0.0. This is a choice and can be changed by you. Because once you enter in the territory of indetermination, assigning a value to an operation which hasn't got a value means making a compromise.
There isn't documentation as such, given the differences found in different platforms.
Oanda (https://www.oanda.com) was the last integration and was at the same time an effort to try to streamline the interfaces and make it as generic as possible. I would have a look at it.
But being your provider Windows based and with OCX in play I guess you'll have to play with comtypes. Although there are, at least, 2 major COM Windows implementations, you are basically on your own. Visual Chart (https://www.visualchart.com) is also Windows based and uses COM and the following still holds:
win32com (pywin32) launched OutOfMemoryError exceptions because it wouldn't fully understand a type.
Although the type was properly decoded, it was clearly going to be a headache and meant fiddling directly with C++ for any needed modification (the major problem being other people compiling pywin32 from scratch or installing a DLL from a non-trusted source, not to mention the lack of proper support for GCC based compilers under Windows that Python exhibits)
comtypes being pure Python was more up to the task of being a target. It still failed to properly decode complex arrays, so a fork of comptypes was needed for full support.
They are plotted. The problem arises because matplotlib makes assumptions about situations where the difference between the top and bottom of a plot is too small and could lead to problems.
The plot below plots the BuySell observer on a different axis to make it clear: I am here. But cannot be seen with the data. The right axis ticks (Y) show values like 3.5 and the top of the axis (already inside the observer) indicates that everything has to be multiplied by 1000 (3.065e3)
The scale is wrong obviously because it goes from 0 to 3.065
As explained above order importing is not a feature of the the platform.
If you have the data in that format:
there are several approaches:
Make a custom data feed with it containing only 2 fields
trigger (or any other name you wish)
In this case you would add the data feed to the system and could at each moment in time and synchronized with the data read if an order has to be executed or not
Read that input with something like a pandas.read_csv module and during each call to next in the strategy, look for the corresponding datetime index in the dataframe to see if an order has to be executed or not.