Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
how does opt.MaximizeAlpha work as compared to opt.TargetWeights?

how does opt.MaximizeAlpha work as compared to opt.TargetWeights?

Is it simple rescaling of target alpha to convert it to weight?

3 responses

Hard to explain.

Briefly: MaximizeAlpha maxes out stronger signals, otherwise ignoring their weight and done.

More detail:
MaximizeAlpha maximizes positions starting with the strongest alpha signals furthest away from zero both positive and negative, and does this up to the position concentration constraint (yet subject also to other constraints specified of course).
The main point: In that process, when MaximizeAlpha runs out of investment room based on a leverage constraint of 1.0 for example, it disregards all remaining stocks, those with lower values (absolute, i.e. ignoring sign, that is: Those closer to zero).

There are often a fewer number of stocks with MaximizeAlpha.
For example, picture 50 stocks with normalized weights -1 to +1 , all different weights (alpha values), one could wind up with just 8 long and 8 short, all weighted about the same. The other 34 with weaker signals -- ignored.

When it's time to try more across-the-board investing in all (or more) stocks delivered up by pipeline rules along with MaximizeAlpha, it is fairly simple. Hard-coded position concentration values can be reduced. Or set dynamically something like

def trade(context, data):  
    conc = 0.9 / len(context.output.alpha)  
    ...  
            opt.PositionConcentration.with_equal_bounds(min = -conc, max = conc),  

In adjusting that number you can see the effect to some degree with record() or print.
Naturally, sometimes it would be better to instead schedule the current number of positions line for some amount of time after trade() at least before any closing of positions.

def before_trading_start(context, data):  
    print(' current number of positions: {} '.format( len(context.portfolio.positions) ))  
    context.output = pipeline_output('pipe')  
    print('.\n number of stocks from pipeline today: {} '.format( len(context.output) ))  

@Blue Seahawk can you describe a situation where TargetAlpha and TargetWeights will do something different?

For example: a factor assigns ranks to all 500 assets in Q500. Capital is $10k, leverage 1, dollar neutral constraint, position concentration 10%.
TargetAlpha will open 10 positions, each with a $1k value, it will long the 5 highest and short the 5 lowest scored stocks.

What would TargetWeights do? If the same then in what situation would do something differently?

There's some discussion of it at https://www.quantopian.com/posts/maximizealpha-under-the-hood-and-targetweights
I'd suggest cloning the fairly simple algo at https://www.quantopian.com/posts/optimization-weights-logging
Change to context.num = 10.
Maybe replace the pipe with highest volume stocks for no worry about partial fills, and this style is easier to read and work with, I think.

def make_pipeline(context):  
    m  = QTradableStocksUS()  # mask  
    m &= USEquityPricing.volume.latest.top(context.num, mask=m)    # adding to mask

    return Pipeline(  
        screen  =  m,  
        columns = {  
            'prc': USEquityPricing.close.latest  
        }  
    )  

The first outputs to compare:

    # Switch between MaximizeAlpha & TargetWeights  
    objective = opt.MaximizeAlpha(c.alpha)  
    #objective = opt.TargetWeights(c.alpha)  

Then compare each of those with different constraints enabled also.

A way to highlight differences in outputs is important. I like CompareIt.