Пример #1
0
def create_instrument_quotes(quotes_effective_date, today, instrument_prices,
                             analyst_scope_code, api_factory):
    # Create prices via instrument, analytic
    # Set our quotes effective dates
    now = datetime.now(pytz.UTC).replace(hour=0,
                                         minute=0,
                                         second=0,
                                         microsecond=0)
    quotes_effective_date = now - timedelta(days=3)
    today = now

    instrument_quotes = {}

    # Create prices for all instruments except cash
    for index, instrument in instrument_prices.iterrows():

        if 'Cash' in instrument['instrument_name']:
            continue

        # Get our Lusid Instrument Id
        luid = api_factory.build(lusid.api.InstrumentsApi).get_instrument(
            identifier_type='Figi',
            identifier=instrument['figi']).lusid_instrument_id

        instrument_quotes[
            luid + str(quotes_effective_date)] = models.UpsertQuoteRequest(
                quote_id=models.QuoteId(quote_series_id=models.QuoteSeriesId(
                    provider='DataScope',
                    instrument_id=luid,
                    instrument_id_type='LusidInstrumentId',
                    quote_type='Price',
                    field='Mid'),
                                        effective_at=quotes_effective_date),
                metric_value=models.MetricValue(
                    value=instrument["price_original"],
                    unit=instrument["currency"]),
                lineage='InternalSystem')

        instrument_quotes[luid + str(today)] = models.UpsertQuoteRequest(
            quote_id=models.QuoteId(quote_series_id=models.QuoteSeriesId(
                provider='DataScope',
                instrument_id=luid,
                instrument_id_type='LusidInstrumentId',
                quote_type='Price',
                field='Mid'),
                                    effective_at=today),
            metric_value=models.MetricValue(value=instrument["price_current"],
                                            unit=instrument["currency"]),
            lineage='InternalSystem')

    response = api_factory.build(lusid.api.QuotesApi).upsert_quotes(
        scope=analyst_scope_code, request_body=instrument_quotes)

    prettyprint.upsert_quotes_response(response)
    def test_add_quote(self):

        request = models.UpsertQuoteRequest(quote_id=models.QuoteId(
            models.QuoteSeriesId(provider="DataScope",
                                 instrument_id="BBG000B9XRY4",
                                 instrument_id_type="Figi",
                                 quote_type="Price",
                                 field="mid"),
            effective_at=datetime(2019, 4, 15, tzinfo=pytz.utc)),
                                            metric_value=models.MetricValue(
                                                value=199.23, unit="USD"))

        self.quotes_api.upsert_quotes(TestDataUtilities.tutorials_scope,
                                      request_body={"quote1": request})
Пример #3
0
def upsert_quotes(
    api_factory,
    scope,
    data_frame,
    instrument_identifier_mapping,
    instrument_identifier_heirarchy,
    required_mapping,
):
    """
    This function takes quotes from a data_frame and upserts them into LUSID
    
    param (lusid.utilities.ClientApiFactory) api_factory: The LUSID api factory to use
    param (str) scope: The LUSID scope to upsert the quotes into
    param (Pandas DataFrame) data_frame: The DataFrame that the quotes are in
    param (dict) instrument_identifier_mapping : The dictionary with the instrument identifier mapping between LUSID and the dataframe
    param (list[str]) instrument_identifier_heirarchy : The heirarchy to use for the LUSID instrument identifiers when upserting quotes
    param (dict) required_mapping: The mapping of the LUSID required quote fields to the dataframe fields
    
    
    returns (Pandas DataFrame): The succesfully upserted quotes
    """

    # Initialise an empty instrument quotes list to hold the quotes
    instrument_quotes = {}

    quote_type_values = {
        "mid_price": {
            "quote_type": "Price",
            "price_side": "Mid",
            "value": "price",
        },
        "mid_rate": {
            "quote_type": "Rate",
            "price_side": "Mid",
            "value": "rate",
        },
    }

    # Iterate over the quotes
    for index, quote in data_frame.iterrows():

        quote_type = quote_type_values[quote[
            required_mapping["quote_type"]]]["quote_type"]
        field = quote_type_values[quote[
            required_mapping["quote_type"]]]["price_side"]

        for identifier in instrument_identifier_heirarchy:

            identifier_value = quote[instrument_identifier_mapping[
                "identifier_mapping"][identifier]]

            if (identifier == "CurrencyPair") and (len(identifier_value) == 6):
                identifier_value = identifier_value[:
                                                    3] + "/" + identifier_value[
                                                        3:]

            if not pd.isna(identifier_value):
                break

        # Add the quote to the list of upsert quote requests
        effective_date = quote[required_mapping["effective_at"]]

        instrument_quotes[identifier + "_" + identifier_value + "_" +
                          effective_date] = models.UpsertQuoteRequest(
                              quote_id=models.QuoteId(
                                  quote_series_id=models.QuoteSeriesId(
                                      provider="DataScope",
                                      instrument_id=identifier_value,
                                      instrument_id_type=identifier,
                                      quote_type=quote_type,
                                      field=field,
                                  ),
                                  effective_at=effective_date,
                              ),
                              metric_value=models.MetricValue(
                                  value=quote[required_mapping["value"]],
                                  unit=quote[required_mapping["currency"]],
                              ),
                              lineage="InternalSystem",
                          )

    # Upsert the quotes into LUSID
    response = api_factory.build(lusid.api.QuotesApi).upsert_quotes(
        scope=scope, request_body=instrument_quotes)

    # Pretty print the response
    # prettyprint.upsert_quotes_response(response)
    return prettyprint.upsert_quotes_response(response)
Пример #4
0
transaction_success = models.UpsertPortfolioTransactionsResponse(
    href="https://www.notadonaim.lusid.com/api/api/code/transactions?asAt=2019-12-05T10%3A25%3A45.6141270%2B00%3A00",
    links=[],
    version="1",
)

quote_success = models.UpsertQuotesResponse(
    failed={
        "BBG001MM1KV4-Figi_2019-10-28": models.Quote(
            as_at="2019-01-16",
            quote_id=models.QuoteId(
                quote_series_id=models.QuoteSeriesId(
                    provider="Default",
                    instrument_id="BBG001MM1KV4",
                    instrument_id_type="Figi",
                    quote_type="Price",
                    field="Mid",
                ),
                effective_at="2019-01-16",
            ),
            uploaded_by="test",
        )
    },
    values={
        "BBG001MM1KV4-Figi_2019-10-28": models.Quote(
            as_at="2019-01-16",
            quote_id=models.QuoteId(
                quote_series_id=models.QuoteSeriesId(
                    provider="Default",
                    instrument_id="BBG001MM1KV4",
                    instrument_id_type="Figi",
    def test_portfolio_aggregation(self):

        effective_date = datetime(2019, 4, 15, tzinfo=pytz.utc)

        portfolio_code = self.test_data_utilities.create_transaction_portfolio(
            TestDataUtilities.tutorials_scope)

        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,
            transactions=transactions)

        prices = [
            models.InstrumentAnalytic(self.instrument_ids[0], 100),
            models.InstrumentAnalytic(self.instrument_ids[1], 200),
            models.InstrumentAnalytic(self.instrument_ids[2], 300)
        ]

        requests = []
        for i in range(3):
            requests.append(
                models.UpsertQuoteRequest(
                    quote_id=models.QuoteId(models.QuoteSeriesId(
                        provider="DataScope",
                        instrument_id=self.instrument_ids[i],
                        instrument_id_type="LusidInstrumentId",
                        quote_type="Price",
                        field="mid"),
                                            effective_at=effective_date),
                    metric_value=models.MetricValue(value=prices[i].value,
                                                    unit="GBP")))

        self.quotes_api.upsert_quotes(
            TestDataUtilities.tutorials_scope,
            quotes={
                "quote" + str(request_number): requests[request_number]
                for request_number in range(len(requests))
            })

        inline_recipe = models.ConfigurationRecipe(
            code='quotes_recipe',
            market=models.MarketContext(
                market_rules=[],
                suppliers=models.MarketContextSuppliers(equity='DataScope'),
                options=models.MarketOptions(
                    default_supplier='DataScope',
                    default_instrument_code_type='LusidInstrumentId',
                    default_scope=TestDataUtilities.tutorials_scope)))

        aggregation_request = models.AggregationRequest(
            inline_recipe=inline_recipe,
            metrics=[
                models.AggregateSpec("Instrument/default/Name", "Value"),
                models.AggregateSpec("Holding/default/PV", "Proportion"),
                models.AggregateSpec("Holding/default/PV", "Sum")
            ],
            group_by=["Instrument/default/Name"],
            effective_at=effective_date)

        #   do the aggregation
        aggregation = self.aggregation_api.get_aggregation_by_portfolio(
            scope=TestDataUtilities.tutorials_scope,
            code=portfolio_code,
            request=aggregation_request)

        for item in aggregation.data:
            print("\t{}\t{}\t{}".format(item["Instrument/default/Name"],
                                        item["Proportion(Holding/default/PV)"],
                                        item["Sum(Holding/default/PV)"]))

        # Asserts
        self.assertEqual(len(aggregation.data), 3)
        self.assertEqual(aggregation.data[0]["Sum(Holding/default/PV)"], 10000)
        self.assertEqual(aggregation.data[1]["Sum(Holding/default/PV)"], 20000)
        self.assertEqual(aggregation.data[2]["Sum(Holding/default/PV)"], 30000)
Пример #6
0
    def test_portfolio_aggregation(self):

        effective_date = datetime(2019, 4, 15, tzinfo=pytz.utc)

        portfolio_code = self.test_data_utilities.create_transaction_portfolio(TestDataUtilities.tutorials_scope)
        self.id_generator.add_scope_and_code("portfolio", TestDataUtilities.tutorials_scope, portfolio_code)

        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)

        prices = [
            (self.instrument_ids[0], 100),
            (self.instrument_ids[1], 200),
            (self.instrument_ids[2], 300)
        ]

        requests = [
            models.UpsertQuoteRequest(
                quote_id=models.QuoteId(
                    models.QuoteSeriesId(
                        provider="DataScope",
                        instrument_id=price[0],
                        instrument_id_type="LusidInstrumentId",
                        quote_type="Price",
                        field="mid"
                    ),
                    effective_at=effective_date
                ),
                metric_value=models.MetricValue(
                    value=price[1],
                    unit="GBP"
                )
            )
            for price in prices
        ]

        self.quotes_api.upsert_quotes(TestDataUtilities.tutorials_scope,
                                      request_body={"quote" + str(request_number): requests[request_number]
                                              for request_number in range(len(requests))})

        recipe_scope = 'cs-tutorials'
        recipe_code = 'quotes_recipe'

        self.id_generator.add_scope_and_code("recipe", recipe_scope, recipe_code)

        demo_recipe = models.ConfigurationRecipe(
            scope=recipe_scope,
            code=recipe_code,
            market=models.MarketContext(
                market_rules=[],
                suppliers=models.MarketContextSuppliers(
                    equity='DataScope'
                ),
                options=models.MarketOptions(
                    default_supplier='DataScope',
                    default_instrument_code_type='LusidInstrumentId',
                    default_scope=TestDataUtilities.tutorials_scope)
            )
        )
        upsert_recipe_request = models.UpsertRecipeRequest(demo_recipe)
        self.recipes_api.upsert_configuration_recipe(upsert_recipe_request)

        valuation_request = models.ValuationRequest(
            recipe_id=models.ResourceId(scope=recipe_scope,code=recipe_code),
            metrics=[
                models.AggregateSpec("Instrument/default/Name", "Value"),
                models.AggregateSpec("Holding/default/PV", "Proportion"),
                models.AggregateSpec("Holding/default/PV", "Sum")
            ],
            group_by=["Instrument/default/Name"],
            portfolio_entity_ids = [
                models.PortfolioEntityId(scope = TestDataUtilities.tutorials_scope, code = portfolio_code)
            ],
            valuation_schedule=models.ValuationSchedule(effective_at=effective_date)
        )

        #   do the aggregation
        aggregation = self.aggregation_api.get_valuation(valuation_request=valuation_request)

        for item in aggregation.data:
            print("\t{}\t{}\t{}".format(item["Instrument/default/Name"], item["Proportion(Holding/default/PV)"],
                                        item["Sum(Holding/default/PV)"]))

        # Asserts
        self.assertEqual(len(aggregation.data),3)
        self.assertEqual(aggregation.data[0]["Sum(Holding/default/PV)"], 10000)
        self.assertEqual(aggregation.data[1]["Sum(Holding/default/PV)"], 20000)
        self.assertEqual(aggregation.data[2]["Sum(Holding/default/PV)"], 30000)
Пример #7
0
    def setup_portfolio(cls, effective_date, portfolio_code) -> None:
        """
        Sets up instrument, quotes and portfolio data from TestDataUtilities
        :param datetime effective_date: The portfolio creation date
        :param str portfolio_code: The code of the the test portfolio
        :return: None
        """

        transactions = [
            cls.test_data_utilities.build_transaction_request(
                instrument_id=cls.instrument_ids[0],
                units=100,
                price=101,
                currency="GBP",
                trade_date=effective_date,
                transaction_type="StockIn",
            ),
            cls.test_data_utilities.build_transaction_request(
                instrument_id=cls.instrument_ids[1],
                units=100,
                price=102,
                currency="GBP",
                trade_date=effective_date,
                transaction_type="StockIn",
            ),
            cls.test_data_utilities.build_transaction_request(
                instrument_id=cls.instrument_ids[2],
                units=100,
                price=103,
                currency="GBP",
                trade_date=effective_date,
                transaction_type="StockIn",
            ),
        ]

        cls.transaction_portfolios_api.upsert_transactions(
            scope=TestDataUtilities.tutorials_scope,
            code=portfolio_code,
            transaction_request=transactions,
        )

        prices = [
            (cls.instrument_ids[0], 100),
            (cls.instrument_ids[1], 200),
            (cls.instrument_ids[2], 300),
        ]

        requests = [
            models.UpsertQuoteRequest(
                quote_id=models.QuoteId(
                    models.QuoteSeriesId(
                        provider="Lusid",
                        instrument_id=price[0],
                        instrument_id_type="LusidInstrumentId",
                        quote_type="Price",
                        field="mid",
                    ),
                    effective_at=effective_date,
                ),
                metric_value=models.MetricValue(value=price[1], unit="GBP"),
            ) for price in prices
        ]

        cls.quotes_api.upsert_quotes(
            TestDataUtilities.tutorials_scope,
            request_body={
                "quote" + str(request_number): requests[request_number]
                for request_number in range(len(requests))
            },
        )