HULL MOVING AVERAGE

Hi 



I am trying to build Hull Moving Average (HMA) but not getting clue about it. pLEAES ADVISE

Hi Ahmed,



You can calculate the HMA using the formula mentioned here by Alan Hull (the creator of HMA).



It uses WMA (weighted moving average), where WMA (price_series, 25) means WMA of price_series over 25 periods.



Using the formula,

HMA (price_series, n) = WMA(

                                                    2 * WMA (price_series, n/2) - WMA (price_series, n),

                                                    Integer(SQRT(n))

                                                )





The program logic for WMA can be referred to here.



Hope this helps!

Hi Gurav,



Thanks to answer my query. I am trying to code it in the python and stucking there, I will try to code the logic in python and getting stuck as I am new to python.

Hi Ahmed!



That's great! The algorithm attached above from tradingview is in PINE language and is somewhat close to Python. 



Do try to code that logic. You can refer to the Python basic course to understand how the data is handled in a Pandas data frame.



Let me know if you are stuck in any particular step!

Hi Gaurav,



I am writing the below code to get the WMA but I am getting the error ValueError: operands could not be broadcast together with shapes (5,) (100,)





def wma_calc(ser,n):

    

    weights = np.arange(1, n+1)             # n + 1 bcuz python startss from 0 in the list/arange function 

    print(ser)

    print (weights)



    return sum(weights * ser) / (n*(n+1)/2)

    



    



def main (in_ticker, in_period, in_interval,  in_outputsize):

    

    ts_data, ts_meta_data = ts.get_intraday(symbol = in_ticker, interval = in_interval)

    dfts = ts_data.copy() # data must be copied before using tran#sp#ose to keep the data intact

    dfts.columns = ["open", "high", "low", "close", "volume"]

    

    #dfts['wma'] = dfts['close'].rolling(window = (in_period)).apply(wma_calc(dfts['close'],in_period))

    dfts['wma'] = dfts['close'].rolling(in_period)).apply(wma_calc(dfts['close'],in_period))

main(in_ticker = 'MSFT', in_period = 5, in_interval = '60min', in_outputsize = 'full')

Hi Ahmed,



The full error text would be helpful in the debug process.



Having said that, the use of apply seems incorrect in the second last line. You can refer to this resource to use rolling apply with arguments.



Hope this helps!

here is the full message. it is broadcasting error and it seems it is related to numpy. 



 File "C:\Users\afzlo.spyder-py3\scripts\hull\hull4.py", line 38, in <module>

    main(in_ticker = 'MSFT', in_period = 5, in_interval = '60min', in_outputsize = 'full')



  File "C:\Users\afzlo.spyder-py3\scripts\hull\hull4.py", line 37, in main

    dfts['wma'] = dfts['close'].rolling(in_period).apply(wma_calc(dfts['close'],in_period))



  File "C:\Users\afzlo.spyder-py3\scripts\hull\hull4.py", line 25, in wma_calc

    return sum(weights * ser) / (n*(n+1)/2)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\series.py", line 682, in array_ufunc

    result = ops.maybe_dispatch_ufunc_to_dunder_op(



  File "pandas_libs\ops_dispatch.pyx", line 91, in pandas.libs.ops_dispatch.maybe_dispatch_ufunc_to_dunder_op



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\ops\common.py", line 65, in new_method

    return method(self, other)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\ops_init
.py", line 343, in wrapper

    result = arithmetic_op(lvalues, rvalues, op)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\ops\array_ops.py", line 190, in arithmetic_op

    res_values = na_arithmetic_op(lvalues, rvalues, op)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\ops\array_ops.py", line 143, in na_arithmetic_op

    result = expressions.evaluate(op, left, right)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\computation\expressions.py", line 233, in evaluate

    return _evaluate(op, op_str, a, b)  # type: ignore



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\computation\expressions.py", line 119, in _evaluate_numexpr

    result = _evaluate_standard(op, op_str, a, b)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\computation\expressions.py", line 68, in _evaluate_standard

    return op(a, b)



  File "C:\Users\afzlo\anaconda3\lib\site-packages\pandas\core\ops\roperator.py", line 17, in rmul

    return right * left



ValueError: operands could not be broadcast together with shapes (5,) (100,) 



 

def wma_calc(ser, n):



    # n + 1 bcuz python startss from 0 in the list/arange function

    weights = np.arange(1, n+1)

    print(ser)

    print(weights)

    return sum(weights * ser) / (n*(n+1)/2)






In the code, you are multiplying weights with ser. You passed n=5, which is used in the calculation of weights. And ser=dfts['close'], which of length 100. So basically you are multiplying two arrays of different dimension. You need to make the dimension of both arrays same.



Try this:



def wma_calc(ser, n):



    # n + 1 bcuz python startss from 0 in the list/arange function

    weights = np.arange(1, n+1, 100)

    print(ser)

    print(weights)

    return sum(weights * ser) / (n*(n+1)/2)




Can read more about the error here.