diff --git a/sdk/Dockerfile b/sdk/Dockerfile index ec7fa8bde53..835af68a393 100644 --- a/sdk/Dockerfile +++ b/sdk/Dockerfile @@ -10,7 +10,5 @@ RUN pip install --no-cache-dir -r requirements.txt -r requirements.dev.txt RUN pip --no-cache-dir install --upgrade awscli -ENV FBN_LUSID_API_URL ${FBN_LUSID_API_URL} - #CMD /bin/bash ENTRYPOINT PYTHONPATH=/usr/src/:/usr/src/tests python -m unittest discover -v \ No newline at end of file diff --git a/sdk/docker-compose.yml b/sdk/docker-compose.yml index d90ea09c7ce..d21b7bd9c7c 100644 --- a/sdk/docker-compose.yml +++ b/sdk/docker-compose.yml @@ -21,14 +21,14 @@ services: environment: - FBN_CLIENT_ID - FBN_CLIENT_SECRET - - FBN_LUSID_API_URL + - FBN_LUSID_API_URL=${FBN_BASE_API_URL}/api - FBN_PASSWORD - FBN_TOKEN_URL - FBN_USERNAME - FBN_PROXY_ADDRESS=http://tinyproxy:8888 - FBN_PROXY_USERNAME=user - FBN_PROXY_PASSWORD=password - - FBN_LUSID_ACCESS_TOKEN + - FBN_ACCESS_TOKEN volumes: - .:/usr/src depends_on: diff --git a/sdk/tests/tutorials/__init__.py b/sdk/tests/tutorials/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/sdk/tests/tutorials/ibor/__init__.py b/sdk/tests/tutorials/ibor/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/sdk/tests/tutorials/ibor/test_bitemporal.py b/sdk/tests/tutorials/ibor/test_bitemporal.py deleted file mode 100644 index e236bb18485..00000000000 --- a/sdk/tests/tutorials/ibor/test_bitemporal.py +++ /dev/null @@ -1,126 +0,0 @@ -import unittest -from datetime import datetime -from time import sleep - -import pytz - -import lusid -from lusidfeature import lusid_feature -from utilities import InstrumentLoader -from utilities import TestDataUtilities - - -class Bitemporal(unittest.TestCase): - - @classmethod - def setUpClass(cls): - - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - - instruments_api = lusid.InstrumentsApi(api_client) - instrument_loader = InstrumentLoader(instruments_api) - cls.instrument_ids = instrument_loader.load_instruments() - - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - def print_transactions(self, as_at, transactions): - print("transactions at: {}".format(as_at)) - - for transaction in transactions: - print("{}\t{}\t{}\t{}\t{}".format(transaction.instrument_uid, - transaction.transaction_date, - transaction.units, - transaction.transaction_price.price, - transaction.total_consideration.amount)) - - @lusid_feature("F2-3") - def test_apply_bitemporal_portfolio_change(self): - portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - initial_transactions = [ - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[0], - units=100, - price=101, - currency="GBP", - trade_date=datetime(2018, 1, 1, tzinfo=pytz.utc), - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[1], - units=100, - price=102, - currency="GBP", - trade_date=datetime(2018, 1, 2, tzinfo=pytz.utc), - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[2], - units=100, - price=103, - currency="GBP", - trade_date=datetime(2018, 1, 3, tzinfo=pytz.utc), - transaction_type="StockIn") - ] - - # add the initial batch of transactions - inital_result = self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=initial_transactions) - - as_at_1 = inital_result.version.as_at_date - sleep(0.5) - - # add another trade for 2018-1-8 - new_trade = self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[3], - units=100, - price=104, - currency="GBP", - trade_date=datetime(2018, 1, 8, tzinfo=pytz.utc), - transaction_type="StockIn") - added_result = self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=[new_trade]) - as_at_2 = added_result.version.as_at_date - sleep(0.5) - - # add back dated trade for 2018-1-5 - backdated_trade = self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[4], - units=100, - price=105, - currency="GBP", - trade_date=datetime(2018, 1, 5, - tzinfo=pytz.utc), - transaction_type="StockIn") - - added_result = self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=[backdated_trade]) - - as_at_3 = added_result.version.as_at_date - sleep(0.5) - - # list transactions at initial upload - transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - as_at=as_at_1) - self.assertEqual(len(transactions.values), 3) - self.print_transactions(as_at_1, transactions.values) - - transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - as_at=as_at_2) - - self.assertEqual(len(transactions.values), 4) - self.print_transactions(as_at_2, transactions.values) - - transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - as_at=as_at_3) - - self.assertEqual(len(transactions.values), 5) - self.print_transactions(as_at_3, transactions.values) - - transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code) - - self.assertEqual(len(transactions.values), 5) - self.print_transactions(datetime.now(), transactions.values) diff --git a/sdk/tests/tutorials/ibor/test_cut_labels.py b/sdk/tests/tutorials/ibor/test_cut_labels.py deleted file mode 100644 index 55a122ca29d..00000000000 --- a/sdk/tests/tutorials/ibor/test_cut_labels.py +++ /dev/null @@ -1,225 +0,0 @@ -import unittest -import uuid -from datetime import date, timedelta - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature - -from lusid import ApiException -from utilities import InstrumentLoader -from utilities import TestDataUtilities - - -class CutLabels(unittest.TestCase): - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - cls.instruments_api = lusid.InstrumentsApi(api_client) - - instrument_loader = InstrumentLoader(cls.instruments_api) - cls.instrument_ids = instrument_loader.load_instruments() - - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - cls.cut_labels = lusid.CutLabelDefinitionsApi(api_client) - - @lusid_feature("F16-3") - def test_cut_labels(self): - def get_guid(): - return str(uuid.uuid4())[:4] - - # define function to format cut labels - def cut_label_formatter(date, cut_label_code): - return str(date) + "N" + cut_label_code - - # Create cut labels - code = {} - - def create_cut_label(hours, minutes, display_name, description, time_zone, code_dict): - # Create the time for the cut label - time = models.CutLocalTime(hours=hours, minutes=minutes) - - # Define the parameters of the cut label in a request - request = models.CutLabelDefinition( - code=display_name + "-" + get_guid(), - description=description, - display_name=display_name, - cut_local_time=time, - time_zone=time_zone) - - # Add the codes of our cut labels to our dictionary - code_dict[request.display_name] = request.code - - # Send the request to LUSID to create the cut label - result = None - try: - result = self.cut_labels.create_cut_label_definition(create_cut_label_definition_request=request) - except ApiException: - result = self.cut_labels.get_cut_label_definition(request.code) - - # Check that result gives same details as input - self.assertEqual(result.display_name, display_name) - self.assertEqual(result.description, description) - self.assertEqual(result.cut_local_time, time) - self.assertEqual(result.time_zone, time_zone) - - # Create cut labels for different time zones - create_cut_label(hours=9, minutes=0, display_name="LondonOpen", description="London Opening Time, 9am in UK", - time_zone="GB", code_dict=code) - create_cut_label(hours=17, minutes=0, display_name="LondonClose", description="London Closing Time, 5pm in UK", - time_zone="GB", code_dict=code) - create_cut_label(hours=9, minutes=0, display_name="SingaporeOpen", description="", time_zone="Singapore", - code_dict=code) - create_cut_label(hours=17, minutes=0, display_name="SingaporeClose", description="", time_zone="Singapore", - code_dict=code) - create_cut_label(hours=9, minutes=0, display_name="NYOpen", description="", time_zone="America/New_York", - code_dict=code) - create_cut_label(hours=17, minutes=0, display_name="NYClose", description="", time_zone="America/New_York", - code_dict=code) - - ## Create portfolio - scope = 'cut_labels_demo' - portfolio_code = self.test_data_utilities.create_transaction_portfolio(scope) - - ## Get the instrument identifiers - instrument1 = self.instrument_ids[0] - instrument2 = self.instrument_ids[1] - instrument3 = self.instrument_ids[2] - - currency = "GBP" - - # set a currency LUID, as the call to GetHoldings returns the LUID not the identifier we are about to create - currency_luid = "CCY_{}".format(currency) - - ## Set initial holdings for each instrument from LondonOpen 5 days ago - initial_holdings_cut_label = cut_label_formatter(date.today() - timedelta(days=5), code["LondonOpen"]) - initial_holdings = [ - # cash balance - self.test_data_utilities.build_cash_funds_in_adjust_holdings_request(currency=currency, units=100000.0), - # instrument 1 - self.test_data_utilities.build_adjust_holdings_request(instrument_id=instrument1, - units=100.0, - price=101.0, - currency=currency, - trade_date=None - ), - # instrument 2 - self.test_data_utilities.build_adjust_holdings_request(instrument_id=instrument2, - units=100.0, - price=102.0, - currency=currency, - trade_date=None - ), - # instrument 3 - self.test_data_utilities.build_adjust_holdings_request(instrument_id=instrument3, - units=100.0, - price=99.0, - currency=currency, - trade_date=None - ) - ] - # add initial holdings to our portfolio from LondonOpen 5 days ago - self.transaction_portfolios_api.set_holdings(scope=scope, - code=portfolio_code, - adjust_holding_request=initial_holdings, - effective_at=initial_holdings_cut_label) - - ## Check initial holdings - # get holdings at LondonOpen today, before transactions occur - get_holdings_cut_label = cut_label_formatter(date.today(), code["LondonOpen"]) - holdings = self.transaction_portfolios_api.get_holdings(scope=scope, - code=portfolio_code, - effective_at=get_holdings_cut_label) - # check that holdings are as expected before transactions occur for each instrument - holdings.values.sort(key=lambda i: i.instrument_uid) - self.assertEqual(len(holdings.values), 4) - self.test_data_utilities.test.assert_cash_holdings(holdings=holdings, - index=0, - instrument_id=currency_luid, - units=100000.0) - self.test_data_utilities.test.assert_holdings(holdings=holdings, - index=1, - instrument_id=instrument1, - units=100.0, - cost_amount=10100.0) - self.test_data_utilities.test.assert_holdings(holdings=holdings, - index=2, - instrument_id=instrument2, - units=100.0, - cost_amount=10200.0) - self.test_data_utilities.test.assert_holdings(holdings=holdings, - index=3, - instrument_id=instrument3, - units=100.0, - cost_amount=9900.0) - - ## Add transactions at different times in different time zones during the day with cut labels - transaction_1_cut_label = cut_label_formatter(date.today(), code["LondonOpen"]) - transaction_2_cut_label = cut_label_formatter(date.today(), code["SingaporeClose"]) - transaction_3_cut_label = cut_label_formatter(date.today(), code["NYOpen"]) - transaction_4_cut_label = cut_label_formatter(date.today(), code["NYClose"]) - transactions = [ - self.test_data_utilities.build_transaction_request(instrument_id=instrument1, - units=100.0, - price=100.0, - currency=currency, - trade_date=transaction_1_cut_label, - transaction_type="Buy"), - self.test_data_utilities.build_transaction_request(instrument_id=instrument2, - units=100.0, - price=100.0, - currency=currency, - trade_date=transaction_2_cut_label, - transaction_type="Buy"), - self.test_data_utilities.build_transaction_request(instrument_id=instrument3, - units=100.0, - price=100.0, - currency=currency, - trade_date=transaction_3_cut_label, - transaction_type="Buy"), - self.test_data_utilities.build_transaction_request(instrument_id=instrument1, - units=100.0, - price=100.0, - currency=currency, - trade_date=transaction_4_cut_label, - transaction_type="Buy") - ] - # Add transactions to the portfolio - self.transaction_portfolios_api.upsert_transactions(scope=scope, - code=portfolio_code, - transaction_request=transactions) - - ## Retrieve holdings at LondonClose today (5pm local time) - # This will mean that the 4th transaction will not be included, demonstrating how cut labels work across time zones - get_holdings_cut_label = cut_label_formatter(date.today(), code["LondonClose"]) - holdings = self.transaction_portfolios_api.get_holdings(scope=scope, - code=portfolio_code, - effective_at=get_holdings_cut_label) - - # check that holdings are as expected after transactions for each instrument - holdings.values.sort(key=lambda i: i.instrument_uid) - self.assertEqual(len(holdings.values), 4) - self.test_data_utilities.test.assert_cash_holdings(holdings=holdings, - index=0, - instrument_id=currency_luid, - units=70000.0) - self.test_data_utilities.test.assert_holdings(holdings=holdings, - index=1, - instrument_id=instrument1, - units=200.0, - cost_amount=20100.0) - self.test_data_utilities.test.assert_holdings(holdings=holdings, - index=2, - instrument_id=instrument2, - units=200.0, - cost_amount=20200.0) - self.test_data_utilities.test.assert_holdings(holdings=holdings, - index=3, - instrument_id=instrument3, - units=200.0, - cost_amount=19900.0) diff --git a/sdk/tests/tutorials/ibor/test_holdings.py b/sdk/tests/tutorials/ibor/test_holdings.py deleted file mode 100644 index d3f23bb9760..00000000000 --- a/sdk/tests/tutorials/ibor/test_holdings.py +++ /dev/null @@ -1,217 +0,0 @@ -import unittest -from datetime import datetime - -import pytz - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature -from utilities import InstrumentLoader -from utilities import TestDataUtilities - - -class Holdings(unittest.TestCase): - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.scopes_api = lusid.ScopesApi(api_client) - cls.portfolios_api = lusid.PortfoliosApi(api_client) - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - cls.property_definitions_api = lusid.PropertyDefinitionsApi(api_client) - cls.instruments_api = lusid.InstrumentsApi(api_client) - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - cls.instrument_loader = InstrumentLoader(cls.instruments_api) - cls.instrument_ids = cls.instrument_loader.load_instruments() - - @lusid_feature("F15-3") - def test_get_holdings(self): - # The currency of the cash and transactions - currency = "GBP" - - # The dates for which transactions are added to the portfolio. All dates/times must be supplied in UTC - day_t1 = datetime(2018, 1, 1, tzinfo=pytz.utc) - day_tplus5 = datetime(2018, 1, 5, tzinfo=pytz.utc) - day_tplus10 = datetime(2018, 1, 10, tzinfo=pytz.utc) - - # Create a portfolio - portfolio_id = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - transactions = [ - # Starting cash position - self.test_data_utilities.build_cash_fundsin_transaction_request(100000, currency, day_t1), - - # Initial transaction on day_t1 - self.test_data_utilities.build_transaction_request(self.instrument_ids[0], 100.0, 101.0, currency, day_t1, - "Buy"), - self.test_data_utilities.build_transaction_request(self.instrument_ids[1], 100.0, 102.0, currency, day_t1, - "Buy"), - self.test_data_utilities.build_transaction_request(self.instrument_ids[2], 100.0, 103.0, currency, day_t1, - "Buy"), - - # On T+5, add a transaction in another instrument and another to increase the amount of instrument 1 - self.test_data_utilities.build_transaction_request(self.instrument_ids[1], 100.0, 104.0, currency, - day_tplus5, "Buy"), - self.test_data_utilities.build_transaction_request(self.instrument_ids[3], 100.0, 105.0, currency, - day_tplus5, "Buy"), - ] - - # Upload the transactions to LUSID - self.transaction_portfolios_api.upsert_transactions(TestDataUtilities.tutorials_scope, code=portfolio_id, - transaction_request=transactions) - - # Get the portfolio holdings on T+10 - holdings = self.transaction_portfolios_api.get_holdings(TestDataUtilities.tutorials_scope, portfolio_id, - effective_at=day_tplus10) - - # Ensure we have 5 holdings: 1 cash position and a position in 4 instruments that aggregates the 5 transactions - self.assertEqual(len(holdings.values), 5, msg="Unexpected number of holdings") - - holdings.values.sort(key=lambda x: x.instrument_uid) - - # Check the cash balance - self.assertEqual(holdings.values[0].instrument_uid, "CCY_{}".format(currency)) - - # Validate the holdings - self.assertEqual(holdings.values[0].holding_type, "B") - - self.assertEqual(holdings.values[1].holding_type, "P", msg="Incorrect holding type") - self.assertEqual(holdings.values[1].instrument_uid, self.instrument_ids[0], msg="Incorrect instrument id") - self.assertEqual(holdings.values[1].units, 100.0, msg="Incorrect units") - self.assertEqual(holdings.values[1].cost.amount, 10100.0, msg="Incorrect amount") - - self.assertEqual(holdings.values[2].holding_type, "P", msg="Incorrect holding type") - self.assertEqual(holdings.values[2].instrument_uid, self.instrument_ids[1], msg="Incorrect instrument id") - self.assertEqual(holdings.values[2].units, 200.0, msg="Incorrect units") - self.assertEqual(holdings.values[2].cost.amount, 20600.0, msg="Incorrect amount") - - self.assertEqual(holdings.values[3].holding_type, "P", msg="Incorrect holding type") - self.assertEqual(holdings.values[3].instrument_uid, self.instrument_ids[2], msg="Incorrect instrument id") - self.assertEqual(holdings.values[3].units, 100.0, msg="Incorrect units") - self.assertEqual(holdings.values[3].cost.amount, 10300.0, msg="Incorrect amount") - - self.assertEqual(holdings.values[4].holding_type, "P", msg="Incorrect holding type") - self.assertEqual(holdings.values[4].instrument_uid, self.instrument_ids[3], msg="Incorrect instrument id") - self.assertEqual(holdings.values[4].units, 100.0, msg="Incorrect units") - self.assertEqual(holdings.values[4].cost.amount, 10500.0, msg="Incorrect amount") - - @lusid_feature("F15-1") - def test_set_target_holdings(self): - - currency = "GBP" - - day1 = datetime(2018, 1, 1, tzinfo=pytz.utc) - day2 = datetime(2018, 1, 5, tzinfo=pytz.utc) - - portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - instrument1 = self.instrument_ids[0] - instrument2 = self.instrument_ids[1] - instrument3 = self.instrument_ids[2] - - holdings_adjustments = [ - - # cash balance - models.AdjustHoldingRequest( - instrument_identifiers={ - TestDataUtilities.lusid_cash_identifier: currency - }, - tax_lots=[ - models.TargetTaxLotRequest(units=100000.0) - ]), - - # instrument 1 - models.AdjustHoldingRequest( - instrument_identifiers={ - TestDataUtilities.lusid_luid_identifier: instrument1 - }, - tax_lots=[ - models.TargetTaxLotRequest(units=100.0, - price=101.0, - cost=models.CurrencyAndAmount(amount=10100.0, currency=currency), - portfolio_cost=10100.0, - purchase_date=day1, - settlement_date=day1) - ]), - - # instrument 2 - models.AdjustHoldingRequest( - instrument_identifiers={ - TestDataUtilities.lusid_luid_identifier: instrument2 - }, - tax_lots=[ - models.TargetTaxLotRequest(units=100.0, - price=102.0, - cost=models.CurrencyAndAmount(amount=10200.0, currency=currency), - portfolio_cost=10200.0, - purchase_date=day1, - settlement_date=day1) - ]) - ] - - # set the initial holdings on day 1 - self.transaction_portfolios_api.set_holdings(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - adjust_holding_request=holdings_adjustments, - effective_at=day1) - - # add subsequent transactions on day 2 - transactions = [ - self.test_data_utilities.build_transaction_request(instrument_id=instrument1, - units=100.0, - price=104.0, - currency=currency, - trade_date=day2, - transaction_type="Buy"), - self.test_data_utilities.build_transaction_request(instrument_id=instrument3, - units=100.0, - price=103.0, - currency=currency, - trade_date=day2, - transaction_type="Buy") - ] - - self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=transactions) - - # get the holdings for day 2 - holdings = self.transaction_portfolios_api.get_holdings(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - effective_at=day2) - - # sort to put the cash instrument first - holdings.values.sort(key=lambda i: i.instrument_uid) - - # cash balance + 3 holdings - self.assertEqual(len(holdings.values), 4) - - # remaining cash balance which takes into account the purchase transactions on day 2 - - # the call to GetHoldings returns the LUID not the identifier we created - currency_luid = "CCY_{}".format(currency) - - # cash - self.assertEqual(holdings.values[0].instrument_uid, currency_luid) - self.assertEqual(holdings.values[0].units, 79300.0) - - # instrument 1 - initial holding + transaction on day 2 - self.assertEqual(holdings.values[1].instrument_uid, instrument1) - self.assertEqual(holdings.values[1].units, 200.0) - self.assertEqual(holdings.values[1].cost.amount, 20500.0) - - # instrument 2 - initial holding - self.assertEqual(holdings.values[2].instrument_uid, instrument2) - self.assertEqual(holdings.values[2].units, 100.0) - self.assertEqual(holdings.values[2].cost.amount, 10200.0) - - # instrument 3 - transaction on day 2 - self.assertEqual(holdings.values[3].instrument_uid, instrument3) - self.assertEqual(holdings.values[3].units, 100.0) - self.assertEqual(holdings.values[3].cost.amount, 10300.0) - - - diff --git a/sdk/tests/tutorials/ibor/test_portfolios.py b/sdk/tests/tutorials/ibor/test_portfolios.py deleted file mode 100644 index fa2c6763911..00000000000 --- a/sdk/tests/tutorials/ibor/test_portfolios.py +++ /dev/null @@ -1,218 +0,0 @@ -import unittest -import uuid -from datetime import datetime - -import pytz - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature -from utilities import InstrumentLoader -from utilities import TestDataUtilities - - -class Portfolios(unittest.TestCase): - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.scopes_api = lusid.ScopesApi(api_client) - cls.portfolios_api = lusid.PortfoliosApi(api_client) - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - cls.property_definitions_api = lusid.PropertyDefinitionsApi(api_client) - cls.instruments_api = lusid.InstrumentsApi(api_client) - - instrument_loader = InstrumentLoader(cls.instruments_api) - cls.instrument_ids = instrument_loader.load_instruments() - - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - @lusid_feature("F1-4") - def test_create_portfolio(self): - guid = str(uuid.uuid4()) - - # details of the new portfolio to be created, created here with the minimum set of mandatory fields - request = models.CreateTransactionPortfolioRequest( - - # descriptive name for the portfolio - display_name="portfolio-{0}".format(guid), - - # unique portfolio code, portfolio codes must be unique across scopes - code="id-{0}".format(guid), - base_currency="GBP") - - # create the portfolio in LUSID in the specified scope - result = self.transaction_portfolios_api.create_portfolio( - scope=TestDataUtilities.tutorials_scope, - create_transaction_portfolio_request=request) - - self.assertEqual(result.id.code, request.code) - - @lusid_feature("F1-1") - def test_create_portfolio_with_properties(self): - guid = str(uuid.uuid4()) - property_name = "fund-style-{0}".format(guid) - data_type_id = models.ResourceId("system", "string") - - # property definition - property_definition = models.CreatePropertyDefinitionRequest( - domain="Portfolio", - scope=TestDataUtilities.tutorials_scope, - code=property_name, - 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)) - - # details of the portfolio to be created - request = models.CreateTransactionPortfolioRequest(display_name="portfolio-{0}".format(guid), - code="id-{0}".format(guid), - 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=TestDataUtilities.tutorials_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) - - @lusid_feature("F13-8") - def test_add_transaction_to_portfolio(self): - # effective date of the portfolio, this is the date the portfolio was created and became live. All dates/times - # must be supplied in UTC - effective_date = datetime(2018, 1, 1, tzinfo=pytz.utc) - - # create the portfolio - portfolio_id = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - # details of the transaction to be added - transaction = models.TransactionRequest( - - # unique transaction id - transaction_id=str(uuid.uuid4()), - - # transaction type, configured during system setup - 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 transaction - self.transaction_portfolios_api.upsert_transactions( - TestDataUtilities.tutorials_scope, - portfolio_id, - transaction_request=[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) - - @lusid_feature("F13-4") - 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( - create_property_definition_request=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, - transaction_request=[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) - - @lusid_feature("F2-4") - def test_list_portfolios(self): - # This defines the scope that the portfolios will be retrieved from - scope = TestDataUtilities.tutorials_scope + str(uuid.uuid4()) - - for i in range(10): - self.test_data_utilities.create_transaction_portfolio(scope) - - # Retrieve the list of portfolios - portfolios = self.portfolios_api.list_portfolios_for_scope(scope) - - self.assertEqual(len(portfolios.values), 10) diff --git a/sdk/tests/tutorials/ibor/test_properties.py b/sdk/tests/tutorials/ibor/test_properties.py deleted file mode 100644 index 6d2a961d612..00000000000 --- a/sdk/tests/tutorials/ibor/test_properties.py +++ /dev/null @@ -1,140 +0,0 @@ -import unittest -from datetime import datetime - -import pytz -import uuid - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature - -from lusid.utilities.api_client_builder import ApiClientBuilder -from utilities.instrument_loader import InstrumentLoader -from utilities.test_data_utilities import TestDataUtilities -from utilities.credentials_source import CredentialsSource - - -class Properties(unittest.TestCase): - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = ApiClientBuilder().build(CredentialsSource.secrets_path()) - - cls.property_definitions_api = lusid.PropertyDefinitionsApi(api_client) - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - cls.instruments_api = lusid.InstrumentsApi(api_client) - cls.portfolios_api = lusid.PortfoliosApi(api_client) - - instrument_loader = InstrumentLoader(cls.instruments_api) - cls.instrument_ids = instrument_loader.load_instruments() - - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - def get_guid(self): - # creates random alphanumeric code - return str(uuid.uuid4())[:12] - - @lusid_feature("F1-5") - 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) - - @lusid_feature("F1-6") - 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) - diff --git a/sdk/tests/tutorials/ibor/test_reconciliation.py b/sdk/tests/tutorials/ibor/test_reconciliation.py deleted file mode 100644 index 51623c85fc6..00000000000 --- a/sdk/tests/tutorials/ibor/test_reconciliation.py +++ /dev/null @@ -1,165 +0,0 @@ -import unittest -from datetime import datetime, timedelta - -import pytz - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature -from utilities import InstrumentLoader -from utilities import TestDataUtilities - - -class Reconciliation(unittest.TestCase): - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - cls.reconciliations_api = lusid.ReconciliationsApi(api_client) - - instruments_api = lusid.InstrumentsApi(api_client) - instrument_loader = InstrumentLoader(instruments_api) - cls.instrument_ids = instrument_loader.load_instruments() - - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - @lusid_feature("F20-1") - def test_reconcile_portfolio(self): - # create the portfolio - portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - today = datetime.now().astimezone(tz=pytz.utc) - yesterday = today - timedelta(1) - - # create transactions for yesterday - yesterdays_transactions = [ - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[0], - units=1000.0, - price=100.0, - currency="GBP", - trade_date=yesterday + timedelta(hours=8), - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[0], - units=2300.0, - price=101.0, - currency="GBP", - trade_date=yesterday + timedelta(hours=12), - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[1], - units=-1000.0, - price=102.0, - currency="GBP", - trade_date=yesterday + timedelta(hours=9), - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[2], - units=1200.0, - price=103.0, - currency="GBP", - trade_date=yesterday + timedelta(hours=16), - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[3], - units=2000.0, - price=103.0, - currency="GBP", - trade_date=yesterday + timedelta(hours=9), - transaction_type="StockIn"), - ] - - # add the transactions to LUSID - self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=yesterdays_transactions) - - # transactions for today - todays_transactions = [ - - # net long 300 - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[0], - units=-3000.0, - price=101.78, - currency="GBP", - trade_date=today + timedelta(hours=8), - transaction_type="StockIn"), - - # net long 1800 - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[0], - units=1500.0, - price=101.78, - currency="GBP", - trade_date=today + timedelta(hours=12), - transaction_type="StockIn"), - - # flat - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[1], - units=1000.0, - price=102.0, - currency="GBP", - trade_date=today + timedelta(hours=12), - transaction_type="StockIn"), - - # net long 2400 - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[2], - units=1200.0, - price=103.0, - currency="GBP", - trade_date=today + timedelta(hours=16), - transaction_type="StockIn"), - - # net long 3000 - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[3], - units=1000.0, - price=103.0, - currency="GBP", - trade_date=today + timedelta(hours=9), - transaction_type="StockIn"), - - # net long 5000 - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[3], - units=2000.0, - price=103.0, - currency="GBP", - trade_date=today + timedelta(hours=20), - transaction_type="StockIn"), - ] - - # add the transactions to LUSID - transactions_response = self.transaction_portfolios_api.upsert_transactions( - scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=todays_transactions) - - # get the time of the last update - last_as_at = transactions_response.version.as_at_date - - # We now have the portfolio with 2 days worth of transactions, going to reconcile from T-1 20:00 to now, - # this should reflect breaks for each instrument equal to the transactions from yesterday till 20:00 today - reconciliation_request = models.PortfoliosReconciliationRequest( - left=models.PortfolioReconciliationRequest( - portfolio_id=models.ResourceId(scope=TestDataUtilities.tutorials_scope, code=portfolio_code), - effective_at=yesterday + timedelta(hours=20), - as_at=last_as_at - ), - right=models.PortfolioReconciliationRequest( - portfolio_id=models.ResourceId(scope=TestDataUtilities.tutorials_scope, code=portfolio_code), - effective_at=today + timedelta(hours=16), - as_at=last_as_at - ), - instrument_property_keys=[TestDataUtilities.lusid_luid_identifier] - ) - - breaks = self.reconciliations_api.reconcile_holdings(portfolios_reconciliation_request=reconciliation_request) - - for rec_break in breaks.values: - print("{}\t{}\t{}".format(rec_break.instrument_uid, rec_break.difference_units, - rec_break.difference_cost.amount)) - - rec_map = {b.instrument_uid: b for b in breaks.values} - - self.assertEqual(-1500, rec_map[self.instrument_ids[0]].difference_units) - self.assertEqual(1000, rec_map[self.instrument_ids[1]].difference_units) - self.assertEqual(1200, rec_map[self.instrument_ids[2]].difference_units) - self.assertEqual(1000, rec_map[self.instrument_ids[3]].difference_units) - diff --git a/sdk/tests/tutorials/ibor/test_reference_portfolios.py b/sdk/tests/tutorials/ibor/test_reference_portfolios.py deleted file mode 100644 index 255d4b50250..00000000000 --- a/sdk/tests/tutorials/ibor/test_reference_portfolios.py +++ /dev/null @@ -1,140 +0,0 @@ -import unittest -import pytz -import json -import logging - -from datetime import datetime - -import lusid -import lusid.models as models - -from lusidfeature import lusid_feature -from utilities import TestDataUtilities -from utilities import InstrumentLoader - - -class ReferencePortfolio(unittest.TestCase): - @classmethod - def setUpClass(cls): - - # Log any exceptions - cls.logger = logging.getLogger() - cls.logger.setLevel(logging.INFO) - - # Create API client - api_client = TestDataUtilities.api_client() - - # Instantiate APIs we will use - cls.reference_portfolio_api = lusid.ReferencePortfolioApi(api_client) - cls.portfolios_api = lusid.PortfoliosApi(api_client) - cls.instruments_api = lusid.InstrumentsApi(api_client) - - # Load instruments - cls.instrument_loader = InstrumentLoader(cls.instruments_api) - cls.instrument_ids = cls.instrument_loader.load_instruments() - - @lusid_feature("F6-1") - def test_create_reference_portfolio(self): - - f39_reference_portfolio_code = "F39p_ReferencePortfolioCode" - f39_reference_portfolio_name = "F39p_Reference Portfolio Name" - - # Details of the new reference portfolio to be created - request = models.CreateReferencePortfolioRequest( - display_name=f39_reference_portfolio_name, - code=f39_reference_portfolio_code, - ) - - # Create the reference portfolio in LUSID in the tutorials scope - result = self.reference_portfolio_api.create_reference_portfolio( - scope=TestDataUtilities.tutorials_scope, - create_reference_portfolio_request=request, - ) - - self.assertEqual(result.id.code, request.code) - - # Delete portfolio once the test is complete - self.portfolios_api.delete_portfolio( - scope=TestDataUtilities.tutorials_scope, code=f39_reference_portfolio_code - ) - - @lusid_feature("F6-2") - def test_upsert_reference_portfolio_constituents(self): - - constituent_weights = [10, 20, 30, 15, 25] - effective_date = datetime(year=2021, month=3, day=29, tzinfo=pytz.UTC) - - f40_reference_portfolio_code = "F40p_ReferencePortfolioCode" - f40_reference_portfolio_name = "F40p_Reference Portfolio Name" - - - # Create a new reference portfolio - request = models.CreateReferencePortfolioRequest( - display_name=f40_reference_portfolio_name, - code=f40_reference_portfolio_code, - created=effective_date, - ) - - self.reference_portfolio_api.create_reference_portfolio( - scope=TestDataUtilities.tutorials_scope, - create_reference_portfolio_request=request, - ) - - # Check that all instruments were created successfully - self.assertEqual(len(constituent_weights), len(self.instrument_ids)) - - # Create the constituent requests - individual_constituent_requests = [ - models.ReferencePortfolioConstituentRequest( - instrument_identifiers={ - TestDataUtilities.lusid_luid_identifier: instrument_id - }, - weight=constituent_weight, - currency="GBP", - ) - for instrument_id, constituent_weight in zip( - self.instrument_ids, constituent_weights - ) - ] - - # Create a bulk constituent upsert request - bulk_constituent_request = models.UpsertReferencePortfolioConstituentsRequest( - effective_from=effective_date, - weight_type="Static", - constituents=individual_constituent_requests, - ) - - # Make the upsert request via the reference portfolio API - self.reference_portfolio_api.upsert_reference_portfolio_constituents( - scope=TestDataUtilities.tutorials_scope, - code=f40_reference_portfolio_code, - upsert_reference_portfolio_constituents_request=bulk_constituent_request, - ) - - # Get reference portfolio holdings - constituent_holdings = ( - self.reference_portfolio_api.get_reference_portfolio_constituents( - scope=TestDataUtilities.tutorials_scope, - code=f40_reference_portfolio_code, - ) - ) - - # Validate count of holdings - self.assertEqual(len(constituent_holdings.constituents), 5) - - # Validate instruments on holdings - for constituent, upserted_instrument in zip( - constituent_holdings.constituents, self.instrument_ids - ): - self.assertEqual(constituent.instrument_uid, upserted_instrument) - - # Validate holding weights - for constituent, weight in zip( - constituent_holdings.constituents, constituent_weights - ): - self.assertEqual(constituent.weight, weight) - - # Delete portfolio once the test is complete - self.portfolios_api.delete_portfolio( - scope=TestDataUtilities.tutorials_scope, code=f40_reference_portfolio_code - ) diff --git a/sdk/tests/tutorials/ibor/test_transactions.py b/sdk/tests/tutorials/ibor/test_transactions.py deleted file mode 100644 index d27197369d9..00000000000 --- a/sdk/tests/tutorials/ibor/test_transactions.py +++ /dev/null @@ -1,156 +0,0 @@ -import unittest -import uuid -from datetime import datetime - -import pytz - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature -from utilities import InstrumentLoader -from utilities import TestDataUtilities - - -class Transactions(unittest.TestCase): - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.transaction_portfolios_api = lusid.TransactionPortfoliosApi(api_client) - cls.instruments_api = lusid.InstrumentsApi(api_client) - - instrument_loader = InstrumentLoader(cls.instruments_api) - cls.instrument_ids = instrument_loader.load_instruments() - - cls.test_data_utilities = TestDataUtilities(cls.transaction_portfolios_api) - - @lusid_feature("F13-9") - def test_load_listed_instrument_transaction(self): - # create the portfolio - portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - trade_date = datetime(2018, 1, 1, tzinfo=pytz.utc) - - # details of the transaction to be added - transaction = models.TransactionRequest( - - # unique transaction id - transaction_id=str(uuid.uuid4()), - - # transaction type, configured during system setup - type="Buy", - instrument_identifiers={TestDataUtilities.lusid_luid_identifier: self.instrument_ids[0]}, - transaction_date=trade_date, - settlement_date=trade_date, - units=100, - transaction_price=models.TransactionPrice(12.3), - total_consideration=models.CurrencyAndAmount(1230, "GBP"), - source="Client" - ) - - # add the transaction - self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=[transaction]) - - # get the transaction - transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code) - - self.assertEqual(len(transactions.values), 1) - self.assertEqual(transactions.values[0].transaction_id, transaction.transaction_id) - - @lusid_feature("F13-10") - def test_load_cash_transaction(self): - # create the portfolio - portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - trade_date = datetime(2018, 1, 1, tzinfo=pytz.utc) - - # details of the transaction to be added - transaction = models.TransactionRequest( - - # unique transaction id - transaction_id=str(uuid.uuid4()), - - # transaction type, configured during system setup - type="FundsIn", - - # Cash instruments are identified using CCY_ followed by the ISO currency codes. - # Cash instruments do not need to be created before use - instrument_identifiers={TestDataUtilities.lusid_cash_identifier: "GBP"}, - - transaction_date=trade_date, - settlement_date=trade_date, - transaction_price=models.TransactionPrice(0.0), - units=0, - total_consideration=models.CurrencyAndAmount(0, "GBP"), - source="Client" - ) - - # add the transaction - self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=[transaction]) - - # get the transaction - transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code) - - self.assertEqual(len(transactions.values), 1) - self.assertEqual(transactions.values[0].transaction_id, transaction.transaction_id) - - @lusid_feature("F13-6") - def test_cancel_transactions(self): - # set effective date - effective_date = datetime(2018, 1, 1, tzinfo=pytz.utc) - - # create portfolio code - portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope) - - # Upsert transactions - transactions = [ - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[0], - units=100, - price=101, - currency="GBP", - trade_date=effective_date, - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[1], - units=100, - price=102, - currency="GBP", - trade_date=effective_date, - transaction_type="StockIn"), - self.test_data_utilities.build_transaction_request(instrument_id=self.instrument_ids[2], - units=100, - price=103, - currency="GBP", - trade_date=effective_date, - transaction_type="StockIn") - ] - - self.transaction_portfolios_api.upsert_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_request=transactions) - - # get transactions - transaction_ids = [] - existing_transactions = self.transaction_portfolios_api.get_transactions( - scope=TestDataUtilities.tutorials_scope, - code=portfolio_code) - - for i in range(len(existing_transactions.values)): - transaction_ids.append(existing_transactions.values[i].transaction_id) - - # cancel transactions - self.transaction_portfolios_api.cancel_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code, - transaction_ids=transaction_ids) - - # verify portfolio is now empty - new_transactions = self.transaction_portfolios_api.get_transactions(scope=TestDataUtilities.tutorials_scope, - code=portfolio_code) - self.assertEqual(len(new_transactions.values), 0) diff --git a/sdk/tests/tutorials/marketdata/test_instruments.py b/sdk/tests/tutorials/marketdata/test_instruments.py deleted file mode 100644 index 3898bd08f76..00000000000 --- a/sdk/tests/tutorials/marketdata/test_instruments.py +++ /dev/null @@ -1,184 +0,0 @@ -import unittest - -import lusid -import lusid.models as models -from lusidfeature import lusid_feature -from lusid.utilities.api_client_builder import ApiClientBuilder -from lusid.exceptions import ApiException -from utilities import TestDataUtilities - - -class Instruments(unittest.TestCase): - property_definitions_api = None - - @classmethod - def setUpClass(cls): - # create a configured API client - api_client = TestDataUtilities.api_client() - - cls.instruments_api = lusid.InstrumentsApi(api_client) - cls.property_definitions_api = lusid.PropertyDefinitionsApi(api_client) - - @classmethod - 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) - - @lusid_feature("F41") - def test_seed_instrument_master(self): - response = self.instruments_api.upsert_instruments(requests={ - - "BBG000FD8G46": models.InstrumentDefinition( - name="HISCOX LTD", - identifiers={ - "Figi": models.InstrumentIdValue(value="BBG000FD8G46"), - "ClientInternal": models.InstrumentIdValue(value="internal_id_1") - } - ), - - "BBG000DW76R4": models.InstrumentDefinition( - name="ITV PLC", - identifiers={ - "Figi": models.InstrumentIdValue(value="BBG000DW76R4"), - "ClientInternal": models.InstrumentIdValue(value="internal_id_2") - } - ), - - "BBG000PQKVN8": models.InstrumentDefinition( - name="MONDI PLC", - identifiers={ - "Figi": models.InstrumentIdValue(value="BBG000PQKVN8"), - "ClientInternal": models.InstrumentIdValue(value="internal_id_3") - } - ), - - "BBG000BDWPY0": models.InstrumentDefinition( - name="NEXT PLC", - identifiers={ - "Figi": models.InstrumentIdValue(value="BBG000BDWPY0"), - "ClientInternal": models.InstrumentIdValue(value="internal_id_4") - } - ), - - "BBG000BF46Y8": models.InstrumentDefinition( - name="TESCO PLC", - identifiers={ - "Figi": models.InstrumentIdValue(value="BBG000BF46Y8"), - "ClientInternal": models.InstrumentIdValue(value="internal_id_5") - } - ) - }) - - self.assertEqual(len(response.values), 5, response.failed) - - @lusid_feature("F21-1") - def test_lookup_instrument_by_unique_id(self): - - figi = "BBG000FD8G46" - - # set up the instrument - response = self.instruments_api.upsert_instruments(requests={ - figi: models.InstrumentDefinition( - name="HISCOX LTD", - identifiers={ - "Figi": models.InstrumentIdValue(value=figi), - "ClientInternal": models.InstrumentIdValue(value="internal_id_1") - } - ) - }) - self.assertEqual(len(response.values), 1, response.failed) - - # look up an instrument that already exists in the instrument master by a - # unique id, in this case an OpenFigi, and also return a list of aliases - looked_up_instruments = self.instruments_api.get_instruments(identifier_type="Figi", - identifiers=[figi], - instrument_property_keys=[ - "Instrument/default/ClientInternal" - ]) - - self.assertTrue(figi in looked_up_instruments.values, msg=f"cannot find {figi}") - - instrument = looked_up_instruments.values[figi] - self.assertTrue(instrument.name, "HISCOX LTD") - - property = next(filter(lambda i: i.key == "Instrument/default/ClientInternal", instrument.properties), None) - self.assertTrue(property.value, "internal_id_1") - - @lusid_feature("F21-1") - def test_list_available_identifiers(self): - - identifiers = self.instruments_api.get_instrument_identifiers() - - for scheme in identifiers.values: - print( - f"name: {scheme.id_name}\nproperty key: {scheme.property_key_value}\nis unique: {scheme.is_unique_identifier}\n") - - @lusid_feature("F21-3") - def test_list_all_instruments(self): - - page_size = 5 - - # list the instruments, restricting the number that are returned - instruments = self.instruments_api.list_instruments(limit=page_size) - - self.assertLessEqual(len(instruments.values), page_size) - - @lusid_feature("F21-4") - def test_list_instruments_by_identifier_type(self): - - figis = ["BBG000FD8G46", "BBG000DW76R4", "BBG000PQKVN8"] - - # get a set of instruments querying by FIGIs - instruments = self.instruments_api.get_instruments(identifier_type="Figi", identifiers=figis) - - for figi in figis: - self.assertTrue(figi in instruments.values, msg=f"{figi} not returned") - - @lusid_feature("F4-4") - def test_edit_instrument_property(self): - - property_value = models.PropertyValue(label_value="Insurance") - property_key = f"Instrument/{TestDataUtilities.tutorials_scope}/CustomSector" - identifier_type = "Figi" - identifier = "BBG000FD8G46" - - # update the property - self.instruments_api.upsert_instruments_properties(instrument_properties=[ - models.UpsertInstrumentPropertyRequest( - identifier_type=identifier_type, - identifier=identifier, - properties=[models.ModelProperty(key=property_key, value=property_value)] - ) - ]) - - # get the instrument with value - instrument = self.instruments_api.get_instrument( - identifier_type=identifier_type, - identifier=identifier, - instrument_property_keys=[property_key] - ) - - self.assertGreaterEqual(len(instrument.properties), 1) - - prop = list( - filter(lambda p: p.key == property_key and p.value.label_value == property_value.label_value, instrument.properties)) - - self.assertEqual(len(prop), 1, f"cannot find property key=${property_key} value={property_value}") diff --git a/sdk/tests/utilities/credentials_source.py b/sdk/tests/utilities/credentials_source.py index 45ae53b4c79..59fe7f35990 100644 --- a/sdk/tests/utilities/credentials_source.py +++ b/sdk/tests/utilities/credentials_source.py @@ -29,7 +29,7 @@ def custom_name_func(testcase_func, param_num, param): @classmethod def fetch_pat(cls): - return os.getenv("FBN_LUSID_ACCESS_TOKEN", None) + return os.getenv("FBN_ACCESS_TOKEN", None) @classmethod def fetch_credentials(cls): diff --git a/sdk/tests/utilities/test_api_client_factory_auth_flow.py b/sdk/tests/utilities/test_api_client_factory_auth_flow.py index be5744cfda8..71213e466c2 100644 --- a/sdk/tests/utilities/test_api_client_factory_auth_flow.py +++ b/sdk/tests/utilities/test_api_client_factory_auth_flow.py @@ -38,6 +38,7 @@ def get_env_vars_without_pat(self): env_vars_wout_pat = {k: env_vars[k] for k in env_vars if k != "FBN_LUSID_ACCESS_TOKEN"} return env_vars_wout_pat + @unittest.skipIf(not CredentialsSource.fetch_credentials().__contains__("access_token"), "do not run if no token present") def test_bad_pat_in_param_but_good_pat_in_env_vars(self): with patch.dict(self.os_environ_dict_str, self.get_pat_env_var(), clear=True): @@ -52,6 +53,7 @@ def test_bad_pat_in_param_but_good_pat_in_env_vars(self): self.assertEquals(401, e.status) + @unittest.skipIf(not CredentialsSource.fetch_credentials().__contains__("access_token"), "do not run if no token present") def test_bad_secrets_file_in_param_but_good_pat_in_env_vars(self): all_env_vars = self.get_env_vars_without_pat() @@ -70,6 +72,7 @@ def test_bad_secrets_file_in_param_but_good_pat_in_env_vars(self): context_manager.output[1], ) + @unittest.skipIf(not CredentialsSource.fetch_credentials().__contains__("access_token"), "do not run if no token present") def test_good_env_pat_but_no_param_pat(self): with patch.dict(self.os_environ_dict_str, self.get_pat_env_var(), clear=True): @@ -78,6 +81,7 @@ def test_good_env_pat_but_no_param_pat(self): self.assertIsInstance(api, InstrumentsApi) self.validate_api(api) + @unittest.skipIf(not CredentialsSource.fetch_credentials().__contains__("access_token"), "do not run if no token present") def test_no_env_pat_but_good_param_pat(self): with patch.dict(self.os_environ_dict_str, {"FBN_LUSID_API_URL": self.source_config_details["api_url"]}, @@ -111,6 +115,7 @@ def test_none_param_pat_but_good_secrets_envs(self): self.assertIsInstance(api, InstrumentsApi) self.validate_api(api) + @unittest.skipIf(not CredentialsSource.fetch_credentials().__contains__("access_token"), "do not run if no token present") def test_none_secrets_param_but_good_env_pat(self): with patch.dict(self.os_environ_dict_str, self.get_pat_env_var(), clear=True): diff --git a/sdk/tests/utilities/test_api_configuration_loader.py b/sdk/tests/utilities/test_api_configuration_loader.py index b08cc3d1c08..d396f466990 100644 --- a/sdk/tests/utilities/test_api_configuration_loader.py +++ b/sdk/tests/utilities/test_api_configuration_loader.py @@ -176,10 +176,7 @@ def test_load_from_environment_vars_only(self): def test_missing_secrets_file_logs_message_at_debug(self): - with self.assertLogs() as captured: - import logging - logger = logging.getLogger() - logger.setLevel(logging.DEBUG) + with self.assertLogs(level="DEBUG") as captured: non_existent_secrets_file = "Thisfiledefinitelydoesnotexist.json" ApiConfigurationLoader.load(non_existent_secrets_file)