Ta-lib william indicator backtesting

//// indicator function using ta-lib, this file is saved here → library/technicals/indicators2
import talib as ta
import numpy as np
import bisect

def william(px, lookback):
sig = ta.WILLR(px.open.values, px.high.values, px.low.values, timeperiod=lookback)
return sig[-1]
////

///strategy code for backtesting
from zipline.api import(symbol,
get_datetime,
order_target_percent,
schedule_function,
date_rules,
time_rules,
attach_pipeline,
pipeline_output,
set_commission,
set_slippage,
get_open_orders,
cancel_order,
)
from library.technicals.indicators2 import william
from zipline.finance import commission, slippage

def initialize(context):
# universe selection
context.securities = [symbol(‘BPCL’),symbol(‘AXISBANK’), symbol(“ICICIBANK”), symbol(‘TATASTEEL’)]

# define strategy parameters
context.params = {'indicator_lookback':375,
				  'indicator_freq':'1m',
				  'buy_signal_threshold':0.5,
				  'sell_signal_threshold':-0.5,
				  'william_period':14,
				  'trade_freq':5,
				  'leverage':2}

# variable to control trading frequency
context.bar_count = 0

# variables to track signals and target portfolio
context.signals = dict((security,0) for security in context.securities)
context.target_position = dict((security,0) for security in context.securities)

# set trading cost and slippage to zero
set_commission(commission.PerShare(cost=0.0, min_trade_cost=0.0))
set_slippage(slippage.FixedSlippage(0.00))

def handle_data(context, data):
context.bar_count = context.bar_count + 1
if context.bar_count < context.params[‘trade_freq’]:
return

# time to trade, call the strategy function
context.bar_count = 0
run_strategy(context, data)

def run_strategy(context, data):
generate_signals(context, data)
generate_target_position(context, data)
rebalance(context, data)

def rebalance(context,data):
for security in context.securities:
order_target_percent(security, context.target_position[security])

def generate_target_position(context, data):
num_secs = len(context.securities)
weight = round(1.0/num_secs,2)*context.params[‘leverage’]

for security in context.securities:
	if context.signals[security] > context.params['buy_signal_threshold']:
		context.target_position[security] = weight
	elif context.signals[security] < context.params['sell_signal_threshold']:
		context.target_position[security] = -weight
	else:
		context.target_position[security] = 0

def generate_signals(context, data):
price_data = data.history(context.securities, ‘close’,
context.params[‘indicator_lookback’], context.params[‘indicator_freq’])

for security in context.securities:
	px = price_data.loc[:,security].values
	context.signals[security] = signal_function(px, context.params)

def signal_function(px, params):
ind1 = william(px, params[“william_period”])

if ind1 < -90:
	return 1
elif ind1 > -10:
	return -1
else:
	return 0

////

/// error message while backtesting
line 56, in handle_data
‘numpy.ndarray’ object has no attribute ‘open’
////

can anyone help me with this?
i want to backtest my strategy with william indicator using talib.

I suggest you familiarize yourself with Numpy and TA-lib first, as well as go through all of the 'getting started' on blueshift help. Also please go through the samples in our GitHub repo like this one for concrete examples.



Your code has multiple issues - you attempt to compute william's R with a wrong signature, the function from TA-Lib takes high, low, close. Second, you want to pass open, high and low to the indicator function, but query only for 'close' field from the 'data.history' method. Finally you pass a numpy array to your signal function, but expect a dataframe - price_data.loc[:,security]  is a Series and calling .values on it convert this to a numpy array.

thank you sir