def test_degenerate_shorting(): # can have situation where you short infinitely if commission/share > share # price c1 = SecurityBase('c1') s = StrategyBase('p', [c1]) # $1/share commission s.set_commissions(lambda q, p: abs(q) * 1) c1 = s['c1'] dts = pd.date_range('2010-01-01', periods=3) # c1 trades at 0.01 data = pd.DataFrame(index=dts, columns=['c1'], data=0.01) s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) s.adjust(1000) try: c1.allocate(-10) assert False except Exception as e: assert 'full_outlay should always be approaching amount' in str(e)
def test_securitybase_allocate(): c1 = SecurityBase('c1') s = StrategyBase('p', [c1]) c1 = s['c1'] dts = pd.date_range('2010-01-01', periods=3) data = pd.DataFrame(index=dts, columns=['c1'], data=100.) # set the price data['c1'][dts[0]] = 91.40246706608193 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) # allocate 100000 to strategy original_capital = 100000. s.adjust(original_capital) # not integer positions c1.integer_positions = False # set the full_outlay and amount full_outlay = 1999.693706988672 amount = 1999.6937069886717 c1.allocate(amount) # the results that we want to be true assert np.isclose(full_outlay, amount, rtol=0.) # check that the quantity wasn't decreased and the full_outlay == amount # we can get the full_outlay that was calculated by # original capital - current capital assert np.isclose(full_outlay, original_capital - s._capital, rtol=0.)
def test_strategybase_tree_allocate(): c1 = SecurityBase('c1') c2 = SecurityBase('c2') s = StrategyBase('p', [c1, 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) # since children have w == 0 this should stay in s s.allocate(1000) assert s.value == 1000 assert s.capital == 1000 assert c1.value == 0 assert c2.value == 0 # now allocate directly to child c1.allocate(500) 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_allocate_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]) 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) # since children have w == 0 this should stay in s m.allocate(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 allocate directly to child s1.allocate(500) 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 c1.allocate(200) 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
def test_strategybase_tree_allocate_update(): 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]]) assert s.price == 100 s.adjust(1000) assert s.price == 100 assert s.value == 1000 assert s._value == 1000 c1.allocate(500) assert c1.position == 5 assert c1.value == 500 assert c1.weight == 500.0 / 999 assert s.capital == 1000 - 501 assert s.value == 999 assert s.price == 99.9 i = 1 s.update(dts[i], data.ix[dts[i]]) assert c1.position == 5 assert c1.value == 525 assert c1.weight == 525.0 / 1024 assert s.capital == 1000 - 501 assert s.value == 1024 assert s.price == 102.4
def test_strategybase_tree_allocate_update(): 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]]) assert s.price == 100 s.adjust(1000) assert s.price == 100 assert s.value == 1000 assert s._value == 1000 c1.allocate(500) assert c1.position == 5 assert c1.value == 500 assert c1.weight == 500.0 / 1000 assert s.capital == 1000 - 500 assert s.value == 1000 assert s.price == 100 i = 1 s.update(dts[i], data.ix[dts[i]]) assert c1.position == 5 assert c1.value == 525 assert c1.weight == 525.0 / 1025 assert s.capital == 1000 - 500 assert s.value == 1025 assert np.allclose(s.price, 102.5)
def test_strategybase_tree_allocate_long_short(): 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) c1.allocate(500) assert c1.position == 5 assert c1.value == 500 assert c1.weight == 500.0 / 999 assert s.capital == 1000 - 501 assert s.value == 999 c1.allocate(-200) assert c1.position == 3 assert c1.value == 300 assert c1.weight == 300.0 / 998 assert s.capital == 1000 - 501 + 199 assert s.value == 998 c1.allocate(-400) assert c1.position == -1 assert c1.value == -100 assert c1.weight == -100.0 / 997 assert s.capital == 1000 - 501 + 199 + 399 assert s.value == 997 # close up c1.allocate(-c1.value) assert c1.position == 0 assert c1.value == 0 assert c1.weight == 0 assert s.capital == 1000 - 501 + 199 + 399 - 101 assert s.value == 996
def test_strategybase_tree_allocate_long_short(): 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) c1.allocate(500) assert c1.position == 5 assert c1.value == 500 assert c1.weight == 500.0 / 1000 assert s.capital == 1000 - 500 assert s.value == 1000 c1.allocate(-200) assert c1.position == 3 assert c1.value == 300 assert c1.weight == 300.0 / 1000 assert s.capital == 1000 - 500 + 200 assert s.value == 1000 c1.allocate(-400) assert c1.position == -1 assert c1.value == -100 assert c1.weight == -100.0 / 1000 assert s.capital == 1000 - 500 + 200 + 400 assert s.value == 1000 # close up c1.allocate(-c1.value) assert c1.position == 0 assert c1.value == 0 assert c1.weight == 0 assert s.capital == 1000 - 500 + 200 + 400 - 100 assert s.value == 1000
def test_outlays(): 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[0]] = 105 data['c2'][dts[0]] = 95 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) # allocate 1000 to strategy s.adjust(1000) # now let's see what happens when we allocate 500 to each child c1.allocate(500) c2.allocate(500) # out update s.update(dts[i]) assert c1.data['outlay'][dts[0]] == (4 * 105) assert c2.data['outlay'][dts[0]] == (5 * 95) i = 1 s.update(dts[i], data.ix[dts[i]]) c1.allocate(-400) c2.allocate(100) # out update s.update(dts[i]) #print(c1.data['outlay']) assert c1.data['outlay'][dts[1]] == (-4 * 100) assert c2.data['outlay'][dts[1]] == 100
def test_outlays(): 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[0]] = 105 data['c2'][dts[0]] = 95 s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) # allocate 1000 to strategy s.adjust(1000) # now let's see what happens when we allocate 500 to each child c1.allocate(500) c2.allocate(500) # out update s.update(dts[i]) assert c1.data['outlay'][dts[0]] == (4 * 105) assert c2.data['outlay'][dts[0]] == (5 * 95) i = 1 s.update(dts[i], data.ix[dts[i]]) c1.allocate(-400) c2.allocate(100) # out update s.update(dts[i]) print c1.data['outlay'] assert c1.data['outlay'][dts[1]] == (-4 * 100) assert c2.data['outlay'][dts[1]] == 100
def test_fixed_commissions(): c1 = SecurityBase('c1') c2 = SecurityBase('c2') s = StrategyBase('p', [c1, c2]) # fixed $1 commission per transaction 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) s.setup(data) i = 0 s.update(dts[i], data.ix[dts[i]]) # allocate 1000 to strategy s.adjust(1000) # now let's see what happens when we allocate 500 to each child c1.allocate(500) c2.allocate(500) # out update s.update(dts[i]) assert c1.value == 400 assert c2.value == 400 assert s.capital == 198 # de-alloc 100 from c1. This should force c1 to sell 2 units to raise at # least 100 (because of commissions) c1.allocate(-100) s.update(dts[i]) assert c1.value == 200 assert s.capital == 198 + 199 # allocate 100 to c2. This should leave things unchaged, since c2 cannot # buy one unit since the commission will cause total outlay to exceed # allocation c2.allocate(100) s.update(dts[i]) assert c2.value == 400 assert s.capital == 198 + 199 # ok try again w/ 101 allocation. This time, it should work c2.allocate(101) s.update(dts[i]) assert c2.value == 500 assert s.capital == 198 + 199 - 101 # ok now let's close the whole position. Since we are closing, we expect # the allocation to go through, even though the outlay > amount c2.allocate(-500) s.update(dts[i]) assert c2.value == 0 assert s.capital == 198 + 199 - 101 + 499 # now we are going to go short c2 # we want to 'raise' 100 dollars. Since we need at a minimum 100, but we # also have commissions, we will actually short 2 units in order to raise # at least 100 c2.allocate(-100) s.update(dts[i]) assert c2.value == -200 assert s.capital == 198 + 199 - 101 + 499 + 199