def addCustomColumns(df, market_upd=False): start = datetime.date( int(df.index.get_level_values('date')[0]) - 10, int(df['month'].values[0]), 1) end_date_ls = [ int(d) for d in datetime.date.today().strftime('%Y-%m-%d').split("-") ] end = datetime.date(end_date_ls[0], end_date_ls[1], end_date_ls[2]) try: url = "https://www.quandl.com/api/v1/datasets/WIKI/{0}.csv?column=4&sort_order=asc&trim_start={1}&trim_end={2}".format( df.index.get_level_values('ticker')[0], start, end) qr = pd.read_csv(url) qr['Date'] = qr['Date'].astype('datetime64[ns]') # quotes = DataReader(df.index.get_level_values('ticker')[0], 'yahoo', start, end, pause=1)['Close'] # quotes = DataReader(df.index.get_level_values('ticker')[0], 'yahoo', start, end, pause=1)['Close'] except: print("Could not read time series data for %s" % df.index.get_level_values('ticker')[0]) exc_type, exc_obj, exc_tb = sys.exc_info() app.logger.info( "Could not read time series data for {3}: {0}, {1}, {2}".format( exc_type, exc_tb.tb_lineno, exc_obj, df.index.get_level_values('ticker')[0])) raise df = addBasicCustomCols(df, qr) df = addGrowthCustomCols(df, qr) df = addTimelineCustomCols(df, qr) pdb.set_trace() if market_upd: # market = DataReader(".INX", 'google', start, end, pause=1)['Close'] market = DataReader('^GSPC', 'yahoo', start, end, pause=1)['Close'] market.to_csv( '/home/ubuntu/workspace/finance/app/static/docs/market.csv') quotes = pd.DataFrame(quotes) market.columns = ['Date', 'market'] market.set_index('Date') quotes['market'] = market else: market = pd.read_csv( '/home/ubuntu/workspace/finance/app/static/docs/market.csv') market.columns = ['Date', 'market'] market['Date'] = market['Date'].apply(pd.to_datetime) market = market.set_index('Date') qr = pd.merge(qr.set_index('Date'), market, left_index=True, right_index=True) df = calcBetas(df, qr) ''' Still need to do: 'enterpriseToEbitda' 'ebitdaMargins' 'ebitda', 'shortRatio' ''' return df
def get_timeseries_gross_return(symbols, startdate, enddate): """Return price return timeseries Keyword arguments: symbols -- Symbol or list of Symbols (string / [string]) startdate -- timeseries start date (datetime.date(year, month, day)) enddate -- timeseries end date (datetime.date(year, month, day)) """ if type(symbols) == str: symbols = [symbols] data = [] for symbol in symbols: try: df = DataReader(symbol, 'yahoo', startdate, enddate)[['Adj Close']] df.columns = [symbol] except: df = pd.DataFrame(np.nan, index=pd.bdate_range(startdate, enddate), columns=[symbol]) data.append(df) return pd.concat(data, axis=1, join='outer')
def get_timeseries_gross_return(symbols, startdate, enddate): """Return price return timeseries Keyword arguments: symbols -- Symbol or list of Symbols (string / [string]) startdate -- timeseries start date (datetime.date(year, month, day)) enddate -- timeseries end date (datetime.date(year, month, day)) """ if type(symbols) == str: symbols = [symbols] data = [] for symbol in symbols: try: df = DataReader(symbol, 'yahoo', startdate, enddate)[['Adj Close']] df.columns = [symbol] except: df = pd.DataFrame(np.nan, index=pd.bdate_range(startdate, enddate), columns=[symbol]) data.append(df) return pd.concat(data, axis=1, join='outer')
def get_timeseries_pricing(symbols, startdate, enddate, field='Adj Close'): """Returns pricing/volume table field timeseries Keyword arguments: symbols -- Symbol or list of Symbols (string / [string]) startdate -- timeseries start date (datetime.date(year, month, day)) enddate -- timeseries end date (datetime.date(year, month, day)) field -- 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close' """ if type(symbols) == str: symbols = [symbols] data = [] for symbol in symbols: try: df = DataReader(symbol, 'yahoo', startdate, enddate)[[field]] df.columns = [symbol] except: df = pd.DataFrame(np.nan, index=pd.bdate_range(startdate, enddate), columns=[symbol]) data.append(df) return pd.concat(data, axis=1, join='outer')
import matplotlib.pyplot as plt from Functions import * start_time = time.time() # Set the start date start = date(1950,1,1) # Define the series codes series = ['UNRATE', 'CIVPART'] # Import the data econ_data = DataReader(series,'fred',start) # Assign new column labels econ_data.columns = ['Unemployment Rate','Participation Rate'] econ_data = econ_data.reset_index() econ_data['decade'] = econ_data['DATE'].astype(str).str[2:3] econ_data['decade'] = econ_data['decade'].astype(str) econ_data['decade'] = econ_data['decade'] + "0s" # Plot econ_data _ = econ_data.plot(subplots=True,title='Labor Market') plt.margins(.2) # Show the plot plt.show() data = econ_data['Unemployment Rate'] x,y = ecdf(data) _ = plt.plot(x, y, marker='.', linestyle='none') _ = plt.xlabel('Unemployment Rate') _ = plt.ylabel('CDF') _ = plt.margins(0.2)
def __update(self): """Updates class attributes.""" p, mv, rf = self.__prices, self.__mv, self.__rf # Select attributes different from 'None' li = [x for x in (p, mv, rf) if x is not None] # if there is no element in the list, i.e., if all attributes are 'None' if len(li) == 0: self.__date = None # if there is only one element not 'None' in the list, 'self.__date' should be equal to its index elif len(li) == 1: self.__date: np.ndarray = li[0].index.to_numpy() # if there is at least 2 attributes that are not 'None' we must verify if rows match in length and in values else: # if lengths match (to prevent ValueError) if self.__check_index_length_match(li): # if length and values are the same if self.__check_index_values_match(li): self.__date = li[0].index.to_numpy().copy() # if lengths are equal among each dataset index, but not the values else: # if values do not match, we force them to take the same print( "Lengths of rows match, but not they have different values." ) self.__date = li[0].index.to_numpy().copy() self.__make_indices_values_match() assert self.__check_index_values_match(li) # if any length mismatch, we truncate all DataFrames or Series else: # Get the oldest date among the list of DataFrames min_date = min([df.index.min() for df in li]) # In the case there is a risk-free rate and that it begins after the other series: try # to complete it with the 3 month proxy if (self.__rf is not None) & (self.__rf.index[0] > min_date): # Get initial date of the risk-free rate series end = rf.index[0] # 3-Month Treasury Constant Maturity Rate (GS3M) rf3m = DataReader('GS3M', 'fred', start=min_date, end=end).resample('MS').mean() # We have to drop the last row to prevent overlapping # We couldn't have used timedelta to go back 1 month as some have 31 days while others 30 rf3m.drop(rf3m.tail(1).index, inplace=True) rf3m.columns = rf.columns rf3m = rf3m.div(100).div(12) # Concatenate both risk-free rates pd.Series rf_concat = pd.concat([rf3m, self.__rf], sort=True) errmsg: str = f"Got {rf_concat.shape} shape, but ({len(li[0].index)}, 1) expected." assert rf_concat.shape[1] == 1, errmsg self.__rf = rf_concat # Join both series in a sole one # self.__rf = rf_concat.iloc[:, 0].add(rf_concat.iloc[:, 1], fill_value=0) else: # Truncate rows of different length according to their dates self.__truncate_rows() # Verify if the rows were correctly truncated not_none_attributes_list = self.__among_not_none_attributes( ) err_message = "Rows were not correctly truncated" assert self.__check_index_length_match( not_none_attributes_list), err_message # Update the 'self.__date' attribute with the first item self.__date = not_none_attributes_list[0].index.to_numpy( ).copy() # Propagate same indexes to the other datasets to force a perfect match self.__make_indices_values_match() # Verify that indices have same indexes err_message = "Values do not match among not 'None' attributes." assert self.__check_index_values_match( self.__among_not_none_attributes()), err_message self.__update()
d1num = (log(stock / strike) + (risk_free_rate + 0.5 * sigma *sigma) * time) d2 = d1 - sigma * sqrt(time) def delta_call_europe(d1): return norm.cdf(d1) def delta_put_europe(d1): return -(norm.cdf(-d1)) delta_call_europe(d1) ######################################################################### oil = DataReader('DCOILWTICO', 'fred', start_data, today) oil.columns = ['WTI'] wec = pdr.get_data_yahoo('WEC', start_data , today) wec = wec['Close'] wec = pd.DataFrame(wec) wec_oil_df = wec.join(oil['WTI'], how='left') wec_oil_df = wec_oil_df[wec_oil_df['WTI'].notnull()] # drop rows with NaN wec_oil_df['SP500_PctReturn'] = wec_oil_df['Close'].pct_change() wec_oil_df['Oil_PctReturn'] = wec_oil_df['WTI'].pct_change() wec_oil_df['SP500_LogReturn'] = np.log(1+wec_oil_df['SP500_PctReturn']) wec_oil_df['Oil_LogReturn'] = np.log(1+wec_oil_df['Oil_PctReturn']) wec_oil_df['1MoCorr_Prices'] = wec_oil_df['Close'].rolling(22).corr(wec_oil_df['WTI']) wec_oil_df['1MoCorr_PctReturn'] = wec_oil_df['SP500_PctReturn'].rolling(22).corr(wec_oil_df['Oil_PctReturn']) wec_oil_df['1MoCorr_LogReturn'] = wec_oil_df['SP500_LogReturn'].rolling(22).corr(wec_oil_df['Oil_LogReturn'])
def stock_info(ticker): today = datetime.today() beginDate = '2020-01-01' endDate = datetime.datetime.now().date() script = "9ho5HG7o00PT-g" secret = "2CQTFbYyYp5aLEN7bHkKGO8X4E3YHQ" beginDate = '2020-12-01' endDate = datetime.today().strftime('%Y-%m-%d') def df_from_response(res): df = pd.DataFrame() for post in res.json()['data']['children']: df = df.append( { 'subreddit': post['data']['subreddit'], 'title': post['data']['title'], 'selftext': post['data']['selftext'], 'num_comments': post['data']['num_comments'], 'upvote_ratio': post['data']['upvote_ratio'], 'date': datetime.fromtimestamp( post['data']['created_utc']).strftime('%Y-%m-%d'), 'ups': post['data']['ups'], 'downs': post['data']['downs'], 'score': post['data']['score'], 'kind': post['kind'], 'id': post['data']['id'], }, ignore_index=True) return df auth = requests.auth.HTTPBasicAuth(script, secret) data = { 'grant_type': 'password', 'username': '******', 'password': '******' } headers = {'User-Agent': 'Final_Project/0.0.1'} request = requests.post('https://www.reddit.com/api/v1/access_token', auth=auth, data=data, headers=headers) token = f"bearer {request.json()['access_token']}" headers = {**headers, **{'Authorization': token}} posts = pd.read_csv("trimmed_posts.csv") selected_cols = ['title', 'selftext'] df = DataReader(ticker, 'yahoo', beginDate, endDate) df['Close'] = df['Adj Close'] df = df.drop(columns=['Adj Close', 'High', 'Low', 'Open'], axis=1) modelData = df['Close'].to_frame() five_rolling = modelData.rolling(window=5).mean() ten_rolling = modelData.rolling(window=10).mean() twenty_rolling = modelData.rolling(window=20).mean() fifty_rolling = modelData.rolling(window=50).mean() hundred_rolling = modelData.rolling(window=100).mean() futureDays = 10 modelData['Target'] = modelData['Close'].shift(-futureDays) X = np.array(modelData.drop(['Target'], 1))[:-futureDays] y = np.array(modelData['Target'])[:-futureDays] Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, test_size=0.25) Xfuture = modelData.drop(['Target'], 1)[:-futureDays] Xfuture = Xfuture.tail(futureDays) Xfuture = np.array(Xfuture) train_data, test_data = df[0:int(len(df) * 0.7)], df[int(len(df) * 0.75):] training_data = train_data['Close'].values test_data = test_data['Close'].values history = [x for x in training_data] model_predictions = [] N_test_observations = len(test_data) for time_point in range(N_test_observations): model = ARIMA(history, order=(4, 1, 0)) model_fit = model.fit(disp=0) output = model_fit.forecast() yhat = output[0] model_predictions.append(yhat) true_test_value = test_data[time_point] history.append(true_test_value) MSE_error = mean_squared_error(test_data, model_predictions) linear = LinearRegression().fit(Xtrain, ytrain) linearPrediction = linear.predict(Xfuture) linearResult = linear.score(Xtrain, ytrain) valid = modelData[X.shape[0]:] valid['Target'] = predictions tree = DecisionTreeRegressor().fit(Xtrain, ytrain) treePrediction = tree.predict(Xfuture) treeResult = tree.score(Xtrain, ytrain) predictions = treePrediction valid = modelData[X.shape[0]:] valid['Predict'] = predictions todaysDate = datetime.datetime.now().date() futureDays = 10 us_bd = CustomBusinessDay(calendar=USFederalHolidayCalendar()) futureDates = pd.date_range(todaysDate, periods=futureDays, freq=us_bd) combinedDFcol = ['Close', 'Predict', 'SM1', 'SM2', 'SM3', 'SM4'] futureDF = pd.DataFrame(index=futureDates, columns=combinedDFcol) futureDF['Predict'] = model_fit.forecast(steps=futureDays)[0] combinedDF = df.append(futureDF, ignore_index=False) combinedDF.index.names = ['Date'] currInfo = yf.Ticker(ticker).info currInfo = yf.Ticker(ticker).info infoDict = { 'longName: ': currInfo['symbol'], 'Current Ask/Bid: ': str(currInfo['ask']) + '/' + str(currInfo['bid']), 'Open Price: ': str(round(currInfo['open'], 2)), 'High/Low Price: ': str(currInfo['dayHigh']) + '/' + str(currInfo['dayLow']), 'Avg Volume: ': str(currInfo['averageVolume']), 'Volume: ': str(currInfo['volume']), '52w High: ': str(round(currInfo['fiftyTwoWeekHigh'], 2)), '52w Low: ': str(round(currInfo['fiftyTwoWeekLow'], 2)), 'MorningStar Rating: ': str(currInfo['morningStarOverallRating']), 'Short Ratio: ': str(currInfo['shortRatio']) } try: new_df = posts[posts[selected_cols].apply( lambda x: x.str.contains(ticker)).all(axis=1)] data = new_df data['Ticker'] = ticker group_df = new_df.groupby('created_utc') \ .agg({'id':'count', 'num_comments':'mean', 'score':'mean'}) \ .rename(columns={'id':'post_count','num_comments':'avg_comments', 'score':'avg_score'}) \ .reset_index() group_df['Ticker'] = ticker except: places = { 'created_utc': 0, 'post_count': 0, 'avg_comments': 0, 'avg_score': 0, 'ticker': ticker } group_df = pd.DataFrame.from_dict(places) super_posts_df = data.loc[data['score'] > 300] if not super_posts_df.empty: super_posts_df = super_posts_df.groupby( ['created_utc', 'Ticker'])['score'].apply(lambda x: (x >= 300).sum()).reset_index( name='Count_Score_300') try: pytrend = TrendReq(hl='en-US', tz=360) pytrend.build_payload(kw_list=[ticker], timeframe=beginDate + ' ' + endDate, geo='US') df = pytrend.interest_over_time() df['Noise'] = df[ticker] df[ticker] = ticker df.index.names = ['Date'] df.columns = ['Ticker', 'isPartial', 'Noise'] mergedNoise = df except: noise = {'Ticker': ticker, 'isPartial': 'No', 'Noise': 0} mergedNoise = pd.DataFrame.from_dict(noise) group_df['created_utc'] = pd.to_datetime(group_df['created_utc']) if not super_posts_df.empty: super_posts_df['created_utc'] = pd.to_datetime( super_posts_df['created_utc']) merged = group_df.merge(mergedNoise, left_on=['created_utc', 'Ticker'], right_on=['Date', 'Ticker'], how='left') if not super_posts_df.empty: merged = merged.merge(super_posts_df, left_on=['created_utc', 'Ticker'], right_on=['created_utc', 'Ticker'], how="left") else: merged['Count_Score_300'] = 0 merged.drop(columns=['isPartial']) stockData = yf.download(ticker, start=beginDate, end=endDate) stockData['Ticker'] = ticker stockReport = pd.DataFrame(stockData, columns=['Ticker', 'Adj Close', 'Volume']) merged = merged.merge(stockReport, left_on=['created_utc', 'Ticker'], right_on=['Date', 'Ticker'], how='left') merged['post_count_change'] = merged['post_count'].pct_change() merged['avg_score_change'] = merged['avg_score'].pct_change() merged['Adj Close_change'] = merged['Adj Close'].pct_change() merged['Volume_change'] = merged['Volume'].pct_change() merged.replace([np.inf, -np.inf], np.nan, inplace=True) merged.replace([np.inf, -np.inf], np.nan).dropna( subset=['post_count_change', 'avg_score_change', 'Volume_change'], how="all") merged = merged.dropna() expected_posts = merged['post_count'].mean() expected_avg_comments = merged['avg_comments'].mean() expected_volume_change = merged['Volume'].mean() expected_300_count = merged['Count_Score_300'].mean() data = pd.DataFrame() length = 0 try: params = {'limit': 100, 'q': ticker, 'restrict_sr': True} res = requests.get("https://oauth.reddit.com/r/WallStreetBets/search", headers=headers, params=params) new_df = df_from_response(res) new_df.sort_values(by=['date'], inplace=True, ascending=False, axis=0) row = new_df.iloc[len(new_df) - 1] fullname = row['kind'] + '_' + row['id'] params['after'] = fullname data = data.append(new_df, ignore_index=True) except: data data['date'] = pd.to_datetime(data['date']) super_posts_live = data.groupby('date')['score'].apply( lambda x: (x >= 300).sum()).reset_index(name='Count_Score_300') if not super_posts_live.empty: super_posts_live = super_posts_live else: super_posts_live['Count_Score_300'] = 0 try: data['Ticker'] = ticker live_group = data.groupby('date') \ .agg({'id':'count', 'num_comments':'mean', 'score':'mean'}) \ .rename(columns={'id':'post_count','num_comments':'avg_comments', 'score':'avg_score'}) \ .reset_index() live_group['Ticker'] = ticker except: places = { 'created_utc': 0, 'post_count': 0, 'avg_comments': 0, 'avg_score': 0, 'ticker': ticker } live_group = pd.DataFrame.from_dict(places) live_group = live_group.merge(super_posts_live, left_on=['date'], right_on=['date'], how="left") live_group = live_group.merge(stockReport, left_on=['date', 'Ticker'], right_on=['Date', 'Ticker'], how='left') live_group['Adj Close_change'] = live_group['Adj Close'].pct_change() live_group['Volume_change'] = live_group['Volume'].pct_change() live_group['post_count_change'] = live_group['post_count'].pct_change() live_group['avg_score_change'] = live_group['avg_score'].pct_change() xfits = live_group[live_group.date > datetime.now() - pd.to_timedelta("3day")] xfits_dates = xfits['date'] xfittings = xfits[[ 'post_count_change', 'avg_score_change', 'Volume_change', 'Count_Score_300' ]] X_fits_scaled = X_scaler.transform(xfittings) social_predictions = model.predict(X_fits_scaled) social_predictions = pd.DataFrame(social_predictions.reshape(-1, 1)) Xnew, _ = make_regression(n_samples=10, n_features=4, noise=0.01, random_state=1) ynew = model.predict(Xnew) future_predict_df = pd.DataFrame(ynew.reshape(-1, 1)) live_group.sort_values(by=['date'], inplace=True, ascending=False) future_dates = pd.date_range(start=today, periods=10).strftime('%Y-%m-%d') futureDates = pd.date_range(todaysDate, periods=futureDays, freq=us_bd) futureDates['SMPredict'] = df.append(future_predict_df, ignore_index=False) SMPredict = pd.DataFrame(index=future_dates, columns=combinedDFcol) future_predict_df = pd.DataFrame(ynew.reshape(-1, 1), future_dates) future_predict_df.rename(columns={0: "SMPredict"}) SMPredict = SMPredict.merge(future_predict_df, left_index=True, right_index=True, how="left") xfits = xfits.drop(columns=[ 'Ticker', 'Adj Close_change', 'Volume_change', 'post_count_change', 'avg_score_change' ]) xfits['SMPredictions'] = social_predictions xfits = xfits.set_index('date') xfits = df.append(SMPredict, ignore_index=False) xfits = xfits.drop(columns=['Ticker', 'isPartial', 'Noise']) xfits.index.name = "Date" combinedDFcol = ['Close', 'Predict', 'SM1', 'SM2', 'SM3', 'SM4'] futureDF = pd.DataFrame(index=futureDates, columns=combinedDFcol) futureDF['Predict'] = model_fit.forecast(steps=futureDays)[0] combinedDF = df.append(futureDF, ignore_index=False) combinedDF.index.name = ['Date'] today_dict = xfits.to_dict() futureSM_prediction = SMPredict.to_dict() carls_dict = combinedDF.to_dict() return ({today_dict, futureSM_prediction, carls_dict})
from statsmodels.tsa.vector_ar.vecm import select_order from statsmodels.tsa.vector_ar.vecm import select_coint_rank from statsmodels.tsa.vector_ar.vecm import VECM from dateutil.relativedelta import relativedelta start_data = datetime.now() - relativedelta(years=66) today = datetime.now() from pandas_datareader.data import DataReader consumer_df = DataReader([ 'PCE', 'UMCSENT', 'UNRATE', 'LCEAMN01USM189S', 'TOTALSL', 'MRTSSM44X72USS', 'HOUST' ], 'fred', start_data, today) consumer_df = consumer_df.dropna() consumer_df.columns = [ 'PCE', 'ConConf', 'Unempl', 'HourlyEarning', 'CCredit', 'RetSales', 'HouseStarts' ] consumer_df = consumer_df.resample('1M').mean() type(consumer_df) # lag order selection lag_order = select_order(data=consumer_df, maxlags=10, deterministic="ci", seasons=12) print(lag_order.summary()) print(lag_order) # Cointegration rank rank_test = select_coint_rank(consumer_df, 0, 2, method="trace", signif=0.05) rank_test.rank
data.plot(title=series_name) plt.show() # combine stock and economic data start = date(1999, 1, 1) # default Jan 1, 2010 series = 'DDCOILWTICO' # West Texas Intermdiate Oil Price data_source = 'fred' # FED Economic Data Service oil = DataReader(series, data_source, start) ticker = 'XOM' # Exxon Mobile Corporation data_source = 'google' stock_data = DataReader(ticker, data_source, start) data = pd.concat([stock[['Close']], oil], axis=1) data.info() data.columns = ['Exxon', 'Oil Price'] data.plot() plt.show() ####################### import pandas as pd from pandas_datareader.data import DataReader from datetime import date # Set start date start = date(1968, 1, 1) series = 'GOLDAMGBD228NLBM' # Import the data gold_price = DataReader(series, 'fred', start)
# T10YIE = 10-Year Breakeven Inflation Rate # NASDAQCOM = NASDAQ # DJIA = Dow Jones Industrial Average # SAVINGS = Total Savings Deposits at all Depository Institutions # SP500 = S&P 500 # CLVMNACSCAB1GQUK = Real Gross Domestic Product for United Kingdom # CLVMNACSCAB1GQDE = Real Gross Domestic Product for Germany series = ['DEXUSEU', 'UNRATE'] # ______________________________________________________ CONNECT TO FRED econ_data = DataReader(series, 'fred', start) # ______________________________________________________ CLEAN DATA econ_data.columns = [ 'U.S. / Euro Foreign Exchange Rate', 'USA Unemployment Rate' ] econ_data = econ_data.reset_index() econ_data['decade'] = econ_data['DATE'].astype(str).str[2:3] econ_data['decade'] = econ_data['decade'].astype(str) econ_data['decade'] = econ_data['decade'] + "0s" # fig, ax = plt.subplots(figsize=(15, 5)) sns.lineplot(x='DATE', y="U.S. / Euro Foreign Exchange Rate", data=econ_data, hue=econ_data.decade.tolist(), ax=ax) #plt.xlabel('Date') #plt.ylabel('U.S. / Euro Foreign Exchange Rate')
import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator, PercentFormatter, FormatStrFormatter import matplotlib.dates as mdates from matplotlib.dates import MonthLocator, DateFormatter from matplotlib import rc, rcParams from dateutil.relativedelta import relativedelta ### Copper/Gold Index vs US 10-Year ################################# ## Data start_data = date(2018, 1, 1) today = datetime.now() copper_gold_df = DataReader(['GOLDAMGBD228NLBM', 'DGS10'], 'fred', start_data, today) copper_gold_df.columns = ['Gold', 'U.S. 10-Year'] copper = DataReader('CHRIS/CME_HG1', 'quandl', start_data, today, access_key="h8vqKTPis9Jf25z6woGz") copper = copper['Last'] * 100 copper = pd.DataFrame(copper) copper.columns = ['copper'] copper_gold_df = copper_gold_df.join(copper, how='left') copper_gold_df['C.G.Index'] = copper_gold_df['copper'] / copper_gold_df['Gold'] copper_gold_df.ffill() ## Inputs start = start_data