def _align_and_warn(returns,<EOL>positions,<EOL>factor_returns,<EOL>factor_loadings,<EOL>transactions=None,<EOL>pos_in_dollars=True):
missing_stocks = positions.columns.difference(<EOL>factor_loadings.index.get_level_values(<NUM_LIT:1>).unique()<EOL>)<EOL>num_stocks = len(positions.columns) - <NUM_LIT:1><EOL>missing_stocks = missing_stocks.drop('<STR_LIT>')<EOL>num_stocks_covered = num_stocks - len(missing_stocks)<EOL>missing_ratio = round(len(missing_stocks) / num_stocks, ndigits=<NUM_LIT:3>)<EOL>if num_stocks_covered == <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if len(missing_stocks) > <NUM_LIT:0>:<EOL><INDENT>if len(missing_stocks) > <NUM_LIT:5>:<EOL><INDENT>missing_stocks_displayed = (<EOL>"<STR_LIT>"<EOL>).format(len(missing_stocks),<EOL>'<STR_LIT:U+002CU+0020>'.join(missing_stocks[:<NUM_LIT:5>].map(str)),<EOL>missing_stocks[-<NUM_LIT:1>])<EOL>avg_allocation_msg = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>missing_stocks_displayed = (<EOL>"<STR_LIT>"<EOL>).format(list(missing_stocks))<EOL>avg_allocation_msg = "<STR_LIT>"<EOL><DEDENT>missing_stocks_warning_msg = (<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT:\n>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT:\n>"<EOL>"<STR_LIT>"<EOL>).format(<EOL>missing_stocks_displayed,<EOL>missing_ratio,<EOL>avg_allocation_msg,<EOL>positions[missing_stocks[:<NUM_LIT:5>].union(missing_stocks[[-<NUM_LIT:1>]])].mean(),<EOL>)<EOL>warnings.warn(missing_stocks_warning_msg)<EOL>positions = positions.drop(missing_stocks, axis='<STR_LIT>',<EOL>errors='<STR_LIT:ignore>')<EOL><DEDENT>missing_factor_loadings_index = positions.index.difference(<EOL>factor_loadings.index.get_level_values(<NUM_LIT:0>).unique()<EOL>)<EOL>missing_factor_loadings_index = positions.index.difference(<EOL>factor_loadings.index.get_level_values(<NUM_LIT:0>).unique()<EOL>)<EOL>if len(missing_factor_loadings_index) > <NUM_LIT:0>:<EOL><INDENT>if len(missing_factor_loadings_index) > <NUM_LIT:5>:<EOL><INDENT>missing_dates_displayed = (<EOL>"<STR_LIT>"<EOL>).format(<EOL>missing_factor_loadings_index[<NUM_LIT:0>],<EOL>missing_factor_loadings_index[-<NUM_LIT:1>]<EOL>)<EOL><DEDENT>else:<EOL><INDENT>missing_dates_displayed = list(missing_factor_loadings_index)<EOL><DEDENT>warning_msg = (<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>).format(len(missing_factor_loadings_index), missing_dates_displayed)<EOL>warnings.warn(warning_msg)<EOL>positions = positions.drop(missing_factor_loadings_index,<EOL>errors='<STR_LIT:ignore>')<EOL>returns = returns.drop(missing_factor_loadings_index, errors='<STR_LIT:ignore>')<EOL>factor_returns = factor_returns.drop(missing_factor_loadings_index,<EOL>errors='<STR_LIT:ignore>')<EOL><DEDENT>if transactions is not None and pos_in_dollars:<EOL><INDENT>turnover = get_turnover(positions, transactions).mean()<EOL>if turnover > PERF_ATTRIB_TURNOVER_THRESHOLD:<EOL><INDENT>warning_msg = (<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT:\n>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>)<EOL>warnings.warn(warning_msg)<EOL><DEDENT><DEDENT>return (returns, positions, factor_returns, factor_loadings)<EOL>
Make sure that all inputs have matching dates and tickers,
and raise warnings if necessary.