Hello, I recently wrote code in Python that does the following:

1.) Draws closing data from Yahoo Finance for x number of shares

2.) finds all possible combinations of x shares in groups of y size (i.e. all combinations of 13 shares in groups of 10)

3.) apply some calculations to each of these groups

4.) returns the optimal weights of each group. (Weights mean what percentage of the money should and must be invested in each share = 100%)

5.) Creates a data frame with all optimal portfolio weights (group weights)

My code works, but it is slow. Each loop on my PC takes an average of 2.45 seconds. This is fine for a small number of permutations as in the example above, but as the number of selections increases, so does the number of options. For example, a list of 30 stocks listed in unique groups of 15 has 155117520 ways my code would take over 12 years ….. I'm just looking for suggestions or instructions to speed up the execution of my code improve. I'm relatively new to coding, but I'm aware that Python is slower than other languages in this task. At the moment, however, I only know a few Python basics. I'm using some for loops in this code that I know are slow, and instead I'm looking at using .apply () if you could help in any way it would be desirable.

```
import pandas as pd
from pandas_datareader import data
import datetime
import numpy as np
import random
import itertools
import requests
import time
time1 = time.time()
start = datetime.datetime(2015, 1, 1)
end = datetime.datetime(2019, 12, 31)
list2 = ()
num = ()
#################SP Download#######################
sptickers1 = ('MMM', 'ABT', 'ABBV', 'ABMD', 'ACN', 'ATVI', 'ADBE', 'AMD', 'AAP', 'AES', 'AFL', 'A', 'APD', 'AKAM', 'ALK', 'ALB', 'ARE', 'ALXN', 'ALGN', 'ALLE', 'AGN', 'ADS', 'LNT', 'ALL', 'GOOGL', 'GOOG', 'MO', 'AMZN', 'AMCR', 'AEE', 'AAL', 'AEP', 'AXP', 'AIG', 'T', 'AMT', 'AWK', 'AMP', 'ABC', 'AME', 'AMGN', 'APH', 'ADI', 'ANSS', 'ANTM', 'AON', 'AOS', 'APA', 'AIV', 'AAPL', 'AMAT', 'APTV', 'ADM', 'ARNC', 'ANET', 'AJG', 'AIZ', 'ATO', 'ADSK', 'ADP', 'AZO', 'AVB', 'AVY', 'BKR', 'BLL', 'BAC', 'BK', 'BAX', 'BDX', 'BBY', 'BIIB', 'BLK', 'BA', 'BKNG', 'BWA', 'BXP', 'BSX', 'BMY', 'AVGO', 'BR', 'CHRW', 'COG', 'CDNS', 'CPB', 'COF', 'CPRI', 'CAH', 'KMX', 'CCL', 'CAT', 'CBOE', 'CBRE', 'CDW', 'CE', 'CNC', 'CNP', 'CTL', 'CERN', 'CF', 'SCHW', 'CHTR', 'CVX', 'CMG', 'CB', 'CHD', 'CI', 'CINF', 'CTAS', 'CSCO', 'C', 'CFG', 'CTXS', 'CLX', 'CME', 'CMS', 'KO', 'CTSH', 'CL', 'CMCSA', 'CMA', 'CAG', 'CXO', 'COP', 'ED', 'STZ', 'COO', 'CPRT', 'GLW', 'CTVA', 'COST', 'COTY', 'CCI', 'CSX', 'CMI', 'CVS', 'DHI', 'DHR', 'DRI', 'DVA', 'DE', 'DAL', 'XRAY', 'DVN', 'FANG', 'DLR', 'DFS', 'DISCA', 'DISCK', 'DISH', 'DG', 'DLTR', 'D', 'DOV', 'DOW', 'DTE', 'DUK', 'DRE', 'DD', 'DXC', 'ETFC', 'EMN', 'ETN', 'EBAY', 'ECL', 'EIX', 'EW', 'EA', 'EMR', 'ETR', 'EOG', 'EFX', 'EQIX', 'EQR', 'ESS', 'EL', 'EVRG', 'ES', 'RE', 'EXC', 'EXPE', 'EXPD', 'EXR', 'XOM', 'FFIV', 'FB', 'FAST', 'FRT', 'FDX', 'FIS', 'FITB', 'FE', 'FRC', 'FISV', 'FLT', 'FLIR', 'FLS', 'FMC', 'F', 'FTNT', 'FTV', 'FBHS', 'FOXA', 'FOX', 'BEN', 'FCX', 'GPS', 'GRMN', 'IT', 'GD', 'GE', 'GIS', 'GM', 'GPC', 'GILD', 'GL', 'GPN', 'GS', 'GWW', 'HRB', 'HAL', 'HBI', 'HOG', 'HIG', 'HAS', 'HCA', 'PEAK', 'HP', 'HSIC', 'HSY', 'HES', 'HPE', 'HLT', 'HFC', 'HOLX', 'HD', 'HON', 'HRL', 'HST', 'HPQ', 'HUM', 'HBAN', 'HII', 'IEX', 'IDXX', 'INFO', 'ITW', 'ILMN', 'INCY', 'IR', 'INTC', 'ICE', 'IBM', 'IP', 'IPG', 'IFF', 'INTU', 'ISRG', 'IVZ', 'IPGP', 'IQV', 'IRM', 'JKHY', 'J', 'JBHT', 'SJM', 'JNJ', 'JCI', 'JPM', 'JNPR', 'KSU', 'K', 'KEY', 'KEYS', 'KMB', 'KIM', 'KMI', 'KLAC', 'KSS', 'KHC', 'KR', 'LB', 'LHX', 'LH', 'LRCX', 'LW', 'LVS', 'LEG', 'LDOS', 'LEN', 'LLY', 'LNC', 'LIN', 'LYV', 'LKQ', 'LMT', 'L', 'LOW', 'LYB', 'MTB', 'M', 'MRO', 'MPC', 'MKTX', 'MAR', 'MMC', 'MLM', 'MAS', 'MA', 'MKC', 'MXIM', 'MCD', 'MCK', 'MDT', 'MRK', 'MET', 'MTD', 'MGM', 'MCHP', 'MU', 'MSFT', 'MAA', 'MHK', 'TAP', 'MDLZ', 'MNST', 'MCO', 'MS', 'MOS', 'MSI', 'MSCI', 'MYL', 'NDAQ', 'NOV', 'NTAP', 'NFLX', 'NWL', 'NEM', 'NWSA', 'NWS', 'NEE', 'NLSN', 'NKE', 'NI', 'NBL', 'JWN', 'NSC', 'NTRS', 'NOC', 'NLOK', 'NCLH', 'NRG', 'NUE', 'NVDA', 'NVR', 'ORLY', 'OXY', 'ODFL', 'OMC', 'OKE', 'ORCL', 'PCAR', 'PKG', 'PH', 'PAYX', 'PAYC', 'PYPL', 'PNR', 'PBCT', 'PEP', 'PKI', 'PRGO', 'PFE', 'PM', 'PSX', 'PNW', 'PXD', 'PNC', 'PPG', 'PPL', 'PFG', 'PG', 'PGR', 'PLD', 'PRU', 'PEG', 'PSA', 'PHM', 'PVH', 'QRVO', 'PWR', 'QCOM', 'DGX', 'RL', 'RJF', 'RTN', 'O', 'REG', 'REGN', 'RF', 'RSG', 'RMD', 'RHI', 'ROK', 'ROL', 'ROP', 'ROST', 'RCL', 'SPGI', 'CRM', 'SBAC', 'SLB', 'STX', 'SEE', 'SRE', 'NOW', 'SHW', 'SPG', 'SWKS', 'SLG', 'SNA', 'SO', 'LUV', 'SWK', 'SBUX', 'STT', 'STE', 'SYK', 'SIVB', 'SYF', 'SNPS', 'SYY', 'TMUS', 'TROW', 'TTWO', 'TPR', 'TGT', 'TEL', 'FTI', 'TFX', 'TXN', 'TXT', 'TMO', 'TIF', 'TJX', 'TSCO', 'TT', 'TDG', 'TRV', 'TFC', 'TWTR', 'TSN', 'UDR', 'ULTA', 'USB', 'UAA', 'UA', 'UNP', 'UAL', 'UNH', 'UPS', 'URI', 'UTX', 'UHS', 'UNM', 'VFC', 'VLO', 'VAR', 'VTR', 'VRSN', 'VRSK', 'VZ', 'VRTX', 'V', 'VNO', 'VMC', 'WRB', 'WAB', 'WMT', 'WBA', 'DIS', 'WM', 'WAT', 'WEC', 'WFC', 'WELL', 'WDC', 'WU', 'WRK', 'WY', 'WHR', 'WMB', 'WLTW', 'WYNN', 'XEL', 'XRX', 'XLNX', 'XYL', 'YUM', 'ZBRA', 'ZBH', 'ZION', 'ZTS')
dstocks = sptickers1(0:13)
df = data.DataReader(dstocks, 'yahoo', start, end)('Close')
combinations = list(itertools.combinations(dstocks, 10))
combinationslist = ()
for i in combinations:
combinationslist.append(list(i))
for i in combinationslist:
try:
start_time = time.time()
df1 = df(i).copy()
dfpct = df1.pct_change().apply(lambda x: np.log(x+1))
sdd = dfpct.std()
sda = sdd.apply(lambda x: x*np.sqrt(250))
var = dfpct.var()
cov_matrix = dfpct.cov()
dfer = df1.resample('Y').last().pct_change()
er = dfer.mean()
p_ret = ()
p_vol = ()
p_weights = ()
num_p = 1000
for portfolio in range(num_p):
n = len(i)
weights = (random.random() for e in range(n))
sum_weights = sum(weights)
weights = (w/sum_weights for w in weights)
p_weights.append(weights)
returns = np.dot(weights, er)
p_ret.append(returns)
p_var = cov_matrix.mul(weights, axis = 0).mul(weights, axis=1).sum().sum()
p_sd = np.sqrt(p_var)
p_sda = p_sd*np.sqrt(250)
p_vol.append(p_sda)
data = {'Returns':p_ret, 'Volatility':p_vol}
for counter, symbol in enumerate(dfpct.columns.tolist()):
data(symbol+ ' Weight') = (w(counter) for w in p_weights)
portfolios = pd.DataFrame(data)
rf = 0.02
optimaln = ((portfolios('Returns')-rf)/portfolios('Volatility')).idxmax()
optimal = portfolios.loc(optimaln)
optimal1 = pd.DataFrame(optimal).transpose()
optimal1I = optimal1.index.tolist()
dictoptimal = portfolios.loc(optimal1I).to_dict(orient='records')
list2.append(dictoptimal)
end_time = time.time()
print("total time taken this loop: ", end_time - start_time)
except:
print('Didnt work')
num.append('didnt work')
continue
print(len(num))
fin = pd.DataFrame.from_dict(list2)
time2 = time.time()
print('program took ' + str(time2-time1) + ' Seconds')
```
```