def get_instrument_weights(self): """ Get the time series of instrument weights, accounting for potentially missing positions, and weights that don't add up. :returns: TxK pd.DataFrame containing weights, columns are instrument names, T covers all subsystem positions """ self.log.terse("Calculating instrument weights") if self.use_estimated_instrument_weights(): raw_instr_weights = self.get_raw_estimated_instrument_weights() else: raw_instr_weights = self.get_raw_fixed_instrument_weights() instrument_list = list(raw_instr_weights.columns) subsys_positions = [ self.get_subsystem_position(instrument_code) for instrument_code in instrument_list ] subsys_positions = pd.concat(subsys_positions, axis=1).ffill() subsys_positions.columns = instrument_list instrument_weights = fix_weights_vs_position_or_forecast( raw_instr_weights, subsys_positions) smooth_weighting = self.parent.config.instrument_weight_ewma_span # smooth instrument_weights = instrument_weights.ewm(smooth_weighting).mean() return instrument_weights
def get_unsmoothed_instrument_weights_fitted_to_position_lengths( self) -> pd.DataFrame: raw_instrument_weights = self.get_unsmoothed_raw_instrument_weights() instrument_list = list(raw_instrument_weights.columns) subsystem_positions = [ self.get_subsystem_position(instrument_code) for instrument_code in instrument_list ] subsystem_positions = pd.concat(subsystem_positions, axis=1).ffill() subsystem_positions.columns = instrument_list ## this should remove when have NAN's ## FIXME CHECK instrument_weights = fix_weights_vs_position_or_forecast( raw_instrument_weights, subsystem_positions) # now on same frequency as positions # Move to daily for space saving and so smoothing makes sense daily_unsmoothed_instrument_weights = instrument_weights.resample( "1B").mean() return daily_unsmoothed_instrument_weights
def _fix_weights_to_forecasts( self, instrument_code: str, monthly_forecast_weights: pd.DataFrame) -> pd.DataFrame: # we get the rule variations from forecast_weight columns, as if we've dropped # expensive rules (when estimating) then get_trading_rules will give # the wrong answer rule_variation_list = list(monthly_forecast_weights.columns) # time series may vary forecasts = self.get_all_forecasts(instrument_code, rule_variation_list) # adjust weights for missing data # also aligns them together with forecasts forecast_weights_fixed_to_forecasts = fix_weights_vs_position_or_forecast( monthly_forecast_weights, forecasts) return forecast_weights_fixed_to_forecasts