Back to Community
Adding weights to ranking system?

So I understand how the percentile ranks work, but what if I wanted to do something like the following...

ROE%TTM (20%, Rank by higher values)
Pr2SalesTTM (20% Ranking by higher values)
3Month%Return (15%, Ranking by higher values)
etc... until my rank filters equal out to 100% and each carry their own weight. And I'd like the system to return a rank based on parameters that between 0-100 for an individual security. So then I could say buy securities with rank > 80 and sell if rank drops below < 70.

I'm sure it can be done, I just imagine it would be a lot of work.

2 responses

Try this, its purpose is to make that easy for experimentation. Mainly set up the factors and then you can start modifying. Longs come from high values, short low values. Everything else for feeding them to Optimize is automatic. As a headstart might look something like this:

from quantopian.pipeline.experimental import QTradableStocksUS

class ROETTM(CustomFactor):  
    inputs = [Fundamentals.roe] ; window_length = 77  
    def compute(self, today, assets, out, roe):  
        roe = nanfill(roe)  
        out[:] = np.mean(roe, axis=0) 

class Pr2SalesTTM(CustomFactor):  
    inputs = [Fundamentals.ps_ratio] ; window_length = 252  
    def compute(self, today, assets, out, ps):  
        ps = nanfill(ps)  
        out[:] = np.mean(ps, axis=0)

class nMonthReturn(CustomFactor): # override window_length when called  
    inputs = [USEquityPricing.close] ; window_length = 21  
    def compute(self, today, assets, out, close):  
        close = nanfill(close)  
        out[:] = (close[-1] - close[0]) / close[0]

def make_pipeline(c):  
    m = VolumeMin(window_length=42).top(1400) & Sector().notnull() & QTradableStocksUS()  # mask  
    #                            Adding to mask, excluding values around the middle, ~ means not.  
    a = -ROETTM      (window_length=252, mask=m); m &= ~(a.percentile_between(20, 80))  # minus to flip long, short  
    b =  Pr2SalesTTM (window_length=252, mask=m); m &= ~(b.percentile_between(20, 80))  
    c = -nMonthReturn(window_length=63,  mask=m); m &= ~(c.percentile_between(20, 80))  
    return Pipeline(  
        screen  = m,  
        columns = {  
            'a': a,  
            'b': b,  
            'c': c,  
            'sector': Sector(mask=m),  
        })  

You can set a breakpoint to examine the pipeline output (o) or add a log line like this:

    if c.log_universe >= 0:  
        log.info('.\n{}'.format(c.ori.head()))

2010-01-05 05:45 before_trading_start:119 INFO .  
                            a         b         c  sector     score  
Equity(239 [AIG])    0.017151  0.000020  0.027447     103  0.013934  
Equity(368 [AMGN])   0.015336  0.000367  0.020931     206  0.000273  
Equity(430 [ANN])    0.016286  0.000030  0.024045     102  0.012295  
Equity(1524 [CHRS])  0.015904  0.000020  0.014161     102 -0.004098  
Equity(1696 [CNW])   0.015860  0.000034  0.022985     310  0.008470  
2010-01-05 05:45 before_trading_start:122 INFO pipe len 60  
2010-01-05 05:45 before_trading_start:124 INFO lng 24  top MNKD 0.068287  bottom OXPS 0.015046  
2010-01-05 05:45 before_trading_start:126 INFO shs 24  top SBAC -0.015046  bottom MCO -0.068287  
2010-01-05 06:31 pvr:554 INFO 2010-01-05 to 2010-07-02  $10000000  2017-11-22 18:58 US/Pacific

I'll have to check this out, thanks for the quick response I really appreciate it.