def CalculateRecentExtensionInfo(db, securityInfoList, excludeRightDividendList, securityInfoQueue):
  '''
  Calculate extend history info.
  #计算指定证券最新一日衍生数据
  '''
  #print '>> CalculateExtensionInfo'
  #收盘价列表
  try:
    closeTuple = (9, 34)
    highDict = OrderedDict()
    lowDict = OrderedDict()
    for close in closeTuple:
      highDict[close] = BaseObject(close)
      lowDict[close] = BaseObject(close)
    #收盘价列表
    priceTuple = (5, 10, 13, 14, 20, 25, 43)
    priceDict = OrderedDict()
    for price in priceTuple:
      priceDict[price] = BaseObject(price)
    #成交金额列表
    volumeTuple = (5, 10, 30, 60, 135)
    volumeDict = OrderedDict()
    for volume in volumeTuple:
      volumeDict[volume] = BaseObject(volume)
    #除权除息日
    noneExcludeInfo = {'date':datetime(1970,1,1), 'type':3}
    if (len(excludeRightDividendList) > 0):
      excludeInfo = excludeRightDividendList[0]
    else:
      excludeInfo = noneExcludeInfo
    #现有记录数量
    recordNum = 0
    recentExtensionInfo = {}
    extensionInfoDict = OrderedDict()
    analysisInfoDict = OrderedDict()
    excludeType = 3
    #遍历指定股票全部信息
    for analysisInfo in securityInfoList:
      #衍生记录
      extensionInfo = OrderedDict()
      extensionInfo['INNER_CODE'] = analysisInfo['INNER_CODE']
      if (db == 'DAY'):
        extensionInfo['TRADE_DATE'] = analysisInfo['TRADE_DATE']
        #除权除息信息
        if ((analysisInfo['TRADE_DATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
          excludeType = excludeInfo['type']
          try:
            excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
          except IndexError:
            excludeInfo = noneExcludeInfo
        else:
          excludeType = 3
      elif (db == 'WEEK'):
        extensionInfo['TRADE_YEAR'] = analysisInfo['TRADE_YEAR']
        extensionInfo['TRADE_WEEK'] = analysisInfo['TRADE_WEEK']
        #除权除息信息
        if ((analysisInfo['FDATE'] >= excludeInfo['date']) and (analysisInfo['LDATE'] <= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
          excludeType = excludeInfo['type']
          try:
            excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
          except IndexError:
            excludeInfo = noneExcludeInfo
        else:
          excludeType = 3
      elif (db == 'MONTH'):
        extensionInfo['TRADE_YEAR'] = analysisInfo['TRADE_YEAR']
        extensionInfo['TRADE_MONTH'] = analysisInfo['TRADE_MONTH']
        #除权除息信息
        if ((analysisInfo['FDATE'] >= excludeInfo['date']) and (analysisInfo['LDATE'] <= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
          excludeType = excludeInfo['type']
          try:
            excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
          except IndexError:
            excludeInfo = noneExcludeInfo
        else:
          excludeType = 3
      #收盘价列表
      for closeType in closeTuple:
        highDict[closeType].append(analysisInfo['THIGH'])
        lowDict[closeType].append(analysisInfo['TLOW'])
      #收盘价列表
      for priceType in priceTuple:
        priceDict[priceType].append(int(analysisInfo['TCLOSE'] * 65536))
      #成交量列表
      for volumeType in volumeTuple:
        volumeDict[volumeType].append(int(analysisInfo['TVOLUME'] * 65536))
      #成交价格均值
      for priceType in priceTuple:
        sumPrice = int(0)
        for price in priceDict[priceType].object():
          sumPrice += int(price)
        sumPrice = Decimal(sumPrice) / 65536
        extensionInfo['MA' + str(priceType)] = Decimal(sumPrice) / len(priceDict[priceType].object())
      #成交量均值
      for volumeType in volumeTuple:
        sumVolume = int(0)
        for volume in volumeDict[volumeType].object():
          sumVolume += int(volume)
        sumVolume = Decimal(sumVolume) / 65536
        extensionInfo['VOL' + str(volumeType)] = Decimal(sumVolume) / len(volumeDict[volumeType].object())
      #KDJ值
      for kdj in constantDict['KDJ']:
        if (recordNum < 1):
          if (equalZero(analysisInfo['THIGH'] - analysisInfo['TLOW']) == True):
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = constantDict['ZERO']
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = constantDict['ZERO']
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = constantDict['ZERO']
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = constantDict['ZERO']
          else:
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = (analysisInfo['TCLOSE'] - analysisInfo['TLOW']) / (analysisInfo['THIGH'] - analysisInfo['TLOW']) * 100
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
        else:
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = \
            Decimal(0) if (equalZero(highDict[kdj[0]].max() - lowDict[kdj[0]].min()) == True) \
            else ((analysisInfo['TCLOSE'] - lowDict[kdj[0]].min()) / (highDict[kdj[0]].max() - lowDict[kdj[0]].min()) * 100)
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = \
            constantDict['KDJ'][kdj]['PARA']['KP1'] * recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] + \
            constantDict['KDJ'][kdj]['PARA']['KP2'] * extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] 
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = \
            constantDict['KDJ'][kdj]['PARA']['DP1'] * recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] + \
            constantDict['KDJ'][kdj]['PARA']['DP2'] * extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] 
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = \
            3 * extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] - \
            2 * extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']]
        
        recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']]
        recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']]
      #EMA值
      for ema in constantDict['EMA']:
        if (recordNum >= 2):
          extensionInfo[constantDict['EMA'][ema]['NAME']] = \
            constantDict['EMA'][ema]['PARA']['P1'] * analysisInfo['TCLOSE'] + \
            constantDict['EMA'][ema]['PARA']['P2'] * recentExtensionInfo[constantDict['EMA'][ema]['NAME']]
        elif (recordNum == 1):
          extensionInfo[constantDict['EMA'][ema]['NAME']] = \
            constantDict['EMA'][ema]['PARA']['P1'] * analysisInfo['TCLOSE'] + \
            constantDict['EMA'][ema]['PARA']['P2'] * analysisInfo['LCLOSE']
        else:
          extensionInfo[constantDict['EMA'][ema]['NAME']] = analysisInfo['TCLOSE']
          
        recentExtensionInfo[constantDict['EMA'][ema]['NAME']] = extensionInfo[constantDict['EMA'][ema]['NAME']]
      #MACD值
      for macd in constantDict['MACD']:
        if (recordNum >= 1):
          extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] = \
            extensionInfo['EMA'+str(macd[0])] - extensionInfo['EMA'+str(macd[1])]
          extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = \
            constantDict['MACD'][macd]['PARA']['P1'] * extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] + \
            constantDict['MACD'][macd]['PARA']['P2'] * recentExtensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]
          extensionInfo[constantDict['MACD'][macd]['NAME']['MACD']] = \
            (extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] - extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]) * 2
        else:
          extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] = constantDict['ZERO']
          extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = constantDict['ZERO']
          extensionInfo[constantDict['MACD'][macd]['NAME']['MACD']] = constantDict['ZERO']
        
        recentExtensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]
      #记录数量
      recordNum += 1
      #基本数据及衍生数据写入队列
      #securityInfoQueue.put({'DB':db,'ANA':analysisInfo,'EXT':extensionInfo, 'XRXD':excludeType})
      analysisInfoDict = analysisInfo
      extensionInfoDict = extensionInfo
      #print 'put:',extensionInfo
    securityInfoQueue.put({'DB':db,'ANA':analysisInfoDict,'EXT':extensionInfoDict, 'XRXD':excludeType})
    #print '<< CalculateExtensionInfo'
  except Exception,e:
    print e
  def calculateData(self, db, singleStockDataList):
    '''
    计算个单股票各指标衍生数据集
    '''
    try:
      closeTuple = (9, 34)
      highDict = collections.OrderedDict()
      lowDict = collections.OrderedDict()
      for close in closeTuple:
        highDict[close] = QN_Heap.Heap(close)
        lowDict[close] = QN_Heap.Heap(close)
      #收盘价列表
      priceTuple = (5, 10, 13, 14, 20, 25, 43)
      priceDict = collections.OrderedDict()
      for price in priceTuple:
        priceDict[price] = QN_Heap.Heap(price)
      #成交金额列表
      volumeTuple = (5, 10, 30, 60, 135)
      volumeDict = collections.OrderedDict()
      for volume in volumeTuple:
        volumeDict[volume] = QN_Heap.Heap(volume)
      '''
      #除权除息日
      noneExcludeInfo = {'date':datetime.datetime(1970,1,1), 'type':3}
      if (len(excludeRightDividendList) > 0):
        excludeInfo = excludeRightDividendList[0]
      else:
        excludeInfo = noneExcludeInfo
      '''
      #现有记录数量
      recordNum = 0
      recentExtensionInfo = dict()
      #日周月合并表导入最多61条记录信息
      totalRecordNum = len(singleStockDataList)
      #遍历指定股票全部信息
      for stockData in singleStockDataList:
        if (totalRecordNum - recordNum <= 61):
          writeMergeTable = True
        else:
          writeMergeTable = False
        #衍生记录
        extensionInfo = collections.OrderedDict()
        extensionInfo['INNER_CODE'] = stockData['INNER_CODE']
        excludeType = 3
        if (db == 'DAY'):
          extensionInfo['TRADE_DATE'] = stockData['TRADE_DATE']
          '''
          #除权除息信息
          if ((stockData['TRADE_DATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
            excludeType = excludeInfo['type']
            try:
              excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
            except IndexError:
              excludeInfo = noneExcludeInfo
          else:
            excludeType = 3
          '''
        elif (db == 'WEEK'):
          extensionInfo['TRADE_YEAR'] = stockData['TRADE_YEAR']
          extensionInfo['TRADE_WEEK'] = stockData['TRADE_WEEK']
          '''
          #除权除息信息
          if ((stockData['FDATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
            excludeType = excludeInfo['type']
            try:
              excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
            except IndexError:
              excludeInfo = noneExcludeInfo
          else:
            excludeType = 3
          '''
        elif (db == 'MONTH'):
          extensionInfo['TRADE_YEAR'] = stockData['TRADE_YEAR']
          extensionInfo['TRADE_MONTH'] = stockData['TRADE_MONTH']
          '''
          #除权除息信息
          if ((stockData['FDATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
            excludeType = excludeInfo['type']
            try:
              excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
            except IndexError:
              excludeInfo = noneExcludeInfo
          else:
            excludeType = 3
          '''
        #收盘价列表
        for closeType in closeTuple:
          highDict[closeType].append(stockData['THIGH'])
          lowDict[closeType].append(stockData['TLOW'])
        #收盘价列表
        for priceType in priceTuple:
          priceDict[priceType].append(int(stockData['TCLOSE'] * 65536))
        #成交量列表
        for volumeType in volumeTuple:
          volumeDict[volumeType].append(int(stockData['TVOLUME'] * 65536))
        #成交价格均值
        for priceType in priceTuple:
          sumPrice = int(0)
          for price in priceDict[priceType].object():
            sumPrice += int(price)
          sumPrice = decimal.Decimal(sumPrice) / 65536
          extensionInfo['MA' + str(priceType)] = decimal.Decimal(sumPrice) / len(priceDict[priceType].object())
        #成交量均值
        for volumeType in volumeTuple:
          sumVolume = int(0)
          for volume in volumeDict[volumeType].object():
            sumVolume += int(volume)
          sumVolume = decimal.Decimal(sumVolume) / 65536
          extensionInfo['VOL' + str(volumeType)] = decimal.Decimal(sumVolume) / len(volumeDict[volumeType].object())
        #KDJ值
        for kdj in QN_constant.constantDict['KDJ']:
          if (recordNum < 1):
            if (common.equalZero(stockData['THIGH'] - stockData['TLOW']) == True):
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']] = QN_constant.constantDict['ZERO']
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']] = QN_constant.constantDict['ZERO']
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']] = QN_constant.constantDict['ZERO']
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['J']] = QN_constant.constantDict['ZERO']
            else:
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']] = (stockData['TCLOSE'] - stockData['TLOW']) / (stockData['THIGH'] - stockData['TLOW']) * 100
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']]
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']]
              extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['J']] = extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']]
          else:
            extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']] = \
              decimal.Decimal(0) if (common.equalZero(highDict[kdj[0]].max() - lowDict[kdj[0]].min()) == True) \
              else ((stockData['TCLOSE'] - lowDict[kdj[0]].min()) / (highDict[kdj[0]].max() - lowDict[kdj[0]].min()) * 100)
            extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']] = \
              QN_constant.constantDict['KDJ'][kdj]['PARA']['KP1'] * recentExtensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']] + \
              QN_constant.constantDict['KDJ'][kdj]['PARA']['KP2'] * extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['RSV']]
            extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']] = \
              QN_constant.constantDict['KDJ'][kdj]['PARA']['DP1'] * recentExtensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']] + \
              QN_constant.constantDict['KDJ'][kdj]['PARA']['DP2'] * extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']]
            extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['J']] = \
              3 * extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']] - \
              2 * extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']]

          recentExtensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['K']]
          recentExtensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[QN_constant.constantDict['KDJ'][kdj]['NAME']['D']]
        #EMA值
        for ema in QN_constant.constantDict['EMA']:
          if (recordNum >= 2):
            extensionInfo[QN_constant.constantDict['EMA'][ema]['NAME']] = \
              QN_constant.constantDict['EMA'][ema]['PARA']['P1'] * stockData['TCLOSE'] + \
              QN_constant.constantDict['EMA'][ema]['PARA']['P2'] * recentExtensionInfo[QN_constant.constantDict['EMA'][ema]['NAME']]
          elif (recordNum == 1):
            extensionInfo[QN_constant.constantDict['EMA'][ema]['NAME']] = \
              QN_constant.constantDict['EMA'][ema]['PARA']['P1'] * stockData['TCLOSE'] + \
              QN_constant.constantDict['EMA'][ema]['PARA']['P2'] * stockData['LCLOSE']
          else:
            extensionInfo[QN_constant.constantDict['EMA'][ema]['NAME']] = stockData['TCLOSE']

          recentExtensionInfo[QN_constant.constantDict['EMA'][ema]['NAME']] = extensionInfo[QN_constant.constantDict['EMA'][ema]['NAME']]
        #MACD值
        for macd in QN_constant.constantDict['MACD']:
          if (recordNum >= 1):
            extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DIF']] = \
              extensionInfo['EMA'+str(macd[0])] - extensionInfo['EMA'+str(macd[1])]
            extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DEA']] = \
              QN_constant.constantDict['MACD'][macd]['PARA']['P1'] * extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DIF']] + \
              QN_constant.constantDict['MACD'][macd]['PARA']['P2'] * recentExtensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DEA']]
            extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['MACD']] = \
              (extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DIF']] - extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DEA']]) * 2
          else:
            extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DIF']] = QN_constant.constantDict['ZERO']
            extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DEA']] = QN_constant.constantDict['ZERO']
            extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['MACD']] = QN_constant.constantDict['ZERO']

          recentExtensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DEA']] = extensionInfo[QN_constant.constantDict['MACD'][macd]['NAME']['DEA']]
        #记录数量
        recordNum += 1

        #基本数据及衍生数据写入队列
        self.queueHandle.put({'DB':db,'ANA':stockData,'EXT':extensionInfo, 'XRXD':excludeType, 'WMT':writeMergeTable})
    except:
      self.logHandle.logInfo(str(traceback.format_exc()))
      print traceback.format_exc()

    return None
def CalculateExtensionInfo(db, securityInfoList, excludeRightDividendList, securityInfoQueue):
  '''
  Calculate extend history info.
  #计算指定证券衍生信息数据
  '''
  #print '>> CalculateExtensionInfo'
  try:
    #中间库数据及计算衍生数据与mongo库数据对照比较
    '''
    我也不想把这段代码嵌在计算函数里面,可是现在使用数据队列的方式,每计算一条记录就抛入队列用于写入操作,所以只有在这里,单个股票数据是最完整的。

    #获取各股票分表信息
    splitDict = {'DAY':200, 'WEEK':100, 'MONTH':50}
    splitSecurityIndex = splitSecurity.SplitSecurity(mssqlDbServer['251']['LAN'], ())
    securityCodeList = splitSecurityIndex.GetSecurityCodeList(db)
    splitIndexDict = splitSecurityIndex.SplitSecurityIndex(securityCodeList, splitDict[db])
    #从Mongo获取指定证券全部K线信息
    mongoHandle = mongoAPI.MongoAPI(server=mongoDbServer['235']['LAN']['SERVER'], port=mongoDbServer['235']['LAN']['PORT'])
    if (db == 'DAY'):
      dbName = 'KDayData'
    elif (db == 'WEEK'):
      dbName = 'KWeeklyData'
    elif (db == 'MONTH'):
      dbName = 'KMonthData'
    else:
      raise Exception('Invalid db type.')
    innerCode = splitIndexDict[securityInfoList[0]['INNER_CODE']]
    colName = 'data_' + splitIndexDict[str(innerCode)]
    #Mongo查询结果集
    queryResult = mongoHandle.find(database=dbName, collection=colName, spec={'_id.IC':innerCode}, sort={'TO':1})
    logHandle = logFile.LogFile(name='DataComparison')
    if (len(securityInfoList) != len(queryResult)):
      #SQL数据记录条数与mongo比较
      logStr = '[' + str(innerCode) + ']SQL(' + str(len(securityInfoList)) + ') != ' + 'Mongo(' + str(len(queryResult)) + ')'
      logHandle.logInfo(logStr)
    '''
    closeTuple = (9, 34)
    highDict = OrderedDict()
    lowDict = OrderedDict()
    for close in closeTuple:
      highDict[close] = BaseObject(close)
      lowDict[close] = BaseObject(close)
    #收盘价列表
    priceTuple = (5, 10, 13, 14, 20, 25, 43)
    priceDict = OrderedDict()
    for price in priceTuple:
      priceDict[price] = BaseObject(price)
    #成交金额列表
    volumeTuple = (5, 10, 30, 60, 135)
    volumeDict = OrderedDict()
    for volume in volumeTuple:
      volumeDict[volume] = BaseObject(volume)
    #除权除息日
    noneExcludeInfo = {'date':datetime(1970,1,1), 'type':3}
    if (len(excludeRightDividendList) > 0):
      excludeInfo = excludeRightDividendList[0]
    else:
      excludeInfo = noneExcludeInfo
    #现有记录数量
    recordNum = 0
    recentExtensionInfo = dict()
    #日周月合并表导入最多61条记录信息
    totalRecordNum = len(securityInfoList)
    #遍历指定股票全部信息
    for analysisInfo in securityInfoList:
      if (totalRecordNum - recordNum <= 61):
        writeMergeTable = True
      else:
        writeMergeTable = False
      #衍生记录
      extensionInfo = OrderedDict()
      extensionInfo['INNER_CODE'] = analysisInfo['INNER_CODE']
      excludeType = 3
      if (db == 'DAY'):
        extensionInfo['TRADE_DATE'] = analysisInfo['TRADE_DATE']
        #除权除息信息
        if ((analysisInfo['TRADE_DATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
          excludeType = excludeInfo['type']
          try:
            excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
          except IndexError:
            excludeInfo = noneExcludeInfo
        else:
          excludeType = 3
      elif (db == 'WEEK'):
        extensionInfo['TRADE_YEAR'] = analysisInfo['TRADE_YEAR']
        extensionInfo['TRADE_WEEK'] = analysisInfo['TRADE_WEEK']
        #除权除息信息
        if ((analysisInfo['FDATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
          excludeType = excludeInfo['type']
          try:
            excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
          except IndexError:
            excludeInfo = noneExcludeInfo
        else:
          excludeType = 3
      elif (db == 'MONTH'):
        extensionInfo['TRADE_YEAR'] = analysisInfo['TRADE_YEAR']
        extensionInfo['TRADE_MONTH'] = analysisInfo['TRADE_MONTH']
        #除权除息信息
        if ((analysisInfo['FDATE'] >= excludeInfo['date']) and (excludeInfo['date'] != noneExcludeInfo['date'])):
          excludeType = excludeInfo['type']
          try:
            excludeInfo = excludeRightDividendList[excludeRightDividendList.index(excludeInfo)+1]
          except IndexError:
            excludeInfo = noneExcludeInfo
        else:
          excludeType = 3
      #收盘价列表
      for closeType in closeTuple:
        highDict[closeType].append(analysisInfo['THIGH'])
        lowDict[closeType].append(analysisInfo['TLOW'])
      #收盘价列表
      for priceType in priceTuple:
        priceDict[priceType].append(int(analysisInfo['TCLOSE'] * 65536))
      #成交量列表
      for volumeType in volumeTuple:
        volumeDict[volumeType].append(int(analysisInfo['TVOLUME'] * 65536))
      #成交价格均值
      for priceType in priceTuple:
        sumPrice = int(0)
        for price in priceDict[priceType].object():
          sumPrice += int(price)
        sumPrice = Decimal(sumPrice) / 65536
        extensionInfo['MA' + str(priceType)] = Decimal(sumPrice) / len(priceDict[priceType].object())
      #成交量均值
      for volumeType in volumeTuple:
        sumVolume = int(0)
        for volume in volumeDict[volumeType].object():
          sumVolume += int(volume)
        sumVolume = Decimal(sumVolume) / 65536
        extensionInfo['VOL' + str(volumeType)] = Decimal(sumVolume) / len(volumeDict[volumeType].object())
      #KDJ值
      for kdj in constantDict['KDJ']:
        if (recordNum < 1):
          if (equalZero(analysisInfo['THIGH'] - analysisInfo['TLOW']) == True):
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = constantDict['ZERO']
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = constantDict['ZERO']
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = constantDict['ZERO']
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = constantDict['ZERO']
          else:
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = (analysisInfo['TCLOSE'] - analysisInfo['TLOW']) / (analysisInfo['THIGH'] - analysisInfo['TLOW']) * 100
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
        else:
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = \
            Decimal(0) if (equalZero(highDict[kdj[0]].max() - lowDict[kdj[0]].min()) == True) \
            else ((analysisInfo['TCLOSE'] - lowDict[kdj[0]].min()) / (highDict[kdj[0]].max() - lowDict[kdj[0]].min()) * 100)
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = \
            constantDict['KDJ'][kdj]['PARA']['KP1'] * recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] + \
            constantDict['KDJ'][kdj]['PARA']['KP2'] * extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] 
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = \
            constantDict['KDJ'][kdj]['PARA']['DP1'] * recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] + \
            constantDict['KDJ'][kdj]['PARA']['DP2'] * extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] 
          extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = \
            3 * extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] - \
            2 * extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']]
        
        recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']]
        recentExtensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']]
      #EMA值
      for ema in constantDict['EMA']:
        if (recordNum >= 2):
          extensionInfo[constantDict['EMA'][ema]['NAME']] = \
            constantDict['EMA'][ema]['PARA']['P1'] * analysisInfo['TCLOSE'] + \
            constantDict['EMA'][ema]['PARA']['P2'] * recentExtensionInfo[constantDict['EMA'][ema]['NAME']]
        elif (recordNum == 1):
          extensionInfo[constantDict['EMA'][ema]['NAME']] = \
            constantDict['EMA'][ema]['PARA']['P1'] * analysisInfo['TCLOSE'] + \
            constantDict['EMA'][ema]['PARA']['P2'] * analysisInfo['LCLOSE']
        else:
          extensionInfo[constantDict['EMA'][ema]['NAME']] = analysisInfo['TCLOSE']
          
        recentExtensionInfo[constantDict['EMA'][ema]['NAME']] = extensionInfo[constantDict['EMA'][ema]['NAME']]
      #MACD值
      for macd in constantDict['MACD']:
        if (recordNum >= 1):
          extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] = \
            extensionInfo['EMA'+str(macd[0])] - extensionInfo['EMA'+str(macd[1])]
          extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = \
            constantDict['MACD'][macd]['PARA']['P1'] * extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] + \
            constantDict['MACD'][macd]['PARA']['P2'] * recentExtensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]
          extensionInfo[constantDict['MACD'][macd]['NAME']['MACD']] = \
            (extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] - extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]) * 2
        else:
          extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] = constantDict['ZERO']
          extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = constantDict['ZERO']
          extensionInfo[constantDict['MACD'][macd]['NAME']['MACD']] = constantDict['ZERO']
        
        recentExtensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]
      #记录数量
      recordNum += 1
      #数据比对
      #record = queryResult.next()

      #基本数据及衍生数据写入队列
      securityInfoQueue.put({'DB':db,'ANA':analysisInfo,'EXT':extensionInfo, 'XRXD':excludeType, 'WMT':writeMergeTable})
      #print 'put:',extensionInfo
    #print '<< CalculateExtensionInfo'
  except Exception,e:
    print e
def CalculateRecentExtensionInfo(db, securityInfoDict, tradeNumDict, excludeRightDividendDict):
  '''
  Calculate extend history info.
  #计算指定证券最新一日衍生数据
  '''
  print '>>', sys._getframe().f_code.co_name
  #收盘价列表
  try:
    closeTuple = (9, 34)
    highDict = OrderedDict()
    lowDict = OrderedDict()
    for close in closeTuple:
      highDict[close] = BaseObject(close)
      lowDict[close] = BaseObject(close)
    #收盘价列表
    priceTuple = (5, 10, 13, 14, 20, 25, 43)
    priceDict = OrderedDict()
    for price in priceTuple:
      priceDict[price] = BaseObject(price)
    #成交金额列表
    volumeTuple = (5, 10, 30, 60, 135)
    volumeDict = OrderedDict()
    for volume in volumeTuple:
      volumeDict[volume] = BaseObject(volume)
    #最新记录信息
    recentInfoDict = {}
    #遍历指定股票全部信息
    for innerCode in securityInfoDict:
      extensionInfo = {}
      for analysisInfo in securityInfoDict[innerCode]:
        #衍生记录
        #收盘价列表
        for closeType in closeTuple:
          highDict[closeType].append(analysisInfo['THIGH'])
          lowDict[closeType].append(analysisInfo['TLOW'])
        #收盘价列表
        for priceType in priceTuple:
          priceDict[priceType].append(int(analysisInfo['TCLOSE'] * 65536))
        #成交量列表
        for volumeType in volumeTuple:
          volumeDict[volumeType].append(int(analysisInfo['TVOLUME'] * 65536))
        #成交价格均值
        for priceType in priceTuple:
          sumPrice = int(0)
          for price in priceDict[priceType].object():
            sumPrice += int(price)
          sumPrice = Decimal(sumPrice) / 65536
          extensionInfo['MA' + str(priceType)] = Decimal(sumPrice) / len(priceDict[priceType].object())
        #成交量均值
        for volumeType in volumeTuple:
          sumVolume = int(0)
          for volume in volumeDict[volumeType].object():
            sumVolume += int(volume)
          sumVolume = Decimal(sumVolume) / 65536
          extensionInfo['VOL' + str(volumeType)] = Decimal(sumVolume) / len(volumeDict[volumeType].object())
      else:
        extensionInfo['INNER_CODE'] = analysisInfo['INNER_CODE']
        if (db == 'DAY'):
          extensionInfo['TRADE_DATE'] = analysisInfo['TRADE_DATE']
          #除权除息信息
          try:
            #交易日恰为除权除息日 或 交易日晚于除权除息日且前一交易日早于除权除息日,则判断当前交易日为除权除息状态
            if ((analysisInfo['TRADE_DATE'] == excludeRightDividendDict[innerCode]['date']) or
                ((securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2]['TRADE_DATE'] < excludeRightDividendDict[innerCode]['date']) and
                 ((analysisInfo['TRADE_DATE'] > excludeRightDividendDict[innerCode]['date'])))):
              extensionInfo['XRXD'] = excludeRightDividendDict[innerCode]['type']
            else:
              extensionInfo['XRXD'] = 3
          except IndexError:
            extensionInfo['XRXD'] = 3
        elif (db == 'WEEK'):
          extensionInfo['TRADE_YEAR'] = analysisInfo['TRADE_YEAR']
          extensionInfo['TRADE_WEEK'] = analysisInfo['TRADE_WEEK']
          #除权除息信息
          try:
            #交易日恰为除权除息日 或 交易日晚于除权除息日且前一交易日早于除权除息日,则判断当前交易日为除权除息状态
            if ((analysisInfo['LAST_TRADE_DATE'] == excludeRightDividendDict[innerCode]['date']) or
                ((securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2]['LAST_TRADE_DATE'] < excludeRightDividendDict[innerCode]['date']) and
                 ((analysisInfo['LAST_TRADE_DATE'] > excludeRightDividendDict[innerCode]['date'])))):
              extensionInfo['XRXD'] = excludeRightDividendDict[innerCode]['type']
            else:
              extensionInfo['XRXD'] = 3
          except IndexError:
            extensionInfo['XRXD'] = 3
        elif (db == 'MONTH'):
          extensionInfo['TRADE_YEAR'] = analysisInfo['TRADE_YEAR']
          extensionInfo['TRADE_MONTH'] = analysisInfo['TRADE_MONTH']
          #除权除息信息
          try:
            #交易日恰为除权除息日 或 交易日晚于除权除息日且前一交易日早于除权除息日,则判断当前交易日为除权除息状态
            if ((analysisInfo['LAST_TRADE_DATE'] == excludeRightDividendDict[innerCode]['date']) or
                ((securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2]['LAST_TRADE_DATE'] < excludeRightDividendDict[innerCode]['date']) and
                 ((analysisInfo['LAST_TRADE_DATE'] > excludeRightDividendDict[innerCode]['date'])))):
              extensionInfo['XRXD'] = excludeRightDividendDict[innerCode]['type']
            else:
              extensionInfo['XRXD'] = 3
          except IndexError:
            extensionInfo['XRXD'] = 3
        #KDJ值
        for kdj in constantDict['KDJ']:
          if (tradeNumDict[innerCode] <= 1):
            if (equalZero(analysisInfo['THIGH'] - analysisInfo['TLOW']) == True):
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = constantDict['ZERO']
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = constantDict['ZERO']
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = constantDict['ZERO']
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = constantDict['ZERO']
            else:
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = (analysisInfo['TCLOSE'] - analysisInfo['TLOW']) / (analysisInfo['THIGH'] - analysisInfo['TLOW']) * 100
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
              extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']]
          else:
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] = \
              Decimal(0) if (equalZero(highDict[kdj[0]].max() - lowDict[kdj[0]].min()) == True) \
              else ((analysisInfo['TCLOSE'] - lowDict[kdj[0]].min()) / (highDict[kdj[0]].max() - lowDict[kdj[0]].min()) * 100)
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] = \
              constantDict['KDJ'][kdj]['PARA']['KP1'] * securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2][constantDict['KDJ'][kdj]['NAME']['K']] + \
              constantDict['KDJ'][kdj]['PARA']['KP2'] * extensionInfo[constantDict['KDJ'][kdj]['NAME']['RSV']] 
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']] = \
              constantDict['KDJ'][kdj]['PARA']['DP1'] * securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2][constantDict['KDJ'][kdj]['NAME']['D']] + \
              constantDict['KDJ'][kdj]['PARA']['DP2'] * extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] 
            extensionInfo[constantDict['KDJ'][kdj]['NAME']['J']] = \
              3 * extensionInfo[constantDict['KDJ'][kdj]['NAME']['K']] - \
              2 * extensionInfo[constantDict['KDJ'][kdj]['NAME']['D']]
          
        #EMA值
        for ema in constantDict['EMA']:
          if (tradeNumDict[innerCode] > 2):
            extensionInfo[constantDict['EMA'][ema]['NAME']] = \
              constantDict['EMA'][ema]['PARA']['P1'] * analysisInfo['TCLOSE'] + \
              constantDict['EMA'][ema]['PARA']['P2'] * securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2][constantDict['EMA'][ema]['NAME']]
          elif (tradeNumDict[innerCode] == 2):
            extensionInfo[constantDict['EMA'][ema]['NAME']] = \
              constantDict['EMA'][ema]['PARA']['P1'] * analysisInfo['TCLOSE'] + \
              constantDict['EMA'][ema]['PARA']['P2'] * analysisInfo['LCLOSE']
          else:
            extensionInfo[constantDict['EMA'][ema]['NAME']] = analysisInfo['TCLOSE']
            
        #MACD值
        for macd in constantDict['MACD']:
          if (tradeNumDict[innerCode] > 1):
            extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] = \
              extensionInfo['EMA'+str(macd[0])] - extensionInfo['EMA'+str(macd[1])]
            extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = \
              constantDict['MACD'][macd]['PARA']['P1'] * extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] + \
              constantDict['MACD'][macd]['PARA']['P2'] * securityInfoDict[innerCode][len(securityInfoDict[innerCode])-2][constantDict['MACD'][macd]['NAME']['DEA']]
            extensionInfo[constantDict['MACD'][macd]['NAME']['MACD']] = \
              (extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] - extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']]) * 2
          else:
            extensionInfo[constantDict['MACD'][macd]['NAME']['DIF']] = constantDict['ZERO']
            extensionInfo[constantDict['MACD'][macd]['NAME']['DEA']] = constantDict['ZERO']
            extensionInfo[constantDict['MACD'][macd]['NAME']['MACD']] = constantDict['ZERO']
          
      #最新记录存入字典
      recentInfoDict[innerCode] = extensionInfo
      print 'innerCode:', innerCode
      print extensionInfo
      print
      
    print '<<', sys._getframe().f_code.co_name
    return recentInfoDict 
    
  except Exception,e:
    print e