From 81834e1672547631b0f470a3c36b6abe8a3bbac3 Mon Sep 17 00:00:00 2001 From: Andy Date: Sun, 7 Apr 2024 00:07:06 +0200 Subject: [PATCH] adding cache fot njit decorators - the result is a 3x speed improvement in with pytest --- jesse/indicators/bandpass.py | 2 +- jesse/indicators/cg.py | 2 +- jesse/indicators/correlation_cycle.py | 2 +- jesse/indicators/cwma.py | 2 +- jesse/indicators/damiani_volatmeter.py | 2 +- jesse/indicators/edcf.py | 2 +- jesse/indicators/efi.py | 2 +- jesse/indicators/emd.py | 4 ++-- jesse/indicators/epma.py | 2 +- jesse/indicators/frama.py | 2 +- jesse/indicators/gauss.py | 2 +- jesse/indicators/heikin_ashi_candles.py | 2 +- jesse/indicators/high_pass.py | 2 +- jesse/indicators/high_pass_2_pole.py | 2 +- jesse/indicators/hurst_exponent.py | 2 +- jesse/indicators/hwma.py | 2 +- jesse/indicators/itrend.py | 2 +- jesse/indicators/jma.py | 2 +- jesse/indicators/lrsi.py | 2 +- jesse/indicators/maaq.py | 2 +- jesse/indicators/mcginley_dynamic.py | 2 +- jesse/indicators/mwdx.py | 2 +- jesse/indicators/nma.py | 2 +- jesse/indicators/pma.py | 2 +- jesse/indicators/reflex.py | 2 +- jesse/indicators/rma.py | 2 +- jesse/indicators/rsx.py | 2 +- jesse/indicators/sqwma.py | 2 +- jesse/indicators/srwma.py | 2 +- jesse/indicators/supersmoother.py | 2 +- jesse/indicators/supersmoother_3_pole.py | 2 +- jesse/indicators/supertrend.py | 2 +- jesse/indicators/trendflex.py | 2 +- jesse/indicators/vi.py | 2 +- jesse/indicators/vlma.py | 2 +- jesse/indicators/voss.py | 2 +- jesse/indicators/vpwma.py | 2 +- 37 files changed, 38 insertions(+), 38 deletions(-) diff --git a/jesse/indicators/bandpass.py b/jesse/indicators/bandpass.py index 62e20260e..24967cf82 100644 --- a/jesse/indicators/bandpass.py +++ b/jesse/indicators/bandpass.py @@ -46,7 +46,7 @@ def bandpass(candles: np.ndarray, period: int = 20, bandwidth: float = 0.3, sou return BandPass(bp[-1], bp_normalized[-1], signal[-1], trigger[-1]) -@njit +@njit(cache=True) def bp_fast(source, hp, alpha, beta): # Function is compiled to machine code when called the first time bp = np.copy(hp) diff --git a/jesse/indicators/cg.py b/jesse/indicators/cg.py index 2025456de..2c9b6d3b4 100644 --- a/jesse/indicators/cg.py +++ b/jesse/indicators/cg.py @@ -26,7 +26,7 @@ def cg(candles: np.ndarray, period: int = 10, source_type: str = "close", sequen return same_length(candles, res) if sequential else res[-1] -@njit +@njit(cache=True) def go_fast(source, period): # Function is compiled to machine code when called the first time res = np.full_like(source, fill_value=np.nan) for i in range(source.size): diff --git a/jesse/indicators/correlation_cycle.py b/jesse/indicators/correlation_cycle.py index 3ec165e44..cd5d39622 100644 --- a/jesse/indicators/correlation_cycle.py +++ b/jesse/indicators/correlation_cycle.py @@ -39,7 +39,7 @@ def correlation_cycle(candles: np.ndarray, period: int = 20, threshold: int = 9, return CC(realPart[-1], imagPart[-1], angle[-1], state[-1]) -@njit +@njit(cache=True) def go_fast(source, period): # Function is compiled to machine code when called the first time # Correlation Cycle Function PIx2 = 4.0 * np.arcsin(1.0) diff --git a/jesse/indicators/cwma.py b/jesse/indicators/cwma.py index 4cec25768..8117ca18e 100644 --- a/jesse/indicators/cwma.py +++ b/jesse/indicators/cwma.py @@ -31,7 +31,7 @@ def cwma(candles: np.ndarray, period: int = 14, source_type: str = "close", sequ return res if sequential else res[-1] -@njit +@njit(cache=True) def vpwma_fast(source, period): newseries = np.copy(source) for j in range(period + 1, source.shape[0]): diff --git a/jesse/indicators/damiani_volatmeter.py b/jesse/indicators/damiani_volatmeter.py index a1c99340c..eea44cca5 100644 --- a/jesse/indicators/damiani_volatmeter.py +++ b/jesse/indicators/damiani_volatmeter.py @@ -42,7 +42,7 @@ def damiani_volatmeter(candles: np.ndarray, vis_atr: int = 13, vis_std: int = 20 return DamianiVolatmeter(vol[-1], t[-1]) -@njit +@njit(cache=True) def damiani_volatmeter_fast(source, sed_std, atrvis, atrsed, vis_std, threshold): # Function is compiled to machine code when called the first time lag_s = 0.5 diff --git a/jesse/indicators/edcf.py b/jesse/indicators/edcf.py index b9883dc1b..5f92ccb05 100644 --- a/jesse/indicators/edcf.py +++ b/jesse/indicators/edcf.py @@ -31,7 +31,7 @@ def edcf(candles: np.ndarray, period: int = 15, source_type: str = "hl2", sequen return res if sequential else res[-1] -@njit +@njit(cache=True) def edcf_fast(source, period): newseries = np.full_like(source, np.nan) diff --git a/jesse/indicators/efi.py b/jesse/indicators/efi.py index 1d12ff9cb..544908241 100644 --- a/jesse/indicators/efi.py +++ b/jesse/indicators/efi.py @@ -31,7 +31,7 @@ def efi(candles: np.ndarray, period: int = 13, source_type: str = "close", seque return res_with_nan if sequential else res_with_nan[-1] -@njit +@njit(cache=True) def efi_fast(source, volume): dif = np.zeros(source.size - 1) for i in range(1, source.size): diff --git a/jesse/indicators/emd.py b/jesse/indicators/emd.py index 89efc133a..a9e739753 100644 --- a/jesse/indicators/emd.py +++ b/jesse/indicators/emd.py @@ -39,7 +39,7 @@ def emd(candles: np.ndarray, period: int = 20, delta=0.5, fraction=0.1, sequenti return EMD(avg_peak[-1], mean[-1], avg_valley[-1]) -@njit +@njit(cache=True) def bp_fast(price, period, delta): # bandpass filter beta = np.cos(2 * np.pi / period) @@ -55,7 +55,7 @@ def bp_fast(price, period, delta): return bp -@njit +@njit(cache=True) def peak_valley_fast(bp, price): peak = np.copy(bp) valley = np.copy(bp) diff --git a/jesse/indicators/epma.py b/jesse/indicators/epma.py index 1fd7b7a75..605c54db8 100644 --- a/jesse/indicators/epma.py +++ b/jesse/indicators/epma.py @@ -32,7 +32,7 @@ def epma(candles: np.ndarray, period: int = 11, offset: int = 4, source_type: st return res if sequential else res[-1] -@njit +@njit(cache=True) def epma_fast(source, period, offset): newseries = np.copy(source) for j in range(period + offset + 1 , source.shape[0]): diff --git a/jesse/indicators/frama.py b/jesse/indicators/frama.py index a300cef02..92b05005d 100644 --- a/jesse/indicators/frama.py +++ b/jesse/indicators/frama.py @@ -36,7 +36,7 @@ def frama(candles: np.ndarray, window: int = 10, FC: int = 1, SC: int = 300, seq return res[-1] -@njit +@njit(cache=True) def frame_fast(candles, n, SC, FC): w = np.log(2.0 / (SC + 1)) diff --git a/jesse/indicators/gauss.py b/jesse/indicators/gauss.py index 0a64aae15..820b97b2b 100644 --- a/jesse/indicators/gauss.py +++ b/jesse/indicators/gauss.py @@ -36,7 +36,7 @@ def gauss(candles: np.ndarray, period: int = 14, poles: int = 4, source_type: st return res if sequential else res[-1] -@njit +@njit(cache=True) def gauss_fast(source, period, poles): N = source.size source = source[~np.isnan(source)] diff --git a/jesse/indicators/heikin_ashi_candles.py b/jesse/indicators/heikin_ashi_candles.py index 4b2e533a0..a66955ff9 100755 --- a/jesse/indicators/heikin_ashi_candles.py +++ b/jesse/indicators/heikin_ashi_candles.py @@ -24,7 +24,7 @@ def heikin_ashi_candles(candles: np.ndarray, sequential: bool = False) -> HA: else: return HA(open[-1], close[-1], high[-1], low[-1]) -@njit +@njit(cache=True) def ha_fast(source): # index consts to facilitate reading the code diff --git a/jesse/indicators/high_pass.py b/jesse/indicators/high_pass.py index e4e3f4122..55c1f6feb 100644 --- a/jesse/indicators/high_pass.py +++ b/jesse/indicators/high_pass.py @@ -33,7 +33,7 @@ def high_pass(candles: np.ndarray, period: int = 48, source_type: str = "close", return None if np.isnan(hpf[-1]) else hpf[-1] -@njit +@njit(cache=True) def high_pass_fast(source, period): # Function is compiled to machine code when called the first time k = 1 alpha = 1 + (np.sin(2 * np.pi * k / period) - 1) / np.cos(2 * np.pi * k / period) diff --git a/jesse/indicators/high_pass_2_pole.py b/jesse/indicators/high_pass_2_pole.py index f00eae1b4..a9d3c16bd 100644 --- a/jesse/indicators/high_pass_2_pole.py +++ b/jesse/indicators/high_pass_2_pole.py @@ -34,7 +34,7 @@ def high_pass_2_pole(candles: np.ndarray, period: int = 48, source_type: str = " return None if np.isnan(hpf[-1]) else hpf[-1] -@njit +@njit(cache=True) def high_pass_2_pole_fast(source, period, K=0.707): # Function is compiled to machine code when called the first time alpha = 1 + (np.sin(2 * np.pi * K / period) - 1) / np.cos(2 * np.pi * K / period) newseries = np.copy(source) diff --git a/jesse/indicators/hurst_exponent.py b/jesse/indicators/hurst_exponent.py index b30feeb12..41400bb5d 100644 --- a/jesse/indicators/hurst_exponent.py +++ b/jesse/indicators/hurst_exponent.py @@ -37,7 +37,7 @@ def hurst_exponent(candles: np.ndarray, min_chunksize: int = 8, max_chunksize: i return None if np.isnan(h) else h -@njit +@njit(cache=True) def hurst_rs(x, min_chunksize, max_chunksize, num_chunksize): """Estimate the Hurst exponent using R/S method. Estimates the Hurst (H) exponent using the R/S method from the time series. diff --git a/jesse/indicators/hwma.py b/jesse/indicators/hwma.py index 26acf70f5..e25366926 100644 --- a/jesse/indicators/hwma.py +++ b/jesse/indicators/hwma.py @@ -37,7 +37,7 @@ def hwma(candles: np.ndarray, na: float = 0.2, nb: float = 0.1, nc: float = 0.1, return res if sequential else res[-1] -@njit +@njit(cache=True) def hwma_fast(source, na, nb, nc): last_a = last_v = 0 last_f = source[0] diff --git a/jesse/indicators/itrend.py b/jesse/indicators/itrend.py index 01c8f6c9f..85c3a1279 100644 --- a/jesse/indicators/itrend.py +++ b/jesse/indicators/itrend.py @@ -31,7 +31,7 @@ def itrend(candles: np.ndarray, alpha: float = 0.07, source_type: str = "hl2", s return ITREND(signal[-1], it[-1], trigger[-1]) -@njit +@njit(cache=True) def itrend_fast(source, alpha): it = np.copy(source) for i in range(2, 7): diff --git a/jesse/indicators/jma.py b/jesse/indicators/jma.py index c997e4925..5eec83901 100644 --- a/jesse/indicators/jma.py +++ b/jesse/indicators/jma.py @@ -28,7 +28,7 @@ def jma(candles: np.ndarray, period:int=7, phase:float=50, power:int=2, source_t return res if sequential else res[-1] -@njit +@njit(cache=True) def jma_helper(src, phaseRatio, beta, alpha): jma_val = np.copy(src) diff --git a/jesse/indicators/lrsi.py b/jesse/indicators/lrsi.py index 08c0f05dd..a013ed0ff 100644 --- a/jesse/indicators/lrsi.py +++ b/jesse/indicators/lrsi.py @@ -26,7 +26,7 @@ def lrsi(candles: np.ndarray, alpha: float = 0.2, sequential: bool = False) -> U return None if np.isnan(rsi[-1]) else rsi[-1] -@njit +@njit(cache=True) def lrsi_fast(alpha, candles): price = (candles[:, 3] + candles[:, 4]) / 2 l0 = np.copy(price) diff --git a/jesse/indicators/maaq.py b/jesse/indicators/maaq.py index 96cec8d28..fff64da5c 100644 --- a/jesse/indicators/maaq.py +++ b/jesse/indicators/maaq.py @@ -48,7 +48,7 @@ def maaq(candles: np.ndarray, period: int = 11, fast_period: int = 2, slow_perio return res if sequential else res[-1] -@njit +@njit(cache=True) def maaq_fast(source, temp, period): newseries = np.copy(source) for i in range(period, source.shape[0]): diff --git a/jesse/indicators/mcginley_dynamic.py b/jesse/indicators/mcginley_dynamic.py index 7f3c5ab99..2eeccb239 100644 --- a/jesse/indicators/mcginley_dynamic.py +++ b/jesse/indicators/mcginley_dynamic.py @@ -33,7 +33,7 @@ def mcginley_dynamic(candles: np.ndarray, period: int = 10, k: float = 0.6, sour return mg if sequential else mg[-1] -@njit +@njit(cache=True) def md_fast(source, k, period): mg = np.full_like(source, np.nan) for i in range(source.size): diff --git a/jesse/indicators/mwdx.py b/jesse/indicators/mwdx.py index e4c7ad064..5e4de2ff5 100644 --- a/jesse/indicators/mwdx.py +++ b/jesse/indicators/mwdx.py @@ -34,7 +34,7 @@ def mwdx(candles: np.ndarray, factor: float = 0.2, source_type: str = "close", s return res if sequential else res[-1] -@njit +@njit(cache=True) def mwdx_fast(source, fac): newseries = np.copy(source) for i in range(1, source.shape[0]): diff --git a/jesse/indicators/nma.py b/jesse/indicators/nma.py index 8a5153dd0..7c47e156b 100644 --- a/jesse/indicators/nma.py +++ b/jesse/indicators/nma.py @@ -29,7 +29,7 @@ def nma(candles: np.ndarray, period: int = 40, source_type: str = "close", seque return res if sequential else res[-1] -@njit +@njit(cache=True) def nma_fast(source, period): # Ensure source values are positive before taking log source = np.clip(source, a_min=1e-10, a_max=None) diff --git a/jesse/indicators/pma.py b/jesse/indicators/pma.py index 6a93a04a4..5d7c097b8 100644 --- a/jesse/indicators/pma.py +++ b/jesse/indicators/pma.py @@ -33,7 +33,7 @@ def pma(candles: np.ndarray, source_type: str = "hl2", sequential: bool = False) return PMA(predict[-1], trigger[-1]) -@njit +@njit(cache=True) def pma_fast(source): predict = np.full_like(source, np.nan) trigger = np.full_like(source, np.nan) diff --git a/jesse/indicators/reflex.py b/jesse/indicators/reflex.py index 29bc17c92..4a4a39aca 100644 --- a/jesse/indicators/reflex.py +++ b/jesse/indicators/reflex.py @@ -37,7 +37,7 @@ def reflex(candles: np.ndarray, period: int = 20, source_type: str = "close", se return None if np.isnan(rf[-1]) else rf[-1] -@njit +@njit(cache=True) def reflex_fast(ssf, period): rf = np.full_like(ssf, 0) ms = np.full_like(ssf, 0) diff --git a/jesse/indicators/rma.py b/jesse/indicators/rma.py index f4756bcee..2494edb15 100644 --- a/jesse/indicators/rma.py +++ b/jesse/indicators/rma.py @@ -34,7 +34,7 @@ def rma(candles: np.ndarray, length: int = 14, source_type="close", sequential=F return res if sequential else res[-1] -@njit +@njit(cache=True) def rma_fast(source, _length): alpha = 1 / _length newseries = np.copy(source) diff --git a/jesse/indicators/rsx.py b/jesse/indicators/rsx.py index 8b6aa44ba..f95bc8deb 100644 --- a/jesse/indicators/rsx.py +++ b/jesse/indicators/rsx.py @@ -26,7 +26,7 @@ def rsx(candles: np.ndarray, period: int = 14, source_type: str = "close", seque return res if sequential else res[-1] -@njit +@njit(cache=True) def rsx_fast(source, period): # variables f0 = 0 diff --git a/jesse/indicators/sqwma.py b/jesse/indicators/sqwma.py index aea84d1ca..af8b78c25 100644 --- a/jesse/indicators/sqwma.py +++ b/jesse/indicators/sqwma.py @@ -31,7 +31,7 @@ def sqwma(candles: np.ndarray, period: int = 14, source_type: str = "close", seq return res if sequential else res[-1] -@njit +@njit(cache=True) def sqwma_fast(source, period): newseries = np.copy(source) for j in range(period + 1, source.shape[0]): diff --git a/jesse/indicators/srwma.py b/jesse/indicators/srwma.py index 985821bf6..e42b69b9f 100644 --- a/jesse/indicators/srwma.py +++ b/jesse/indicators/srwma.py @@ -31,7 +31,7 @@ def srwma(candles: np.ndarray, period: int = 14, source_type: str = "close", seq return res if sequential else res[-1] -@njit +@njit(cache=True) def srwma_fast(source, period): newseries = np.copy(source) for j in range(period + 1, source.shape[0]): diff --git a/jesse/indicators/supersmoother.py b/jesse/indicators/supersmoother.py index 49582c274..ca1227aac 100644 --- a/jesse/indicators/supersmoother.py +++ b/jesse/indicators/supersmoother.py @@ -33,7 +33,7 @@ def supersmoother(candles: np.ndarray, period: int = 14, source_type: str = "clo return res if sequential else res[-1] -@njit +@njit(cache=True) def supersmoother_fast(source, period): a = np.exp(-1.414 * np.pi / period) b = 2 * a * np.cos(1.414 * np.pi / period) diff --git a/jesse/indicators/supersmoother_3_pole.py b/jesse/indicators/supersmoother_3_pole.py index c2703e05e..bde8d988c 100644 --- a/jesse/indicators/supersmoother_3_pole.py +++ b/jesse/indicators/supersmoother_3_pole.py @@ -37,7 +37,7 @@ def supersmoother_3_pole(candles: np.ndarray, period: int = 14, source_type: str return res if sequential else res[-1] -@njit +@njit(cache=True) def supersmoother_fast(source, period): a = np.exp(-np.pi / period) b = 2 * a * np.cos(1.738 * np.pi / period) diff --git a/jesse/indicators/supertrend.py b/jesse/indicators/supertrend.py index 4813ecbe4..faa32237b 100644 --- a/jesse/indicators/supertrend.py +++ b/jesse/indicators/supertrend.py @@ -32,7 +32,7 @@ def supertrend(candles: np.ndarray, period: int = 10, factor: float = 3, sequent return SuperTrend(super_trend[-1], changed[-1]) -@njit +@njit(cache=True) def supertrend_fast(candles, atr, factor, period): # Calculation of SuperTrend upper_basic = (candles[:, 3] + candles[:, 4]) / 2 + (factor * atr) diff --git a/jesse/indicators/trendflex.py b/jesse/indicators/trendflex.py index 7659c4e00..0daaf2160 100644 --- a/jesse/indicators/trendflex.py +++ b/jesse/indicators/trendflex.py @@ -38,7 +38,7 @@ def trendflex(candles: np.ndarray, period: int = 20, source_type: str = "close", return None if np.isnan(tf[-1]) else tf[-1] -@njit +@njit(cache=True) def trendflex_fast(ssf, period): tf = np.full_like(ssf, 0) ms = np.full_like(ssf, 0) diff --git a/jesse/indicators/vi.py b/jesse/indicators/vi.py index c8a88310b..2f956e655 100644 --- a/jesse/indicators/vi.py +++ b/jesse/indicators/vi.py @@ -28,7 +28,7 @@ def vi(candles: np.ndarray, period: int = 14, sequential: bool = False) -> VI: return VI(vpn_with_nan[-1], vmn_with_nan[-1]) -@njit +@njit(cache=True) def vi_fast(candles, period): candles_close = candles[:, 2] candles_high = candles[:, 3] diff --git a/jesse/indicators/vlma.py b/jesse/indicators/vlma.py index 2be732482..5dc5e84e0 100644 --- a/jesse/indicators/vlma.py +++ b/jesse/indicators/vlma.py @@ -52,7 +52,7 @@ def vlma(candles: np.ndarray, min_period: int = 5, max_period: int = 50, matype: return res if sequential else res[-1] -@njit +@njit(cache=True) def vlma_fast(source, a, b, c, d, min_period, max_period): newseries = np.copy(source) period = np.zeros_like(source) diff --git a/jesse/indicators/voss.py b/jesse/indicators/voss.py index 4a7602cc2..8e1e26f0d 100644 --- a/jesse/indicators/voss.py +++ b/jesse/indicators/voss.py @@ -34,7 +34,7 @@ def voss(candles: np.ndarray, period: int = 20, predict: int = 3, bandwith: floa return VossFilter(voss_val[-1], filt[-1]) -@njit +@njit(cache=True) def voss_fast(source, period, predict, bandwith): voss = np.full_like(source, 0) filt = np.full_like(source, 0) diff --git a/jesse/indicators/vpwma.py b/jesse/indicators/vpwma.py index 5256b33c1..1a11af041 100644 --- a/jesse/indicators/vpwma.py +++ b/jesse/indicators/vpwma.py @@ -32,7 +32,7 @@ def vpwma(candles: np.ndarray, period: int = 14, power: float = 0.382, source_ty return res if sequential else res[-1] -@njit +@njit(cache=True) def vpwma_fast(source, period, power): newseries = np.copy(source) for j in range(period + 1, source.shape[0]):