def _calculate_portfolio_returns_tms(self, tickers, open_to_open_returns_df: QFDataFrame, exposure_values_df: QFDataFrame) \ -> SimpleReturnsSeries: """ SimpleReturnsSeries of the portfolio - for each date equal to the portfolio performance over the last open-to-open period, ex. value indexed as 2010-02-15 would refer to the portfolio value change between open at 14th and open at 15th, and would be based on the signal from 2010-02-13; the first index of the series is the Day 3 of the backtest, as the first signal calculation occurs after Day 1 (see ORDER OF ACTIONS below) the last index of the series is test_end_date and the portfolio exposure is being set to zero on the opening of the test_end_date ORDER OF ACTIONS: -- Day 1 -- signal is generated, based on the historic data INCLUDING prices from Day 1 suggested exposure for Day 2 is calculated -- Day 2 -- a trade is entered, held or exited (or nothing happens) regarding the suggested exposure this action is performed on the opening of the day -- Day 3 -- at the opening the open-to-open return is calculated now it is possible to estimate current portfolio value the simple return of the portfolio (Day 3 to Day 2) is saved and indexed with Day 3 date """ open_to_open_returns_df = open_to_open_returns_df.dropna(how="all") shifted_signals_df = exposure_values_df.shift(2, axis=0) shifted_signals_df = shifted_signals_df.iloc[2:] daily_returns_of_strategies_df = shifted_signals_df * open_to_open_returns_df daily_returns_of_strategies_df = daily_returns_of_strategies_df.dropna( axis=0, how='all') daily_returns_of_strategies_df = cast_dataframe( daily_returns_of_strategies_df, SimpleReturnsDataFrame) # type: SimpleReturnsDataFrame weights = Portfolio.one_over_n_weights(tickers) # for strategies based on more than one ticker (ex. VolLongShort) use the line below: # weights = QFSeries(np.ones(daily_returns_of_strategies_df.num_of_columns)) portfolio_rets_tms, _ = Portfolio.constant_weights( daily_returns_of_strategies_df, weights) return portfolio_rets_tms
def test_drifting_weights_alloc_not_fully_invested(self): expected_df = self.alloc_for_not_fully_invested_drift_weights _, actual_df = Portfolio.drifting_weights(self.assets_df, self.weights_not_full_invest) assert_dataframes_equal(expected_df, actual_df, absolute_tolerance=1e-06)
def test_drifting_weights_not_fully_invested(self): expected_series = self.rets_for_not_fully_invested_drift_weights actual_series, _ = Portfolio.drifting_weights( self.assets_df, self.weights_not_full_invest) assert_series_equal(expected_series, actual_series, absolute_tolerance=1e-06)
def _calculate_box( asset_returns_df: SimpleReturnsDataFrame) -> SimpleReturnsSeries: portfolio = EqualRiskContributionPortfolio(asset_returns_df.cov()) weights = portfolio.get_weights() portfolio_rets, _ = Portfolio.constant_weights(asset_returns_df, weights) return portfolio_rets