Exemple #1
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
Exemple #2
0
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)
Exemple #3
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)
Exemple #4
0
def test_set_commissions():
    s = StrategyBase('s')

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

    s.setup(data)
    s.update(dts[0])
    s.adjust(1000)

    s.allocate(500, 'c1')
    assert s.capital == 499

    s.set_commissions(lambda x, y: 0.0)
    s.allocate(-500, 'c1')
    assert s.capital == 999
Exemple #5
0
def test_set_commissions():
    s = StrategyBase('s')

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

    s.setup(data)
    s.update(dts[0])
    s.adjust(1000)

    s.allocate(500, 'c1')
    assert s.capital == 499

    s.set_commissions(lambda x, y: 0.0)
    s.allocate(-500, 'c1')
    assert s.capital == 999
Exemple #6
0
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
Exemple #7
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
Exemple #8
0
def test_strategybase_multiple_calls_no_post_update():
    s = StrategyBase('s')
    s.set_commissions(lambda q, p: 1)

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

    data.c2[dts[0]] = 95
    data.c1[dts[1]] = 95
    data.c2[dts[2]] = 95
    data.c2[dts[3]] = 95
    data.c2[dts[4]] = 95
    data.c1[dts[4]] = 105

    s.setup(data)

    # define strategy logic
    def algo(target):
        # close out any open positions
        target.flatten()

        # get stock w/ lowest price
        c = target.universe.ix[target.now].idxmin()

        # allocate all capital to that stock
        target.allocate(target.value, c)

    # replace run logic
    s.run = algo

    # start w/ 1000
    s.adjust(1000)

    # loop through dates manually
    i = 0

    # update t0
    s.update(dts[i])

    assert len(s.children) == 0
    assert s.value == 1000

    # run t0
    s.run(s)

    assert len(s.children) == 1
    assert s.value == 999
    assert s.capital == 49

    c2 = s['c2']
    assert c2.value == 950
    assert c2.weight == 950.0 / 999
    assert c2.price == 95

    # update t1
    i = 1
    s.update(dts[i])

    assert s.value == 1049
    assert s.capital == 49
    assert len(s.children) == 1

    assert 'c2' in s.children
    c2 == s['c2']
    assert c2.value == 1000
    assert c2.weight == 1000.0 / 1049.0
    assert c2.price == 100

    # run t1 - close out c2, open c1
    s.run(s)

    assert len(s.children) == 2
    assert s.value == 1047
    assert s.capital == 2

    c1 = s['c1']
    assert c1.value == 1045
    assert c1.weight == 1045.0 / 1047
    assert c1.price == 95

    assert c2.value == 0
    assert c2.weight == 0
    assert c2.price == 100

    # update t2
    i = 2
    s.update(dts[i])

    assert len(s.children) == 2
    assert s.value == 1102
    assert s.capital == 2

    assert c1.value == 1100
    assert c1.weight == 1100.0 / 1102
    assert c1.price == 100

    assert c2.value == 0
    assert c2.weight == 0
    assert c2.price == 95

    # run t2
    s.run(s)

    assert len(s.children) == 2
    assert s.value == 1100
    assert s.capital == 55

    assert c1.value == 0
    assert c1.weight == 0
    assert c1.price == 100

    assert c2.value == 1045
    assert c2.weight == 1045.0 / 1100
    assert c2.price == 95

    # update t3
    i = 3
    s.update(dts[i])

    assert len(s.children) == 2
    assert s.value == 1100
    assert s.capital == 55

    assert c1.value == 0
    assert c1.weight == 0
    assert c1.price == 100

    assert c2.value == 1045
    assert c2.weight == 1045.0 / 1100
    assert c2.price == 95

    # run t3
    s.run(s)

    assert len(s.children) == 2
    assert s.value == 1098
    assert s.capital == 53

    assert c1.value == 0
    assert c1.weight == 0
    assert c1.price == 100

    assert c2.value == 1045
    assert c2.weight == 1045.0 / 1098
    assert c2.price == 95

    # update t4
    i = 4
    s.update(dts[i])

    assert len(s.children) == 2
    assert s.value == 1098
    assert s.capital == 53

    assert c1.value == 0
    assert c1.weight == 0
    # accessing price should refresh - this child has been idle for a while -
    # must make sure we can still have a fresh prices
    assert c1.price == 105
    assert len(c1.prices) == 5

    assert c2.value == 1045
    assert c2.weight == 1045.0 / 1098
    assert c2.price == 95

    # run t4
    s.run(s)

    assert len(s.children) == 2
    assert s.value == 1096
    assert s.capital == 51

    assert c1.value == 0
    assert c1.weight == 0
    assert c1.price == 105

    assert c2.value == 1045
    assert c2.weight == 1045.0 / 1096
    assert c2.price == 95