def analyzePriceFollow(target_date, stock_id, is_index, threshold): file_postfix = 'Timing_%s_%s' % (u.stockFileName(stock_id, is_index), threshold) timing = u.read_csv(c.path_dict['strategy'] + file_postfix + '.csv', encoding='gbk') timing_number = len(timing) # Find the matched timing date and trend timing_index = -1 for i in range(timing_number): date = dt.datetime.strptime(timing.ix[i, 'date'], '%Y-%m-%d').date() if date <= target_date: timing_index = i else: break # Report results if timing_index != -1: date = dt.datetime.strptime(timing.ix[timing_index, 'date'], '%Y-%m-%d').date() trend = timing.ix[timing_index, 'trend'] if date == target_date: # Given target_date is Timing Date print('Date', target_date, ': Trend of', u.stockFileName(stock_id, is_index), 'Goes', trend) else: print('Date', target_date, ': Trend of', u.stockFileName(stock_id, is_index), 'Does Not Change, Still', trend) else: print('Date', target_date, ': Trend of', u.stockFileName(stock_id, is_index), 'Not Available, No Timing Data')
def loadDailyHFQ(stock_id, is_index): fullpath = c.fullpath_dict['lshq'] % u.stockFileName(stock_id, is_index) # Ensure data file is available if not u.hasFile(fullpath): print('Require LSHQ of %s!' % u.stockFileName(stock_id, is_index)) return None # Read data file df = u.read_csv(fullpath) return df
def lshqCompare(): # Check pre-requisite basics = loadStockBasics() if u.isNoneOrEmpty(basics): print('Need to have stock basics!') raise SystemExit # Iterate over all stocks stocks_number = len(basics) unmatched = [] for i in range(stocks_number): stock_id = u.stockID(basics.loc[i,'code']) file = c.file_trading_lshq % u.stockFileName(stock_id, False) if not fileCompare(src_path + file, tar_path + file): unmatched.append(stock_id) # Output Unmatched print(unmatched)
def getDailyHFQ(stock_id, is_index, date_start, date_end, time_to_market, incremental): hfq = None # For incremental update, use the next day of last update as the date start. if incremental: hfq = loadDailyHFQ(stock_id, is_index) if not u.isNoneOrEmpty(hfq): hfq.set_index('date',inplace=True) hfq.sort_index(ascending=True,inplace=True) last_day = hfq.index[len(hfq)-1] date_start = u.nextDayFromStr(last_day) # Check if existing data file is already up-to-date if date_end < date_start: return # Download if gs.is_debug: print('Download Daily HFQ: %s, start=%s, end=%s' % (stock_id, u.dateToStr(date_start), u.dateToStr(date_end))) df = get_daily_hfq(stock_id=stock_id, is_index=is_index, date_start=date_start, date_end=date_end, time_to_market=time_to_market) if not u.isNoneOrEmpty(df): # Default df has 'date' set as index with type pandas.tslib.Timestamp, # so merged results will contain 00:00:00 along with date. # With below series of operation, index of df will be converted to type # str, thus avoid above issue. df.reset_index(inplace=True) df['date'] = df['date'].map(lambda x:str(x.date())) df.set_index('date',inplace=True) df.sort_index(ascending=True,inplace=True) # For incremental update, merge data if incremental: if (not u.isNoneOrEmpty(df)) and (not u.isNoneOrEmpty(hfq)): df = hfq.append(df) # Format Columns if not u.isNoneOrEmpty(df): for column in ['open', 'high', 'close', 'low', 'volume', 'amount', 'factor']: df[column] = df[column].map(lambda x:'%.3f' % float(x)) # Save to CSV File if not u.isNoneOrEmpty(df): u.to_csv(df, c.path_dict['lshq'], c.file_dict['lshq'] % u.stockFileName(stock_id, is_index))
def strategyAncleXu(stock_id, is_index): # Load Stock Daily QFQ Data lshq = loadDailyQFQ(stock_id, is_index) if u.isNoneOrEmpty(lshq): raise SystemExit # Calculate Long Range High/Low lshq['range_high_long'] = 0.0 lshq['range_low_long'] = 0.0 lshq_number = len(lshq) for i in range(lshq_number): index_beg = (i - bar_range_long) if (i - bar_range_long) > 0 else 0 index_end = i if i > 0 else 1 lshq.ix[i, 'range_high_long'] = np.max(lshq['high'][index_beg:index_end]) lshq.ix[i, 'range_low_long'] = np.min(lshq['low'][index_beg:index_end]) # Calculate Short Range High/Low lshq['range_high_short'] = 0.0 lshq['range_low_short'] = 0.0 for i in range(lshq_number): index_beg = (i - bar_range_short) if (i - bar_range_short) > 0 else 0 index_end = i if i > 0 else 1 lshq.ix[i, 'range_high_short'] = np.max(lshq['high'][index_beg:index_end]) lshq.ix[i, 'range_low_short'] = np.min(lshq['low'][index_beg:index_end]) # Calculate R and Avg(R) lshq['R'] = 0.0 lshq['Avg_R'] = 0.0 for i in range(lshq_number): prev_close = lshq.ix[i - 1, 'close'] if i > 0 else lshq.ix[i, 'open'] high = lshq.ix[i, 'high'] low = lshq.ix[i, 'low'] lshq.ix[i, 'R'] = np.max([ np.abs(high - low), np.abs(high - prev_close), np.abs(low - prev_close) ]) index_beg = (i - r_range) if (i - r_range) > 0 else 0 index_end = i if i > 0 else 1 lshq.ix[i, 'Avg_R'] = np.mean(lshq['R'][index_beg:index_end]) # Save to CSV File file_postfix = 'AncleXu_%s' % u.stockFileName(stock_id, is_index) u.to_csv(lshq, c.path_dict['strategy'], c.file_dict['strategy'] % file_postfix) # Run Strategy lshq['long_open'] = False lshq['long_close'] = False lshq['short_open'] = False lshq['short_close'] = False has_long_open = False has_short_open = False event_index = [] for i in range(lshq_number): close = lshq.ix[i, 'close'] range_high_long = lshq.ix[i, 'range_high_long'] range_low_long = lshq.ix[i, 'range_low_long'] range_high_short = lshq.ix[i, 'range_high_short'] range_low_short = lshq.ix[i, 'range_low_short'] has_event = False if has_long_open == False: if close > range_high_long: # Long Open lshq.ix[i, 'long_open'] = True has_long_open = True has_event = True else: if close < range_low_short: lshq.ix[i, 'long_close'] = True has_long_open = False has_event = True if has_short_open == False: if close < range_low_long: # Short Open lshq.ix[i, 'short_open'] = True has_short_open = True has_event = True else: if close > range_high_short: lshq.ix[i, 'short_close'] = True has_short_open = False has_event = True if has_event: event_index.append(i) # Strategy Statistics stats = lshq.ix[event_index, [ 'date', 'close', 'long_open', 'long_close', 'short_open', 'short_close' ]] if gs.is_debug: print(stats.head(10)) stats_number = len(stats) long_number = 0 short_number = 0 long_open_date = [] long_open_price = [] long_close_date = [] long_close_price = [] short_open_date = [] short_open_price = [] short_close_date = [] short_close_price = [] for i in range(stats_number): index = stats.index[i] print('Type is:', type(stats.ix[index, 'long_open'])) if stats.ix[index, 'long_open'] == True: # Long Open long_open_date.append(stats.ix[index, 'date']) long_open_price.append(stats.ix[index, 'close']) if stats.ix[index, 'long_close'] == True: # Long Close long_close_date.append(stats.ix[index, 'date']) long_close_price.append(stats.ix[index, 'close']) long_number = long_number + 1 if stats.ix[index, 'short_open'] == True: # Short Open short_open_date.append(stats.ix[index, 'date']) short_open_price.append(stats.ix[index, 'close']) if stats.ix[index, 'short_close'] == True: # Short Close short_close_date.append(stats.ix[index, 'date']) short_close_price.append(stats.ix[index, 'close']) short_number = short_number + 1 # Profit Statistics long_profit = [] total_long_profit = 0.0 for i in range(long_number): profit = long_close_price[i] - long_open_price[i] long_profit.append(profit) total_long_profit = total_long_profit + profit short_profit = [] total_short_profit = 0.0 for i in range(short_number): profit = short_open_price[i] - short_close_price[i] short_profit.append(profit) total_short_profit = total_short_profit + profit print('\nStrategy Complete:') print('Total Long Trading = %04d, Total Long Profit = %.2f' % (long_number, total_long_profit)) print('Total Short Trading = %04d, Total Short Profit = %.2f' % (short_number, total_short_profit)) print('Total Trading = %04d, Total Profit = %.2f' % (long_number + short_number, total_long_profit + total_short_profit)) for i in range(long_number): print( ' B%04d, Open (%s) = %4.2f, Close (%s) = %4.2f, Profit = %4.2f' % (i + 1, long_open_date[i], long_open_price[i], long_close_date[i], long_close_price[i], long_profit[i])) print( ' -------------------------------------------------------------------' ) for i in range(short_number): print( ' S%04d, Open (%s) = %4.2f, Close (%s) = %4.2f, Profit = %4.2f' % (i + 1, short_open_date[i], short_open_price[i], short_close_date[i], short_close_price[i], short_profit[i])) # Trading Dataframe data_index_number = long_number + short_number data_columns = [ 'type', 'open_date', 'open_price', 'close_date', 'close_price', 'profit' ] data_columns_number = len(data_columns) data_init = np.random.randn(data_index_number * data_columns_number) for i in range(data_index_number * data_columns_number): data_init[i] = np.nan data_index = [] for i in range(data_index_number): data_index.append(i) trading = pd.DataFrame(data_init.reshape(data_index_number, data_columns_number), index=data_index, columns=data_columns) for i in range(long_number): trading.ix[i, 'type'] = 'B%04d' % (i + 1) trading.ix[i, 'open_date'] = long_open_date[i] trading.ix[i, 'open_price'] = long_open_price[i] trading.ix[i, 'close_date'] = long_close_date[i] trading.ix[i, 'close_price'] = long_close_price[i] trading.ix[i, 'profit'] = long_profit[i] for i in range(short_number): trading.ix[i + long_number, 'type'] = 'S%04d' % (i + 1) trading.ix[i + long_number, 'open_date'] = short_open_date[i] trading.ix[i + long_number, 'open_price'] = short_open_price[i] trading.ix[i + long_number, 'close_date'] = short_close_date[i] trading.ix[i + long_number, 'close_price'] = short_close_price[i] trading.ix[i + long_number, 'profit'] = short_profit[i] # Save to CSV File u.to_csv(trading, c.path_dict['strategy'], c.file_dict['strategy_r'] % file_postfix)
def optimizePriceFollow(stock_list, is_index, threshold_list, method): stock_number = len(stock_list) if stock_number < 1: print('Stock Number:', stock_number) raise SystemExit threshold_number = len(threshold_list) if threshold_number < 1: print('Threshold Number:', threshold_number) raise SystemExit for stock_id in stock_list: # Load Results from Different Threshold file_postfix = 'PriceFollow_%s_All' % u.stockFileName( stock_id, is_index) df = u.read_csv(c.path_dict['strategy'] + c.file_dict['strategy'] % file_postfix) row_number = len(df) for i in range(1, threshold_number - 1): t_prev = threshold_list[i - 1] t_curr = threshold_list[i] t_next = threshold_list[i + 1] t_total = t_prev + t_curr + t_next column_postfix = '_%s' % t_curr # Slice Interested Columns select_columns = [] for t in [t_prev, t_curr, t_next]: select_columns.append('predict' + '_%s' % t) select_columns.append('confirm' + column_postfix) df2 = pd.DataFrame.copy(df.loc[:, select_columns]) # Calculate Weighted Predict df2['weighted_predict' + column_postfix] = np.nan for j in range(1, row_number): # Method 1: Threshold Weighted Predict if method == 'Threshold Weighted': predict = 0.0 for t in [t_prev, t_curr, t_next]: predict = predict + t * df2.ix[j, 'predict' + '_%s' % t] predict = predict / t_total df2.ix[j, 'weighted_predict' + column_postfix] = predict # Method 2: Equally Weighted Predict elif method == 'Equally Weighted': predict = 0.0 for t in [t_prev, t_curr, t_next]: predict = predict + 1.0 * df2.ix[j, 'predict' + '_%s' % t] predict = predict / 3.0 df2.ix[j, 'weighted_predict' + column_postfix] = predict # Method 3: Single Predict else: predict = df2.ix[j, 'predict' + column_postfix] df2.ix[j, 'weighted_predict' + column_postfix] = predict # Optimize for Given Segments within Range [1, -1] to Find Best Cutoff print('Optimization Starts for Threshold:', t_curr) segments = 10 delta_mean = [] delta_stddev = [] for j in range(1, row_number): weighted_predict = df2.ix[j, 'weighted_predict' + column_postfix] confirm = df2.ix[j, 'confirm' + column_postfix] for k in range(1, segments): ratio = float(k) / float(segments) cutoff = 1.0 * (1.0 - ratio) + (-1.0) * ratio predict_cutoff = 1 if weighted_predict > cutoff else -1 delta_cutoff = predict_cutoff - confirm if not np.isnan( confirm) else np.nan df2.ix[j, 'delta' + '_%.2f' % cutoff] = delta_cutoff # Save to CSV File file_postfix = 'PriceFollow_%s_Cutoff_%s' % (u.stockFileName( stock_id, is_index), t_curr) u.to_csv(df2, c.path_dict['strategy'], c.file_dict['strategy'] % file_postfix) # Gather Mean of Delta_Cutoffs for k in range(1, segments): ratio = float(k) / float(segments) cutoff = 1.0 * (1.0 - ratio) + (-1.0) * ratio describe = df2['delta' + '_%.2f' % cutoff].describe() delta_mean.append(np.abs(describe['mean'])) delta_stddev.append(describe['std']) # Find Best Cutoff delta_mean_min = min(delta_mean) delta_mean_index = delta_mean.index(delta_mean_min) print('Delta Mean:', delta_mean) print('Delta Stddev:', delta_stddev) print('Delta Mean Min:', delta_mean_min) print('Delta Mean Index:', delta_mean_index) ratio = float(delta_mean_index + 1) / float(segments) best_cutoff = 1.0 * (1.0 - ratio) + (-1.0) * ratio print('Best Cutoff:', best_cutoff) print('Optimization Ends for Threshold:', t_curr)
def strategyPriceFollow(stock_id, is_index, trend_threshold): # Load Stock Daily QFQ Data lshq = loadDailyQFQ(stock_id, is_index) if u.isNoneOrEmpty(lshq): raise SystemExit # Calculate Trend, Trend High, Trend Low, Trend Ref lshq['trend'] = 'Up' for column in ['trend_high', 'trend_low', 'trend_ref']: lshq[column] = 0.0 for column in ['predict', 'confirm']: lshq[column] = np.nan lshq_number = len(lshq) trends = [] trend_turning_points = [] trend_index_highs = [] trend_index_lows = [] index_high = 0 index_low = 0 for i in range(lshq_number): if i == 0: # Initialization lshq.ix[i, 'trend'] = 'Up' trends.append('Up') trend_turning_points.append(i) for column in ['trend_high', 'trend_low', 'trend_ref']: lshq.ix[i, column] = lshq.ix[i, 'close'] else: trend = lshq.ix[i - 1, 'trend'] trend_high = lshq.ix[i - 1, 'trend_high'] trend_low = lshq.ix[i - 1, 'trend_low'] trend_ref = lshq.ix[i - 1, 'trend_ref'] trend_cur = lshq.ix[i, 'close'] up_to_down = False down_to_up = False if trend == 'Up': if (1.0 - trend_cur / trend_high) > trend_threshold: lshq.ix[i, 'trend'] = 'Down' up_to_down = True trends.append('Down') trend_turning_points.append(i) trend_index_highs.append(index_high) else: lshq.ix[i, 'trend'] = 'Up' up_to_down = False else: if (trend_cur / trend_low - 1.0) > trend_threshold: lshq.ix[i, 'trend'] = 'Up' down_to_up = True trends.append('Up') trend_turning_points.append(i) trend_index_lows.append(index_low) else: lshq.ix[i, 'trend'] = 'Down' down_to_up = False if trend == 'Up': if up_to_down == False: # Up trend continues if trend_cur > trend_high: lshq.ix[i, 'predict'] = 1.0 for j in range( index_high + 1, i + 1 ): # New high confirms all trades since last high to be up-trend lshq.ix[j, 'confirm'] = 1.0 lshq.ix[i, 'trend_high'] = trend_cur index_high = i else: ratio = (1.0 - trend_cur / trend_high) / trend_threshold lshq.ix[i, 'predict'] = 1.0 * (1.0 - ratio) + ( -1.0) * ratio # Map to [1.0, -1.0] lshq.ix[i, 'trend_high'] = trend_high lshq.ix[i, 'trend_ref'] = trend_ref else: # Up trend reverses lshq.ix[i, 'predict'] = -1.0 for j in range( index_high + 1, i + 1 ): # Turning point confirms all trades since last high to be down-trend lshq.ix[j, 'confirm'] = -1.0 lshq.ix[i, 'trend_ref'] = trend_high lshq.ix[i, 'trend_low'] = trend_cur index_low = i else: if down_to_up == False: # Down trend continues if trend_cur < trend_low: lshq.ix[i, 'predict'] = -1.0 for j in range( index_low + 1, i + 1 ): # New low confirms all trades since last low to be down-trend lshq.ix[j, 'confirm'] = -1.0 lshq.ix[i, 'trend_low'] = trend_cur index_low = i else: ratio = (trend_cur / trend_low - 1.0) / trend_threshold lshq.ix[i, 'predict'] = (-1.0) * (1.0 - ratio) + ( 1.0) * ratio # Map to [1.0, -1.0] lshq.ix[i, 'trend_low'] = trend_low lshq.ix[i, 'trend_ref'] = trend_ref else: # Down trend reverses lshq.ix[i, 'predict'] = 1.0 for j in range( index_low + 1, i + 1 ): # Turning point confirms all trades since last low to be up-trend lshq.ix[j, 'confirm'] = 1.0 lshq.ix[i, 'trend_ref'] = trend_low lshq.ix[i, 'trend_high'] = trend_cur index_high = i # Handle Last Trend if i == lshq_number - 1: if lshq.ix[i, 'trend'] == 'Up': trend_index_highs.append(i) else: trend_index_lows.append(i) # Calculate Trend Price lshq['trend_price'] = 0.0 trend_number = len(trends) print('Trend # =', trend_number) index_ref = 0 index_tar = 0 price_ref = 0.0 price_tar = 0.0 idx_high = 0 idx_low = 0 for i in range(trend_number): trend = trends[i] index_tar = trend_index_highs[ idx_high] if trend == 'Up' else trend_index_lows[idx_low] price_ref = lshq.ix[index_ref, 'close'] price_tar = lshq.ix[index_tar, 'close'] for index in range(index_ref, index_tar): ratio = float(index - index_ref) / float(index_tar - index_ref) lshq.ix[ index, 'trend_price'] = price_ref * (1.0 - ratio) + price_tar * ratio if trend == 'Up': index_ref = trend_index_highs[idx_high] idx_high = idx_high + 1 else: index_ref = trend_index_lows[idx_low] idx_low = idx_low + 1 # Handle Last Trend if i == trend_number - 1: lshq.ix[index_tar, 'trend_price'] = price_tar # Record Timing Data trend_number = len(trends) timing = u.createDataFrame(trend_number, ['date', 'trend']) for i in range(trend_number): trend = trends[i] index = trend_turning_points[i] timing.ix[i, 'date'] = lshq.ix[index, 'date'] timing.ix[i, 'trend'] = trend timing.set_index('date', inplace=True) timing.sort_index(ascending=True, inplace=True) # Save to CSV File file_postfix = 'Timing_%s_%s' % (u.stockFileName( stock_id, is_index), trend_threshold) u.to_csv(timing, c.path_dict['strategy'], file_postfix + '.csv', encoding='gbk') # Format Data Frame for column in ['trend_high', 'trend_low', 'trend_ref', 'trend_price']: lshq[column] = lshq[column].map(lambda x: '%.3f' % x) lshq[column] = lshq[column].astype(float) lshq.set_index('date', inplace=True) lshq.sort_index(ascending=True, inplace=True) # Save to CSV File file_postfix = 'PriceFollow_%s_%s' % (u.stockFileName( stock_id, is_index), trend_threshold) u.to_csv(lshq, c.path_dict['strategy'], c.file_dict['strategy'] % file_postfix)
def mergePriceFollow(stock_list, is_index, threshold_list): stock_number = len(stock_list) if stock_number < 1: print('Stock Number:', stock_number) raise SystemExit threshold_number = len(threshold_list) if threshold_number < 1: print('Threshold Number:', threshold_number) raise SystemExit # Init Price Follow Statistics for All Indexes stats_columns = ['date', 'index'] for i in range(1, threshold_number - 1): stats_columns.append('wpredict_%s' % threshold_list[i]) stats_columns.append('wtrend_%s' % threshold_list[i]) stats = u.createDataFrame(stock_number, stats_columns) for s in range(stock_number): stock_id = stock_list[s] # Load Results from Different Threshold dfs = [] for i in range(threshold_number): threshold = threshold_list[i] file_postfix = 'PriceFollow_%s_%s' % (u.stockFileName( stock_id, is_index), threshold) fullpath = c.path_dict[ 'strategy'] + c.file_dict['strategy'] % file_postfix df = u.read_csv(fullpath) dfs.append(df) # Compose Final Results drop_columns = [ 'trend', 'trend_high', 'trend_low', 'trend_ref', 'trend_price', 'predict', 'confirm' ] df = dfs[0].drop(drop_columns, axis=1) for i in range(threshold_number): threshold = threshold_list[i] column = 'trend' df[column + '_%s' % threshold] = dfs[i][column] for i in range(threshold_number): threshold = threshold_list[i] column = 'trend_price' df[column + '_%s' % threshold] = dfs[i][column] for i in range(threshold_number): threshold = threshold_list[i] column = 'predict' df[column + '_%s' % threshold] = dfs[i][column] for i in range(threshold_number): threshold = threshold_list[i] column = 'confirm' df[column + '_%s' % threshold] = dfs[i][column] # Weighted Predict Columns cutoff = 0.0 # Optimized cutoff for weighted predict for i in range(1, threshold_number - 1): t_prev = threshold_list[i - 1] t_curr = threshold_list[i] t_next = threshold_list[i + 1] t_total = t_prev + t_curr + t_next column_postfix = '_%s' % t_curr df['wpredict' + column_postfix] = np.nan df['wtrend' + column_postfix] = np.nan row_number = len(df) for j in range(1, row_number): wpredict = 0.0 for t in [t_prev, t_curr, t_next]: wpredict = wpredict + t * df.ix[j, 'predict' + '_%s' % t] wpredict = wpredict / t_total df.ix[j, 'wpredict' + column_postfix] = wpredict df.ix[j, 'wtrend' + column_postfix] = 'Up' if wpredict >= cutoff else 'Down' # Fill One Row of Statistics last_index = len(df) - 1 stats.ix[s, 'date'] = df.ix[last_index, 'date'] stats.ix[s, 'index'] = stock_id for i in range(1, threshold_number - 1): column_postfix = '_%s' % threshold_list[i] stats.ix[s, 'wpredict' + column_postfix] = df.ix[last_index, 'wpredict' + column_postfix] stats.ix[s, 'wtrend' + column_postfix] = df.ix[last_index, 'wtrend' + column_postfix] # Format Columns df.set_index('date', inplace=True) # Save to CSV File file_postfix = 'PriceFollow_%s_All' % u.stockFileName( stock_id, is_index) u.to_csv(df, c.path_dict['strategy'], c.file_dict['strategy'] % file_postfix) # Format Columns stats.set_index('date', inplace=True) # Save to CSV File file_postfix = 'PriceFollow_Statistics' u.to_csv(stats, c.path_dict['strategy'], c.file_dict['strategy'] % file_postfix)
def validDailyHFQ(stock_id, is_index, force_update): if force_update == True: return False else: return u.hasFile(c.fullpath_dict['lshq'] % u.stockFileName(stock_id, is_index))
def updateSamplePrice(benchmark_id, stock_ids, is_index, period): ''' 函数功能: -------- 根据基准指数的时间范围和采样周期,对指定股票/指数列表的收盘价格进行全采样。 输入参数: -------- benchmark_id : string, 指数代码 e.g. '000300',隐含起止时间。 period : string, 采样周期 e.g. 'M',支持'D', 'W', and 'M'。 输出参数: -------- 采样成功时,allprice : pandas.Series,采样结果。 采样失败时,None ''' # Load Benchmark benchmark = loadDailyQFQ(benchmark_id, True) if u.isNoneOrEmpty(benchmark): print('Require Benchmark LSHQ File: %s!' % u.stockFileName(benchmark_id, True)) return None # Resample Benchmark benchmark['date'] = benchmark['date'].astype(np.datetime64) benchmark.set_index('date', inplace=True) benchmark.sort_index(ascending=True, inplace=True) if gs.is_debug: print(benchmark.head(10)) drop_columns = ['open', 'high', 'low', 'volume', 'amount'] benchmark.drop(drop_columns, axis=1, inplace=True) bench_resample = pd.DataFrame() if period == 'D': bench_resample = benchmark else: bench_resample = benchmark.resample(period).first() bench_resample['close'] = benchmark['close'].resample(period).last() # Resample daily data by weekly may introduce N/A price (due to holiday weeks) # This does not exist for monthly resample (as no holiday month so far) if period == 'W': bench_resample.dropna(axis=0, how='any', inplace=True) bench_resample['close'] = bench_resample['close'].map(lambda x: '%.3f' % x) bench_resample['close'] = bench_resample['close'].astype(float) stock_list = [bench_resample] # Iterate over all stocks stocks_number = len(stock_ids) for i in range(stocks_number): # Load Stock LSHQ stock_id = u.stockID(stock_ids[i]) stock = loadDailyQFQ(stock_id, is_index) if u.isNoneOrEmpty(stock): print('Require Stock/Index LSHQ File: %s!' % u.stockFileName(stock_id, is_index)) continue stock['date'] = stock['date'].astype(np.datetime64) stock.set_index('date', inplace=True) stock.sort_index(ascending=True, inplace=True) if gs.is_debug: print(stock.head(10)) # Resample Stock LSHQ stock.drop(drop_columns, axis=1, inplace=True) if period == 'D': stock_resample = stock else: stock_resample = stock.resample(period).first() stock_resample['close'] = stock['close'].resample(period).last() stock_resample['close'] = stock_resample['close'].map( lambda x: '%.3f' % x) stock_resample['close'] = stock_resample['close'].astype(float) # Merge Benchmark with Stock df = pd.merge(bench_resample, stock_resample, how='left', left_index=True, right_index=True, sort=True, suffixes=('', '_' + stock_id)) df.drop(['close'], axis=1, inplace=True) stock_list.append(df) # Merge Results allprice = pd.concat(stock_list, axis=1, join='inner') return allprice