The error "input lengths are different" is raised when the lengths of the three inputs to the talib ADX function are not equal. The function needs the high, low, and price data to all have the same number of days of data.
How does this happen and why does it only give an error at certain times? The culprit is missing data. There can be instances where price data isn't available or valid and the algo needs to account for that. Adding the 'dropna' method attempted to address this but created its own problems. If there is ever any data missing in one of the three fetches then the 'dropna' method will simply delete that row. That data will now have fewer rows than the others and therefore the talib.ADX function will fail.
So, the issue is what to do if there is ever missing data. The talib.ADX function doesn't like being passed NaN values so doing nothing is not an option. Maybe forward fill any missing data? Maybe don't calculate ADX if there are any NaNs?
However, if one simply wants to drop any rows with NaNs then one would need to drop that row for ALL the data if ANY field has a NaN. This is easiest to accomplish if all the data were in a single dataframe (rather than three separate series). This has the side benefit of speeding up the data fetch too. Something like this could work.
# fetch multiple data fields with a single call
price_data_panel = data.history(context.MY_SECURITY, fields=["high", "low", "price"], bar_count=4, frequency="1d")
# the result is a pandas panel. maybe turn it into a dataframe which is a bit easier to use
price_data_df = price_data_panel.to_frame()
# use dropna to delete rows where any value is NaN
price_data_df.dropna(inplace=True)
# now use the dataframe columns in the talib.ADX function
ta_ADX = talib.ADX(price_data_df.high, price_data_df.low, price_data_df.price, 2)
One issue this doesn't address is the situation where too many rows are dropped and the talib.ADX function doesn't have enough data. Save that for a later day...
One should maybe consider doing this in a custom factor using pipeline rather than using the data.history method. It will be faster and also easier to combine and weight with other signals.
Hope this helps. Good luck.