def maximise_without_discrete_weights(expected_returns: meanEstimates, covariance_matrix: covarianceEstimate, risk_aversion: float): missing_instruments = covariance_matrix.assets_with_missing_data() covariance_with_valid_data = covariance_matrix.without_missing_data() list_of_instruments = covariance_with_valid_data.columns if len(list_of_instruments) == 0: weight_list = [] else: expected_returns_as_list = expected_returns.list_in_key_order( list_of_instruments) covariance_as_np = covariance_with_valid_data.values weight_list = optimise_from_covariance_and_expected_returns_with_risk_coefficient( covariance_as_np=covariance_as_np, expected_returns_as_list=expected_returns_as_list, risk_aversion=risk_aversion) weights = portfolioWeights([ (key, weight) for key, weight in zip(list_of_instruments, weight_list) ]) weights = weights.with_zero_weights_for_missing_keys(missing_instruments) return weights
def get_perc_of_capital_position_size_all_strategies(data) -> portfolioWeights: instrument_list = get_instruments_with_positions_all_strategies(data) weights = portfolioWeights([( instrument_code, get_perc_of_capital_position_size_for_instrument_across_strategies( data, instrument_code), ) for instrument_code in instrument_list]) return weights
def get_maximum_portfolio_weight_at_date( self, relevant_date: datetime.datetime = arg_not_supplied ) -> portfolioWeights: max_portfolio_weight = self.get_maximum_portfolio_weight_as_df() max_weight_at_date = get_row_of_df_aligned_to_weights_as_dict( max_portfolio_weight, relevant_date) return portfolioWeights(max_weight_at_date)
def get_portfolio_weights_for_relevant_date(self, relevant_date: datetime.datetime = arg_not_supplied) \ -> portfolioWeights: weights_as_df = self.get_original_portfolio_weight_df() weights_at_date = get_row_of_df_aligned_to_weights_as_dict(weights_as_df, relevant_date) portfolio_weights = portfolioWeights(weights_at_date) return portfolio_weights
def get_per_contract_value( self, relevant_date: datetime.datetime = arg_not_supplied ) -> portfolioWeights: df_of_values = self.get_per_contract_value_as_proportion_of_capital_df() values_at_date = get_row_of_df_aligned_to_weights_as_dict( df_of_values, relevant_date ) contract_values = portfolioWeights(values_at_date) return contract_values
def multiplied_out_risk_weight_for_sub_portfolios(weights_for_portfolio: portfolioWeights, div_mult_for_portfolio:float = 1.0, weight_for_subportfolio: float = .5) -> portfolioWeights: asset_names = list(weights_for_portfolio.keys()) mult_weights = portfolioWeights([ (asset_name, weight_for_subportfolio * div_mult_for_portfolio * weights_for_portfolio[asset_name]) for asset_name in asset_names]) return mult_weights
def get_per_contract_values(data: dataBlob, strategy_name: str, list_of_instruments: list) -> portfolioWeights: per_contract_values = portfolioWeights([( instrument_code, get_perc_of_strategy_capital_for_instrument_per_contract( data, strategy_name=strategy_name, instrument_code=instrument_code), ) for instrument_code in list_of_instruments]) return per_contract_values
def get_perc_of_capital_position_size_across_instruments_for_strategy( data, strategy_name: str) -> portfolioWeights: instrument_list = get_instruments_with_positions(data, strategy_name) weights = portfolioWeights([( instrument_code, get_perc_of_capital_position_size_for_instrument( data, strategy_name, instrument_code), ) for instrument_code in instrument_list]) return weights
def get_position_contracts_for_relevant_date( self, relevant_date: datetime.datetime = arg_not_supplied ) -> portfolioWeights: position_contracts_as_df = self.get_position_contracts_as_df() position_contracts_at_date = get_row_of_df_aligned_to_weights_as_dict( position_contracts_as_df, relevant_date ) position_contracts = portfolioWeights(position_contracts_at_date) return position_contracts
def get_maximum_position_contracts( data, strategy_name: str, list_of_instruments: list) -> portfolioWeights: maximum_position_contracts = dict([( instrument_code, get_maximum_position_contracts_for_instrument_strategy( data, instrument_strategy=instrumentStrategy( strategy_name=strategy_name, instrument_code=instrument_code)), ) for instrument_code in list_of_instruments]) return portfolioWeights(maximum_position_contracts)
def _get_portfolio_risk_given_weights(self, portfolio_weights: pd.DataFrame) -> pd.Series: risk_series = [] common_index = self.common_index() p = progressBar(len(common_index), show_timings=True, show_each_time=False) for relevant_date in common_index: p.iterate() weights_on_date = portfolioWeights( get_row_of_df_aligned_to_weights_as_dict(portfolio_weights, relevant_date)) covariance = self.get_covariance_matrix(relevant_date) risk_on_date = calculate_risk(weights = weights_on_date, covariance = covariance) risk_series.append(risk_on_date) p.finished() risk_series = pd.Series(risk_series, common_index) return risk_series
def optimise_with_fixed_contract_values(per_contract_value: portfolioWeights, expected_returns: meanEstimates, covariance_matrix: covarianceEstimate, risk_aversion: float, max_portfolio_weights: portfolioWeights, original_portfolio_weights: portfolioWeights, costs: meanEstimates, use_process_pool: bool = False, max_risk_as_variance:float = NO_RISK_LIMIT, previous_weights: portfolioWeights = arg_not_supplied)\ -> portfolioWeights: missing_instruments = covariance_matrix.assets_with_missing_data() list_of_instruments = covariance_matrix.assets_with_data() grid_parameters = gridParameters( list_of_instruments=list_of_instruments, max_portfolio_weights=max_portfolio_weights, original_portfolio_weights=original_portfolio_weights, per_contract_value=per_contract_value) optimisation_parameters = build_optimisation_parameters( list_of_instruments=list_of_instruments, per_contract_value=per_contract_value, expected_returns=expected_returns, covariance_matrix=covariance_matrix, risk_aversion=risk_aversion, costs=costs, max_risk_as_variance=max_risk_as_variance, previous_weights=previous_weights) weight_list = grid_search_optimise_with_fixed_contract_values_and_processed_inputs( grid_parameters=grid_parameters, optimisation_parameters=optimisation_parameters, use_process_pool=use_process_pool) weights = portfolioWeights([ (key, weight) for key, weight in zip(list_of_instruments, weight_list) ]) weights = weights.with_zero_weights_for_missing_keys(missing_instruments) return weights
def maxima(self) -> portfolioWeights: return portfolioWeights( self._get_dict_for_value_across_codes("maximum"))
def get_data_for_objective_instance( data: dataBlob, strategy_name: str, previous_positions: dict, raw_optimal_position_data: dict, ) -> dataForObjectiveInstance: list_of_instruments = list(raw_optimal_position_data.keys()) data.log.msg("Getting data for optimisation") previous_positions_as_weights_object = portfolioWeights(previous_positions) previous_positions_as_weights_object = ( previous_positions_as_weights_object. with_zero_weights_for_missing_keys(list_of_instruments)) positions_optimal = portfolioWeights([ (instrument_code, raw_position_entry.optimal_position) for instrument_code, raw_position_entry in raw_optimal_position_data.items() ]) reference_prices = dict([(instrument_code, raw_position_entry.reference_price) for instrument_code, raw_position_entry in raw_optimal_position_data.items()]) reference_contracts = dict([(instrument_code, raw_position_entry.reference_contract) for instrument_code, raw_position_entry in raw_optimal_position_data.items()]) reference_dates = dict([(instrument_code, raw_position_entry.reference_date) for instrument_code, raw_position_entry in raw_optimal_position_data.items()]) data.log.msg("Getting maximum positions") maximum_position_contracts = get_maximum_position_contracts( data, strategy_name=strategy_name, list_of_instruments=list_of_instruments) data.log.msg("Getting covariance matrix") covariance_matrix = get_covariance_matrix_for_instrument_returns( data, list_of_instruments=list_of_instruments) data.log.msg("Getting per contract values") per_contract_value = get_per_contract_values( data, strategy_name=strategy_name, list_of_instruments=list_of_instruments) data.log.msg("Getting costs") costs = calculate_costs_per_portfolio_weight( data, per_contract_value=per_contract_value, strategy_name=strategy_name, list_of_instruments=list_of_instruments) constraints = get_constraints(data, strategy_name=strategy_name, list_of_instruments=list_of_instruments) speed_control = get_speed_control(data) data_for_objective = dataForObjectiveInstance( positions_optimal=positions_optimal, per_contract_value=per_contract_value, covariance_matrix=covariance_matrix, costs=costs, reference_dates=reference_dates, reference_prices=reference_prices, reference_contracts=reference_contracts, previous_positions=previous_positions_as_weights_object, maximum_position_contracts=maximum_position_contracts, constraints=constraints, speed_control=speed_control, ) return data_for_objective
def starting_weights(self) -> portfolioWeights: return portfolioWeights( self._get_dict_for_value_across_codes("start_weight"))
def direction(self) -> portfolioWeights: return portfolioWeights( self._get_dict_for_value_across_codes("direction"))
def diversification_multiplier_from_list(correlation_list: CorrelationList, weight_df: pd.DataFrame, ewma_span: int = 125, **kwargs) -> pd.Series: # FIXME THE FREQUENCY OF WEIGHT_DF MAY NOT MATCH EMWA_SPAN WHICH IS UNITLES IN ANY CASE... """ Given a CorrelationList object, and a dataframe of weights, work out the div multiplier :param correlation_list_object: CorrelationList to use for calculation :type correlation_list_object: CorrelationList :param weight_df_raw: Weights of assets :type weight_df_raw: TxN pd.DataFrame :param ewma_span: Smoothing parameter to use on output (1= no smoothing) :type ewma_span: int :param max: Maximum allowable value :type max: float :param **kwargs: Used for single period calculation :returns: Tx1 pd.Series """ # align weights to corr list columns weight_df = weight_df[correlation_list.column_names] ref_periods = [ fit_period.period_start for fit_period in correlation_list.fit_dates ] # here's where we stack up the answers div_mult_vector = [] for (corrmatrix, start_of_period) in zip(correlation_list.corr_list, ref_periods): weight_slice = weight_df[:start_of_period] if weight_slice.shape[0] == 0: # empty space div_mult_vector.append(1.0) continue # take the current weights and work out the DM weights_dict = weight_slice.iloc[-1].to_dict() weights = portfolioWeights(weights_dict) div_multiplier = diversification_mult_single_period( corrmatrix, weights, **kwargs) div_mult_vector.append(div_multiplier) # In same space as correlations probably annually div_mult_df = pd.Series(div_mult_vector, index=ref_periods) # Change to business days, so moving average will make sense div_mult_df_daily = div_mult_df.resample("1B").ffill() # take a moving average to smooth the jumps div_mult_df_smoothed = div_mult_df_daily.ewm(span=ewma_span).mean() return div_mult_df_smoothed