Exemple #1
0
 def schedule(self,
              start_date: dt.date = None,
              end_date: dt.date = None,
              backcast: bool = None):
     if None in [self.id, self.__position_source_id]:
         raise MqValueError(
             'Can only schedule reports with valid IDs and Position Source IDs.'
         )
     if self.position_source_type != PositionSourceType.Portfolio and None in [
             start_date, end_date
     ]:
         raise MqValueError(
             'Must specify schedule start and end dates for report.')
     if None in [start_date, end_date]:
         position_dates = GsPortfolioApi.get_position_dates(
             self.position_source_id)
         if len(position_dates) == 0:
             raise MqValueError(
                 'Cannot schedule reports for a portfolio with no positions.'
             )
         if start_date is None:
             start_date = business_day_offset(min(position_dates) - relativedelta(years=1), -1, roll='forward') \
                 if backcast else min(position_dates)
         if end_date is None:
             end_date = min(
                 position_dates) if backcast else business_day_offset(
                     dt.date.today(), -1, roll='forward')
     GsReportApi.schedule_report(report_id=self.id,
                                 start_date=start_date,
                                 end_date=end_date,
                                 backcast=backcast)
Exemple #2
0
 def save(self):
     """ Create a report using GsReportApi if it doesn't exist. Update the report if it does. """
     target_report = TargetReport(
         position_source_id=self.position_source_id,
         position_source_type=self.position_source_type,
         type_=self.type,
         parameters=self.parameters)
     if self.id:
         target_report.id = self.id
         GsReportApi.update_report(target_report)
     else:
         GsReportApi.create_report(target_report)
Exemple #3
0
 def save(self):
     """ Create a report in Marquee if it doesn't exist. Update the report if it does. """
     target_report = TargetReport(name=self.name,
                                  position_source_id=self.position_source_id,
                                  position_source_type=self.position_source_type,
                                  type_=self.type,
                                  parameters=self.parameters if self.parameters else ReportParameters())
     if self.id:
         target_report.id = self.id
         GsReportApi.update_report(target_report)
     else:
         report = GsReportApi.create_report(target_report)
         self.__id = report.id
Exemple #4
0
 def get_factor_risk_report(self,
                            risk_model_id: str = None,
                            fx_hedged: bool = None) -> FactorRiskReport:
     if self.positioned_entity_type in [
             EntityType.PORTFOLIO, EntityType.ASSET
     ]:
         position_source_type = self.positioned_entity_type.value.capitalize(
         )
         reports = GsReportApi.get_reports(
             limit=100,
             position_source_type=position_source_type,
             position_source_id=self.id,
             report_type=f'{position_source_type} Factor Risk')
         if fx_hedged:
             reports = [
                 report for report in reports
                 if report.parameters.fx_hedged == fx_hedged
             ]
         if risk_model_id:
             reports = [
                 report for report in reports
                 if report.parameters.risk_model == risk_model_id
             ]
         if len(reports) > 1:
             raise MqError(
                 f'This {position_source_type} has more than one factor risk report that matches '
                 'your parameters. Please specify the risk model ID and fxHedged value in the '
                 'function parameters.')
         if len(reports) == 0:
             raise MqError(
                 f'This {position_source_type} has no factor risk reports that match your parameters.'
             )
         return FactorRiskReport.from_target(reports[0])
     raise NotImplementedError
Exemple #5
0
    def poll_report(self, report_id: str, timeout: int = 600, step: int = 30):
        poll = True
        end = dt.datetime.now() + dt.timedelta(seconds=timeout)

        while poll and dt.datetime.now() <= end:
            try:
                status = GsReportApi.get_report(report_id).status
                if status not in set(ReportStatus.error,
                                     ReportStatus.cancelled,
                                     ReportStatus.done):
                    _logger.info(
                        f'Report is {status} as of {dt.datetime.now().isoformat()}'
                    )
                    time.sleep(step)
                else:
                    poll = False
                    if status == ReportStatus.error:
                        raise MqError(
                            f'Report {report_id} has failed for {self.id}. \
                                        Please reach out to the Marquee team for assistance.'
                        )
                    elif status == ReportStatus.cancelled:
                        _logger.info(
                            f'Report {report_id} has been cancelled. Please reach out to the \
                                       Marquee team if you believe this is a mistake.'
                        )
                    else:
                        _logger.info(f'Report {report_id} is now complete')
            except Exception as err:
                raise MqError(
                    f'Could not fetch report status with error {err}')

        raise MqError('The report is taking longer than expected to complete. \
                       Please check again later or reach out to the Marquee team for assistance.'
                      )
def test_get_reports(mocker):
    id_1 = 'RX1'
    id_2 = 'RX2'

    mock_response = {'results': (
        Report.from_dict({'id': id_1, 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1',
                          'type': 'Portfolio Performance Analytics', 'parameters': {'transactionCostModel': 'FIXED'}}),
        Report.from_dict({'id': id_2, 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP2',
                          'type': 'Portfolio Performance Analytics', 'parameters': {'transactionCostModel': 'FIXED'}})
    ), 'totalResults': 2}

    expected_response = (
        Report(id=id_1, positionSourceType='Portfolio', positionSourceId='MP1', type='Portfolio Performance Analytics',
               parameters=ReportParameters(transactionCostModel='FIXED')),
        Report(id=id_2, positionSourceType='Portfolio', positionSourceId='MP2', type='Portfolio Performance Analytics',
               parameters=ReportParameters(transactionCostModel='FIXED'))
    )

    # mock GsSession
    mocker.patch.object(
        GsSession.__class__,
        'default_value',
        return_value=GsSession.get(
            Environment.QA,
            'client_id',
            'secret'))
    mocker.patch.object(GsSession.current, '_get', return_value=mock_response)

    # run test
    response = GsReportApi.get_reports()
    GsSession.current._get.assert_called_with('/reports?limit=100', cls=Report)
    assert response == expected_response
def test_get_report_jobs(mocker):
    id_1 = 'RJW55950MF0S0HKN'

    mock_response = {'results': (
        ReportJob.from_dict({'id': id_1, 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1',
                             'parameters': {'transactionCostModel': 'FIXED'}}),
        ReportJob.from_dict({'id': id_1, 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP2',
                             'parameters': {'transactionCostModel': 'FIXED'}})
    ), 'totalResults': 2}

    expected_response = (
        ReportJob(id=id_1, positionSourceType='Portfolio', positionSourceId='MP1',
                  parameters=ReportParameters(transactionCostModel='FIXED')),
        ReportJob(id=id_1, positionSourceType='Portfolio', positionSourceId='MP2',
                  parameters=ReportParameters(transactionCostModel='FIXED'))
    )

    # mock GsSession
    mocker.patch.object(
        GsSession.__class__,
        'default_value',
        return_value=GsSession.get(
            Environment.QA,
            'client_id',
            'secret'))
    mocker.patch.object(GsSession.current, '_get', return_value=mock_response)

    # run test
    response = GsReportApi.get_report_jobs(id_1)
    GsSession.current._get.assert_called_with('/reports/{id}/jobs'.format(id=id_1))
    assert response == expected_response
Exemple #8
0
def test_get_risk_factor_data_results(mocker):
    mock_response = [{
        "date": "2003-01-03",
        "factor": "Value",
        "factorCategory": "Style",
        "pnl": 0.002877605406002121,
        "exposure": 12.105457414400002,
        "sensitivity": 0.026861678358408886,
        "proportionOfRisk": 0.0038230454885067183
    }, {
        "date": "2003-01-06",
        "factor": "Value",
        "factorCategory": "Style",
        "pnl": 0,
        "exposure": 12.1028697664,
        "sensitivity": 0.02668134999120776,
        "proportionOfRisk": 0.0036290846167489335
    }]
    # mock GsSession
    mocker.patch.object(GsSession.__class__,
                        'default_value',
                        return_value=GsSession.get(Environment.QA, 'client_id',
                                                   'secret'))
    mocker.patch.object(GsSession.current, '_get', return_value=mock_response)

    # run test
    response = GsReportApi.get_risk_factor_data_results('reportId')

    GsSession.current._get.assert_called_with(
        '/risk/factors/reports/reportId/results')
    assert response == mock_response
Exemple #9
0
 def get_performance_report(self) -> PerformanceReport:
     reports = GsReportApi.get_reports(
         limit=1,
         position_source_type='Portfolio',
         position_source_id=self.id,
         report_type='Portfolio Performance Analytics')
     return PerformanceReport.from_target(reports[0]) if reports else None
Exemple #10
0
def test_schedule_report(mocker):
    id_1 = 'RX1'
    start_date = dt.date(2019, 2, 18)
    end_date = dt.date(2019, 2, 19)

    mock_response = ""

    # mock GsSession
    mocker.patch.object(GsSession.__class__,
                        'default_value',
                        return_value=GsSession.get(Environment.QA, 'client_id',
                                                   'secret'))
    mocker.patch.object(GsSession.current, '_post', return_value=mock_response)

    # run test
    response = GsReportApi.schedule_report(id_1, start_date, end_date)

    report_schedule_request = ReportScheduleRequest(startDate=start_date,
                                                    endDate=end_date)
    GsSession.current._post.assert_called_with(
        '/reports/{id}/schedule'.format(id=id_1),
        report_schedule_request,
        cls=ReportScheduleRequest)

    assert response == mock_response
Exemple #11
0
 def __get_latest_create_report(self) -> Report:
     """ Used to find baskets's most recent price/publish info """
     report = GsReportApi.get_reports(limit=1,
                                      position_source_id=self.id,
                                      report_type='Basket Create',
                                      order_by='>latestExecutionTime')
     return get(report, '0')
Exemple #12
0
 def result(self):
     """
     :return: a Pandas DataFrame containing the results of the report job
     """
     status = self.status()
     if status == ReportStatus.cancelled:
         raise MqValueError(
             'This report job in status "cancelled". Cannot retrieve results.'
         )
     if status == ReportStatus.error:
         raise MqValueError(
             'This report job is in status "error". Cannot retrieve results.'
         )
     if status != ReportStatus.done:
         raise MqValueError(
             'This report job is not done. Cannot retrieve results.')
     if self.__report_type in [
             ReportType.Portfolio_Factor_Risk, ReportType.Asset_Factor_Risk
     ]:
         results = GsReportApi.get_factor_risk_report_results(
             risk_report_id=self.__report_id,
             start_date=self.__start_date,
             end_date=self.__end_date)
         return pd.DataFrame(results)
     if self.__report_type == ReportType.Portfolio_Performance_Analytics:
         query = DataQuery(where={'reportId': self.__report_id},
                           start_date=self.__start_date,
                           end_date=self.__end_date)
         results = GsDataApi.query_data(
             query=query, dataset_id=ReportDataset.PPA_DATASET.value)
         return pd.DataFrame(results)
     return None
Exemple #13
0
 def get_results(self,
                 mode: FactorRiskResultsMode = FactorRiskResultsMode.Portfolio,
                 factors: List[str] = None,
                 factor_categories: List[str] = None,
                 start_date: dt.date = None,
                 end_date: dt.date = None,
                 currency: Currency = None,
                 return_format: ReturnFormat = ReturnFormat.DATA_FRAME) -> Union[Dict, pd.DataFrame]:
     """
     Get the raw results associated with the factor risk report
     :param mode: results mode; defaults to the portfolio level
     :param factors: optional list of factors; defaults to all of them
     :param factor_categories: optional list of factor categories; defaults to all of them
     :param start_date: start date
     :param end_date: end date
     :param currency: currency
     :param return_format: return format; defaults to a Pandas DataFrame, but can be manually
     set to ReturnFormat.JSON
     :return: risk report results
     """
     results = GsReportApi.get_factor_risk_report_results(risk_report_id=self.id,
                                                          view=mode.value,
                                                          factors=factors,
                                                          factor_categories=factor_categories,
                                                          currency=currency,
                                                          start_date=start_date,
                                                          end_date=end_date)
     return pd.DataFrame(results) if return_format == ReturnFormat.DATA_FRAME else results
Exemple #14
0
 def get_table(self,
               mode: FactorRiskTableMode = None,
               factors: List[str] = None,
               factor_categories: List[str] = None,
               date: dt.date = None,
               currency: Currency = None,
               order_by_column: str = None,
               order_type: OrderType = None,
               return_format: ReturnFormat = ReturnFormat.DATA_FRAME) -> Union[Dict, pd.DataFrame]:
     table = GsReportApi.get_factor_risk_report_table(risk_report_id=self.id,
                                                      mode=mode,
                                                      factors=factors,
                                                      factor_categories=factor_categories,
                                                      currency=currency,
                                                      date=date,
                                                      order_by_column=order_by_column,
                                                      order_type=order_type)
     if return_format == ReturnFormat.DATA_FRAME:
         column_info = table.get('table').get('metadata').get('columnInfo')
         column_info[0].update({'columns': ['name', 'symbol', 'sector']})
         rows = table.get('table').get('rows')
         sorted_columns = []
         for column_group in column_info:
             sorted_columns = sorted_columns + column_group.get('columns')
         rows_data_frame = pd.DataFrame(rows)
         rows_data_frame = rows_data_frame[sorted_columns]
         rows_data_frame = rows_data_frame.set_index('name')
         return rows_data_frame
     return table
Exemple #15
0
    def update(self) -> Dict:
        """
        Update your custom basket

        :return: dictionary containing asset id and report id

        **Usage**

        Make updates to your basket's metadata, pricing options, publishing options, or composition

        **See also**

        :func:`get_details` :func:`poll_status` :func:`create`

        """
        self.__finish_populating_attributes_for_existing_basket()
        edit_inputs, rebal_inputs = self.__get_updates()
        if edit_inputs is None and rebal_inputs is None:
            raise MqValueError('Update failed: Nothing on the basket was changed')
        elif edit_inputs is not None and rebal_inputs is None:
            response = GsIndexApi.edit(self.id, edit_inputs)
        elif rebal_inputs is not None and edit_inputs is None:
            response = GsIndexApi.rebalance(self.id, rebal_inputs)
        else:
            response = self.__edit_and_rebalance(edit_inputs, rebal_inputs)
        gs_asset = GsAssetApi.get_asset(self.id)
        self.__latest_create_report = GsReportApi.get_report(response.report_id)
        self.__error_messages.remove(ErrorMessage.UNMODIFIABLE)
        self.__init__(gs_asset=gs_asset)
        return response.as_dict()
Exemple #16
0
    def get(cls, report_id: str, acceptable_types: List[ReportType] = None):
        # This map cant be instantiated / stored at the top of this file, bc the Factor/RiskReport classes aren't
        # defined there. Don't know the best place to put this
        report_type_to_class_type = {
            ReportType.Portfolio_Factor_Risk: type(FactorRiskReport()),
            ReportType.Asset_Factor_Risk: type(FactorRiskReport()),
            ReportType.Portfolio_Performance_Analytics:
            type(PerformanceReport())
        }

        report = GsReportApi.get_report(report_id=report_id)
        if acceptable_types is not None and report.type not in acceptable_types:
            raise MqValueError('Unexpected report type found.')
        if report.type in report_type_to_class_type:
            return report_type_to_class_type[report.type](
                report_id=report.id,
                position_source_id=report.position_source_id,
                position_source_type=report.position_source_type,
                report_type=report.type,
                parameters=report.parameters,
                status=report.status)
        return Report(report_id=report.id,
                      position_source_id=report.position_source_id,
                      position_source_type=report.position_source_type,
                      report_type=report.type,
                      parameters=report.parameters,
                      status=report.status)
Exemple #17
0
def test_get_report_status(mocker):
    id_1 = 'RJW55950MF0S0HKN'

    mock_response = ({
        'reportJobId': id_1,
        'startDate': dt.date(2018, 12, 12),
        'endDate': dt.date(2018, 12, 18)
    }, {
        'reportJobId': id_1,
        'startDate': dt.date(2017, 12, 12),
        'endDate': dt.date(2017, 12, 16)
    })

    # mock GsSession
    mocker.patch.object(GsSession.__class__,
                        'default_value',
                        return_value=GsSession.get(Environment.QA, 'client_id',
                                                   'secret'))
    mocker.patch.object(GsSession.current, '_get', return_value=mock_response)

    # run test
    response = GsReportApi.get_report_status(id_1)
    GsSession.current._get.assert_called_with(
        '/reports/{id}/status'.format(id=id_1))
    assert response == mock_response
Exemple #18
0
    def create(self) -> Dict:
        """
        Create a new custom basket in Marquee

        :return: dictionary containing asset id and report id

        **Usage**

        Create a new custom basket in Marquee

        **See also**

        :func:`get_details` :func:`poll_status` :func:`update`

        """
        inputs, pricing, publish = {}, {}, {}
        for prop in CustomBasketsCreateInputs.properties():
            set_(inputs, prop, get(self, prop))
        for prop in CustomBasketsPricingParameters.properties():
            set_(pricing, prop, get(self, prop))
        for prop in PublishParameters.properties():
            set_(publish, prop, get(self, prop))
        set_(inputs, 'position_set', self.position_set.to_target(common=False))
        set_(inputs, 'pricing_parameters',
             CustomBasketsPricingParameters(**pricing))
        set_(inputs, 'publish_parameters', PublishParameters(**publish))
        create_inputs = CustomBasketsCreateInputs(**inputs)

        response = GsIndexApi.create(create_inputs)
        gs_asset = GsAssetApi.get_asset(response.asset_id)
        self.__latest_create_report = GsReportApi.get_report(
            response.report_id)
        self.__init__(gs_asset=gs_asset, _finish_init=True)
        return response.as_dict()
Exemple #19
0
def test_update_report(mocker):
    id_1 = 'RX1'

    report = Report.from_dict({
        'id': id_1,
        'positionSourceType': 'Portfolio',
        'positionSourceId': 'MP25',
        'type': 'Portfolio Performance Analytics',
        'parameters': {
            'transactionCostModel': 'FIXED'
        }
    })

    # mock GsSession
    mocker.patch.object(GsSession.__class__,
                        'default_value',
                        return_value=GsSession.get(Environment.QA, 'client_id',
                                                   'secret'))
    mocker.patch.object(GsSession.current, '_put', return_value=report)

    # run test
    response = GsReportApi.update_report(report)
    GsSession.current._put.assert_called_with('/reports/{id}'.format(id=id_1),
                                              report,
                                              cls=Report)
    assert response == report
Exemple #20
0
 def get(cls, report_id: str, **kwargs):
     """
     Get a thematic report from the unique report identifier
     :param report_id: Marquee report ID
     :return: returns a ThematicReport object that correlates to the Marquee report
     """
     return cls.from_target(GsReportApi.get_report(report_id))
Exemple #21
0
 def get_view(self,
              mode: FactorRiskViewsMode,
              factor: str = None,
              factor_category: str = None,
              start_date: dt.date = None,
              end_date: dt.date = None,
              currency: Currency = None) -> Dict:
     """
     Get the results associated with the factor risk report as seen on the Marquee user interface
     :param mode: views mode
     :param factor: optional factor name
     :param factor_category: optional factor category
     :param start_date: start date
     :param end_date: end date
     :param currency: currency
     :return: risk report results
     """
     return GsReportApi.get_factor_risk_report_view(
         risk_report_id=self.id,
         view=mode.value,
         factor=factor,
         factor_category=factor_category,
         currency=currency,
         start_date=start_date,
         end_date=end_date
     )
Exemple #22
0
def test_get_factor_risk_report_view(mocker):
    report_id = 'RP123'
    mock_response = {
        "summary": {
            "riskModel": "BARRA_USSLOWL",
            "fxHedged": True,
            "assetCount": 1,
            "longExposure": 415,
            "shortExposure": 0,
            "factorProportionOfRisk": 70.28206437467601,
            "specificProportionOfRisk": 29.71793562532398,
            "date": "2021-08-12"
        }
    }
    # mock GsSession
    mocker.patch.object(
        GsSession.__class__,
        'default_value',
        return_value=GsSession.get(
            Environment.QA,
            'client_id',
            'secret'))
    mocker.patch.object(GsSession.current, '_get', return_value=mock_response)

    # run test
    response = GsReportApi.get_factor_risk_report_view(report_id, view='Risk')

    GsSession.current._get.assert_called_with(f'/risk/factors/reports/{report_id}/views?view=Risk')
    assert response == mock_response
Exemple #23
0
 def get_performance_report(self) -> PerformanceReport:
     reports = GsReportApi.get_reports(
         limit=100,
         position_source_type='Portfolio',
         position_source_id=self.id,
         report_type='Portfolio Performance Analytics')
     if len(reports) == 0:
         raise MqError('This portfolio has no performance report.')
     return PerformanceReport.from_target(reports[0])
Exemple #24
0
 def get_most_recent_job(self):
     jobs = GsReportApi.get_report_jobs(self.id)
     most_current_job = sorted(jobs, key=lambda i: i['createdTime'], reverse=True)[0]
     return ReportJobFuture(report_id=self.id,
                            job_id=most_current_job.get('id'),
                            report_type=ReportType(most_current_job.get('reportType')),
                            start_date=dt.datetime.strptime(most_current_job.get('startDate'),
                                                            "%Y-%m-%d").date(),
                            end_date=dt.datetime.strptime(most_current_job.get('endDate'),
                                                          "%Y-%m-%d").date())
Exemple #25
0
 def get_factor_data(self,
                     factor: str,
                     start_date: dt.date = None,
                     end_date: dt.date = None):
     return GsReportApi.get_risk_factor_data_results(
         risk_report_id=self.get_id(),
         factors=[factor],
         factor_categories=None,
         start_date=start_date,
         end_date=end_date)
Exemple #26
0
 def get_thematic_report(self) -> ThematicReport:
     if self.positioned_entity_type in [EntityType.PORTFOLIO, EntityType.ASSET]:
         position_source_type = self.positioned_entity_type.value.capitalize()
         reports = GsReportApi.get_reports(limit=100,
                                           position_source_type=position_source_type,
                                           position_source_id=self.id,
                                           report_type=f'{position_source_type} Thematic Analytics')
         if len(reports) == 0:
             raise MqError(f'This {position_source_type} has no thematic analytics report.')
         return ThematicReport.from_target(reports[0])
     raise NotImplementedError
Exemple #27
0
 def get_factor_risk_reports(self, fx_hedged: bool = None) -> List[FactorRiskReport]:
     if self.positioned_entity_type in [EntityType.PORTFOLIO, EntityType.ASSET]:
         position_source_type = self.positioned_entity_type.value.capitalize()
         reports = GsReportApi.get_reports(limit=100,
                                           position_source_type=position_source_type,
                                           position_source_id=self.id,
                                           report_type=f'{position_source_type} Factor Risk')
         if fx_hedged:
             reports = [report for report in reports if report.parameters.fx_hedged == fx_hedged]
         if len(reports) == 0:
             raise MqError(f'This {position_source_type} has no factor risk reports that match your parameters.')
         return [FactorRiskReport.from_target(report) for report in reports]
     raise NotImplementedError
Exemple #28
0
 def get_results(self,
                 factors: List[str] = None,
                 factor_categories: List[str] = None,
                 start_date: dt.date = None,
                 end_date: dt.date = None,
                 currency: Currency = None,
                 return_format: ReturnFormat = ReturnFormat.DATA_FRAME) -> Union[Dict, pd.DataFrame]:
     results = GsReportApi.get_risk_factor_data_results(risk_report_id=self.id,
                                                        factors=factors,
                                                        factor_categories=factor_categories,
                                                        currency=currency,
                                                        start_date=start_date,
                                                        end_date=end_date)
     return pd.DataFrame(results) if return_format == ReturnFormat.DATA_FRAME else results
Exemple #29
0
 def schedule(self, start_date: dt.date = None, end_date: dt.date = None):
     if None in [self.id, self.__position_source_id]:
         raise MqValueError(
             'Can only schedule reports with valid IDs and Position Source IDs.'
         )
     if self.position_source_type != PositionSourceType.Portfolio and None in [
             start_date, end_date
     ]:
         raise MqValueError(
             'Must specify schedule start and end dates for report.')
     if None in [start_date, end_date]:
         position_dates = GsPortfolioApi.get_position_dates(
             self.position_source_id)
         if len(position_dates) == 0:
             raise MqValueError(
                 'Cannot schedule reports for a portfolio with no positions.'
             )
         if start_date is None:
             start_date = min(position_dates)
         if end_date is None:
             end_date = max(position_dates)
     GsReportApi.schedule_report(report_id=self.id,
                                 start_date=start_date,
                                 end_date=end_date)
Exemple #30
0
 def __edit_and_rebalance(self, edit_inputs: CustomBasketsEditInputs,
                          rebal_inputs: CustomBasketsRebalanceInputs) -> CustomBasketsResponse:
     """ If updates require edit and rebalance, rebal will not be scheduled until/if edit report succeeds """
     _logger.info('Current update request requires multiple reports. Your rebalance request will be submitted \
                   once the edit report has completed. Submitting basket edits now...')
     response = GsIndexApi.edit(self.id, edit_inputs)
     report_id = response.report_id
     self.__latest_create_report = GsReportApi.get_report(response.report_id)
     report_status = self.poll_report(report_id, timeout=600, step=15)
     if report_status != ReportStatus.done:
         raise MqError(f'The basket edit report\'s status is {status}. The current rebalance request will \
                         not be submitted in the meantime.')
     _logger.info('Your basket edits have completed successfuly. Submitting rebalance request now...')
     response = GsIndexApi.rebalance(self.id, rebal_inputs)
     return response