This function sorts stocks into quantiles. To do so I used this function that accepts `sig_df`

(dataframe with the timeseries of stocks signal) and number of quantiles as imput:

`qs = ['Q' + str(i) for i in range(1, len(perc)+1)] q_labels= list(itertools.chain.from_iterable( itertools.repeat(x, int(sig_df.shape[1]/q_num)) for x in qs)) rank_labels = ['rank_{}'.format(i) for i in range(sig_df.shape[1])] bucketed_names = pd.DataFrame( sig_df.columns.values[np.argsort(-sig_df.values, axis=1)], columns=[q_labels, rank_labels] ) `

The second function computes portfolio returns, based on the names bucketed in the function above. It accepts two input a `df`

containing stocks return and the output from the function above. To do so I used:

`bucketed_returns = dict() for i in range(1, int(ret_df.shape[1]/bucketed_names.Q1.shape[1])): Q = [] for row in bucketed_names['Q' + str(i)].itertuples(): temp = ret_df.loc[list(row[:1]) ,list(row[1:])] Q.append(float(np.dot(temp, weights))) bucketed_returns['Q' + str(i)] = Q bucketed_returns = pd.DataFrame(bucketed_returns) `

To optimize this code I thought about multiprocessing – not able to code that – or maybe there could be a better way remaining in pandas/numpy environment.