def test_strategybase_tree_rebalance(): c1 = SecurityBase('c1') c2 = SecurityBase('c2') s = StrategyBase('p', [c1, c2]) 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) data['c1'][dts[1]] = 105 data['c2'][dts[1]] = 95 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) s.adjust(1000) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # now rebalance c1 s.rebalance(0.5, 'c1') assert c1.position == 5 assert c1.value == 500 assert s.capital == 1000 - 501 assert s.value == 999 assert c1.weight == 500.0 / 999 assert c2.weight == 0
def test_strategybase_tree_rebalance(): c1 = SecurityBase('c1') c2 = SecurityBase('c2') s = StrategyBase('p', [c1, c2]) s.set_commissions(lambda q, p: 1) 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) data['c1'][dts[1]] = 105 data['c2'][dts[1]] = 95 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) s.adjust(1000) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # now rebalance c1 s.rebalance(0.5, 'c1') assert c1.position == 4 assert c1.value == 400 assert s.capital == 1000 - 401 assert s.value == 999 assert c1.weight == 400.0 / 999 assert c2.weight == 0
def test_rebalance_child_not_in_tree(): s = StrategyBase('p') 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 s.setup(data) i = 0 s.update(dts[i]) s.adjust(1000) # rebalance to 0 w/ child that is not present - should ignore s.rebalance(0, 'c2') assert s.value == 1000 assert s.capital == 1000 assert len(s.children) == 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)
def test_strategybase_tree_rebalance_base(): c1 = SecurityBase('c1') c2 = SecurityBase('c2') s = StrategyBase('p', [c1, c2]) 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) data['c1'][dts[1]] = 105 data['c2'][dts[1]] = 95 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) s.adjust(1000) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # check that 2 rebalances of equal weight lead to two different allocs # since value changes after first call s.rebalance(0.5, 'c1') assert c1.position == 5 assert c1.value == 500 assert s.capital == 1000 - 501 assert s.value == 999 assert c1.weight == 500.0 / 999 assert c2.weight == 0 s.rebalance(0.5, 'c2') assert c2.position == 4 assert c2.value == 400 assert s.capital == 1000 - 501 - 401 assert s.value == 998 assert c2.weight == 400.0 / 998 assert c1.weight == 500.0 / 998 # close out everything s.flatten() # adjust to get back to 1000 s.adjust(4) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # now rebalance but set fixed base base = s.value s.rebalance(0.5, 'c1', base=base) assert c1.position == 5 assert c1.value == 500 assert s.capital == 1000 - 501 assert s.value == 999 assert c1.weight == 500.0 / 999 assert c2.weight == 0 s.rebalance(0.5, 'c2', base=base) assert c2.position == 5 assert c2.value == 500 assert s.capital == 1000 - 501 - 501 assert s.value == 998 assert c2.weight == 500.0 / 998 assert c1.weight == 500.0 / 998
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
def test_strategybase_tree_rebalance_base(): c1 = SecurityBase('c1') c2 = SecurityBase('c2') s = StrategyBase('p', [c1, c2]) s.set_commissions(lambda q, p: 1) 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) data['c1'][dts[1]] = 105 data['c2'][dts[1]] = 95 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) s.adjust(1000) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # check that 2 rebalances of equal weight lead to two different allocs # since value changes after first call s.rebalance(0.5, 'c1') assert c1.position == 4 assert c1.value == 400 assert s.capital == 1000 - 401 assert s.value == 999 assert c1.weight == 400.0 / 999 assert c2.weight == 0 s.rebalance(0.5, 'c2') assert c2.position == 4 assert c2.value == 400 assert s.capital == 1000 - 401 - 401 assert s.value == 998 assert c2.weight == 400.0 / 998 assert c1.weight == 400.0 / 998 # close out everything s.flatten() # adjust to get back to 1000 s.adjust(4) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # now rebalance but set fixed base base = s.value s.rebalance(0.5, 'c1', base=base) assert c1.position == 4 assert c1.value == 400 assert s.capital == 1000 - 401 assert s.value == 999 assert c1.weight == 400.0 / 999 assert c2.weight == 0 s.rebalance(0.5, 'c2', base=base) assert c2.position == 4 assert c2.value == 400 assert s.capital == 1000 - 401 - 401 assert s.value == 998 assert c2.weight == 400.0 / 998 assert c1.weight == 400.0 / 998
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