Exemplo n.º 1
0
def test_weigh_inv_vol():
    algo = algos.WeighInvVol(lookback=pd.DateOffset(days=5))

    s = bt.Strategy('s')

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

    # high vol c1
    data['c1'].ix[dts[1]] = 105
    data['c1'].ix[dts[2]] = 95
    data['c1'].ix[dts[3]] = 105
    data['c1'].ix[dts[4]] = 95

    # low vol c2
    data['c2'].ix[dts[1]] = 100.1
    data['c2'].ix[dts[2]] = 99.9
    data['c2'].ix[dts[3]] = 100.1
    data['c2'].ix[dts[4]] = 99.9

    s.setup(data)
    s.update(dts[4])
    s.temp['selected'] = ['c1', 'c2']

    assert algo(s)
    weights = s.temp['weights']
    assert len(weights) == 2
    assert weights['c2'] > weights['c1']
    aae(weights['c1'], 0.020, 3)
    aae(weights['c2'], 0.980, 3)
Exemplo n.º 2
0
def test_weigh_inv_vol():
    algo = algos.WeighInvVol(lookback=pd.DateOffset(days=5))

    s = bt.Strategy('s')

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

    # high vol c1
    data['c1'].ix[dts[1]] = 105
    data['c1'].ix[dts[2]] = 95
    data['c1'].ix[dts[3]] = 105
    data['c1'].ix[dts[4]] = 95

    # low vol c2
    data['c2'].ix[dts[1]] = 100.1
    data['c2'].ix[dts[2]] = 99.9
    data['c2'].ix[dts[3]] = 100.1
    data['c2'].ix[dts[4]] = 99.9

    s.setup(data)
    s.update(dts[4])
    s.temp['selected'] = ['c1', 'c2']

    assert algo(s)
    weights = s.temp['weights']
    assert len(weights) == 2
    assert weights['c2'] > weights['c1']
    aae(weights['c1'], 0.020, 3)
    aae(weights['c2'], 0.980, 3)
Exemplo n.º 3
0
def test_weigh_inv_vol():
    algo = algos.WeighInvVol(lookback=pd.DateOffset(days=5))

    s = bt.Strategy("s")

    dts = pd.date_range("2010-01-01", periods=5)
    data = pd.DataFrame(index=dts, columns=["c1", "c2"], data=100.0)

    # high vol c1
    data["c1"].ix[dts[1]] = 105
    data["c1"].ix[dts[2]] = 95
    data["c1"].ix[dts[3]] = 105
    data["c1"].ix[dts[4]] = 95

    # low vol c2
    data["c2"].ix[dts[1]] = 100.1
    data["c2"].ix[dts[2]] = 99.9
    data["c2"].ix[dts[3]] = 100.1
    data["c2"].ix[dts[4]] = 99.9

    s.setup(data)
    s.update(dts[4])
    s.temp["selected"] = ["c1", "c2"]

    assert algo(s)
    weights = s.temp["weights"]
    assert len(weights) == 2
    assert weights["c2"] > weights["c1"]
    aae(weights["c1"], 0.020, 3)
    aae(weights["c2"], 0.980, 3)
Exemplo n.º 4
0
def test_weigh_randomly():
    s = bt.Strategy('s')
    s.temp['selected'] = ['c1', 'c2', 'c3']

    algo = algos.WeighRandomly()
    assert algo(s)
    weights = s.temp['weights']
    assert len( weights ) == 3
    assert sum( weights.values() ) == 1.

    algo = algos.WeighRandomly( (0.3,0.5), 0.95)
    assert algo(s)
    weights = s.temp['weights']
    assert len( weights ) == 3
    aae( sum( weights.values() ), 0.95 )
    for c in s.temp['selected']:
        assert weights[c] <= 0.5
        assert weights[c] >= 0.3
Exemplo n.º 5
0
def test_strategy_tree_paper():
    dts = pd.date_range('2010-01-01', periods=3)
    data = pd.DataFrame(index=dts, columns=['a'], data=100.)
    data['a'].ix[dts[1]] = 101
    data['a'].ix[dts[2]] = 102

    s = Strategy('s', [
        bt.algos.SelectWhere(data > 100),
        bt.algos.WeighEqually(),
        bt.algos.Rebalance()
    ])

    m = Strategy('m', [], [s])
    s = m['s']

    m.setup(data)
    m.update(dts[0])
    m.run()

    assert m.price == 100
    assert s.price == 100
    assert s._paper_trade
    assert s._paper.price == 100

    s.update(dts[1])
    m.run()

    assert m.price == 100
    assert m.value == 0
    assert s.value == 0
    assert s.price == 99.9901

    s.update(dts[2])
    m.run()

    assert m.price == 100
    assert m.value == 0
    assert s.value == 0
    aae(s.price, 100.9801, 4)
Exemplo n.º 6
0
def test_strategy_tree_paper():
    dts = pd.date_range('2010-01-01', periods=3)
    data = pd.DataFrame(index=dts, columns=['a'], data=100.)
    data['a'].ix[dts[1]] = 101
    data['a'].ix[dts[2]] = 102

    s = Strategy('s',
                 [bt.algos.SelectWhere(data > 100),
                  bt.algos.WeighEqually(),
                  bt.algos.Rebalance()])

    m = Strategy('m', [], [s])
    s = m['s']

    m.setup(data)
    m.update(dts[0])
    m.run()

    assert m.price == 100
    assert s.price == 100
    assert s._paper_trade
    assert s._paper.price == 100

    s.update(dts[1])
    m.run()

    assert m.price == 100
    assert m.value == 0
    assert s.value == 0
    assert s.price == 99.9901

    s.update(dts[2])
    m.run()

    assert m.price == 100
    assert m.value == 0
    assert s.value == 0
    aae(s.price, 100.9801, 4)
Exemplo n.º 7
0
def test_strategybase_tree_decimal_position_rebalance():
    c1 = SecurityBase('c1')
    c2 = SecurityBase('c2')
    s = StrategyBase('p', [c1, c2])
    s.use_integer_positions(False)

    c1 = s['c1']
    c2 = s['c2']

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

    s.setup(data)

    i = 0
    s.update(dts[i], data.ix[dts[i]])

    s.adjust(1000.2)
    s.rebalance(0.42, 'c1')
    s.rebalance(0.58, 'c2')

    aae(c1.value, 420.084)
    aae(c2.value, 580.116)
    aae(c1.value + c2.value, 1000.2)
Exemplo n.º 8
0
def test_strategybase_tree_rebalance_level2():
    c1 = SecurityBase('c1')
    c12 = copy.deepcopy(c1)
    c2 = SecurityBase('c2')
    c22 = copy.deepcopy(c2)
    s1 = StrategyBase('s1', [c1, c2])
    s2 = StrategyBase('s2', [c12, c22])
    m = StrategyBase('m', [s1, s2])

    s1 = m['s1']
    s2 = m['s2']

    c1 = s1['c1']
    c2 = s1['c2']

    c12 = s2['c1']
    c22 = s2['c2']

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

    m.setup(data)

    i = 0
    m.update(dts[i], data.ix[dts[i]])

    m.adjust(1000)

    assert m.value == 1000
    assert m.capital == 1000
    assert s1.value == 0
    assert s2.value == 0
    assert c1.value == 0
    assert c2.value == 0

    # now rebalance child s1 - since its children are 0, no waterfall alloc
    m.rebalance(0.5, 's1')

    assert s1.value == 500
    assert m.capital == 1000 - 500
    assert m.value == 1000
    assert s1.weight == 500.0 / 1000
    assert s2.weight == 0

    # now allocate directly to child of child
    s1.rebalance(0.4, 'c1')

    assert s1.value == 499
    assert s1.capital == 500 - 201
    assert c1.value == 200
    assert c1.weight == 200.0 / 499
    assert c1.position == 2

    assert m.capital == 1000 - 500
    assert m.value == 999
    assert s1.weight == 499.0 / 999
    assert s2.weight == 0

    assert c12.value == 0

    # now rebalance child s1 again and make sure c1 also gets proportional
    # increase
    m.rebalance(0.8, 's1')
    assert s1.value == 798.2
    aae(m.capital, 199.8, 1)
    assert m.value == 998
    assert s1.weight == 798.2 / 998
    assert s2.weight == 0
    assert c1.value == 300.0
    assert c1.weight == 300.0 / 798.2
    assert c1.position == 3

    # now rebalance child s1 to 0 - should close out s1 and c1 as well
    m.rebalance(0, 's1')

    assert s1.value == 0
    assert m.capital == 997
    assert m.value == 997
    assert s1.weight == 0
    assert s2.weight == 0
    assert c1.weight == 0
Exemplo n.º 9
0
def test_strategybase_prices():
    dts = pd.date_range('2010-01-01', periods=21)
    rawd = [13.555, 13.75, 14.16, 13.915, 13.655,
            13.765, 14.02, 13.465, 13.32, 14.65,
            14.59, 14.175, 13.865, 13.865, 13.89,
            13.85, 13.565, 13.47, 13.225, 13.385,
            12.89]
    data = pd.DataFrame(index=dts, data=rawd, columns=['a'])

    s = StrategyBase('s')
    s.setup(data)

    # buy 100 shares on day 1 - hold until end
    # just enough to buy 100 shares + 1$ commission
    s.adjust(1356.50)

    s.update(dts[0])
    # allocate all capital to child a
    # a should be dynamically created and should have
    # 100 shares allocated. s.capital should be 0
    s.allocate(s.value, 'a')

    assert s.capital == 0
    assert s.value == 1355.50
    assert len(s.children) == 1
    aae(s.price, 99.92628, 5)

    a = s['a']
    assert a.position == 100
    assert a.value == 1355.50
    assert a.weight == 1
    assert a.price == 13.555
    assert len(a.prices) == 1

    # update through all dates and make sure price is ok
    s.update(dts[1])
    aae(s.price, 101.3638, 4)

    s.update(dts[2])
    aae(s.price, 104.3863, 4)

    s.update(dts[3])
    aae(s.price, 102.5802, 4)

    # finish updates and make sure ok at end
    for i in range(4, 21):
        s.update(dts[i])

    assert len(s.prices) == 21
    aae(s.prices[-1], 95.02396, 5)
    aae(s.prices[-2], 98.67306, 5)
Exemplo n.º 10
0
 def test_endpoints(self):
     self.check('/logviewer/')
     self.check('/logviewer/query/', code=404)
     # check query endpoints
     spec = self.get_keywith(conf.url, 'apps/logviewer/query-')
     base = '/logviewer/query/aggD'
     df = self.df
     df_user1 = df['user.id_1'].eq(1)
     df_uri1 = df['uri_1'].eq(1)
     # check filters
     for col in ['status', 'ip']:
         eq_(self.get('{}/filter{}/'.format(base, col)).json(),
             [{col: x} for x in sorted(df[col].unique())]
             )
     eq_(self.get('{}/filter{}/'.format(base, 'users')).json(),
         [{'user.id': x} for x in
          sorted(df[df_user1]['user.id'].unique())]
         )
     eq_(self.get('{}/filter{}/'.format(base, 'uri')).json(),
         (df[df_uri1]['uri'].value_counts()
          .astype(int)
          .rename_axis('uri').reset_index(name='views')
          .sort_values(by=['views', 'uri'], ascending=[False, True])[:100]
          .to_dict('r'))
         )
     # check KPIs
     eq_(self.get('{}/kpi-{}/'.format(base, 'pageviews')).json(),
         [{'value': len(df[df_uri1].index)}]
         )
     eq_(self.get('{}/kpi-{}/'.format(base, 'sessions')).json(),
         [{'value': df[df_user1]['new_session'].sum()}]
         )
     eq_(self.get('{}/kpi-{}/'.format(base, 'users')).json(),
         [{'value': df[df_user1]['user.id'].nunique()}]
         )
     eq_(self.get('{}/kpi-{}/'.format(base, 'urls')).json(),
         [{'value': df[df_uri1]['uri'].nunique()}]
         )
     r = self.get('{}/kpi-{}/'.format(base, 'avgtimespent')).json()
     aae(r[0]['value'],
         df[df_user1]['session_time'].sum() / df[df_user1]['new_session'].sum(),
         4)
     r = self.get('{}/kpi-{}/'.format(base, 'avgloadtime')).json()
     aae(r[0]['value'], df['duration'].mean(), 4)
     # check top10
     topten = [{'col': 'user.id', 'url': 'users', 'values': 'views', 'flag': True},
               {'col': 'ip', 'url': 'ip', 'values': 'requests'},
               {'col': 'status', 'url': 'status', 'values': 'requests'},
               {'col': 'uri', 'url': 'uri', 'values': 'views', 'flag': True}]
     for top in topten:
         cond = (df[top['col'] + '_1'].eq(1)
                 if top.get('flag') else slice(None))
         eq_(self.get('{}/topten{}/'.format(base, top['url'])).json(),
             (df[cond][top['col']].value_counts()
             .astype(int)
             .rename_axis(top['col']).reset_index(name=top['values'])
             .sort_values(by=[top['values'], top['col']],
                          ascending=[False, True])[:10]
             .to_dict('r'))
             )
     # check trend
     dff = logviewer.pdagg(df[df_uri1],
                           [{'key': 'time', 'freq': 'D'}],
                           {'duration': ['count']})
     dff['time'] = dff['time'].dt.strftime('%Y-%m-%d 00:00:00')
     dff['pageviews'] = dff['duration_count'].astype(int)
     dff = dff[dff['pageviews'].ne(0)]
     eq_(self.get('{}/{}/'.format(base, 'pageviewstrend')).json(),
         dff.drop('duration_count', 1).to_dict('r')
         )
     dff = logviewer.pdagg(df[df_user1],
                           [{'key': 'time', 'freq': 'D'}],
                           {'new_session': ['sum']})
     dff['time'] = dff['time'].dt.strftime('%Y-%m-%d 00:00:00')
     dff['sessions'] = dff['new_session_sum'].astype(int)
     dff = dff[dff['sessions'].ne(0)]
     eq_(self.get('{}/{}/'.format(base, 'sessionstrend')).json(),
         dff.drop('new_session_sum', 1).query('sessions != 0').to_dict('r')
         )
     # TODO trend queries
     for q in spec.kwargs.kwargs.queries.keys():
         if q.endswith('trend'):
             self.check('{}/{}/'.format(base, q))
Exemplo n.º 11
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)
Exemplo n.º 12
0
def test_strategybase_tree_rebalance_level2():
    c1 = SecurityBase('c1')
    c12 = copy.deepcopy(c1)
    c2 = SecurityBase('c2')
    c22 = copy.deepcopy(c2)
    s1 = StrategyBase('s1', [c1, c2])
    s2 = StrategyBase('s2', [c12, c22])
    m = StrategyBase('m', [s1, s2])

    s1 = m['s1']
    s2 = m['s2']

    c1 = s1['c1']
    c2 = s1['c2']

    c12 = s2['c1']
    c22 = s2['c2']

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

    m.setup(data)

    i = 0
    m.update(dts[i], data.ix[dts[i]])

    m.adjust(1000)

    assert m.value == 1000
    assert m.capital == 1000
    assert s1.value == 0
    assert s2.value == 0
    assert c1.value == 0
    assert c2.value == 0

    # now rebalance child s1 - since its children are 0, no waterfall alloc
    m.rebalance(0.5, 's1')

    assert s1.value == 500
    assert m.capital == 1000 - 500
    assert m.value == 1000
    assert s1.weight == 500.0 / 1000
    assert s2.weight == 0

    # now allocate directly to child of child
    s1.rebalance(0.4, 'c1')

    assert s1.value == 500
    assert s1.capital == 500 - 200
    assert c1.value == 200
    assert c1.weight == 200.0 / 500
    assert c1.position == 2

    assert m.capital == 1000 - 500
    assert m.value == 1000
    assert s1.weight == 500.0 / 1000
    assert s2.weight == 0

    assert c12.value == 0

    # now rebalance child s1 again and make sure c1 also gets proportional
    # increase
    m.rebalance(0.8, 's1')
    assert s1.value == 800
    aae(m.capital, 200, 1)
    assert m.value == 1000
    assert s1.weight == 800 / 1000
    assert s2.weight == 0
    assert c1.value == 300.0
    assert c1.weight == 300.0 / 800
    assert c1.position == 3

    # now rebalance child s1 to 0 - should close out s1 and c1 as well
    m.rebalance(0, 's1')

    assert s1.value == 0
    assert m.capital == 1000
    assert m.value == 1000
    assert s1.weight == 0
    assert s2.weight == 0
    assert c1.weight == 0
Exemplo n.º 13
0
def test_strategybase_prices():
    dts = pd.date_range('2010-01-01', periods=21)
    rawd = [
        13.555, 13.75, 14.16, 13.915, 13.655, 13.765, 14.02, 13.465, 13.32,
        14.65, 14.59, 14.175, 13.865, 13.865, 13.89, 13.85, 13.565, 13.47,
        13.225, 13.385, 12.89
    ]
    data = pd.DataFrame(index=dts, data=rawd, columns=['a'])

    s = StrategyBase('s')
    s.set_commissions(lambda q, p: 1)
    s.setup(data)

    # buy 100 shares on day 1 - hold until end
    # just enough to buy 100 shares + 1$ commission
    s.adjust(1356.50)

    s.update(dts[0])
    # allocate all capital to child a
    # a should be dynamically created and should have
    # 100 shares allocated. s.capital should be 0
    s.allocate(s.value, 'a')

    assert s.capital == 0
    assert s.value == 1355.50
    assert len(s.children) == 1
    aae(s.price, 99.92628, 5)

    a = s['a']
    assert a.position == 100
    assert a.value == 1355.50
    assert a.weight == 1
    assert a.price == 13.555
    assert len(a.prices) == 1

    # update through all dates and make sure price is ok
    s.update(dts[1])
    aae(s.price, 101.3638, 4)

    s.update(dts[2])
    aae(s.price, 104.3863, 4)

    s.update(dts[3])
    aae(s.price, 102.5802, 4)

    # finish updates and make sure ok at end
    for i in range(4, 21):
        s.update(dts[i])

    assert len(s.prices) == 21
    aae(s.prices[-1], 95.02396, 5)
    aae(s.prices[-2], 98.67306, 5)