def _calculate_trades(self, prices_array: QFDataArray, exposures_df: QFDataFrame) -> List[Trade]: trade_data_list = [] shifted_signals_df = exposures_df.shift(1, axis=0) for ticker, exposures_tms in shifted_signals_df.iteritems(): trade_data_partial_list = self.generate_trades_for_ticker(prices_array, exposures_tms, ticker) trade_data_list.extend(trade_data_partial_list) return trade_data_list
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