Back to Community
Price Data Absent For Equities

I just noticed the the price data for equities were missing in a lot of instances. This makes it impossible for talib.RSI to be used in these instances on a minute level. Is there a way to fix this? I even tried writing my own RSI function and I get the same result.

Clone Algorithm
5
Loading...
Backtest from to with initial capital
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
# Backtest ID: 59d9333dcc5efc54521167cb
There was a runtime error.
4 responses

Try:

dvol = AverageDollarVolume(window_length=3)  # use 3 or more 

If that doesn't resolve it, also see if this helps:

    op = data.history(context.security_list, 'open',  5, '1d').ffill()  

It does take care of op in the case of DXYN which was nan in debugger on first break due to no volume all day, no trades on the day requested with 1. It had trading on the previous day so , 5, '1d').ffill() copies the previous value to the current, replacing the nan and 2 would have worked. So dvol with window_length=1 may not be doing what you want, it allowed a stock through with no trades all day.

If you switch to minute level, regarding ffill(), considering the possibility of a bunch of nans at the head of whatever window, add .bfill() on the end of that also to backfill them.

I'd probably compare an RSI factor, maybe adding nanfill which also has a way to count nans, could be used to decide what percentage of nan instances are acceptable before excluding the equity, instead of too much ffill. That might be pretty cool. Other routes, Q500US etc, and/or [class] Volume factors beyond the built-in AverageDollarVolume you're already using.

Sweet! Thanks. I'll try ffill(). I didn't realize you could even do that.

You are the man! That worked beautifully! Question? If I set a stop loss or try to do a moving average comparison at a minute level, and there is no price data to compare against, as was in the case here in which I did not forward fill, does that mean that the comparison will return false, even though the price hasn't changed?

Correct if I understand you. You can do things like this in the debugger to know for sure on things like that:

> np.nan > 2  
   False  
> np.nan < 2  
   False  
> np.nan == 2  
   False  
> np.nan == np.nan  
   False  
> np.nan != np.nan  
   True  

So when nan is present, everything's pretty much always false, you're right, except it isn't equal to itself, and that can be useful. If I wanted to avoid np, could do if some_var != some_var and know it's a nan if True.

I'll share with you something I did with your code to toss some ideas out there for use with the debugger. Since DXYN is a handy available example of a nan here, this can force it to be in the mix (or not) even when pipeline screens it out, to be able to see what changes in the code would do, going step by step in the debugger:

def my_rebalance(context,data):  
    if sid(2384) not in context.security_list:  
        print 'DXYN absent'  
    inject_dxyn = 1   # on or off  
    if inject_dxyn:  
        if sid(2384) not in context.security_list:   # 2384 is DXYN  
            context.security_list.append(sid(2384))

    op = data.history(context.security_list, 'open',  2, '1d') #.ffill().bfill()  
    pc = data.history(context.security_list, 'price', 2, '1d') #.ffill().bfill()

    if inject_dxyn:  
        context.security_list = [sid(2384)]  
    for s in context.security_list:  
        cp = data.current(s,'price')  ; cp=cp  
        if op[s][-1] > pc[s][-2] * GAP_UP:  
            context.security_listF[s] = s  
            context.rsi[s] = 100  

That cp=cp is just to quiet the variable unused warning.

Then in the watch window, some ideas for things to place there:

s                  (I almost always have this first)  
str(op[s].values)  
str(pc[s].values)  
pc[s][-2] * GAP_UP  

By the way, did you know you can even have a function in the watch window folks?
As an example, and you just have to fix this up, replacing ma and period and then in watch, it should show the return value:
getRSI(ma, s, period)
You can also run functions from the debugger console feeding them different inputs. Just thought it might be worth mentioning.