Example #1
0
def loadAssetTypeSpecialCaseFromFile(file):
    """
	[String] file => [Dictionary] ID -> [Dictionary] security info
	"""
    stringToTuple = compose(tuple, partial(map, lambda s: s.strip()),
                            lambda s: s.split(','))


    updatePosition = lambda position: mergeDict(
     position
      , { 'Portfolio': str(int(position['Portfolio'])) \
           if isinstance(position['Portfolio'], float) \
           else position['Portfolio']
       , 'AssetType': stringToTuple(position['AssetType'])
       }
    )


    return \
    compose(
     dict
      , partial(map, lambda p: (p['ID'], p))
      , partial(map, updatePosition)
      , getRawPositions
      , fileToLines
      , partial(join, getDataDirectory())
    )(file)
Example #2
0
def getGenevaPositions(portfolio, date, mode):
    """
	[String] portfolio, [String] date (yyyymmdd), [String] mode
		=> [Iterator] Investment positions of the portfolio on that date
	"""
    """
		[String] file (Geneva investment positions report, Excel format)
			=> [Iterator] positions
	"""
    readGenevaInvestmentPositionFile = compose(
        partial(
            map, lambda p: mergeDict(
                p, {'Remarks1': 'Geneva investment positions report'})),
        lambda lines: getPositions(lines)[1], fileToLines,
        lambda file: lognContinue(
            'readGenevaInvestmentPositionFile(): {0}'.format(file), file))
    """
		[String] portfolio, [String] date (yyyymmdd), [String] mode
			=> [String] file 
	"""
    getGenevaInvestmentPositionFile = lambda portfolio, date, mode: \
     join( getInputDirectory(mode)
      , portfolio + '_Investment_Positions_' + date + '.xlsx'
      )


    return \
    compose(
     readGenevaInvestmentPositionFile
      , getGenevaInvestmentPositionFile
    )(portfolio, date, mode)
Example #3
0
def getAllPositionsBlp(date, mode):
    """
	[String] date (yyyymmdd), [String] mode
		=> [Iterator] positions of all portfolios on the date from Bloomberg
	"""
    getBlpPositionFile = lambda date, mode: \
     join(getInputDirectory(mode), 'risk_m2_mav_' + date + '.xlsx')

    # [Iterable] lines => [List] line that contains the date
    findDateLine = partial(
        firstOf,
        lambda line: len(line) > 1 and line[1].startswith('Risk-Mon Steven'))

    # [String] The string containing date => [String] date (yyyymmdd)
    # it looks like: Risk Report LQA Master as of 20200429
    getDateFromString = lambda s: s.split()[-1]

    getDateFromLines = compose(
        getDateFromString, lambda line: lognRaise('Failed to find date line')
        if line == None else line[1], findDateLine)

    floatToString = lambda x: str(int(x)) if isinstance(x, float) else x


    updatePosition = lambda date, position: \
     mergeDict( position
        , { 'AsOfDate': date
          , 'Remarks1': 'Bloomberg MAV Risk-Mon Steven'
          , 'Account Code': floatToString(position['Account Code'])
          }
        )


    getPositions = lambda date, lines: \
    compose(
     partial(map, partial(updatePosition, date))
      , partial(filterfalse, lambda p: p['Account Code'] == '')
      , getRawPositions
      , lambda lines: dropwhile(lambda line: line[0] != 'Name', lines)
    )(lines)


    return \
    compose(
     lambda t: getPositions(t[0], t[1])
      , lambda lines: (getDateFromLines(lines), lines)
      , fileToLines
      , lambda file: lognContinue('getAllPositionsBlp(): {0}'.format(file), file)
      , getBlpPositionFile
    )(date, mode)
Example #4
0
def loadLiquiditySpecialCaseFromFile(file):
    """
	[String] file => [Dictionary] id -> [Dictionary] liquidity data
	"""
    toDate = lambda x: \
     fromExcelOrdinal(x) if isinstance(x, float) else \
     datetime.strptime(x, '%m/%d/%Y')

    updatePosition = lambda position: mergeDict(
        position, {'CALC_MATURITY': toDate(position['CALC_MATURITY'])})


    return \
    compose(
     dict
      , partial(map, lambda p: (p['ID'], p))
      , partial(map, updatePosition)
      , getRawPositionsFromFile
    )(file)
Example #5
0
def getGenevaLqaPositions(positions):
	"""
	[Iterable] positions => [Iterable] positions

	Read Geneva consolidated tax lot positions, then do the following: 

	1) take out those not suitable for liquidity test (cash, FX forward, etc.);
	2) Add Id, IdType and Position fields for LQA processing.

	"""

	# [Dictonary] p => [Dictionary] enriched position with id and idType
	addIdnType = compose(
		lambda t: mergeDict(t[2], {'Id': t[0], 'IdType': t[1]})
	  , lambda p: (*getIdnType(p), p)
	)


	return compose(
		partial(map, addIdnType)
	  , partial(filterfalse, noNeedLiquidityGeneva)
	  , lambda positions: lognContinue('getGenevaLqaPositions(): start', positions)
	)(positions)
Example #6
0
def getBlpLqaPositions(positions):
	"""
	[Iterable] positions => ( [Iterable] CLO positions
					 	    , [Iterable] nonCLO positions
					 	    )

	Read Bloomberg raw positions, then do the following: 

	1) take out those not suitable to do liquidity test (cash, FX forward, etc.);
	2) take out DIF fund positions, since they will come from Geneva;
	2) split into clo and nonCLO positions.

	Return (CLO positions, nonCLO positions)
	"""
	removeUnwantedPositions = compose(
		partial( filterfalse
	  		   , lambda p: p['Asset Type'] in [ 'Cash', 'Foreign Exchange Forward'
	  		   								  , 'Repo Liability', 'Money Market'] \
					or p['Name'] in ['.FSFUND HK', 'CLFLDIF HK']	# open ended funds
			   )
	  
	  , partial(filterfalse, lambda p: p['Position'] == '' or p['Position'] <= 0)
	)


	# [Dictionary] position => [Dictioanry] position with id and idtype
	updatePositionId = compose(
		lambda t: mergeDict(t[2], {'Id': t[0], 'IdType': t[1]})
	  , lambda position: (*getIdnType(position), position)
	)


	isCLOPortfolio = lambda p: p['Account Code'] in \
						['12229', '12734', '12366', '12630', '12549', '12550', '13007']


	"""
	[Iterable] positions => ( [Iterable] CLO positions
							, [Iterable] non CLO positions
							)

	Split the positions into All, CLO and non-CLO group
	"""
	splitCLO = lambda positions: \
		reduce( lambda acc, el: ( chain(acc[0], [el])
								, acc[1]
								) if isCLOPortfolio(el) else \
								
								( acc[0]
								, chain(acc[1], [el])
								)
	  		  , positions
	  		  , ([], [])
	  		  )


	return \
	compose(
		splitCLO
	  , partial(map, updatePositionId)
	  , removeUnwantedPositions		
	  , lambda positions: lognContinue('getBlpLqaPositions(): start', positions)
	)(positions)
Example #7
0
	Example:

	[ {'Id': '1 HK', 'Position': 100, ...}
	  , {'Id': '1 HK', 'Position': 200, ...}
	]

	=>

	{'Id': '1 HK', 'Position': 300, ...}

	NOTE: consolidated position is hard to tell whether it is a blp position or
	a geneva position. Therefore we 'Position' field to store the total quantity.
"""
consolidateGroup = lambda group: \
	mergeDict(group[0].copy(), {'Position': sum(map(getQuantity, group))})



"""[Iterable] positions => [Iterable] consolidated positions"""
consolidate = compose(
	  partial(map, consolidateGroup)
	, lambda d: d.values()
	, partial(groupbyToolz, lambda p: p['Id'])
)	



def lognContinue(msg, x):
	logger.debug(msg)
	return x
Example #8
0
 def updateSecurityId(p):
     if len(p['SECURITIES'].split()[0]) == 12:  # it's ISIN
         return mergeDict(p, {'SECURITIES': p['SECURITIES'].split()[0]})
     else:
         return p