def my_rebalance_opt(context, data):
    """
    Our monthly rebalancing routine
    """

    # First update the stock universe.
    context.output = pipeline_output('investment_universe')
    context.security_list = context.output.index

    # Get data
    hist_window = max(context.momentum_window,
                      context.momentum_window2) + context.exclude_days

    hist = data.history(context.security_list, "close", hist_window, "1d")

    data_end = -1 * context.exclude_days  # exclude most recent data

    momentum1_start = -1 * (context.momentum_window + context.exclude_days)
    momentum_hist1 = hist[momentum1_start:data_end]

    momentum2_start = -1 * (context.momentum_window2 + context.exclude_days)
    momentum_hist2 = hist[momentum2_start:data_end]

    # Calculate momentum scores for all stocks.
    momentum_list = momentum_hist1.apply(slope)  # Mom Window 1
    momentum_list2 = momentum_hist2.apply(slope)  # Mom Window 2

    # Combine the lists and make average
    momentum_concat = pd.concat((momentum_list, momentum_list2))
    mom_by_row = momentum_concat.groupby(momentum_concat.index)
    mom_means = mom_by_row.mean()

    # Calculate inverse volatility, for position size.
    inv_vola_table = hist.apply(inv_vola_calc)

    alpha = (mom_means * inv_vola_table).dropna()

    objective = opt.MaximizeAlpha(alpha)

    constrain_gross_leverage = opt.MaxGrossLeverage(MAX_GROSS_LEVERAGE)

    constrain_pos_size = opt.PositionConcentration.with_equal_bounds(
        -MAX_SHORT_POSITION_SIZE,
        MAX_LONG_POSITION_SIZE,
    )

    market_neutral = opt.DollarNeutral()

    sector_neutral = opt.NetPartitionExposure.with_equal_bounds(
        labels=context.output.sector,
        min=-MAX_SHORT_SECTOR_SIZE,
        max=MAX_LONG_SECTOR_SIZE,
    )

    order_optimal_portfolio(objective,
                            constraints=[
                                constrain_gross_leverage, constrain_pos_size,
                                market_neutral, sector_neutral
                            ],
                            universe=context.security_list)
Esempio n. 2
0
def rebalance(context, data):
    ### Optimize API
    pipeline_data = context.pipeline_data

    ### Extract from pipeline any specific risk factors you want
    # to neutralize that you have already calculated
    risk_factor_exposures = pd.DataFrame(
        {'market_beta': pipeline_data.market_beta.fillna(1.0)})
    # We fill in any missing factor values with a market beta of 1.0.
    # We do this rather than simply dropping the values because we have
    # want to err on the side of caution. We don't want to exclude
    # a security just because it's missing a calculated market beta,
    # so we assume any missing values have full exposure to the market.

    ### Here we define our objective for the Optimize API. We have
    # selected MaximizeAlpha because we believe our combined factor
    # ranking to be proportional to expected returns. This routine
    # will optimize the expected return of our algorithm, going
    # long on the highest expected return and short on the lowest.
    objective = opt.MaximizeAlpha(pipeline_data.combined_rank)

    ### Define the list of constraints
    constraints = []
    # Constrain our maximum gross leverage
    constraints.append(opt.MaxGrossLeverage(MAX_GROSS_LEVERAGE))
    # Require our algorithm to remain dollar neutral
    constraints.append(opt.DollarNeutral())
    # Add a sector neutrality constraint using the sector
    # classifier that we included in pipeline
    constraints.append(
        opt.NetPartitionExposure.with_equal_bounds(
            labels=pipeline_data.sector,
            min=-MAX_SECTOR_EXPOSURE,
            max=MAX_SECTOR_EXPOSURE,
        ))
    # Take the risk factors that you extracted above and
    # list your desired max/min exposures to them -
    # Here we selection +/- 0.01 to remain near 0.
    neutralize_risk_factors = opt.WeightedExposure(
        loadings=risk_factor_exposures,
        min_exposures={'market_beta': -MAX_BETA_EXPOSURE},
        max_exposures={'market_beta': MAX_BETA_EXPOSURE})
    constraints.append(neutralize_risk_factors)

    # With this constraint we enforce that no position can make up
    # greater than MAX_SHORT_POSITION_SIZE on the short side and
    # no greater than MAX_LONG_POSITION_SIZE on the long side. This
    # ensures that we do not overly concentrate our portfolio in
    # one security or a small subset of securities.
    constraints.append(
        opt.PositionConcentration.with_equal_bounds(
            min=-MAX_SHORT_POSITION_SIZE, max=MAX_LONG_POSITION_SIZE))

    ### Put together all the pieces we defined above by passing
    # them into the order_optimal_portfolio function. This handles
    # all of our ordering logic, assigning appropriate weights
    # to the securities in our universe to maximize our alpha with
    # respect to the given constraints.
    order_optimal_portfolio(objective=objective, constraints=constraints)
Esempio n. 3
0
def do_portfolio_construction(context, data):
    pipeline_data = context.pipeline_data
    todays_universe = pipeline_data.index

    # Objective
    # ---------
    # For our objective, we simply use our naive ranks as an alpha coefficient
    # and try to maximize that alpha.
    #
    # This is a **very** naive model. Since our alphas are so widely spread out,
    # we should expect to always allocate the maximum amount of long/short
    # capital to assets with high/low ranks.
    #
    # A more sophisticated model would apply some re-scaling here to try to generate
    # more meaningful predictions of future returns.
    objective = opt.MaximizeAlpha(pipeline_data.alpha)

    # Constraints
    # -----------
    # Constrain our gross leverage to 1.0 or less. This means that the absolute
    # value of our long and short positions should not exceed the value of our
    # portfolio.
    constrain_gross_leverage = opt.MaxGrossLeverage(MAX_GROSS_LEVERAGE)

    # Constrain individual position size to no more than a fixed percentage
    # of our portfolio. Because our alphas are so widely distributed, we
    # should expect to end up hitting this max for every stock in our universe.
    constrain_pos_size = opt.PositionConcentration.with_equal_bounds(
        -MAX_SHORT_POSITION_SIZE,
        MAX_LONG_POSITION_SIZE,
    )

    # Constrain ourselves to allocate the same amount of capital to
    # long and short positions.
    market_neutral = opt.DollarNeutral()

    # Constrain ourselve to have a net leverage of 0.0 in each sector.
    sector_neutral = opt.NetPartitionExposure.with_equal_bounds(
        labels=pipeline_data.sector,
        min=-0.0001,
        max=0.0001,
    )

    # Run the optimization. This will calculate new portfolio weights and
    # manage moving our portfolio toward the target.
    algo.order_optimal_portfolio(
        objective=objective,
        constraints=[
            constrain_gross_leverage,
            constrain_pos_size,
            market_neutral,
            sector_neutral,
        ],
        universe=todays_universe,
    )
Esempio n. 4
0
def my_rebalance(context, data):
    """
    Execute orders according to our schedule_function() timing. 
    """

    risk_model_factors = context.risk_factors
    risk_model_factors = risk_model_factors.join(context.predicted_probs,
                                                 how='right').dropna()

    predictions = risk_model_factors.ML

    # Filter out stocks that can not be traded
    predictions = predictions.loc[data.can_trade(predictions.index)]
    # Select top and bottom N stocks
    predictions = pd.concat([
        predictions.nlargest(N_STOCKS_TO_TRADE // 2),
        predictions.nsmallest(N_STOCKS_TO_TRADE // 2)
    ])

    todays_universe = predictions.index

    predictions -= 0.5  # predictions are probabilities ranging from 0 to 1
    # Setup Optimization Objective
    objective = opt.MaximizeAlpha(predictions)

    # Setup Optimization Constraints
    constrain_gross_leverage = opt.MaxGrossLeverage(1.0)
    constrain_pos_size = opt.PositionConcentration.with_equal_bounds(-.02, .02)
    market_neutral = opt.DollarNeutral()
    # TypeError: cannot do label indexing on <class 'pandas.indexes.base.Index'> with these indexers [nan] of <type 'float'>
    sector_neutral = opt.NetPartitionExposure.with_equal_bounds(
        labels=context.risk_factors.Sector.dropna(),
        min=-0.0001,
        max=0.0001,
    )

    # Run the optimization. This will calculate new portfolio weights and
    # manage moving our portfolio toward the target.
    order_optimal_portfolio(
        objective=objective,
        constraints=[
            constrain_gross_leverage,
            constrain_pos_size,
            market_neutral,
            sector_neutral,
        ],
        universe=todays_universe,
    )
def do_portfolio_construction(context, data):
    pipeline_data = context.pipeline_data
    todays_universe = pipeline_data.index

    # Objective here was to maximise alpha which is
    # our factor defined in the pipeline.
    objective = opt.MaximizeAlpha(pipeline_data.alpha)

    # Constrain our gross leverage to 1.0 or less.
    # This means that the absolute value of our long and short positions
    # should not exceed the value of our portfolio.
    constrain_gross_leverage = opt.MaxGrossLeverage(MAX_GROSS_LEVERAGE)

    # Constrain individual position size to no more than a fixed percentage
    # of our portfolio.
    constrain_pos_size = opt.PositionConcentration.with_equal_bounds(
        -MAX_SHORT_POSITION_SIZE,
        MAX_LONG_POSITION_SIZE,
    )

    # Constrain ourselves to allocate the same amount of capital to
    # long and short positions. Not used in the simulations in this work.
    market_neutral = opt.DollarNeutral()

    # Constrain the maximum average exposure
    # to individual sectors to -10% - 10%.
    sector_neutral = opt.NetPartitionExposure.with_equal_bounds(
        labels=pipeline_data.sector,
        min=-0.10,
        max=0.10,
    )

    # Run the optimization.
    # This will calculate new portfolio weights and
    # manage moving our portfolio toward the target.
    algo.order_optimal_portfolio(
        objective=objective,
        constraints=[
            constrain_gross_leverage,
            constrain_pos_size,
            # market_neutral, ---> not used in the study.
            sector_neutral,
        ],
        universe=todays_universe,
    )