"""Implements mean reversion features."""importnumpyasnpfromnumpy.typingimportNDArrayfromnumbaimportnjit,prange
[docs]@njit(nogil=True)defvwap_distance(close:NDArray[np.float64],volume:NDArray[np.float64],n_periods:int,is_log:bool)->NDArray[np.float64]:""" Calculate the distance of the current price from the VWAP (Volume Weighted Average Price). The VWAP is calculated over a specified number of periods, and the distance is expressed as a percentage. :param close: close price series :param volume: corresponding volume series :param n_periods: number of periods to calculate VWAP :param is_log: if True, calculate log distance :return: array of distances from VWAP """n=close.sizeout=np.empty(n,np.float64)out[:n_periods]=np.nan# fill first windowifn<n_periods:returnoutwsum=0.0# Σ P·Vvsum=0.0# Σ V# initial windowforkinrange(n_periods):wsum+=close[k]*volume[k]vsum+=volume[k]ifvsum>0:out[n_periods-1]=close[n_periods-1]/(wsum/vsum)-1.0# rolling updateforiinrange(n_periods,n):left_pv=close[i-n_periods]*volume[i-n_periods]wsum+=close[i]*volume[i]-left_pvvsum+=volume[i]-volume[i-n_periods]ifvsum>0:ifis_log:out[i]=np.log(close[i]/(wsum/vsum))else:out[i]=close[i]/(wsum/vsum)-1.0else:# empty 4-h window (extremely rare)out[i]=out[i-1]returnout