美文网首页
10.1 Observers and Statistics

10.1 Observers and Statistics

作者: wanggs66 | 来源:发表于2020-04-28 22:18 被阅读0次

    Observers 是backtrader中通过手机相关信息用于统计目的观察变量,可以在plot中展示,常见的plot中通常包含3类Observers :

    • Cash and Value (what’s happening with the money in the broker)

    • Trades (aka Operations)

    • Buy/Sell Orders

    在Cerebro中将stdstats 设置为True时,plot会自动添加这三类Observers

    Example:

    import backtrader as bt
    
    ...
    
    cerebro = bt.Cerebro()  # default kwarg: stdstats=True
    
    cerebro.addobserver(bt.observers.Broker)
    cerebro.addobserver(bt.observers.Trades)
    cerebro.addobserver(bt.observers.BuySell)
    

    Accessing the Observers

    可以通过self.stats.observers的方式访问

    Observer Implementation

    The implementation is very similar to that of an Indicator:

    class Broker(Observer):
        alias = ('CashValue',)
        lines = ('cash', 'value')
    
        plotinfo = dict(plot=True, subplot=True)
    
        def next(self):
            self.lines.cash[0] = self._owner.broker.getcash()
            self.lines.value[0] = value = self._owner.broker.getvalue()
    

    Steps:

    • Derive from Observer (and not from Indicator)

    • Declare lines and params as needed (Broker has 2 lines but no params)

    • There will be an automatic attribute _owner which is the strategy holding the observer

    Observers come in action:

    • After all Indicators have been calculated

    • After the Strategy next method has been executed

    • That means: at the end of the cycle … they observe what has happened 在其他操作执行结束之后, Observers 观察记录发生了什么

    In the Broker case it’s simply blindly recording the broker cash and portfolio values at each point in time.

    Developing Observers

    To produce a meaningful observer, the implementation can use the following information:

    • self._owner is the currently strategy being executed

    As such anything within the strategy is available to the observer

    • Default internal things available in the strategy which may be useful:
      • broker -> attribute giving access to the broker instance the strategy creates order against

    As seen in Broker, cash and portfolio values are collected by invoking the methods getcash and getvalue

    • _orderspending -> list orders created by the strategy and for which the broker has notified an event to the strategy.
      The BuySell observer traverses the list looking for orders which have executed (totally or partially) to create an average execution price for the given point in time (index 0)

    • _tradespending -> list of trades (a set of completed buy/sell or sell/buy pairs) which is compiled from the buy/sell orders

    An Observer can obviously access other observers over the self._owner.stats path.

    Example: Custom OrderObserver

    import math
    
    import backtrader as bt
    
    
    class OrderObserver(bt.observer.Observer):
        lines = ('created', 'expired',)
    
        plotinfo = dict(plot=True, subplot=True, plotlinelabels=True)
    
        plotlines = dict(
            created=dict(marker='*', markersize=8.0, color='lime', fillstyle='full'),
            expired=dict(marker='s', markersize=8.0, color='red', fillstyle='full')
    )
    
        def next(self):
            for order in self._owner._orderspending:
                if order.data is not self.data:
                    continue
    
                if not order.isbuy():
                    continue
    
                # Only interested in "buy" orders, because the sell orders
                # in the strategy are Market orders and will be immediately
                # executed
    
                if order.status in   [bt.Order.Accepted, bt.Order.Submitted]:
                    self.lines.created[0] = order.created.price
    
                elif order.status in [bt.Order.Expired]:
                    self.lines.expired[0] = order.created.price
    

    Saving/Keeping the statistics

    As of now backtrader has not implemented any mechanism to track the values of observers storing them into files. The best way to do it:

    • Open a file in the start method of the strategy

    • Write the values down in the next method of the strategy

    Considering the DrawDown observer, it could be done like this

    class MyStrategy(bt.Strategy):
    
        def start(self):
    
            self.mystats = open('mystats.csv', 'wb')
            self.mystats.write('datetime,drawdown, maxdrawdown\n')
    
        def next(self):
                self.mystats.write(self.data.datetime.date(0).strftime('%Y-%m-%d'))
            self.mystats.write(',%.2f' % self.stats.drawdown.drawdown[-1])
            self.mystats.write(',%.2f' % self.stats.drawdown.maxdrawdown-1])
            self.mystats.write('\n')

    相关文章

      网友评论

          本文标题:10.1 Observers and Statistics

          本文链接:https://www.haomeiwen.com/subject/bqavwhtx.html