Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Money Flow Index for Pipeline

Hey girls and guys,

I am new to the community and love it so far. I am now trying to implement some CustomFactors, however, there is a challenge, I don't really know how to approach maybe somebody could help.

Basically what I am trying to do ist to program the Money Flow Index as described in here: MFI

class MoneyFlowIndex(CustomFactor):  
    inputs = [USEquityPricing.high, USEquityPricing.low, USEquityPricing.close, USEquityPricing.volume]  
    window_length = 20  
    def compute(self, today, asset_ids, out, high, low, close, volume):  
        typical_price = (high + low + close)/3  
        money_flow = typical_price * volume  
        pos_money_flow = 0  
        neg_money_flow = 0  
        for i in range(1, self.window_length):  
            if money_flow[i-1] - money_flow[i] > 0:  
                pos_money_flow += money_flow[i]  
            elif money_flow[i-1] - money_flow[i] < 0:  
                neg_money_flow += money_flow[i]  
        money_ration = pos_money_flow/neg_money_flow  
        out[:] = 100 - 100/(1 + money_ratio)  

There are basically two problems I see. First of all I would need a window which goes one further than the window size to calculate all the changes.

Second, my iteration over the data rows doesn't work out and I probably have to use a filter I only have limited experience. Sorry for the beginner questions but the pipeline really needs some getting used to.

Thanks
Benjamin

5 responses

Hi Benjamin, you may find this post by Gil Wassermann helpful.

Sweet thanks Karl, exactly what I was looking for!

Hello, I'm a new quantopian 🤣. how to add this to pipeline?

@ali al-karaawi. First off, welcome to Quantopian. For an understanding of pipeline and how to add factors you should read the tutorial on pipelines especially lesson 10 on custom factors. Basically, you first define your custom factor. I this case (thanks to Gil Wassermann) one can simply copy the code from the notebook referenced in the above linked post.

class MFI(CustomFactor):  
    """  
    Money Flow Index  
    Volume Indicator  
    **Default Inputs:**  USEquityPricing.high, USEquityPricing.low, USEquityPricing.close, USEquityPricing.volume  
    **Default Window Length:** 15 (14 + 1-day for difference in prices)  
    http://www.fmlabs.com/reference/default.htm?url=MoneyFlowIndex.htm  
    """     

    inputs = [USEquityPricing.high, USEquityPricing.low, USEquityPricing.close, USEquityPricing.volume]  
    window_length = 15

    def compute(self, today, assets, out, high, low, close, vol):

        # calculate typical price  
        typical_price = (high + low + close) / 3.

        # calculate money flow of typical price  
        money_flow = typical_price * vol

        # get differences in daily typical prices  
        tprice_diff = (typical_price - np.roll(typical_price, 1, axis=0))[1:]

        # create masked arrays for positive and negative money flow  
        pos_money_flow = np.ma.masked_array(money_flow[1:], tprice_diff < 0, fill_value = 0.)  
        neg_money_flow = np.ma.masked_array(money_flow[1:], tprice_diff > 0, fill_value = 0.)

        # calculate money ratio  
        money_ratio = np.sum(pos_money_flow, axis=0) / np.sum(neg_money_flow, axis=0)

        # MFI  
        out[:] = 100. - (100. / (1. + money_ratio))  

Once the custom factor is defined, simply place it into the pipeline definition. Something like this

def make_pipeline():  
    money_flow_index = MFI()  
    close_price = USEquityPricing.close.latest  
    return Pipeline(  
        columns={  
            'money_flow_index': money_flow_index,  
            'close_price': close_price,  
        },  
        screen=QTradableStocksUS(),  
    )

Hope that helps. See attached notebook.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

thank u so much @Dan Whitnable
it's great idea to use np.ma.masked_array instead of if