Manual stepping of cerebro



  • Hi,
    I very much need to have cerebro step (ie send the next datafeed line) from another piece of code.
    Ideally I would like to not call cerebro.run(), but cerebro.step() at my convenience.

    I looked around but couldn't find any easy way to hack something like the IBData feed (wich is live) and the Pandas data feed (which reads Pandas frames, but get's iterated through by cerebro as I call run).
    Would there be an example around?

    thank you for this great project


  • administrators

    @gquantcoder said in Manual stepping of cerebro:

    I would like to not call cerebro.run(), but cerebro.step() at my convenience

    It is a nice wish but it cannot be really realized as such. The core aims at being able to service data feeds which also need to talk to let the resampler know a cycle has come to an end, so the system needs to wake up at given intervals to deliver resampled bars in live data feeds.

    This is of course not an obstacle in pure backtesting, because there is no real-time clock in use, but it would mean that backtrader would have two different running systems.

    The most obvious approach is to develop your own data feed (as you seem to be suggesting). There is documentation on how to approach it

    One example probably worth looking into might be feeds/blaze.py in the sources. This expects the iterator to be a cursor to a database (it could be actually anything) and loads the appropriate columns into the corresponding lines.



  • Thank you for your reply,

    It is unclear to me how to make the blaze data feed into a "live" one (which could then push data as needed).

    What about adding a moc-strategy in cerebro, and this strategy would block the process until an external signal would free it, making cerebro cycle once through the actual strategies and being blocked again as it enters the moc-strategy.

    But I would prefer making a "live" datafeed. The documentation doesn't explain how to make one. If I had a clue I could start modifying the blaze datafeed accordingly.

    Thanks


  • administrators

    The `blazeĀ“ data feed takes data from the iterator. When queried ... an iterator doesn't have an obligation to immediately return. It can block until it decides to return data.

    Rather than thinking about "pushing data", you consider that you block until you want to return the data, which is effectively the same thing.

    You simply then need to implement a source which implements the iterator protocol (__iter__ or the __len__ / __getitem__ combination). The collections Abstract Base Classes provide most of the machinery you may ever need by simply providing a single method.

    Your other option is to do something like Oanda.

    • When _load is called you return

      • True if you have filled the buffers

      • False if the data source is exhausted

      • None (periodically) to let other elements, like the resampler, decide if a resampled bar has to be returned because the real time clock has gone over a boundary.

        There is no obligation to return None if you are only backtesting or you have no plans to mix multiple datas, but you will cooperate best with the other elements if you do.

      • The periodicity is controlled in this case with a queue.Queue which raises an Exception after a period qget if no message from the actual data source (probably running in a background thread) has arrived.

    • You also override the method live to return True. Although this only plays a role in a real connection to real live feeds And since your goal is to step, you probably don't need this.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.