Back to Community
Using talib with USEquityPricing ? Is there any way?

Is there a way to use Talib with USQuitypricing? I am pretty new to Algo trading and Quantopian. Just learnt the basics of python but I am programmer for some time.

Please focus on this commented line LINE NUMBER 60-

fastk, fastd = talib.STOCHRSI(USEquityPricing.close, timeperiod=14, fastk_period=5, fastd_period=3, fastd_matype=0)

How can I make the Talib to work with USEquityPricing here specially while making pipeline?

Please be a little detailed if you can help?

Clone Algorithm
1
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
from quantopian.algorithm import attach_pipeline,pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import AverageDollarVolume,SimpleMovingAverage
from quantopian.pipeline.filters.morningstar import Q1500US
from quantopian.pipeline.data import morningstar
import talib;
import datetime;
import numpy as np


def initialize(context):
    
    schedule_function(my_rebalance,date_rules.week_start(),time_rules.market_open(hours=1))
    
    myPipeline = makePipeline()
    attach_pipeline(myPipeline,'my_pipeline')
    
def before_trading_start(context, data):
    context.output = pipeline_output('my_pipeline')
    
    #Long positions
    context.longs = context.output[context.output['longs']].index.tolist()
    
    # Short positions
    context.shorts = context.output[context.output['shorts']].index.tolist()
    
    context.longWeight,context.shortWeight = my_compute_weights(context)
    

def my_compute_weights(context):
    
    if len(context.longs)==0:
        longWeight = 0
    else:
        longWeight = 0.5 / len(context.longs)
  
    if len(context.shorts)==0:
        shortWeight = 0
    else:
        shortWeight = 0.5 / len(context.shorts)
    
    return (longWeight,shortWeight)
    
def makePipeline():
    
    # Base Universe
    baseUniverse = Q1500US()
    
    # Dollar Volume (30 Days) Grab the Info
    dollarVolume = AverageDollarVolume(window_length=30)
    
    # Grab the top 5% in avg dollar volume
    highDollarVolume = dollarVolume.percentile_between(90,100)
    
    # Create mask 
    baseAndDollarUniverse = baseUniverse & highDollarVolume
    
    # Calculate Stoch RSI fast and slow
    #fastk, fastd = talib.STOCHRSI(USEquityPricing.close, timeperiod=14, fastk_period=5, fastd_period=3, fastd_matype=0)

    
    # Stoch RSI Fast crosses up Stoch RSI slow
    
    
    
    # Calculate SMA 60 and SMA 200
    smaFast = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, mask=baseAndDollarUniverse)
    smaSlow = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, mask=baseAndDollarUniverse)
    
    
    # Filter to trade if SMA 60 crosses up SMA200 Buy and otherwise SELL
    percentSMADiff = (smaFast - smaSlow)/smaSlow
    shorts = percentSMADiff < 0
    longs = percentSMADiff > 0
    
    # Final securities to trade
    securitiesToTrade = (shorts | longs)
    
    # Return Pipeline
    return Pipeline(
        columns={
            'longs': longs,
            'shorts': shorts,
            'percentDifference':percentSMADiff
        },
        screen=securitiesToTrade
    )


def my_rebalance(context, data):
    
    for security in context.portfolio.positions:
        if security not in context.longs and security not in context.shorts and data.can_trade(security):
            #stochFast, stochSlow = talib.STOCHRSI(security['price'])
            #log.info("stochFast", stochFast);
            #log.info("stochSlow", stochSlow);
            order_target_percent(security, 0)
            
    for security in context.longs:
        if data.can_trade(security):
            print("security", security)
            order_target_percent(security, context.longWeight)
    
    for security in context.shorts:
        if data.can_trade(security):
            order_target_percent(security, context.shortWeight)
There was a runtime error.
4 responses

@Ray Trader,

How can I make the Talib to work with USEquityPricing here specially while making pipeline?

You can do this by creating a custom factor.
Something like this:

# Custom factor talib STOCH_RSI_FK  
from quantopian.pipeline import Pipeline, factors, filters, classifiers  
from quantopian.algorithm import attach_pipeline, pipeline_output  
from quantopian.pipeline.data.builtin import USEquityPricing  
from quantopian.pipeline.factors import CustomFactor  
import talib;  
# -------------------------------------------------------------------------------------------  
STK_SET = filters.StaticAssets(symbols('SPY', 'TLT')); PERIOD = 14; FK = 5; FD = 3; FDMA = 0;  
# -------------------------------------------------------------------------------------------  
class STOCH_RSI_FK(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = PERIOD + FK + FD + 1

    def compute(self, today, assets, out, close):  
        stoch_rsi_fk  = []  
        for C in close.T:  
            StochRsiFk = talib.STOCHRSI(C, PERIOD, FK, FD, FDMA)[0][-1]  
            stoch_rsi_fk.append(StochRsiFk) 

        out[:] = stoch_rsi_fk

def initialize(context):  
    fast_k = STOCH_RSI_FK(mask = STK_SET)  
    attach_pipeline(Pipeline({'fast_k': fast_k,}, screen = STK_SET), 'pipe')  

def before_trading_start(context, data):  
    output = pipeline_output('pipe')  
    fast_k = output.fast_k  
    record(fast_k = fast_k[0])  

If somebody can do it in a more elegant way please post it here.

This version uses pandas and applies the stochrsi as a lambda-expression. It seems to be a bit faster when traded with many symbols...

# Custom factor talib STOCH_RSI_FK  
from quantopian.pipeline import Pipeline, factors, filters, classifiers  
from quantopian.algorithm import attach_pipeline, pipeline_output  
from quantopian.pipeline.data.builtin import USEquityPricing  
from quantopian.pipeline.factors import CustomFactor  
import talib;  
import pandas as pd

# -------------------------------------------------------------------------------------------  
STK_SET = filters.StaticAssets(symbols('SPY', 'TLT')); PERIOD = 14; FK = 5; FD = 3; FDMA = 0;

# -------------------------------------------------------------------------------------------


class STOCH_RSI_FK(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = PERIOD + FK + FD + 1

    def compute(self, today, assets, out, C):  
        stoch_rsi_fk = pd.DataFrame(C).apply(lambda x: talib.STOCHRSI(x, PERIOD, FK, FD, FDMA)[0][-1], axis=0)  
        out[:] = stoch_rsi_fk


def initialize(context):  
    fast_k = STOCH_RSI_FK(mask=STK_SET)  
    attach_pipeline(Pipeline({'fast_k': fast_k, }, screen=STK_SET), 'pipe')


def before_trading_start(context, data):  
    output = pipeline_output('pipe')  
    fast_k = output.fast_k  
    record(fast_k=fast_k[0])  

P. S.:
Be aware that talib doesn't handle nans very well, so in order to avoid exceptions you need to get rid of them first. In my version I would do something like this:

class STOCH_RSI_FK(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = PERIOD + FK + FD + 1

    def compute(self, today, assets, out, C):  
        # Set all values for a symbol to zero if it has nans before passing them to talib:  
        C[np.isnan(C).any(),:] = 0

        stoch_rsi_fk = pd.DataFrame(C).apply(lambda x: talib.STOCHRSI(x, PERIOD, FK, FD, FDMA)[0][-1], axis=0)  
        out[:] = stoch_rsi_fk

In Vladimir's version you could do it that way:

class STOCH_RSI_FK(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = PERIOD + FK + FD + 1

    def compute(self, today, assets, out, close):  
        stoch_rsi_fk  = []  
        for C in close.T:  
            # If there are any nans, just append nan and don't pass them to talib  
            if np.isnan(C).any():  
                stoch_rsi_fk.append(np.nan)  
                continue  
            StochRsiFk = talib.STOCHRSI(C, PERIOD, FK, FD, FDMA)[0][-1]  
            stoch_rsi_fk.append(StochRsiFk)  
        out[:] = stoch_rsi_fk


And if you want both fastk and fastd as outputs of the same CustomFactor, you can that too

class STOCH_RSI(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = PERIOD + FK + FD + 1  
    # If you want 2 outputs, you need to add them here:  
    outputs = ['fastk', 'fastd']

    def compute(self, today, assets, out, C):  
        # Set all values for a symbol to zero if it has nans:  
        C[np.isnan(C).any(),:] = 0  
        df = pd.DataFrame(C)

        fastk = df.apply(lambda x: talib.STOCHRSI(x, PERIOD, FK, FD, FDMA)[0][-1], axis=0)  
        fastd = df.apply(lambda x: talib.STOCHRSI(x, PERIOD, FK, FD, FDMA)[1][-1], axis=0)

        out[:].fastk = fastk  
        out[:].fastd = fastd

fastk, slowk = STOCH_RSI()

Thank you all. I will take some time to go through this.