def create_ratings_property(self, *ratings): ratings = [*ratings] global scope scope = "Derived" for rating in ratings: property_definition = models.CreatePropertyDefinitionRequest( domain="Instrument", scope=scope, code=f"{rating}Rating", display_name=f"{rating}Rating", data_type_id=lusid.ResourceId(scope="system", code="number"), ) try: # create property definition self.property_definitions_api.create_property_definition( create_property_definition_request=property_definition ) except lusid.ApiException as e: if json.loads(e.body)["name"] == "PropertyAlreadyExists": logging.info( f"Property {property_definition.domain}/{property_definition.scope}/{property_definition.display_name} already exists" )
def check_or_create_property(api_factory, property_key): split_prop = property_key.split("/") if len(split_prop) != 3: raise ValueError( f"Invalid Value: {property_key}. The property key must have exactly two '/' slashes!" ) domain = split_prop[0] scope = split_prop[1] code = split_prop[2] prop_def_req = models.CreatePropertyDefinitionRequest( domain=domain, scope=scope, code=code, display_name=f"{code}", data_type_id=models.ResourceId(scope="system", code="string")) try: api_factory.build( lusid.api.PropertyDefinitionsApi).create_property_definition( create_property_definition_request=prop_def_req) except ApiException: logging.info( f"Property definition {domain}/{scope}/{code} already exists.")
def test_create_portfolio_with_properties(self): _, scope, property_code, _ = self.id_generator.generate_scope_and_code( "property_definition", scope=TestDataUtilities.tutorials_scope, code_prefix="fund-style-", annotations=["Portfolio"]) data_type_id = models.ResourceId("system", "string") # property definition property_definition = models.CreatePropertyDefinitionRequest( domain="Portfolio", scope=TestDataUtilities.tutorials_scope, code=property_code, value_required=False, display_name="Fund Style", life_time="Perpetual", data_type_id=data_type_id) # create the property definition property_definition_result = self.property_definitions_api.create_property_definition( create_property_definition_request=property_definition) # property value property_value = "Active" portfolio_property = models.ModelProperty( key=property_definition_result.key, value=models.PropertyValue(label_value=property_value)) _, scope, portfolio_code = self.id_generator.generate_scope_and_code( "portfolio", scope=TestDataUtilities.tutorials_scope, code_prefix="portfolio-") # details of the portfolio to be created request = models.CreateTransactionPortfolioRequest( display_name=portfolio_code, code=portfolio_code, base_currency="GBP", # set the property value when creating the portfolio properties={property_definition_result.key: portfolio_property}) # create the portfolio portfolio = self.transaction_portfolios_api.create_portfolio( scope=scope, create_transaction_portfolio_request=request) portfolio_code = portfolio.id.code self.assertEqual(portfolio_code, request.code) portfolio_properties = self.portfolios_api.get_portfolio_properties( TestDataUtilities.tutorials_scope, portfolio_code) self.assertEqual(len(portfolio_properties.properties), 1) self.assertEqual( portfolio_properties.properties[ property_definition_result.key].value.label_value, property_value)
def test_create_portfolio_with_metric_property(self): uuid = self.get_guid() effective_date = datetime(year=2018, month=1, day=1, tzinfo=pytz.utc) # details of property to be created metric_property_definition = models.CreatePropertyDefinitionRequest( domain="Portfolio", scope=TestDataUtilities.tutorials_scope, code="fund-NAV-{}".format(uuid), display_name="fund NAV", life_time="Perpetual", value_required=False, data_type_id=models.resource_id.ResourceId( scope="system", code="currencyAndAmount")) # create property definitions metric_property_definition_result = self.property_definitions_api.create_property_definition( metric_property_definition) # create the property values metric_property_value_request = models.PropertyValue( metric_value=models.MetricValue(value=1100000, unit="GBP")) # metric_property_value_request = models.PropertyValue(label_value="Active") # Details of the new portfolio to be created, created here with the minimum set of mandatory fields create_portfolio_request = models.CreateTransactionPortfolioRequest( code="ud-{}".format(uuid), display_name="portfolio-{}".format(uuid), base_currency="GBP", created=effective_date, properties={ metric_property_definition_result.key: models.PerpetualProperty( key=metric_property_definition_result.key, value=metric_property_value_request) }) # Create portfolio portfolio_result = self.transaction_portfolios_api.create_portfolio( scope=TestDataUtilities.tutorials_scope, create_transaction_portfolio_request=create_portfolio_request) portfolio_properties = self.portfolios_api.get_portfolio_properties( scope=TestDataUtilities.tutorials_scope, code=portfolio_result.id.code).properties metric_property = portfolio_properties[ metric_property_definition_result.key] # Perform assertions on codes, keys, values and units self.assertEqual(portfolio_result.id.code, create_portfolio_request.code) self.assertEqual( list(portfolio_properties.keys())[0], metric_property_definition_result.key) self.assertEqual(metric_property.value.metric_value.value, metric_property_value_request.metric_value.value) self.assertEqual(metric_property.value.metric_value.unit, metric_property_value_request.metric_value.unit)
def test_create_portfolio_with_label_property(self): # Details of property to be created uuid = self.get_guid() effective_date = datetime(year=2018, month=1, day=1, tzinfo=pytz.utc) label_property_definition = models.CreatePropertyDefinitionRequest( domain="Portfolio", scope=TestDataUtilities.tutorials_scope, code="fund-style-{}".format(uuid), display_name="fund style", life_time="Perpetual", value_required=False, data_type_id=models.resource_id.ResourceId(scope="system", code="string")) # create property definition label_property_definition_request = self.property_definitions_api.create_property_definition( label_property_definition) # create property values property_value = models.PropertyValue(label_value="Active") # Details of new portfolio to be created create_portfolio_request = models.CreateTransactionPortfolioRequest( code="ud-{}".format(uuid), display_name="portfolio-{}".format(uuid), base_currency="GBP", created=effective_date, properties={ label_property_definition_request.key: models.PerpetualProperty( key=label_property_definition_request.key, value=property_value) }) # create portfolio portfolio_request = self.transaction_portfolios_api.create_portfolio( scope=TestDataUtilities.tutorials_scope, create_transaction_portfolio_request=create_portfolio_request) # get properties for assertions portfolio_properties = self.portfolios_api.get_portfolio_properties( scope=TestDataUtilities.tutorials_scope, code=portfolio_request.id.code).properties label_property = portfolio_properties[ label_property_definition_request.key] # Perform assertions on keys, codes and values self.assertEqual( list(portfolio_properties.keys())[0], label_property_definition_request.key) self.assertEqual(portfolio_request.id.code, create_portfolio_request.code) self.assertEqual(label_property.value.label_value, property_value.label_value)
def load_properties(properties_api, id_generator, scopes, codes): for scope in scopes: for code in codes: try: properties_api.create_property_definition( create_property_definition_request=models.CreatePropertyDefinitionRequest( domain="Order", scope=scope, code=code, display_name=code, constraint_style="Property", data_type_id=lusid.ResourceId(scope="system", code="string"), ) ) except lusid.ApiException as e: if json.loads(e.body)["name"] == "PropertyAlreadyExists": pass # ignore if the property definition exists finally: id_generator.add_scope_and_code("property_definition", scope, code, ["Order"])
def ensure_property_definition(cls, code): try: cls.property_definitions_api.get_property_definition( domain="Instrument", scope=TestDataUtilities.tutorials_scope, code=code) except ApiException as e: # property definition doesn't exist (returns 404), so create one property_definition = models.CreatePropertyDefinitionRequest( domain="Instrument", scope=TestDataUtilities.tutorials_scope, life_time="Perpetual", code=code, value_required=False, data_type_id=models.ResourceId("system", "string")) # create the property cls.property_definitions_api.create_property_definition( definition=property_definition)
def create_transaction_property(self): # Details of the property property_definition = models.CreatePropertyDefinitionRequest( domain="Transaction", scope=self.scope, code=self.code, display_name=self.code, data_type_id=lusid.ResourceId(scope="system", code="string"), ) # create property definition try: self.property_definitions_api.create_property_definition( create_property_definition_request=property_definition ) except lusid.ApiException as e: if json.loads(e.body)["name"] == "PropertyAlreadyExists": self.root_logger.info( f"Property {property_definition.domain}/{property_definition.scope}/{property_definition.code} already exists" )
def request_define_property(domain, scope, code, display_name, api_factory): # Create a request to define our strategy property property_request = models.CreatePropertyDefinitionRequest( domain='Transaction', scope=scope, code='strategy', value_required=False, display_name='strategy', data_type_id=models.ResourceId(scope='system', code='string')) # Call LUSID to create our new property property_response = api_factory.build( lusid.api.PropertyDefinitionsApi).create_property_definition( create_property_definition_request=property_request) # Grab the key off the response to use when referencing this property in other LUSID calls strategy_property_key = property_response.key # Pretty print our strategy property key prettyprint.heading('Strategy Property Key: ', strategy_property_key) return strategy_property_key
def test_add_transaction_to_portfolio_with_property(self): guid = str(uuid.uuid4()) property_name = "traderId-{0}".format(guid) # details of the property to be created property_definition = models.CreatePropertyDefinitionRequest( # The domain the property is to be applied to domain="Transaction", # the scope the property will be created in scope=TestDataUtilities.tutorials_scope, life_time="Perpetual", # when the property value is set it will be valid forever and cannot be changed. # properties whose values can change over time should be created with LifeTimeEnum.TIMEVARIANT code=property_name, value_required=False, display_name="Trader Id", data_type_id=models.ResourceId("system", "string")) # create the property definition property_definition_result = self.property_definitions_api.create_property_definition( definition=property_definition) # effective date for which portfolio is created effective_date = datetime(2018, 1, 1, tzinfo=pytz.utc) # create the portfolio portfolio_id = self.test_data_utilities.create_transaction_portfolio( TestDataUtilities.tutorials_scope) property_value_as_string = "A Trader" property_value = models.PropertyValue(property_value_as_string) # details of the transaction to be added transaction = models.TransactionRequest( transaction_id=str(uuid.uuid4()), type="Buy", instrument_identifiers={ TestDataUtilities.lusid_luid_identifier: self.instrument_ids[0] }, transaction_date=effective_date, settlement_date=effective_date, units=100, transaction_price=models.TransactionPrice(12.3), total_consideration=models.CurrencyAndAmount(1230, "GBP"), source="Client", # add the property to the transaction properties={ property_definition_result.key: models.PerpetualProperty(property_definition_result.key, property_value) }) # add the transaction self.transaction_portfolios_api.upsert_transactions( TestDataUtilities.tutorials_scope, portfolio_id, transactions=[transaction]) # get the trades trades = self.transaction_portfolios_api.get_transactions( TestDataUtilities.tutorials_scope, portfolio_id) self.assertEqual(len(trades.values), 1) self.assertEqual(trades.values[0].transaction_id, transaction.transaction_id) self.assertEqual( trades.values[0].properties[ property_definition_result.key].value.label_value, property_value_as_string)
def test_create_portfolio_with_mv_property(self): # Details of property to be created effective_date = datetime(year=2018, month=1, day=1, tzinfo=pytz.utc) scope = "MultiValueProperties" code = "MorningstarQuarterlyRating" portfolio_code = "Portfolio-MVP" multi_value_property_definition = models.CreatePropertyDefinitionRequest( domain="Portfolio", scope=scope, code=code, display_name=code, constraint_style="Collection", data_type_id=lusid.ResourceId(scope="system", code="string"), ) # create property definition try: self.property_definitions_api.create_property_definition( create_property_definition_request= multi_value_property_definition) except lusid.ApiException as e: if json.loads(e.body)["name"] == "PropertyAlreadyExists": logging.info( f"Property {multi_value_property_definition.domain}/{multi_value_property_definition.scope}/{multi_value_property_definition.display_name} already exists" ) finally: self.id_generator.add_scope_and_code( "property_definition", multi_value_property_definition.scope, multi_value_property_definition.code, ["Portfolio"]) schedule = [ '{ "2019-12-31" : "5"}', '{ "2020-03-31" : "4"}', '{ "2020-06-30" : "3"}', '{ "2020-09-30" : "3"}', ] # Details of new portfolio to be created create_portfolio_request = models.CreateTransactionPortfolioRequest( code=portfolio_code, display_name=portfolio_code, base_currency="GBP", created=effective_date, ) # create portfolio try: self.transaction_portfolios_api.create_portfolio( scope=scope, create_transaction_portfolio_request=create_portfolio_request, ) except lusid.ApiException as e: if json.loads(e.body)["name"] == "PortfolioWithIdAlreadyExists": logging.info( f"Portfolio {create_portfolio_request.code} already exists" ) finally: self.id_generator.add_scope_and_code("portfolio", scope, portfolio_code) self.portfolios_api.upsert_portfolio_properties( scope=scope, code=portfolio_code, request_body={ f"Portfolio/{scope}/{code}": models.ModelProperty( key=f"Portfolio/{scope}/{code}", value=models.PropertyValue( label_value_set=models.LabelValueSet(values=schedule)), ) }, ) # get properties for assertions portfolio_properties = self.portfolios_api.get_portfolio_properties( scope=scope, code=portfolio_code).properties label_value_set = portfolio_properties[ f"Portfolio/MultiValueProperties/{code}"].value.label_value_set.values self.assertCountEqual(label_value_set, schedule)
def create_property_definitions_from_file(client, scope, domain, data_frame, missing_property_columns): """ Creates the property definitions for all the columns in a file :param LusidApi client: The LusidApi client to use :param str scope: The scope to create the property definitions in :param str domain: The domain to create the property definitions in :param Pandas Series data_frame_dtypes: The dataframe dtypes to add definitions for :return: dict property_key_mapping: A mapping of data_frame columns to property keys """ missing_property_data_frame = data_frame.loc[:, missing_property_columns] # Ensure that all data types in the file have been mapped if not (set([ str(data_type) for data_type in missing_property_data_frame.dtypes.unique() ]) <= set(globals['data_type_mapping'])): raise Exception( '''There are data types in the data_frame which have not been mapped to LUSID data types, please ensure that all data types have been mapped before retrying''' ) # Initialise a dictionary to hold the keys property_key_mapping = {} # Iterate over the each column and its data type for column_name, data_type in missing_property_data_frame.dtypes.iteritems( ): # Make the column name LUSID friendly lusid_friendly_code = make_code_lusid_friendly(column_name) # If there is no data Pandas infers a type of float, would prefer to infer object if missing_property_data_frame[column_name].isnull().all(): print('{} is null'.format(column_name)) data_type = 'object' data_frame[column_name] = data_frame[column_name].astype( 'object', copy=False) # Create a request to define the property, assumes value_required is false for all property_request = models.CreatePropertyDefinitionRequest( domain=domain, scope=scope, code=lusid_friendly_code, value_required=False, display_name=column_name, data_type_id=models.ResourceId( scope='default', code=globals['data_type_mapping'][str(data_type)])) # Call LUSID to create the new property property_response = client.property_definitions.create_property_definition( definition=property_request) print('Created - {} - with datatype {}'.format( property_response.key, property_response.data_type_id.code)) # Grab the key off the response to use when referencing this property in other LUSID calls property_key_mapping[column_name] = property_response.key return property_key_mapping, data_frame