You load the 4000+ tickers, run your indicators on them (a single GenericCSVData would be enough for each, here the assumption is that all of them have the same format)
For example those with the larger positive distance: close - SimpleMovingAverage
You do something with the top 10 (print out the names for example)
Case 2: 1 data feed with 4000+ price columns
You create an extended data feed with 4000+ lines (for example with the names close0001, close0002 ...)
You run individual indicators on each of the closesABCD: close0001 - bt.ind.SMA(close0001)
You keep the top 10 and print them out (index based for example)
Although the 2nd case can for sure be fully automated with for loops and is probably less expensive in terms of memory and CPU, it seems not as clear as the 1st one.
putting the order.cancel in order. accepted / submitted
As stated in the answer above. The right place is Completed. Using any of the ones mentioned above guarantees that you will be cancelling the other bracket immediately, yes or yes (unless there isn't cash enough and you receive a Margin)
I manually cross-checked the number and they seem fine for all dates but the last , i.e. 31st of January 2011. To get to the result given by the analyzer I need to compute the result from the close of 31/12/2010 to the close of 28/01/2011. Why the last day isn't taken into account? I cheat-on-open so everything should be after the close.
It seems your data would end on 2011-01-28. The analyzer doesn't know your data ends there ... and the end of the montha and/or next month has not been seen. It can only calculate it when stopping (stop method) and you can therefore only see that in the corresponding strategy stop method.
The summary: you are trying to reuse a Cerebro for the execution of the same Strategy on different data sets.
You need 2 execution runs and in each you add the appropriate data feed to the system. After run a cerebro instance holds all the strategies, datas, analyzers and indicators after they have come to the last point. The instance is not meant to run again with a different data feed.
Create another cerebro instance (given it is the same strategy, a loop make sense)
I know I can extend a datafeed, but is it possible to do that with multiple?
If you know how to extend (subclass) a data feed, you can in fact create as many subclasses (extension) of a data feed as needed to support your custom lines. The limits are set by your available RAM (whether Python has a limit on the actual number of user defined classes ... unknown) and CPU time.
After the different findings in this topic, the following will be the final commit
The original behavior for the v7 feed will be retained
A new parameter named swapcloses (default: False) will be added
If swapcloses=True the allegedly adjusted and non-adjusted closing prices will be swapped, which will allow to place them in the right column.
There seems to be no clear pattern to decide when Yahoo will be returning the adjusted price or the unadjusted (leaving aside that as seen above, sometimes it is impossible to reconstruct the prices with the given values)
Even if not obvious, a 2 liner of the original data (you can fake it if you wish) would be key to actually try to reproduce your behavior.
All those ipdb statements are only confusing, giving information about many things which have nothing to do with the potential problem.
In any case this is probably due to a recent pull request was issued to remove the usage of ix (deprecated in the latest versions of Pandas), which is replaced with either loc (label based) or iloc (numeric based) and which didn't catch all use cases (In most occasions the datetime timestamps are the index of the dataframe)
The latest development commit contains some code to correct the situation and simplify the autodetection: