Beispiel #1
0
def test_set_notional():
    algo = algos.SetNotional( 1000. )

    s = bt.FixedIncomeStrategy('s')

    dts = pd.date_range('2010-01-01', periods=3)
    data = pd.DataFrame(index=dts, columns=['c1', 'c2'], data=100)

    s.setup(data)
    algo(s)
    assert s.temp['notional_value'] == 1000
Beispiel #2
0
def test_rebalance_fixedincome():
    algo = algos.Rebalance()
    c1 = bt.Security('c1')
    c2 = bt.CouponPayingSecurity('c2')
    s = bt.FixedIncomeStrategy('s', children = [c1, c2])

    dts = pd.date_range('2010-01-01', periods=3)
    data = pd.DataFrame(index=dts, columns=['c1', 'c2'], data=100)
    coupons = pd.DataFrame(index=dts, columns=['c2'], data=0)
    s.setup(data, coupons=coupons)
    s.update(dts[0])
    s.temp['notional_value'] = 1000
    s.temp['weights'] = {'c1': 1}
    assert algo(s)
    assert s.value == 0.
    assert s.notional_value == 1000
    assert s.capital == -1000
    c1 = s['c1']
    assert c1.value == 1000
    assert c1.notional_value == 1000
    assert c1.position == 10
    assert c1.weight == 1.

    s.temp['weights'] = {'c2': 1}

    assert algo(s)
    assert s.value == 0.
    assert s.notional_value == 1000
    assert s.capital == -1000*100
    c2 = s['c2']
    assert c1.value == 0
    assert c1.notional_value == 0
    assert c1.position == 0
    assert c1.weight == 0
    assert c2.value == 1000*100
    assert c2.notional_value == 1000
    assert c2.position == 1000
    assert c2.weight == 1.
Beispiel #3
0
def benchmark_2():
    x = np.random.randn(10000, 1000) * 0.01
    idx = pd.date_range('1990-01-01', freq='B', periods=x.shape[0])
    data = np.exp(pd.DataFrame(x, index=idx).cumsum())
    bidoffer = data * 0.01
    coupons = data * 0.
    s = bt.FixedIncomeStrategy(
        's',
        algos=[
            bt.algos.RunMonthly(),
            bt.algos.SelectRandomly(len(data.columns) / 2),
            bt.algos.WeighRandomly(),
            bt.algos.Rebalance()
        ],
        children=[bt.CouponPayingSecurity(c) for c in data])

    t = bt.Backtest(s,
                    data,
                    additional_data={
                        'bidoffer': bidoffer,
                        'coupons': coupons
                    })
    return bt.run(t)
Beispiel #4
0
def test_RenomalizedFixedIncomeResult():
    dts = pd.date_range('2010-01-01', periods=5)
    data = pd.DataFrame(index=dts, columns=['a'], data=1.)
    data['a'][dts[0]] = 0.99
    data['a'][dts[1]] = 1.01
    data['a'][dts[2]] = 0.99
    data['a'][dts[3]] = 1.01
    data['a'][dts[4]] = 0.99

    weights = pd.DataFrame(index=dts, columns=['a'], data=1.)
    weights['a'][dts[0]] = 1.
    weights['a'][dts[1]] = 2.
    weights['a'][dts[2]] = 1.
    weights['a'][dts[3]] = 2.
    weights['a'][dts[4]] = 1.

    coupons = pd.DataFrame(index=dts, columns=['a'], data=0.)

    algos = [
        bt.algos.SelectAll(),
        bt.algos.WeighTarget(weights),
        bt.algos.SetNotional('notional'),
        bt.algos.Rebalance()
    ]
    children = [bt.CouponPayingSecurity('a')]

    s = bt.FixedIncomeStrategy('s', algos, children=children)

    t = bt.Backtest(s,
                    data,
                    initial_capital=0,
                    additional_data={
                        'notional': pd.Series(1e6, dts),
                        'coupons': coupons
                    },
                    progress_bar=False)
    res = bt.run(t)

    t = res.backtests['s']

    # Due to the relationship between the time varying notional and the prices,
    # the strategy has lost money, but price == 100, so "total return" is zero
    assert t.strategy.value < 0.
    assert t.strategy.price == 100.
    assert res.stats['s'].total_return == 0

    # Renormalizing results to a constant size "fixes" this
    norm_res = bt.backtest.RenormalizedFixedIncomeResult(
        1e6, *res.backtest_list)
    aae(norm_res.stats['s'].total_return, t.strategy.value / 1e6, 16)

    # Check that using the lagged notional value series leads to the same results
    # as the original calculation. This proves that we can re-derive the price
    # series from the other data available on the strategy
    notl_values = t.strategy.notional_values.shift(1)
    notl_values[
        dts[0]] = 1e6  # The notional value *before* any trades are put on
    norm_res = bt.backtest.RenormalizedFixedIncomeResult(
        notl_values, *res.backtest_list)

    assert norm_res.stats['s'].total_return == res.stats['s'].total_return
    assert norm_res.prices.equals(res.prices)
Beispiel #5
0
def test_Results_helper_functions_fi():

    names = ['foo', 'bar']
    dates = pd.date_range(start='2017-01-01',
                          end='2017-12-31',
                          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[names[0]] = np.random.normal(loc=0.1 / n,
                                     scale=0.2 / np.sqrt(n),
                                     size=n)
    rdf[names[1]] = np.random.normal(loc=0.04 / n,
                                     scale=0.05 / np.sqrt(n),
                                     size=n)

    pdf = 100 * np.cumprod(1 + rdf)
    notional = pd.Series(1e6, index=pdf.index)

    # algo to fire on the beginning of every month and to run on the first date
    runDailyAlgo = bt.algos.RunDaily(run_on_first_date=True)

    # algo to select all securities
    selectAll = bt.algos.SelectAll()

    # algo to set the weights
    #  it will only run when runMonthlyAlgo returns true
    #  which only happens on the first of every month
    weighRandomly = bt.algos.WeighRandomly()

    # algo to set the notional of the fixed income strategy
    setNotional = bt.algos.SetNotional('notional')

    # algo to rebalance the current weights to weights set by weighSpecified
    #  will only run when weighSpecifiedAlgo returns true
    #  which happens every time it runs
    rebalAlgo = bt.algos.Rebalance()

    # a strategy that rebalances monthly to specified weights
    strat = bt.FixedIncomeStrategy(
        'random',
        [runDailyAlgo, selectAll, weighRandomly, setNotional, rebalAlgo])

    backtest = bt.Backtest(strat,
                           pdf,
                           initial_capital=0,
                           integer_positions=False,
                           progress_bar=False,
                           additional_data={
                               'mydata': pdf,
                               'notional': notional
                           })
    bidoffer = 1.
    backtest2 = bt.Backtest(strat,
                            pdf,
                            initial_capital=0,
                            integer_positions=False,
                            progress_bar=False,
                            additional_data={
                                'mydata':
                                pdf,
                                'notional':
                                notional,
                                'bidoffer':
                                pd.DataFrame(bidoffer, pdf.index, pdf.columns)
                            })
    random.seed(1234)
    res = bt.run(backtest)
    random.seed(1234)
    res2 = bt.run(backtest2)

    assert (type(res.get_security_weights()) is pd.DataFrame)

    assert (type(res.get_transactions()) is pd.DataFrame)
    assert len(res.get_transactions()) > 0

    assert (type(res.get_weights()) is pd.DataFrame)

    # Make sure the insertion of the first row applies to additional data as well
    assert backtest.data.index.equals(backtest.additional_data['mydata'].index)

    # Check that bid/offer is accounted for
    transactions = res.get_transactions()
    transactions['price'] = transactions['price'] + 0.5 * bidoffer
    assert (res2.get_transactions().price -
            res2.get_transactions().price).abs().sum() == 0