def test_rebalance_with_commissions(): algo = algos.Rebalance() s = bt.Strategy('s') s.set_commissions(lambda q, p: 1) dts = pd.date_range('2010-01-01', periods=3) data = pd.DataFrame(index=dts, columns=['c1', 'c2'], data=100) s.setup(data) s.adjust(1000) s.update(dts[0]) s.temp['weights'] = {'c1': 1} assert algo(s) assert s.value == 999 assert s.capital == 99 c1 = s['c1'] assert c1.value == 900 assert c1.position == 9 assert c1.weight == 900 / 999. s.temp['weights'] = {'c2': 1} assert algo(s) assert s.value == 997 assert s.capital == 97 c2 = s['c2'] assert c1.value == 0 assert c1.position == 0 assert c1.weight == 0 assert c2.value == 900 assert c2.position == 9 assert c2.weight == 900. / 997
def test_rebalance(): algo = algos.Rebalance() s = bt.Strategy('s') dts = pd.date_range('2010-01-01', periods=3) data = pd.DataFrame(index=dts, columns=['c1', 'c2'], data=100) s.setup(data) s.adjust(1000) s.update(dts[0]) s.temp['weights'] = {'c1': 1} assert algo(s) assert s.value == 1000 assert s.capital == 0 c1 = s['c1'] assert c1.value == 1000 assert c1.position == 10 assert c1.weight == 1. s.temp['weights'] = {'c2': 1} assert algo(s) assert s.value == 1000 assert s.capital == 0 c2 = s['c2'] assert c1.value == 0 assert c1.position == 0 assert c1.weight == 0 assert c2.value == 1000 assert c2.position == 10 assert c2.weight == 1.
def test_rebalance_with_cash(): algo = algos.Rebalance() s = bt.Strategy('s') s.set_commissions(lambda q, p: 1) 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) s.adjust(1000) s.update(dts[0]) s.temp['weights'] = {'c1': 1} # set cash amount s.temp['cash'] = 0.5 assert algo(s) assert s.value == 999 assert s.capital == 599 c1 = s['c1'] assert c1.value == 400 assert c1.position == 4 assert c1.weight == 400.0 / 999 s.temp['weights'] = {'c2': 1} # change cash amount s.temp['cash'] = 0.25 assert algo(s) assert s.value == 997 assert s.capital == 297 c2 = s['c2'] assert c1.value == 0 assert c1.position == 0 assert c1.weight == 0 assert c2.value == 700 assert c2.position == 7 assert c2.weight == 700.0 / 997
def bt_strategy(self, data, cats, graph_path): rsmpl = { 'days': 'B', 'weeks': 'W-Fri', 'months': 'BM', 'years': 'BY' }[self.roll_ptype] first_date = data.index[0] + relativedelta(**{self.est_ptype: self.est_plen}) run_dates = asfreq_actual(data[data.columns[0]], str(self.roll_plen) + rsmpl) run_dates = data.loc[run_dates.index] run_dates = run_dates.loc[run_dates.index > first_date] run_dates = run_dates.iloc[:-1] run_dates.loc[data.index[-1]] = data.iloc[-1] fee_func_parial = partial(fee_func, ff=self.fix_fee, pf=self.prc_fee) algo_stack = [ algos.RunOnDate(*run_dates.index.tolist()), algos.SelectAll(), SaveWeights(), WeightHRP(plen=self.est_plen, ptype=self.est_ptype, robust=self.robust, ddev=self.ddev, cats=cats, graph_path=graph_path), GapWeights(self.reb_gap), ] if self.is_tvol: algo_stack.append(WeightTargetVol(self.tvol, plen=self.est_plen, ptype=self.est_ptype, kmax=self.leverage)) algo_stack.extend([ WeightAdjust(self.leverage, self.weight_round), LimitWeights(self.min_weight, self.max_weight, self.leverage), WeightsToPerm(), CheckFeeBankrupt(fee_func_parial), algos.Rebalance() ]) strategy = bt.Strategy(self.name(), algo_stack) return bt.Backtest(strategy, data.copy(), initial_capital=self.init_balance, commissions=fee_func_parial, integer_positions=self.int_pos, progress_bar=True)
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.
def test_rebalance_updatecount(): algo = algos.Rebalance() s = bt.Strategy('s') s.use_integer_positions(False) dts = pd.date_range('2010-01-01', periods=3) data = pd.DataFrame(index=dts, columns=['c1', 'c2', 'c3', 'c4','c5'], data=100) s.setup(data) s.adjust(1000) s.update(dts[0]) s.temp['weights'] = {'c1': 0.25, 'c2':0.25, 'c3':0.25, 'c4':0.25} update = bt.core.SecurityBase.update bt.core.SecurityBase._update_call_count = 0 def side_effect(self, *args, **kwargs): bt.core.SecurityBase._update_call_count += 1 return update(self, *args, **kwargs) with mock.patch.object(bt.core.SecurityBase, 'update', side_effect) as mock_update: assert algo(s) assert s.value == 1000 assert s.capital == 0 # Update is called once when each weighted security is created (4) # and once for each security after all allocations are made (4) assert bt.core.SecurityBase._update_call_count == 8 s.update(dts[1]) s.temp['weights'] = {'c1': 0.5, 'c2':0.5} update = bt.core.SecurityBase.update bt.core.SecurityBase._update_call_count = 0 def side_effect(self, *args, **kwargs): bt.core.SecurityBase._update_call_count += 1 return update(self, *args, **kwargs) with mock.patch.object(bt.core.SecurityBase, 'update', side_effect) as mock_update: assert algo(s) # Update is called once for each weighted security before allocation (4) # and once for each security after all allocations are made (4) assert bt.core.SecurityBase._update_call_count == 8 s.update(dts[2]) s.temp['weights'] = {'c1': 0.25, 'c2':0.25, 'c3':0.25, 'c4':0.25} update = bt.core.SecurityBase.update bt.core.SecurityBase._update_call_count = 0 def side_effect(self, *args, **kwargs): bt.core.SecurityBase._update_call_count += 1 return update(self, *args, **kwargs) with mock.patch.object(bt.core.SecurityBase, 'update', side_effect) as mock_update: assert algo(s) # Update is called once for each weighted security before allocation (2) # and once for each security after all allocations are made (4) assert bt.core.SecurityBase._update_call_count == 6