def _create(self): # If a priceables portfolio, try resolving to MQ portfolio if self.__priceables: self.save() self.priceables = None return # If a positions portfolio, create using MQ API port = GsPortfolioApi.create_portfolio( portfolio=MQPortfolio(name=self.name, currency=self.currency, entitlements=self.entitlements.to_target())) PositionedEntity.__init__(self, port.id, EntityType.PORTFOLIO) Entity.__init__(self, port.id, EntityType.PORTFOLIO) self.__id = port.id self._PositionedEntity__entity_type = EntityType.PORTFOLIO self.entitlements = Entitlements.from_target(port.entitlements) self.currency = Currency(port.currency) # If the portfolio contains positions, upload them to the MQ portfolio and schedule reports if self.position_sets: position_sets = self.position_sets self.position_sets = None self.update_positions(position_sets, False) self._schedule_first_reports( [pos_set.date for pos_set in position_sets]) self.position_sets = None
def __init__(self, priceables: Optional[Union[PriceableImpl, Iterable[PriceableImpl], dict]] = (), name: Optional[str] = 'Portfolio ' + dt.datetime.today().strftime("%d %b, %Y"), position_sets: Optional[List] = None, currency: Optional[Currency] = Currency.USD, entitlements: Entitlements = None, *, portfolio_id: str = None): """ Creates a portfolio object which can be used to hold instruments :param priceables: constructed with an instrument, portfolio, iterable of either, or a dictionary where key is name and value is a priceable """ PriceableImpl.__init__(self) Entity.__init__(self, portfolio_id, EntityType.PORTFOLIO) self.__name = name self.__id = portfolio_id self.__currency = currency self.__need_to_schedule_reports = False self.__entitlements = entitlements if entitlements else Entitlements() self.__position_sets = position_sets # Can't initialize a portfolio with both priceables or position sets if priceables and position_sets: raise ValueError( 'Cannot initialize a portfolio with both position sets and priceables. Please pick one.' ) if portfolio_id: # Can't add positions to an existing portfolio within the constructor if position_sets: raise ValueError( 'Cannot add positions to an existing portfolio at construction.' 'Please initialize the portfolio without the position sets and then update positions using the ' 'update_positions(position_sets) function.') PositionedEntity.__init__(self, portfolio_id, EntityType.PORTFOLIO) if isinstance(priceables, dict): priceables_list = [] for name, priceable in priceables.items(): priceable.name = name priceables_list.append(priceable) self.priceables = priceables_list else: self.priceables = priceables
def resolve_entities(reference_list: List[Dict], entity_cache: Dict = None): """ Utility function to fetch entities (assets, countries, etc.). Allows us to split functionality that requires data fetching. :param reference_list: A list of entity references (entityId and entityType dictionaries) :param entity_cache: Map of entity id to the entity for external cache management :return: None """ entity_cache = entity_cache or {} for reference in reference_list: # Check if the entity is in the cache entity_id = reference.get(ENTITY_ID) if entity_id in entity_cache: entity = entity_cache[entity_id] else: try: entity = Entity.get(entity_id, 'MQID', reference.get(ENTITY_TYPE)) except MqRequestError as e: _logger.warning(e) entity = entity_id if reference[TYPE] == DATA_ROW: # If the reference is for a data row, simply set the entity of the row. reference[REFERENCE].entity = entity elif reference[TYPE] == PROCESSOR: # If the reference is for a processor, set the given parameter as the entity. setattr(reference[REFERENCE], reference[PARAMETER], entity) data_query_info = reference[REFERENCE].children.get(reference[PARAMETER]) if not data_query_info: raise MqValueError( f'{reference[PARAMETER]} does not exist in children of ' f'{reference[REFERENCE].__class__.__name__}') data_query_info.entity = entity
def resolve_entities(reference_list: List[Dict]): """ Utility function to fetch entities (assets, countries, etc.). Allows us to split functionality that requires data fetching. :param reference_list: A list of entity references (entityId and entityType dictionaries) :return: None """ entity_cache = {} for reference in reference_list: # Create a hash key of the entity data so we don't fetch the same entity multiple times. key = hash((reference.get(ENTITY_ID), reference.get(ENTITY_TYPE))) if key in entity_cache: entity = entity_cache[key] else: entity = Entity.get(reference.get(ENTITY_ID), 'MQID', reference.get(ENTITY_TYPE)) if reference[TYPE] == DATA_ROW: # If the reference is for a data row, simply set the entity of the row. reference[REFERENCE].entity = entity elif reference[TYPE] == PROCESSOR: # If the reference is for a processor, set the given parameter as the entity. setattr(reference[REFERENCE], reference[PARAMETER], entity) data_query_info = reference[REFERENCE].children.get( reference[PARAMETER]) if not data_query_info: raise MqValueError( f'{reference[PARAMETER]} does not exist in children of ' f'{reference[REFERENCE].__class__.__name__}') data_query_info.entity = entity
def process(self, entity: Entity) -> ProcessorResult: """ Fetch the entity and resolve the field """ try: # First try to get the value off the entity entity_dict = entity.get_entity() data = get(entity_dict, self.field) if data: return ProcessorResult(True, data) # If not found, try to get the value from the asset identifiers identifier = next( iter( filter(lambda x: x['type'] == self.field, entity_dict.get('identifiers', []))), None) if identifier: return ProcessorResult(True, identifier['value']) # Return a failed processor result if no field was found on the object or it's identifiers return ProcessorResult( False, f'Unable to find {self.field} in identifiers for entity {entity.get_marquee_id()}' ) except ValueError: return ProcessorResult(False, "Could not get field on entity")
def __add_required_rdates(self, entity: Entity, rdate_entity_map: Dict[str, Set[Tuple]]): start, end = get(self, 'start'), get(self, 'end') entity_id = entity.get_marquee_id() if isinstance(entity, Entity) else '' if isinstance(start, RelativeDate): base_date = str(start.base_date) if start.base_date_passed_in else None rdate_entity_map[entity_id].add((start.rule, base_date)) if isinstance(end, RelativeDate): base_date = str(end.base_date) if end.base_date_passed_in else None rdate_entity_map[entity_id].add((end.rule, base_date))