コード例 #1
0
    def test_04_pg_create_with_portfolio_not_exist(self):

        """
        Test description:
        -----------------
        Here we test attempting to add a portfolio which does not exist to a portfolio group.

        Expected outcome:
        -----------------
        We expect the entire request to fail with a PortfolioNotFound error.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_4_pg_create_with_portfolio_not_exist.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame
        )

        self.log_error_requests_title("portfolio_groups", responses)

        # Check that LUSID cannot find the portfolio

        self.assertEqual(
            json.loads(responses["portfolio_groups"]["errors"][0].body)["name"],
            "PortfolioNotFound",
        )

        # Check there are no successful requests

        self.assertEqual(len(responses["portfolio_groups"]["success"]), 0)
コード例 #2
0
    def test_portfolio_missing_attribute(self):

        unique_id = create_scope_id()
        data_frame = pd.read_csv(
            Path(__file__).parent.joinpath(self.file_name))
        data_frame["FundCode"] = data_frame["FundCode"] + "-" + unique_id

        mapping_required = {"code": "FundCode"}
        mapping_optional = {
            "description": "description",
            "created": "created",
            "base_currency": "base_currency",
        }

        with self.assertRaises(ValueError) as error:

            cocoon.cocoon.load_from_data_frame(
                api_factory=self.api_factory,
                scope=self.scope,
                data_frame=data_frame,
                mapping_required=mapping_required,
                mapping_optional=mapping_optional,
                file_type="reference_portfolio",
                identifier_mapping={},
                property_columns=[],
                properties_scope=self.scope,
                sub_holding_keys=[],
            )

        self.assertEqual(
            error.exception.args[0],
            """The required attributes {'display_name'} are missing from the mapping. Please
                             add them.""",
        )
コード例 #3
0
    def setUpClass(cls) -> None:

        secrets_file = Path(__file__).parent.parent.parent.joinpath(
            "secrets.json")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)

        cls.alias = models.TransactionConfigurationTypeAlias(
            type=create_scope_id().replace("-", ""),
            description="TESTBUY1",
            transaction_class="TESTBUY1",
            transaction_group="SYSTEM1",
            transaction_roles="AllRoles",
        )

        cls.movements = [
            models.TransactionConfigurationMovementDataRequest(
                movement_types="StockMovement",
                side="Side1",
                direction=1,
                properties={},
                mappings=[],
            ),
            models.TransactionConfigurationMovementDataRequest(
                movement_types="CashCommitment",
                side="Side2",
                direction=-1,
                properties={},
                mappings=[],
            ),
        ]

        cls.response = create_transaction_type_configuration(
            cls.api_factory, cls.alias, cls.movements)
コード例 #4
0
    def setUpClass(cls) -> None:
        cls.scope = create_scope_id().replace("-", "_")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file
        )

        cls.sample_data = pd.read_csv(seed_sample_data_override_csv)
コード例 #5
0
    def setUpClass(cls) -> None:

        cls.portfolio_scope = create_scope_id()
        secrets_file = Path(__file__).parent.parent.parent.joinpath("secrets.json")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file
        )
        cls.unique_portfolios = pd.read_csv(
            Path(__file__).parent.joinpath(
                "data/port_group_tests/test_1_pg_create_with_portfolios.csv"
            )
        )["FundCode"].tolist()

        def create_portfolio_model(code):
            model = models.CreateTransactionPortfolioRequest(
                display_name=code,
                code=code,
                base_currency="GBP",
                description="Paper transaction portfolio",
                created="2020-02-25T00:00:00Z",
            )
            return model

        try:

            for code in cls.unique_portfolios:
                cls.api_factory.build(
                    lusid.api.TransactionPortfoliosApi
                ).create_portfolio(
                    scope=cls.portfolio_scope,
                    create_transaction_portfolio_request=create_portfolio_model(code),
                )
        except lusid.exceptions.ApiException as e:
            if e.status == 404:
                logger.error(f"The portfolio {code} already exists")
コード例 #6
0
    def test_11_pg_add_bad_and_good_portfolios(self):

        """
        Test description:
        -----------------
        Here we test updating a portfolio group with good and bad portfolios.

        Expected result:
        -----------------
        Good portfolios should be added and bad ones not added.

        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_11_pg_add_bad_and_good_portfolios.csv",
            self.portfolio_scope,
        )

        # Create the portfolio group as a seperate request
        port_group_request = lusid.models.CreatePortfolioGroupRequest(
            code=data_frame["PortGroupCode"][0],
            display_name=data_frame["PortGroupCode"][0],
        )

        self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group(
            scope=test_case_scope, create_portfolio_group_request=port_group_request
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame
        )

        self.log_error_requests_title("portfolio_groups", responses)

        remove_dupe_df = data_frame[~data_frame["FundCode"].str.contains("BAD_PORT")]

        self.assertEqual(
            first=sorted(
                [
                    code.to_dict()
                    for code in responses["portfolio_groups"]["success"][0].portfolios
                ],
                key=lambda item: item.get("code"),
            ),
            second=sorted(
                [
                    lusid.models.ResourceId(
                        code=remove_dupe_df["FundCode"].tolist()[0],
                        scope=self.portfolio_scope,
                    ).to_dict(),
                    lusid.models.ResourceId(
                        code=remove_dupe_df["FundCode"].tolist()[1],
                        scope=self.portfolio_scope,
                    ).to_dict(),
                ],
                key=lambda item: item.get("code"),
            ),
        )
コード例 #7
0
    def test_05_pg_create_with_duplicate_portfolios(self):
        """
        Test description:
        -----------------
        Here we test attempting to add two of the same portfolios to a portfolio group.

        Expected result:
        ----------------
        We expect that each unique portfolio gets added and duplicates should be ignored.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_5_pg_create_with_duplicate_portfolios.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(scope=test_case_scope,
                                                    data_frame=data_frame)

        self.log_error_requests_title("portfolio_groups", responses)

        data_frame.drop_duplicates(inplace=True)

        # Check that there is a request for each unique portfolio

        self.assertEqual(
            len([
                port_group for nested_group in [
                    port_group.portfolios
                    for port_group in responses["portfolio_groups"]["success"]
                ] for port_group in nested_group
            ]),
            len(data_frame),
        )

        # Check that a request is generated with unqiue portfolio only

        self.assertEqual(
            first=sorted(
                [
                    code.to_dict() for code in responses["portfolio_groups"]
                    ["success"][0].portfolios
                ],
                key=lambda item: item.get("code"),
            ),
            second=sorted(
                [
                    lusid.models.ResourceId(
                        code=data_frame["FundCode"][0],
                        scope=data_frame["Scope"][0]).to_dict(),
                    lusid.models.ResourceId(
                        code=data_frame["FundCode"][1],
                        scope=data_frame["Scope"][1]).to_dict(),
                ],
                key=lambda item: item.get("code"),
            ),
        )
コード例 #8
0
    def test_load_instrument_lookthrough_portfolio(self):
        code = create_scope_id()
        scope = "test-lookthrough"

        data_frame = pd.DataFrame({
            "instrument_name": [
                "Portfolio",
            ],
            "client_internal": [code],
            "lookthrough_code": [code],
        })

        mapping = {
            "identifier_mapping": {
                "ClientInternal": "client_internal",
            },
            "required": {
                "name": "instrument_name"
            },
            "optional": {
                "look_through_portfolio_id.scope": f"${scope}",
                "look_through_portfolio_id.code": "lookthrough_code",
            },
        }

        # create portfolio
        port_response = self.api_factory.build(
            lusid.api.TransactionPortfoliosApi).create_portfolio(
                scope=scope,
                create_transaction_portfolio_request=lusid.models.
                CreateTransactionPortfolioRequest(display_name=code,
                                                  description=code,
                                                  code=code,
                                                  base_currency="USD"),
            )

        # Upsert lookthrough instrument of portfolio
        instr_response = cocoon.load_from_data_frame(
            api_factory=self.api_factory,
            scope=scope,
            data_frame=data_frame,
            mapping_required=mapping["required"],
            mapping_optional=mapping["optional"],
            file_type="instruments",
            identifier_mapping=mapping["identifier_mapping"],
            property_columns=[],
        )

        self.assertEqual(len(instr_response["instruments"]["success"]), 1)
        self.assertEqual(len(instr_response["instruments"]["errors"]), 0)
        self.assertEqual(
            instr_response["instruments"]["success"]
            [0].values[f"ClientInternal: {code}"].lookthrough_portfolio.code,
            code,
        )
コード例 #9
0
    def test_07_pg_create_with_properties(self) -> None:
        """
        Test description:
        -----------------
        Here we test creating a portfolio group with properties.

        Expected output:
        ----------------
        The response contains the upserted properties.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_7_pg_create_with_properties.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope,
            data_frame=data_frame,
            property_columns=["location", "MifidFlag"],
            properties_scope=test_case_scope,
        )

        self.log_error_requests_title("portfolio_groups", responses)

        response_with_properties = self.api_factory.build(
            lusid.api.PortfolioGroupsApi).get_group_properties(
                scope=test_case_scope,
                code=data_frame["PortGroupCode"].tolist()[0],
            )

        self.assertEqual(
            {
                "PortfolioGroup/" + test_case_scope + "/location":
                lusid.models.ModelProperty(
                    key="PortfolioGroup/" + test_case_scope + "/location",
                    value=lusid.models.PropertyValue(label_value="UK"),
                    effective_from=datetime.datetime.min.replace(
                        tzinfo=tzutc()),
                    effective_until=datetime.datetime.max.replace(
                        tzinfo=tzutc()),
                ),
                "PortfolioGroup/" + test_case_scope + "/MifidFlag":
                lusid.models.ModelProperty(
                    key="PortfolioGroup/" + test_case_scope + "/MifidFlag",
                    value=lusid.models.PropertyValue(label_value="Y"),
                    effective_from=datetime.datetime.min.replace(
                        tzinfo=tzutc()),
                    effective_until=datetime.datetime.max.replace(
                        tzinfo=tzutc()),
                ),
            },
            response_with_properties.properties,
        )
コード例 #10
0
    def setUpClass(cls) -> None:

        secrets_file = Path(__file__).parent.parent.parent.joinpath(
            "secrets.json")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)
        cls.portfolios_api = cls.api_factory.build(lusid.api.PortfoliosApi)
        cls.unique_id = create_scope_id()
        cls.logger = logger.LusidLogger("debug")
        cls.scope = "ModelFundTest"
        cls.file_name = "data/reference-portfolio/reference-test.csv"
コード例 #11
0
    def test_02_pg_create_with_no_portfolio(self) -> None:

        """
        Test description:
        -----------------
        Here we test adding one new portfolio group with no portfolios.

        Expected outcome:
        -----------------
        We expect one successful new portfolio group with no portfolios.

        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_2_pg_create_with_no_portfolio.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame, mapping_optional={}
        )

        self.log_error_requests_title("portfolio_groups", responses)

        # Check that the portfolio group is created

        self.assertEqual(
            first=len(
                [
                    port_group._id
                    for port_group in responses["portfolio_groups"]["success"]
                ]
            ),
            second=len(data_frame),
        )

        # Check that the correct portfolio group code is used
        self.assertEqual(
            first=responses["portfolio_groups"]["success"][0].id,
            second=lusid.models.ResourceId(
                scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0]
            ),
        )

        # Check that the portfolio group request has now portfolios
        self.assertTrue(
            len(responses["portfolio_groups"]["success"][0].portfolios) == 0
        )
コード例 #12
0
    def setUpClass(cls) -> None:
        cls.scope = create_scope_id().replace("-", "_")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)

        cls.test_dataframe = pd.read_csv(sample_data_csv)
        cls.sample_data = pd.read_csv(sample_data_csv)

        seed_data(
            cls.api_factory,
            ["portfolios", "instruments", "transactions"],
            cls.scope,
            cls.test_dataframe,
            sub_holding_keys=[f"Transaction/{cls.scope}/strategy"],
            file_type="DataFrame",
        )
コード例 #13
0
    def setUpClass(cls) -> None:
        cls.scope = create_scope_id().replace("-", "_")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)

        cls.sample_data = pd.read_excel(
            Path(__file__).parent.joinpath(
                "data/seed_sample_data/sample_data_excel.xlsx"))

        seed_data(
            cls.api_factory,
            ["portfolios", "instruments", "transactions"],
            cls.scope,
            Path(__file__).parent.joinpath(
                "data/seed_sample_data/sample_data_excel.xlsx"),
            sub_holding_keys=[f"Transaction/{cls.scope}/strategy"],
            file_type="xlsx",
        )
コード例 #14
0
    def test_10_pg_add_no_new_portfolio(self) -> None:

        """
        Test description:
        ------------
        Here we test adding an existing portfolio to portfolio group.

        Expected result:
        ----------------
        The portfolio group response should be returned with one unmodified portfolio.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_10_pg_add_no_new_portfolio.csv",
            self.portfolio_scope,
        )

        port_group_request = lusid.models.CreatePortfolioGroupRequest(
            code=data_frame["PortGroupCode"][0],
            display_name=data_frame["PortGroupCode"][0],
            values=[
                lusid.models.ResourceId(
                    code=data_frame["FundCode"][0], scope=self.portfolio_scope
                )
            ],
        )

        self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group(
            scope=test_case_scope, create_portfolio_group_request=port_group_request,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame,
        )

        self.log_error_requests_title("portfolio_groups", responses)

        self.assertEqual(
            first=responses["portfolio_groups"]["success"][0].portfolios[0],
            second=lusid.models.ResourceId(
                code=data_frame["FundCode"][0], scope=data_frame["Scope"][0]
            ),
        )
コード例 #15
0
    def test_03_pg_create_multiple_groups_no_portfolio(self) -> None:

        """
        Test description:
        -----------------
        Here we test adding multiple new portfolio group with no portfolios.

        Expected outcome
        -----------------
        We expect successful requests/responses for multiple new portfolio groups.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_3_pg_create_multiple_groups_no_portfolio.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame, mapping_optional={}
        )

        self.log_error_requests_title("portfolio_groups", responses)

        # Check that there is a requet per portfolio group

        self.assertEqual(
            first=len(
                [
                    port_group._id
                    for port_group in responses["portfolio_groups"]["success"]
                ]
            ),
            second=len(data_frame),
        )

        # Check that the portfolio group code matches the code in the dataframe

        self.assertEqual(
            first=responses["portfolio_groups"]["success"][1].id,
            second=lusid.models.ResourceId(
                scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[1]
            ),
        )
コード例 #16
0
    def test_08_pg_add_bad_portfolio(self):

        """
        Description:
        ------------
        Here we test add a portfolio which does not exist to a current portfolio group.

        Expected results:
        -----------------
        The portfolio group is returned without the portfolios added.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_8_pg_add_bad_portfolio.csv",
            self.portfolio_scope,
        )

        # Create the portfolio group as a seperate request
        port_group_request = lusid.models.CreatePortfolioGroupRequest(
            code=data_frame["PortGroupCode"][0],
            display_name=data_frame["PortGroupCode"][0],
        )

        self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group(
            scope=test_case_scope, create_portfolio_group_request=port_group_request
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame
        )

        self.log_error_requests_title("portfolio_groups", responses)

        self.assertTrue(len(responses["portfolio_groups"]["errors"]) == 0)

        self.assertEqual(
            first=responses["portfolio_groups"]["success"][0].id,
            second=lusid.models.ResourceId(
                scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0]
            ),
        )
コード例 #17
0
    def test_update_alias_which_does_not_exist(self):

        alias_which_does_not_exist = deepcopy(
            self.class_transaction_type_config)[0]
        alias_which_does_not_exist.aliases[0].type = create_scope_id()

        upsert_transaction_type_alias(self.api_factory,
                                      [alias_which_does_not_exist])

        get_transaction_types = (self.system_configuration_api.
                                 list_configuration_transaction_types())

        uploaded_alias = []

        for trans_type in get_transaction_types.transaction_configs:
            for alias in trans_type.aliases:
                if alias.type == alias_which_does_not_exist.aliases[0].type:
                    uploaded_alias.append(trans_type)

        self.assertEqual(uploaded_alias[0], alias_which_does_not_exist)
コード例 #18
0
    def test_09_pg_add_duplicate_portfolio(self) -> None:

        """
        Description:
        ------------
        Here we test adding duplicate portfolios to a portfolio group.

        Expected outcome:
        -----------------
        We expect the one portfolio to be added.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_9_pg_add_duplicate_portfolio.csv",
            self.portfolio_scope,
        )

        # Create the portfolio group as a seperate request
        port_group_request = lusid.models.CreatePortfolioGroupRequest(
            code=data_frame["PortGroupCode"][0],
            display_name=data_frame["PortGroupCode"][0],
        )

        self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group(
            scope=test_case_scope, create_portfolio_group_request=port_group_request
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame
        )

        self.log_error_requests_title("portfolio_groups", responses)

        self.assertEqual(
            first=responses["portfolio_groups"]["success"][0].portfolios[0],
            second=lusid.models.ResourceId(
                code=data_frame["FundCode"][0], scope=data_frame["Scope"][0]
            ),
        )
コード例 #19
0
    def test_06_pg_create_duplicate_port_group(self):

        """
        Test description:
        -----------------
        Here we test create two of the same portfolio groups

        Expected results
        -----------------
        We expect one successful requesy for the portfolio group

        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_6_pg_create_duplicate_port_group.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame, mapping_optional={}
        )

        self.log_error_requests_title("portfolio_groups", responses)

        # Check for one successful request

        self.assertEqual(len(responses["portfolio_groups"]["success"]), 1)

        # Check the successful request has same code as dataframe portfolio group

        self.assertEqual(
            first=responses["portfolio_groups"]["success"][0].id,
            second=lusid.models.ResourceId(
                scope=test_case_scope, code=data_frame["PortGroupCode"].tolist()[0]
            ),
        )
コード例 #20
0
    def setUpClass(cls) -> None:
        cls.scope = create_scope_id().replace("-", "_")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)

        cls.sample_data = pd.read_csv(seed_sample_data_override_csv)

        seed_data(
            cls.api_factory,
            ["portfolios", "instruments", "transactions"],
            cls.scope,
            seed_sample_data_override_csv,
            mappings=dict(
                load_json_file(
                    Path(__file__).parent.parent.parent.joinpath(
                        "integration",
                        "cocoon",
                        "data",
                        "seed_sample_data",
                        "seed_sample_data_override.json",
                    ))),
            sub_holding_keys=[f"Transaction/{cls.scope}/strategy"],
            file_type="csv",
        )
コード例 #21
0
    def test_01_pg_create_with_portfolios(self) -> None:

        """
        Test description:
        ------------------
        Here we test adding multiple new portfolio groups with multiple portfolios.

        Expected outcome:
        -----------------
        We expect one successful request/response per portfolio group with multiple portfolios.
        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_1_pg_create_with_portfolios.csv",
            self.portfolio_scope,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame
        )

        self.log_error_requests_title("portfolio_groups", responses)

        # Test that there is a successful request per line in the dataframe
        self.assertEqual(
            len(
                [
                    port_group
                    for nested_group in [
                        port_group.portfolios
                        for port_group in responses["portfolio_groups"]["success"]
                    ]
                    for port_group in nested_group
                ]
            ),
            len(data_frame),
        )

        # Test that all the portfolios in the dataframe are in the request
        self.assertEqual(
            first=sorted(
                [
                    code.to_dict()
                    for code in responses["portfolio_groups"]["success"][0].portfolios
                ],
                key=lambda item: item.get("code"),
            ),
            second=sorted(
                [
                    lusid.models.ResourceId(
                        code=data_frame["FundCode"][1], scope=data_frame["Scope"][1]
                    ).to_dict(),
                    lusid.models.ResourceId(
                        code=data_frame["FundCode"][0], scope=data_frame["Scope"][0]
                    ).to_dict(),
                ],
                key=lambda item: item.get("code"),
            ),
        )

        self.assertEqual(
            first=responses["portfolio_groups"]["success"][1].portfolios,
            second=[
                lusid.models.ResourceId(
                    code=data_frame["FundCode"][2], scope=data_frame["Scope"][2]
                )
            ],
        )
コード例 #22
0
import unittest
from pathlib import Path
import pandas as pd
from lusidtools import cocoon as cocoon
from parameterized import parameterized
import lusid
from lusidtools import logger
from datetime import datetime
import pytz
from lusidtools.cocoon.utilities import create_scope_id

unique_properties_scope = create_scope_id()


def expected_response(property_scope="TestPropertiesScope1"):
    return {
        "instruments":
        lusid.models.UpsertInstrumentsResponse(
            values={
                "ClientInternal: imd_34534539":
                lusid.models.Instrument(
                    lusid_instrument_id="LUIDUnknown",
                    version=lusid.models.Version(
                        as_at_date=datetime.now(pytz.UTC),
                        effective_from=datetime.now(pytz.UTC),
                    ),
                    name="USTreasury_6.875_2025",
                    identifiers={
                        "ClientInternal": "imd_34534539",
                        "Figi": "BBG000DQQNJ8",
                        "Isin": "US912810EV62",
コード例 #23
0
 def setUpClass(cls) -> None:
     cls.scope = create_scope_id().replace("-", "_")
     cls.api_factory = Mock()
コード例 #24
0
    def test_load_instrument_lookthrough(self, _, df, mapping):

        if "default scope" in _:
            self.skipTest("Default parameter using '$' is not supported")

        scope = "test-lookthrough-loading-lusidtools"
        df = pd.read_csv(df)

        # replace lookthrough scope
        df = df.replace({"replace_scope": scope})

        # populate portfolio ids with random codes
        codes = {
            row["client_internal"]: create_scope_id(use_uuid=True) if
            "Portfolio" in row["instrument_name"] else row["client_internal"]
            for index, row in df.iterrows()
        }
        df = df.replace(codes)

        # create portfolios
        [
            self.api_factory.build(
                lusid.api.TransactionPortfoliosApi).create_portfolio(
                    scope=scope,
                    create_transaction_portfolio_request=lusid.models.
                    CreateTransactionPortfolioRequest(
                        display_name=row["client_internal"],
                        description=row["client_internal"],
                        code=row["client_internal"],
                        base_currency="USD",
                    ),
                ) if "Portfolio" in row["instrument_name"] else None
            for index, row in df.drop_duplicates("client_internal").iterrows()
        ]

        # Upsert lookthrough instrument of portfolio
        instr_response = cocoon.load_from_data_frame(
            api_factory=self.api_factory,
            scope=scope,
            data_frame=df,
            mapping_required=mapping["required"],
            mapping_optional=mapping["optional"],
            file_type="instruments",
            identifier_mapping=mapping["identifier_mapping"],
            property_columns=[],
        )

        # check successes, errors and instrument lookthrough codes
        self.assertEqual(
            len(instr_response["instruments"]["success"][0].values.values()),
            len(df))
        self.assertEqual(len(instr_response["instruments"]["errors"]), 0)

        # check lookthrough code on response
        [
            self.assertEqual(
                instr_response["instruments"]["success"]
                [0].values[f"ClientInternal: {row['client_internal']}"].
                lookthrough_portfolio.code,
                row["lookthrough_code"],
            ) if "id" not in row["client_internal"] else None
            for index, row in df.iterrows()
        ]

        # tear down this test
        [
            self.api_factory.build(lusid.api.PortfoliosApi).delete_portfolio(
                scope=scope, code=code) if "id" not in code else None
            for code in list(codes.values())
        ]
        [
            self.api_factory.build(lusid.api.InstrumentsApi).delete_instrument(
                "ClientInternal", CI) for CI in list(df["client_internal"])
        ]
コード例 #25
0
import unittest
from lusidtools.extract.group_holdings import get_holdings_for_group
from pathlib import Path
from lusidtools.cocoon.utilities import create_scope_id
from parameterized import parameterized

from lusidtools import logger
import lusid
from lusidtools import cocoon as cocoon
import pandas as pd

from lusid.models import CurrencyAndAmount

# Create the Portfolios, Portfolio Groups and Holdings
scope = create_scope_id()


class CocoonTestsExtractGroupHoldings(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        secrets_file = Path(__file__).parent.parent.parent.joinpath(
            "secrets.json")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)
        cls.logger = logger.LusidLogger("debug")

        cls.scope = scope

        portfolio_holdings = pd.read_csv(
            Path(__file__).parent.joinpath("./data/holdings-example.csv"))
        portfolio_groups = pd.read_csv(
コード例 #26
0
    def test_12_pg_add_portfolios_different_scopes(self) -> None:

        """
        Test description:
        -----------------
        Here we test adding portfolios with multiple scopes.

        Expected outcome:
        -----------------
        Request should be successful - returned with portfolios with multiple scopes.

        """

        test_case_scope = create_scope_id()
        data_frame = self.csv_to_data_frame_with_scope(
            "data/port_group_tests/test_12_pg_add_portfolios_different_scopes.csv",
            self.portfolio_scope,
        )

        port_scope_for_test = create_scope_id()
        self.api_factory.build(lusid.api.TransactionPortfoliosApi).create_portfolio(
            scope=port_scope_for_test,
            create_transaction_portfolio_request=models.CreateTransactionPortfolioRequest(
                display_name=data_frame["FundCode"][0],
                code=data_frame["FundCode"][0],
                base_currency="GBP",
            ),
        )

        port_group_request = lusid.models.CreatePortfolioGroupRequest(
            code=data_frame["PortGroupCode"][0],
            display_name=data_frame["PortGroupCode"][0],
            values=[
                lusid.models.ResourceId(
                    code=data_frame["FundCode"][0], scope=port_scope_for_test
                )
            ],
        )

        self.api_factory.build(lusid.api.PortfolioGroupsApi).create_portfolio_group(
            scope=test_case_scope, create_portfolio_group_request=port_group_request,
        )

        responses = self.cocoon_load_from_dataframe(
            scope=test_case_scope, data_frame=data_frame,
        )

        self.log_error_requests_title("portfolio_groups", responses)

        self.assertTrue(
            expr=all(
                [
                    id in responses["portfolio_groups"]["success"][0].portfolios
                    for id in [
                        lusid.models.ResourceId(
                            code=data_frame["FundCode"][1], scope=data_frame["Scope"][1]
                        ),
                        lusid.models.ResourceId(
                            code=data_frame["FundCode"][0], scope=port_scope_for_test
                        ),
                        lusid.models.ResourceId(
                            code=data_frame["FundCode"][0], scope=data_frame["Scope"][0]
                        ),
                        lusid.models.ResourceId(
                            code=data_frame["FundCode"][2], scope=data_frame["Scope"][2]
                        ),
                    ]
                ]
            )
        )
コード例 #27
0
import unittest
from pathlib import Path
import lusid
import lusid.models as models
from lusidtools.cocoon.utilities import create_scope_id
from lusidtools.cocoon.transaction_type_upload import upsert_transaction_type_alias
import logging
import json
from copy import deepcopy

logger = logging.getLogger()
new_buy_transaction_type = "BUY-LPT-TEST"
new_sell_transaction_type = "SELL-LPT-TEST"
type_which_does_not_exist = create_scope_id()


class CocoonTestTransactionTypeUpload(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:

        secrets_file = Path(__file__).parent.parent.parent.joinpath(
            "secrets.json")
        cls.api_factory = lusid.utilities.ApiClientFactory(
            api_secrets_filename=secrets_file)

        cls.system_configuration_api = cls.api_factory.build(
            lusid.api.SystemConfigurationApi)

        cls.class_transaction_type_config = [
            models.TransactionConfigurationData(
                aliases=[
コード例 #28
0
    def test_load_from_data_frame_attributes_and_properties_success(
        self,
        _,
        file_name,
        mapping_required,
        mapping_optional,
        property_columns,
    ) -> None:
        """
        Test that a reference portfolio can be loaded successfully

        :param str file_name: The name of the test data file
        :param dict{str, str} mapping_required: The dictionary mapping the dataframe fields to LUSID's required base transaction/holding schema
        :param dict{str, str} mapping_optional: The dictionary mapping the dataframe fields to LUSID's optional base transaction/holding schema
        :param list[str] property_columns: The columns to create properties for
        :param any expected_outcome: The expected outcome

        :return: None
        """

        unique_id = create_scope_id()
        data_frame = pd.read_csv(Path(__file__).parent.joinpath(file_name))
        data_frame.drop_duplicates(inplace=True)
        data_frame["FundCode"] = data_frame["FundCode"] + "-" + unique_id

        responses = cocoon.cocoon.load_from_data_frame(
            api_factory=self.api_factory,
            scope=self.scope,
            data_frame=data_frame,
            mapping_required=mapping_required,
            mapping_optional=mapping_optional,
            file_type="reference_portfolio",
            identifier_mapping={},
            property_columns=property_columns,
            properties_scope=self.scope,
            sub_holding_keys=[],
        )

        # Check that the count of portfolios uploaded equals count of portfolios in DataFrame

        self.assertEqual(
            first=len(responses["reference_portfolios"]["success"]),
            second=len(data_frame),
        )

        # Assert that by no unmatched_identifiers are returned in the response for reference_portfolios
        self.assertFalse(responses["reference_portfolios"].get(
            "unmatched_identifiers", False))

        # Check that the portfolio IDs of porfolios uploaded matches the IDs of portfolios in DataFrame

        response_codes = [
            response.id.code if isinstance(response, lusid.models.Portfolio)
            else response.origin_portfolio_id.code
            for response in responses["reference_portfolios"]["success"]
        ]

        self.assertEqual(
            first=response_codes,
            second=list(data_frame[mapping_required["code"]].values),
        )

        # Check that properties get added to portfolio

        for portfolio in responses["reference_portfolios"]["success"]:

            get_portfolio = self.portfolios_api.get_portfolio(
                scope=portfolio.id.scope,
                code=portfolio.id.code,
                property_keys=[
                    f"Portfolio/{self.scope}/strategy",
                    f"Portfolio/{self.scope}/custodian",
                ],
            )

            property_keys_from_params = [
                f"Portfolio/{self.scope}/{code}" for code in property_columns
                if len(property_columns) > 0
            ]

            self.assertCountEqual(
                [prop for prop in get_portfolio.properties],
                property_keys_from_params,
            )