Пример #1
0
def get_factor_performance_attribution(portfolio_name,
                                       start_date,
                                       end_date,
                                       factor_ids,
                                       model_id=DEFAULT_MODEL_ID):
    oper = OpOperation(schema.Query)
    sim = oper.model(id=model_id).simulation(
        position_set=schema.PositionSetInput(
            id=get_portfolio_id(portfolio_name), type="PORTFOLIO"),
        from_=start_date,
        to=end_date,
    )
    performance = sim.performance
    performance.date()
    performance.percent_return_cumulative.attribution.factors(
        id=factor_ids).__fields__("id", "value")
    results = oper()
    results
    df = pd.DataFrame(data=[
        (p.date, f.id, f.value) for p in results.model.simulation.performance
        for f in p.percent_return_cumulative.attribution.factors
    ],
                      columns=['date', 'id', 'value'])
    df.value = df.value + 1
    df['daily_value'] = df.groupby('id')['value'].pct_change(1)
    df.value = df.value - 1
    return df
Пример #2
0
def get_portfolio_performance(
    name,
    start_date,
    end_date,
    base=None,
    interval=schema.PositionSetInterval.AUTO,
    model_id=DEFAULT_MODEL_ID,
):
    summary_fields = ["trading", "factors", "specific"]
    factor_fields = ["id", "name", "category", "value"]
    if base is None:
        base = []
    oper = OpOperation(schema.Query)
    model = oper.model(id=model_id)
    port = schema.PositionSetInput(id=get_portfolio_id(name), type="PORTFOLIO")
    model.simulation(position_set=port,
                     from_=start_date,
                     to=end_date,
                     base=base,
                     interval=interval).performance.__fields__("date")
    attr = oper.model.simulation.performance.percent_return_cumulative.attribution
    attr.summary.__fields__(*summary_fields)
    attr.factors.__fields__(*factor_fields)
    res = oper()

    df_summary = pd.DataFrame(
        data=[(
            p.date,
            *[
                p.percent_return_cumulative.attribution.summary[f]
                for f in summary_fields
            ],
        ) for p in res.model.simulation.performance],
        columns=["date"] + summary_fields,
    )
    # We're given cumulative values but may want daily values.
    df_summary["trading_daily"] = (1 + df_summary.trading).pct_change()
    df_summary.trading_daily.iat[0] = df_summary.trading[0]
    df_summary["factors_daily"] = (1 + df_summary.factors).pct_change()
    df_summary.factors_daily.iat[0] = df_summary.factors[0]
    df_summary["specific_daily"] = (1 + df_summary.specific).pct_change()
    df_summary.specific_daily.iat[0] = df_summary.specific[0]
    df_summary[
        "total"] = df_summary.trading + df_summary.factors + df_summary.specific
    df_summary["total_daily"] = (1 + df_summary.total).pct_change()
    df_summary.total_daily.iat[0] = df_summary.total[0]

    factor_data = []
    for p in res.model.simulation.performance:
        for pf in p.percent_return_cumulative.attribution.factors:
            factor_data.append([p.date] + [pf[f] for f in factor_fields])
    df_factors = pd.DataFrame(data=factor_data,
                              columns=["date"] + factor_fields)
    return df_summary, df_factors
Пример #3
0
def df_to_position_set(df: pd.DataFrame):
    dates = []
    for dt in df.date.unique():
        equities = [
            schema.PositionSetEquityInput(
                id=schema.PositionSetEquityIdInput(sedol=row.sedol),
                economic_exposure=row.economic_exposure,
            ) for _, row in df[df.date == dt].iterrows()
        ]
        dates += [schema.PositionSetDateInput(equities=equities, date=dt)]
    return schema.PositionSetInput(dates=dates)
Пример #4
0
def get_performance_contributors(portfolio_name,
                                 start_date,
                                 end_date,
                                 model_id=DEFAULT_MODEL_ID):
    oper = OpOperation(schema.Query)
    sim = oper.model(id=model_id).simulation(
        position_set=schema.PositionSetInput(
            id=get_portfolio_id(portfolio_name), type="PORTFOLIO"),
        from_=start_date,
        to=end_date,
    )
    sim.performance_contributors(
        equity_id_format="MODEL_PROVIDER_ID").__fields__(
            "id", "sedol", "average_percent_equity", "total")
    sim.performance_contributors.attribution.summary.__fields__(
        "factors", "specific", "trading")
    results = oper()
    values = [[
        pc.sedol,
        pc.id,
        pc.average_percent_equity,
        pc.total,
        pc_at.factors,
        pc_at.specific,
        pc_at.trading,
    ] for pc in results.model.simulation.performance_contributors
              for pc_at in [pc.attribution.summary]]
    return pd.DataFrame(
        data=values,
        columns=[
            "sedol",
            "model_provider_id",
            "average_percent_equity",
            "total",
            "factors",
            "specific",
            "trading",
        ],
    )
Пример #5
0
def get_exposure_contributors(portfolio_name,
                              start_date,
                              end_date,
                              model_id=DEFAULT_MODEL_ID):
    oper = OpOperation(schema.Query)
    ec = oper.model(id=model_id).simulation(
        position_set=schema.PositionSetInput(
            id=get_portfolio_id(portfolio_name), type="PORTFOLIO"),
        from_=start_date,
        to=end_date,
    )
    ec.exposure_contributors(
        equity_id_format="MODEL_PROVIDER_ID").__fields__("date")
    ec.exposure_contributors.contributors.__fields__("sedol", "id",
                                                     "percent_equity")
    results = oper()
    values = [[ec_date.date, ec.sedol, ec.id, ec.percent_equity]
              for ec_date in results.model.simulation.exposure_contributors
              for ec in ec_date.contributors]
    return pd.DataFrame(
        data=values,
        columns=["date", "sedol", "model_provider_id", "percent_equity"])
Пример #6
0
def optimize_portfolio(portfolio_name,
                       dt,
                       objective,
                       constraints,
                       constants=schema.OptimizationConstantsInput(),
                       forecast=None,
                       model_id=DEFAULT_MODEL_ID):
    '''Optimize an uploaded portfolio'''
    pos_data = []
    position_set = schema.PositionSetInput(id=get_portfolio_id(portfolio_name),
                                           type="PORTFOLIO")
    oper = OpOperation(schema.Query)
    if forecast is None:
        optimization = oper.model(id=model_id).optimization(
            position_set=position_set,
            objective=[objective],
            constants=constants,
            constraints=constraints,
            on=[dt])
    else:
        optimization = oper.model(id=model_id).optimization(
            position_set=position_set,
            objective=[objective],
            constants=constants,
            constraints=constraints,
            on=[dt],
            forecast=forecast)
    opt_dates = optimization.positions().dates
    opt_dates.date()
    opt_dates.equities().id().model_provider_id()
    opt_dates.equities().__fields__("id", "economic_exposure")
    results = oper()
    pos_data += [[
        pos_date.date, equity.id.model_provider_id, equity.economic_exposure
    ] for pos_date in results.model.optimization.positions.dates
                 for equity in pos_date.equities]
    columns = ["date", "model_provider_id", "economic_exposure"]
    df_pos = pd.DataFrame(data=pos_data, columns=columns)
    return df_pos
Пример #7
0
def get_market_impact_date(mi_date,
                           deltas,
                           nav,
                           denominator=None,
                           model_id=DEFAULT_MODEL_ID):
    if denominator == None:
        denominator = nav
    equities = [
        schema.PositionSetEquityInput(
            id=schema.PositionSetEquityIdInput(model_provider_id=id),
            economic_exposure=pct_equity * nav,
        ) for id, pct_equity in deltas.items()
    ]
    ps_delta = schema.PositionSetDateInput(date=mi_date, equities=equities)
    oper = OpOperation(schema.Query)
    market_impact = (oper.model(id=model_id).simulation(
        position_set=schema.PositionSetInput()).market_impact(
            position_set_delta=ps_delta,
            equity_id_format="MODEL_PROVIDER_ID",
            scale_format="DEFAULT",
        ))
    market_impact.cost()
    market_impact.contributors().__fields__("id", "cost")
    res = oper()
    total_cost = res.model.simulation.market_impact.cost
    total_cost_pct = total_cost / denominator
    df_total = pd.DataFrame(
        data=[[mi_date, total_cost, total_cost_pct]],
        columns=["date", "total_cost", "total_cost_pct"],
    )

    contributors = [(mi_date, c.id, c.cost, c.cost / denominator)
                    for c in res.model.simulation.market_impact.contributors]
    df_contrib = pd.DataFrame(
        data=contributors,
        columns=["date", "model_provider_id", "cost", "cost_pct"])
    return df_total, df_contrib
Пример #8
0
def load_optimized_portfolio(df,
                             portfolio_name,
                             nav,
                             forecast_horizon,
                             objective,
                             model_id=DEFAULT_MODEL_ID):
    if portfolio_name not in [p.name for p in op.get_portfolios()]:
        op.create_portfolio(portfolio_name)

    errors = []
    for dt in df.date.unique():
        rows = list(row for index, row in df[df.date == dt].iterrows())
        oper = op.OpOperation(schema.Query)
        long_len = len([r for r in rows if r.expected_return > 0])
        if long_len > 0:
            long_base = nav / long_len
        short_len = len([r for r in rows if r.expected_return <= 0])
        if short_len > 0:
            short_base = -nav / short_len
        equities = [
            schema.PositionSetEquityInput(
                id=schema.PositionSetEquityIdInput(sedol=row.sedol),
                economic_exposure=long_base
                if row.expected_return > 0 else short_base,
            ) for row in rows
        ]

        position_set_dates = [
            schema.PositionSetDateInput(equities=equities, date=dt)
        ]
        position_set = schema.PositionSetInput(dates=position_set_dates)

        forecast_equities = [
            schema.ForecastEquityInput(
                id=schema.PositionSetEquityIdInput(sedol=row.sedol),
                expected_percent_return=row.expected_return,
            ) for row in rows
        ]
        forecast = schema.ForecastInput(horizon=forecast_horizon,
                                        equities=forecast_equities)

        constants = schema.OptimizationConstantsInput(equity=nav)
        optimization = oper.model(id=model_id).optimization(
            position_set=position_set,
            objective=[objective],
            constants=constants,
            constraints=constraints,
            forecast=forecast,
        )
        opt_dates = optimization.positions().dates
        opt_dates.date()
        opt_dates.equities().id().sedol()
        opt_dates.equities().__fields__("id", "economic_exposure")
        results = None
        try:
            results = oper()
        except op.GqlError as gql_err:
            errors.append((dt, gql_err))
        values = [[pos_date.date, equity.id.sedol, equity.economic_exposure]
                  for pos_date in results.model.optimization.positions.dates
                  for equity in pos_date.equities]
        columns = ["date", "sedol", "economic_exposure"]
        df_pos = pd.DataFrame(data=values, columns=columns)
        upload_portfolio_positions(portfolio_name, df_pos, nav=nav)
    return errors