def query_index_intersection(self, index1, index2): constituents1 = self.query_index_constituents_at_date( index1, now_day()) constituents2 = self.query_index_constituents_at_date( index2, now_day()) intersection = list_intersection(constituents1, constituents2) print '指数' + index1 + '共有' + str(len(constituents1)) + '只成分股份 ' + '指数' + index2 + '共有' + str(len(constituents2)) + '只成分股份 ' + \ '共有成分股为' + str(len(intersection)) + '只'
def query_index_constituents_at_date(self, index, date=''): # 如果没写就取当天的 if date == '': date = now_day() sql = 'SELECT {date}, {constituents} FROM {table} WHERE {date} = (SELECT MAX({date}) FROM {table} WHERE {date} <= "{input_date}");'.format( date=IndexConstituent.DATE_KEY, constituents=IndexConstituent.CONSTITUENTS_KEY, table=IndexCollector._constituent_tablename(index), input_date=date) result = self.db.execute(sql).fetchone() return result[1].split(',')
def stock_in_index(self, stock_code): result = [] # 不过说实话,最多的中证全指,上证指数之类的没意义又耗时,可以去掉不查 indexs = [ i for i in IndexCollector.ALL_INDEXS if i not in ['000985', '000001', '399001'] ] for index in indexs: constituents = self.query_index_constituents_at_date( index, now_day()) if stock_code in constituents: result.append(index) return self.query_indexs_info(result)
def query_stocks_in_constituents(self, fund_codes, index_code): fund_codes = to_container(fund_codes) constituents = self.query_index_constituents_at_date( index_code, now_day()) print '指数' + index_code + "成分股共" + str(len(constituents)) + '只' for fund_code in fund_codes: fund_info = self.fund_analysis.querycode(fund_code)[0] stocks = self.stock_analysis.translate_names( fund_info.get_raw_stocks()) contain_count = len( list((set(stocks).union(set(constituents))) ^ (set(stocks) ^ set(constituents)))) print fund_info.shortname + str( len(stocks)) + '大持仓, ' + str(contain_count) + '在指数成分股中'
def query_indexs(self, indexs=IndexCollector.ATTENTION_INDEXS, begin_date='2004-01-01', end_date=''): indexs = to_container(indexs) # 虽然对外的接口都处理了这个情况,但是我接口间还是需要用到的 if end_date == '': end_date = now_day() indexs_info = self.query_indexs_info(indexs) result = [] for index_info in indexs_info: print 'start query index quotations ' + index_info.code + ' ' + index_info.name # 本身获取股票的历史行情是不一定要填起始日期的,但用于指数分析时成分股的begin_date不应超过指数的启用日期,不然无意义 # 懒得考虑结束时间比开始早或者结束时间比指数启动还早的情况了哦 real_begin_date = max(begin_date, index_info.begin_time) if real_begin_date > end_date: result.append((index_info, [])) continue # 先获取指数的成分股哦 constituents = self.query_index_constituents_in_range( index_info.code, begin_date, end_date) if len(constituents) == 0: result.append((index_info, [])) continue index_quotation = [] # 这里返回的是时间段+成分股,注意时间段都是成分股变化之时,包夹在开始和结束时间之内的 for (index, constituent_info) in enumerate(constituents): (date, constituent_stocks) = constituent_info if index < len(constituents) - 1: (next_date, _) = constituents[index + 1] next_date = before_day(next_date) else: next_date = end_date # 因为query_stocks_pepb_in_range的日期是[]形式的,所以要往后延展一天,不然最后一天会重复 stock_codes = constituent_stocks.split(',') quotations = self.stock_analysis.query_stocks_pepb_in_range( stock_codes, date, next_date) index_quotation += quotations result.append((index_info, index_quotation)) return result
def query_index_constituents_in_range(self, index, begin_date='', end_date=''): # 如果开始日期本身就比指数的启用日期还早,那么就以启用日期开始 index_begin_date = self._index_begin_date(index) if begin_date < index_begin_date: begin_date = index_begin_date if end_date == '': end_date = now_day() # 实际开始时间应该要取到比开始日期小的最大的一个,然则我已经放弃使用一句sql获取 sql = 'SELECT {date}, {constituents} FROM {table} WHERE {date} <= "{end_date}";'.format( date=IndexConstituent.DATE_KEY, constituents=IndexConstituent.CONSTITUENTS_KEY, table=IndexCollector._constituent_tablename(index), end_date=end_date) raw_results = self.db.execute(sql).fetchall() results = [] last = None for raw_result in raw_results: if begin_date == raw_result[0]: last = None results.append(raw_result) elif begin_date < raw_result[0]: # 这里有个问题,就是需要加上第一次大于前的那个(如果有的话),情况很简单,假设数据库里的数据是 # 2010-06-30, 2011-01-01, 2011-06-01 ,2012-01-01... # 而你的开始日期设为2011-03-01,那还得获得2011-01-01的数据哦 if last != None: # 修改为实际开始的日期 results.append((begin_date, last[1])) last = None results.append(raw_result) else: last = raw_result # sql = 'SELECT {date}, {constituents} FROM {table} WHERE {date} >= "{begin_date}" AND {date} <= "{end_date}";'.format( # date=IndexConstituent.DATE_KEY, constituents=IndexConstituent.CONSTITUENTS_KEY,table=IndexCollector._constituent_tablename(index), begin_date=begin_date, end_date=end_date) # result = self.db.execute(sql).fetchall() return results