Skip to content

BT seems unable to composite three or more layers strategy, ZeroDivisionError #433

@tunkills

Description

@tunkills

When I only composite two layers strategy,it woks well, but when I add more layer strategy,such as there is a grandson strategy, threre is something wrong!
"ZeroDivisionError: Could not update third on 2017-01-02 00:00:00. Last value was 0 and net flows were 0. Currentvalue is 1000000.0. Therefore, we are dividing by zero to obtain the return for the period."


import numpy as np
import pandas as pd
import bt
import warnings


warnings.simplefilter('ignore', FutureWarning)
warnings.simplefilter('ignore', UserWarning)


# create fake index data

names = ['foo', 'bar', 'rf']

dates = pd.date_range('20170101', '20171231', freq=pd.tseries.offsets.BDay())
n = len(dates)

rdf = pd.DataFrame(np.zeros((n, len(names))), index=dates, columns=names)

np.random.seed(1)
rdf['foo'] = np.random.normal(loc=0.1/n, scale=0.2/np.sqrt(n), size=n)
rdf['bar'] = np.random.normal(loc=0.04/n, scale=0.05/np.sqrt(n), size=n)
rdf['rf'] = 0.0

pdf = 100 * np.cumprod(1+rdf)

# composite three layer strategy
weights = pd.Series([0.6, 0.2, 0.1], index=rdf.columns)
strat = bt.Strategy('static',
                    [bt.algos.RunMonthly(run_on_first_date=True),
                     bt.algos.WeighSpecified(**weights),
                     bt.algos.Rebalance()]
                    )

second_strat = bt.Strategy('second',
                           [bt.algos.RunMonthly(run_on_first_date=True),
                            bt.algos.SelectAll(),
                            bt.algos.WeighEqually(),
                            bt.algos.Rebalance()],
                           children=[strat, 'foo'])

third_strat = bt.Strategy('third',
                          [bt.algos.RunMonthly(run_on_first_date=True),
                           bt.algos.SelectAll(),
                           bt.algos.WeighEqually(),
                           bt.algos.Rebalance()],
                          children=[second_strat, 'bar'])
third_bk = bt.Backtest(third_strat, pdf, integer_positions=False)
third_re = bt.run(third_bk)

``

File "bt/core.py", line 777, in bt.core.StrategyBase.update

ZeroDivisionError: Could not update third on 2017-01-02 00:00:00. Last value was 0 and net flows were 0. Currentvalue is 1000000.0. Therefore, we are dividing by zero to obtain the return for the period.
`

I find the problem may be caused by


class StrategyBase(Node):
......
    @cy.locals(
        newpt=cy.bint,
        val=cy.double,
        ret=cy.double,
        coupons=cy.double,
        notl_val=cy.double,
        bidoffer_paid=cy.double,
    )
    def update(self, date, data=None, inow=None):
    .......
     # update paper trade if necessary
        if self._paper_trade:
            if newpt:
                self._paper.update(date)
                self._paper.run()
                self._paper.update(date)
            # update price
            self._price = self._paper.price
            self._prices.values[inow] = self._price`

when I comment out the lines “if self._paper_trade:” and below, it works well.
But I'm not sure if this modification will cause other issues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions