openbacktesting 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. openbacktesting/__init__.py +85 -0
  2. openbacktesting/aggregation.py +8 -0
  3. openbacktesting/broker/__init__.py +54 -0
  4. openbacktesting/broker/commission.py +57 -0
  5. openbacktesting/broker/core.py +1122 -0
  6. openbacktesting/broker/execution.py +62 -0
  7. openbacktesting/broker/instrument.py +106 -0
  8. openbacktesting/broker/ledger.py +60 -0
  9. openbacktesting/broker/models.py +236 -0
  10. openbacktesting/broker/observations.py +99 -0
  11. openbacktesting/broker/requests.py +192 -0
  12. openbacktesting/broker/sizing.py +76 -0
  13. openbacktesting/colors.py +175 -0
  14. openbacktesting/data/__init__.py +20 -0
  15. openbacktesting/data/aggregation.py +39 -0
  16. openbacktesting/data/context.py +30 -0
  17. openbacktesting/data/core.py +218 -0
  18. openbacktesting/data/generators.py +54 -0
  19. openbacktesting/data/strategy_data.py +103 -0
  20. openbacktesting/data/timeframe.py +69 -0
  21. openbacktesting/engine.py +34 -0
  22. openbacktesting/helpers.py +77 -0
  23. openbacktesting/indicator_api.py +10 -0
  24. openbacktesting/indicator_methods.py +123 -0
  25. openbacktesting/indicator_types.py +19 -0
  26. openbacktesting/indicators/__init__.py +7 -0
  27. openbacktesting/indicators/api.py +97 -0
  28. openbacktesting/indicators/calculus.py +75 -0
  29. openbacktesting/indicators/candles/__init__.py +0 -0
  30. openbacktesting/indicators/candles/cdl_doji.py +17 -0
  31. openbacktesting/indicators/candles/cdl_engulfing.py +14 -0
  32. openbacktesting/indicators/candles/cdl_eveningstar.py +15 -0
  33. openbacktesting/indicators/candles/cdl_hammer.py +14 -0
  34. openbacktesting/indicators/candles/cdl_harami.py +14 -0
  35. openbacktesting/indicators/candles/cdl_inside.py +14 -0
  36. openbacktesting/indicators/candles/cdl_marubozu.py +14 -0
  37. openbacktesting/indicators/candles/cdl_morningstar.py +15 -0
  38. openbacktesting/indicators/candles/cdl_shootingstar.py +14 -0
  39. openbacktesting/indicators/candles/cdl_z.py +28 -0
  40. openbacktesting/indicators/candles/ha.py +19 -0
  41. openbacktesting/indicators/catalog.json +8348 -0
  42. openbacktesting/indicators/common.py +94 -0
  43. openbacktesting/indicators/cycles/__init__.py +0 -0
  44. openbacktesting/indicators/cycles/dsp.py +10 -0
  45. openbacktesting/indicators/cycles/ebsw.py +10 -0
  46. openbacktesting/indicators/cycles/ht_dcperiod.py +10 -0
  47. openbacktesting/indicators/cycles/ht_dcphase.py +10 -0
  48. openbacktesting/indicators/cycles/ht_phasor.py +17 -0
  49. openbacktesting/indicators/cycles/ht_sine.py +17 -0
  50. openbacktesting/indicators/cycles/ht_trendmode.py +10 -0
  51. openbacktesting/indicators/cycles/msw.py +19 -0
  52. openbacktesting/indicators/methods.py +5762 -0
  53. openbacktesting/indicators/momentum/__init__.py +0 -0
  54. openbacktesting/indicators/momentum/ac.py +9 -0
  55. openbacktesting/indicators/momentum/ao.py +10 -0
  56. openbacktesting/indicators/momentum/apo.py +10 -0
  57. openbacktesting/indicators/momentum/bias.py +10 -0
  58. openbacktesting/indicators/momentum/bop.py +10 -0
  59. openbacktesting/indicators/momentum/brar.py +26 -0
  60. openbacktesting/indicators/momentum/cci.py +10 -0
  61. openbacktesting/indicators/momentum/cfo.py +10 -0
  62. openbacktesting/indicators/momentum/cg.py +10 -0
  63. openbacktesting/indicators/momentum/cmo.py +10 -0
  64. openbacktesting/indicators/momentum/coppock.py +10 -0
  65. openbacktesting/indicators/momentum/crsi.py +28 -0
  66. openbacktesting/indicators/momentum/cti.py +10 -0
  67. openbacktesting/indicators/momentum/dm.py +17 -0
  68. openbacktesting/indicators/momentum/er.py +10 -0
  69. openbacktesting/indicators/momentum/eri.py +17 -0
  70. openbacktesting/indicators/momentum/fisher.py +17 -0
  71. openbacktesting/indicators/momentum/fosc.py +10 -0
  72. openbacktesting/indicators/momentum/gator.py +13 -0
  73. openbacktesting/indicators/momentum/ibs.py +7 -0
  74. openbacktesting/indicators/momentum/inertia.py +22 -0
  75. openbacktesting/indicators/momentum/kdj.py +18 -0
  76. openbacktesting/indicators/momentum/kst.py +30 -0
  77. openbacktesting/indicators/momentum/lrsi.py +10 -0
  78. openbacktesting/indicators/momentum/macd.py +27 -0
  79. openbacktesting/indicators/momentum/macdext.py +27 -0
  80. openbacktesting/indicators/momentum/macdfix.py +18 -0
  81. openbacktesting/indicators/momentum/mom.py +10 -0
  82. openbacktesting/indicators/momentum/pgo.py +10 -0
  83. openbacktesting/indicators/momentum/pmo.py +13 -0
  84. openbacktesting/indicators/momentum/po.py +10 -0
  85. openbacktesting/indicators/momentum/ppo.py +20 -0
  86. openbacktesting/indicators/momentum/psl.py +12 -0
  87. openbacktesting/indicators/momentum/pvo.py +20 -0
  88. openbacktesting/indicators/momentum/qqe.py +31 -0
  89. openbacktesting/indicators/momentum/rci.py +20 -0
  90. openbacktesting/indicators/momentum/rmi.py +7 -0
  91. openbacktesting/indicators/momentum/roc.py +10 -0
  92. openbacktesting/indicators/momentum/rocp.py +10 -0
  93. openbacktesting/indicators/momentum/rocr.py +10 -0
  94. openbacktesting/indicators/momentum/rocr100.py +10 -0
  95. openbacktesting/indicators/momentum/rsi.py +10 -0
  96. openbacktesting/indicators/momentum/rsx.py +10 -0
  97. openbacktesting/indicators/momentum/rvgi.py +26 -0
  98. openbacktesting/indicators/momentum/slope.py +17 -0
  99. openbacktesting/indicators/momentum/smc_sweep.py +18 -0
  100. openbacktesting/indicators/momentum/smi.py +21 -0
  101. openbacktesting/indicators/momentum/smi_stochastic.py +15 -0
  102. openbacktesting/indicators/momentum/squeeze.py +47 -0
  103. openbacktesting/indicators/momentum/squeeze_pro.py +53 -0
  104. openbacktesting/indicators/momentum/stc.py +20 -0
  105. openbacktesting/indicators/momentum/stoch.py +19 -0
  106. openbacktesting/indicators/momentum/stochf.py +19 -0
  107. openbacktesting/indicators/momentum/stochrsi.py +19 -0
  108. openbacktesting/indicators/momentum/td_seq.py +17 -0
  109. openbacktesting/indicators/momentum/trix.py +19 -0
  110. openbacktesting/indicators/momentum/trixh.py +20 -0
  111. openbacktesting/indicators/momentum/tsi.py +26 -0
  112. openbacktesting/indicators/momentum/uo.py +22 -0
  113. openbacktesting/indicators/momentum/vwmacd.py +20 -0
  114. openbacktesting/indicators/momentum/wavetrend.py +15 -0
  115. openbacktesting/indicators/momentum/willr.py +10 -0
  116. openbacktesting/indicators/overlap/__init__.py +0 -0
  117. openbacktesting/indicators/overlap/alligator.py +13 -0
  118. openbacktesting/indicators/overlap/alma.py +33 -0
  119. openbacktesting/indicators/overlap/anchored_vwap.py +50 -0
  120. openbacktesting/indicators/overlap/anchored_vwap_bands.py +13 -0
  121. openbacktesting/indicators/overlap/avgprice.py +10 -0
  122. openbacktesting/indicators/overlap/dema.py +10 -0
  123. openbacktesting/indicators/overlap/ema.py +12 -0
  124. openbacktesting/indicators/overlap/frama.py +29 -0
  125. openbacktesting/indicators/overlap/fwma.py +10 -0
  126. openbacktesting/indicators/overlap/hilo.py +26 -0
  127. openbacktesting/indicators/overlap/hl2.py +10 -0
  128. openbacktesting/indicators/overlap/hlc3.py +10 -0
  129. openbacktesting/indicators/overlap/hma.py +10 -0
  130. openbacktesting/indicators/overlap/ht_trendline.py +10 -0
  131. openbacktesting/indicators/overlap/hwma.py +10 -0
  132. openbacktesting/indicators/overlap/ichimoku.py +44 -0
  133. openbacktesting/indicators/overlap/jma.py +10 -0
  134. openbacktesting/indicators/overlap/kama.py +10 -0
  135. openbacktesting/indicators/overlap/linreg.py +15 -0
  136. openbacktesting/indicators/overlap/linregangle.py +10 -0
  137. openbacktesting/indicators/overlap/linregintercept.py +10 -0
  138. openbacktesting/indicators/overlap/linregslope.py +10 -0
  139. openbacktesting/indicators/overlap/ma.py +10 -0
  140. openbacktesting/indicators/overlap/ma_envelopes.py +16 -0
  141. openbacktesting/indicators/overlap/mama.py +17 -0
  142. openbacktesting/indicators/overlap/mavp.py +17 -0
  143. openbacktesting/indicators/overlap/mcgd.py +10 -0
  144. openbacktesting/indicators/overlap/medprice.py +10 -0
  145. openbacktesting/indicators/overlap/midpoint.py +10 -0
  146. openbacktesting/indicators/overlap/midprice.py +10 -0
  147. openbacktesting/indicators/overlap/mmar.py +21 -0
  148. openbacktesting/indicators/overlap/ohlc4.py +10 -0
  149. openbacktesting/indicators/overlap/pwma.py +10 -0
  150. openbacktesting/indicators/overlap/rainbow.py +25 -0
  151. openbacktesting/indicators/overlap/rma.py +10 -0
  152. openbacktesting/indicators/overlap/sinwma.py +10 -0
  153. openbacktesting/indicators/overlap/sma.py +14 -0
  154. openbacktesting/indicators/overlap/ssf.py +10 -0
  155. openbacktesting/indicators/overlap/supertrend.py +21 -0
  156. openbacktesting/indicators/overlap/swma.py +10 -0
  157. openbacktesting/indicators/overlap/t3.py +10 -0
  158. openbacktesting/indicators/overlap/tema.py +10 -0
  159. openbacktesting/indicators/overlap/trima.py +10 -0
  160. openbacktesting/indicators/overlap/tsf.py +10 -0
  161. openbacktesting/indicators/overlap/typprice.py +10 -0
  162. openbacktesting/indicators/overlap/vidya.py +10 -0
  163. openbacktesting/indicators/overlap/vwap.py +10 -0
  164. openbacktesting/indicators/overlap/vwma.py +10 -0
  165. openbacktesting/indicators/overlap/wcp.py +10 -0
  166. openbacktesting/indicators/overlap/wma.py +10 -0
  167. openbacktesting/indicators/overlap/zlma.py +10 -0
  168. openbacktesting/indicators/performance/__init__.py +0 -0
  169. openbacktesting/indicators/performance/drawdown.py +18 -0
  170. openbacktesting/indicators/performance/log_return.py +10 -0
  171. openbacktesting/indicators/performance/percent_return.py +10 -0
  172. openbacktesting/indicators/predicates.py +88 -0
  173. openbacktesting/indicators/registry.py +571 -0
  174. openbacktesting/indicators/runtime.py +290 -0
  175. openbacktesting/indicators/statistics/__init__.py +0 -0
  176. openbacktesting/indicators/statistics/beta.py +10 -0
  177. openbacktesting/indicators/statistics/correl.py +10 -0
  178. openbacktesting/indicators/statistics/entropy.py +10 -0
  179. openbacktesting/indicators/statistics/kurtosis.py +10 -0
  180. openbacktesting/indicators/statistics/mad.py +10 -0
  181. openbacktesting/indicators/statistics/md.py +10 -0
  182. openbacktesting/indicators/statistics/median.py +10 -0
  183. openbacktesting/indicators/statistics/mode.py +48 -0
  184. openbacktesting/indicators/statistics/quantile.py +10 -0
  185. openbacktesting/indicators/statistics/skew.py +10 -0
  186. openbacktesting/indicators/statistics/stderr.py +10 -0
  187. openbacktesting/indicators/statistics/stdev.py +10 -0
  188. openbacktesting/indicators/statistics/variance.py +10 -0
  189. openbacktesting/indicators/statistics/zscore.py +10 -0
  190. openbacktesting/indicators/trend/__init__.py +0 -0
  191. openbacktesting/indicators/trend/adx.py +28 -0
  192. openbacktesting/indicators/trend/adxr.py +28 -0
  193. openbacktesting/indicators/trend/amat.py +19 -0
  194. openbacktesting/indicators/trend/aroon.py +18 -0
  195. openbacktesting/indicators/trend/atr_stop.py +33 -0
  196. openbacktesting/indicators/trend/chop.py +20 -0
  197. openbacktesting/indicators/trend/cksp.py +17 -0
  198. openbacktesting/indicators/trend/cpr.py +57 -0
  199. openbacktesting/indicators/trend/decay.py +10 -0
  200. openbacktesting/indicators/trend/decreasing.py +18 -0
  201. openbacktesting/indicators/trend/dpo.py +12 -0
  202. openbacktesting/indicators/trend/dx.py +19 -0
  203. openbacktesting/indicators/trend/edecay.py +10 -0
  204. openbacktesting/indicators/trend/increasing.py +18 -0
  205. openbacktesting/indicators/trend/long_run.py +10 -0
  206. openbacktesting/indicators/trend/minus_dm.py +10 -0
  207. openbacktesting/indicators/trend/pivot_points.py +89 -0
  208. openbacktesting/indicators/trend/pivothigh.py +23 -0
  209. openbacktesting/indicators/trend/pivotlow.py +23 -0
  210. openbacktesting/indicators/trend/plus_dm.py +10 -0
  211. openbacktesting/indicators/trend/pmax.py +18 -0
  212. openbacktesting/indicators/trend/psar.py +19 -0
  213. openbacktesting/indicators/trend/qstick.py +10 -0
  214. openbacktesting/indicators/trend/sarext.py +35 -0
  215. openbacktesting/indicators/trend/short_run.py +10 -0
  216. openbacktesting/indicators/trend/tsignals.py +26 -0
  217. openbacktesting/indicators/trend/ttm_trend.py +16 -0
  218. openbacktesting/indicators/trend/vhf.py +10 -0
  219. openbacktesting/indicators/trend/volatility_stop.py +33 -0
  220. openbacktesting/indicators/trend/vortex.py +17 -0
  221. openbacktesting/indicators/trend/xsignals.py +29 -0
  222. openbacktesting/indicators/types.py +344 -0
  223. openbacktesting/indicators/utility/__init__.py +0 -0
  224. openbacktesting/indicators/utility/barssince.py +21 -0
  225. openbacktesting/indicators/utility/change.py +7 -0
  226. openbacktesting/indicators/utility/cross.py +12 -0
  227. openbacktesting/indicators/utility/crossover.py +11 -0
  228. openbacktesting/indicators/utility/crossunder.py +11 -0
  229. openbacktesting/indicators/utility/cum.py +7 -0
  230. openbacktesting/indicators/utility/falling.py +10 -0
  231. openbacktesting/indicators/utility/highest.py +7 -0
  232. openbacktesting/indicators/utility/highestbars.py +29 -0
  233. openbacktesting/indicators/utility/lowest.py +7 -0
  234. openbacktesting/indicators/utility/lowestbars.py +29 -0
  235. openbacktesting/indicators/utility/percentile_linear_interpolation.py +12 -0
  236. openbacktesting/indicators/utility/percentile_nearest_rank.py +16 -0
  237. openbacktesting/indicators/utility/percentrank.py +7 -0
  238. openbacktesting/indicators/utility/range.py +8 -0
  239. openbacktesting/indicators/utility/rising.py +10 -0
  240. openbacktesting/indicators/utility/rolling_count.py +12 -0
  241. openbacktesting/indicators/utility/rolling_sum.py +7 -0
  242. openbacktesting/indicators/utility/running_max.py +7 -0
  243. openbacktesting/indicators/utility/running_min.py +7 -0
  244. openbacktesting/indicators/utility/shift.py +7 -0
  245. openbacktesting/indicators/utility/valuewhen.py +25 -0
  246. openbacktesting/indicators/volatility/__init__.py +0 -0
  247. openbacktesting/indicators/volatility/aberration.py +21 -0
  248. openbacktesting/indicators/volatility/accbands.py +20 -0
  249. openbacktesting/indicators/volatility/adr.py +7 -0
  250. openbacktesting/indicators/volatility/atr.py +12 -0
  251. openbacktesting/indicators/volatility/avolume.py +10 -0
  252. openbacktesting/indicators/volatility/bbands.py +20 -0
  253. openbacktesting/indicators/volatility/ce.py +25 -0
  254. openbacktesting/indicators/volatility/cvi.py +10 -0
  255. openbacktesting/indicators/volatility/donchian.py +20 -0
  256. openbacktesting/indicators/volatility/hvol.py +10 -0
  257. openbacktesting/indicators/volatility/hwc.py +27 -0
  258. openbacktesting/indicators/volatility/kc.py +27 -0
  259. openbacktesting/indicators/volatility/massi.py +10 -0
  260. openbacktesting/indicators/volatility/natr.py +19 -0
  261. openbacktesting/indicators/volatility/pdist.py +10 -0
  262. openbacktesting/indicators/volatility/rvi.py +21 -0
  263. openbacktesting/indicators/volatility/starc.py +11 -0
  264. openbacktesting/indicators/volatility/thermo.py +28 -0
  265. openbacktesting/indicators/volatility/true_range.py +31 -0
  266. openbacktesting/indicators/volatility/ui.py +10 -0
  267. openbacktesting/indicators/volume/__init__.py +0 -0
  268. openbacktesting/indicators/volume/ad.py +10 -0
  269. openbacktesting/indicators/volume/adosc.py +19 -0
  270. openbacktesting/indicators/volume/aobv.py +31 -0
  271. openbacktesting/indicators/volume/cmf.py +12 -0
  272. openbacktesting/indicators/volume/efi.py +12 -0
  273. openbacktesting/indicators/volume/emv.py +10 -0
  274. openbacktesting/indicators/volume/eom.py +19 -0
  275. openbacktesting/indicators/volume/iii.py +9 -0
  276. openbacktesting/indicators/volume/kvo.py +28 -0
  277. openbacktesting/indicators/volume/marketfi.py +10 -0
  278. openbacktesting/indicators/volume/mfi.py +12 -0
  279. openbacktesting/indicators/volume/nvi.py +26 -0
  280. openbacktesting/indicators/volume/obv.py +10 -0
  281. openbacktesting/indicators/volume/pvi.py +26 -0
  282. openbacktesting/indicators/volume/pvol.py +10 -0
  283. openbacktesting/indicators/volume/pvr.py +10 -0
  284. openbacktesting/indicators/volume/pvt.py +10 -0
  285. openbacktesting/indicators/volume/rvol.py +8 -0
  286. openbacktesting/indicators/volume/vfi.py +18 -0
  287. openbacktesting/indicators/volume/vosc.py +10 -0
  288. openbacktesting/indicators/volume/wad.py +10 -0
  289. openbacktesting/indicators/volume/wvad.py +9 -0
  290. openbacktesting/inputs.py +51 -0
  291. openbacktesting/lib.py +31 -0
  292. openbacktesting/logs.py +129 -0
  293. openbacktesting/optimization.py +8 -0
  294. openbacktesting/optimizer/__init__.py +25 -0
  295. openbacktesting/optimizer/_semantics.py +155 -0
  296. openbacktesting/optimizer/identity.py +45 -0
  297. openbacktesting/optimizer/models.py +92 -0
  298. openbacktesting/optimizer/plan.py +129 -0
  299. openbacktesting/optimizer/portfolio-result.schema.json +4984 -0
  300. openbacktesting/optimizer/query.py +257 -0
  301. openbacktesting/optimizer/runner.py +98 -0
  302. openbacktesting/optimizer/storage.py +261 -0
  303. openbacktesting/optimizer/validation.py +64 -0
  304. openbacktesting/parallel.py +9 -0
  305. openbacktesting/plotting/__init__.py +23 -0
  306. openbacktesting/plotting/collector.py +509 -0
  307. openbacktesting/plotting/encoding.py +102 -0
  308. openbacktesting/plotting/types.py +92 -0
  309. openbacktesting/portfolio/__init__.py +15 -0
  310. openbacktesting/portfolio/analysis.py +245 -0
  311. openbacktesting/portfolio/builder.py +381 -0
  312. openbacktesting/portfolio/catalog.json +1404 -0
  313. openbacktesting/portfolio/helpers.py +92 -0
  314. openbacktesting/portfolio/metrics.py +186 -0
  315. openbacktesting/portfolio/models.py +63 -0
  316. openbacktesting/portfolio/periods.py +164 -0
  317. openbacktesting/portfolio/rates.py +14 -0
  318. openbacktesting/portfolio/snapshot.py +111 -0
  319. openbacktesting/portfolio/stats.py +272 -0
  320. openbacktesting/portfolio/trades.py +136 -0
  321. openbacktesting/portfolio/trading.py +215 -0
  322. openbacktesting/py.typed +0 -0
  323. openbacktesting/runtime.py +330 -0
  324. openbacktesting/simulation/__init__.py +17 -0
  325. openbacktesting/simulation/collection.py +13 -0
  326. openbacktesting/simulation/config.py +241 -0
  327. openbacktesting/simulation/core.py +528 -0
  328. openbacktesting/simulation/optimization.py +326 -0
  329. openbacktesting/simulation/parallel.py +145 -0
  330. openbacktesting/simulation/variants.py +107 -0
  331. openbacktesting/strategy/__init__.py +19 -0
  332. openbacktesting/strategy/bar_state.py +14 -0
  333. openbacktesting/strategy/base.py +810 -0
  334. openbacktesting/strategy/declaration.py +90 -0
  335. openbacktesting/strategy/helpers.py +198 -0
  336. openbacktesting/strategy/inputs.py +460 -0
  337. openbacktesting/strategy/sizing.py +80 -0
  338. openbacktesting/strategy/templates.py +160 -0
  339. openbacktesting/strategy_data.py +10 -0
  340. openbacktesting/test/BTCUSD.csv +157 -0
  341. openbacktesting/test/EURUSD.csv +5001 -0
  342. openbacktesting/test/GOOG.csv +2149 -0
  343. openbacktesting/test/__init__.py +29 -0
  344. openbacktesting/test/__main__.py +11 -0
  345. openbacktesting/test/_test.py +1312 -0
  346. openbacktesting/util.py +31 -0
  347. openbacktesting-0.2.0.dist-info/METADATA +151 -0
  348. openbacktesting-0.2.0.dist-info/RECORD +350 -0
  349. openbacktesting-0.2.0.dist-info/WHEEL +4 -0
  350. openbacktesting-0.2.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,10 @@
1
+ """ta.log_return: Computation wrapper for the pinned dependency with canonical outputs."""
2
+
3
+ from pandas_ta_classic.performance.log_return import log_return as _calculate
4
+
5
+ from ..common import named_series
6
+
7
+
8
+ def compute(*, close, length, cumulative, talib):
9
+ result = _calculate(close=close, length=length, cumulative=cumulative, talib=talib)
10
+ return named_series(result, "ta.log_return", "log_return")
@@ -0,0 +1,10 @@
1
+ """ta.percent_return: Computation wrapper for the pinned dependency with canonical outputs."""
2
+
3
+ from pandas_ta_classic.performance.percent_return import percent_return as _calculate
4
+
5
+ from ..common import named_series
6
+
7
+
8
+ def compute(*, close, length, cumulative, talib):
9
+ result = _calculate(close=close, length=length, cumulative=cumulative, talib=talib)
10
+ return named_series(result, "ta.percent_return", "percent_return")
@@ -0,0 +1,88 @@
1
+ """Crossing checks on currently visible inputs; no indicator registration or full-history computation."""
2
+
3
+ from collections.abc import Sequence
4
+ from numbers import Real
5
+
6
+ import numpy as np
7
+ import pandas as pd
8
+
9
+ from .types import IndicatorHandle
10
+
11
+ CrossInput = Sequence[float] | np.ndarray | pd.Series | IndicatorHandle | float
12
+
13
+
14
+ def _last_pair(value: CrossInput) -> tuple[float, float] | None:
15
+ if isinstance(value, Real):
16
+ return float(value), float(value)
17
+ if isinstance(value, (str, bytes)) or not isinstance(
18
+ value, (Sequence, np.ndarray, pd.Series, IndicatorHandle)
19
+ ):
20
+ raise TypeError("Crossing inputs must be numeric sequences, single-channel handles, or numeric constants")
21
+ if isinstance(value, (np.ndarray, IndicatorHandle)) and value.ndim != 1:
22
+ raise ValueError("Crossing checks accept only single-channel sequences; select an output channel first")
23
+ if len(value) < 2:
24
+ return None
25
+ if isinstance(value, IndicatorHandle) and not value[-2:].valid.all():
26
+ return None
27
+ if isinstance(value, pd.Series):
28
+ return float(value.iloc[-2]), float(value.iloc[-1])
29
+ return float(value[-2]), float(value[-1])
30
+
31
+
32
+ def _cross_sides(left: CrossInput, right: CrossInput) -> tuple[bool, bool]:
33
+ previous_left, previous_right = _last_pair(left), _last_pair(right)
34
+ if previous_left is None or previous_right is None:
35
+ return False, False
36
+ before_left, current_left = previous_left
37
+ before_right, current_right = previous_right
38
+ if not np.isfinite((before_left, current_left, before_right, current_right)).all():
39
+ return False, False
40
+ return (
41
+ current_left > current_right and before_left <= before_right,
42
+ current_left < current_right and before_left >= before_right,
43
+ )
44
+
45
+
46
+ class CrossPredicates:
47
+ """Immediate self.ta boolean predicates with the same equality boundaries as crossing indicators."""
48
+
49
+ def is_cross(self, left: CrossInput, right: CrossInput) -> bool:
50
+ """Check whether either-direction crossing occurs on the last currently visible bar.
51
+
52
+ Args:
53
+ left: Single-channel handle, numeric sequence, or numeric constant; column-name strings are not accepted.
54
+ right: Single-channel handle, numeric sequence, or numeric constant; constants act as fixed thresholds.
55
+
56
+ Returns:
57
+ Python bool. Equality is allowed on the preceding bar; current equality is not a crossing.
58
+ False with fewer than two bars or NaN/infinity in either of the last two bars.
59
+ Calls in next read only the currently visible input prefix, without registering indicators or affecting warmup.
60
+ """
61
+ up, down = _cross_sides(left, right)
62
+ return up or down
63
+
64
+ def is_crossover(self, left: CrossInput, right: CrossInput) -> bool:
65
+ """Check whether the current left value is strictly above the right, with the preceding left value at or below the right.
66
+
67
+ Args:
68
+ left: Single-channel handle, numeric sequence, or numeric constant; column-name strings are not accepted.
69
+ right: Single-channel handle, numeric sequence, or numeric constant; constants act as fixed thresholds.
70
+
71
+ Returns:
72
+ Python bool. Read only the last two bars; False with fewer than two bars or NaN/infinity.
73
+ Valid positions match the ta.crossover sequence; no registration, and calls in next are allowed.
74
+ """
75
+ return _cross_sides(left, right)[0]
76
+
77
+ def is_crossunder(self, left: CrossInput, right: CrossInput) -> bool:
78
+ """Check whether the current left value is strictly below the right, with the preceding left value at or above the right.
79
+
80
+ Args:
81
+ left: Single-channel handle, numeric sequence, or numeric constant; column-name strings are not accepted.
82
+ right: Single-channel handle, numeric sequence, or numeric constant; constants act as fixed thresholds.
83
+
84
+ Returns:
85
+ Python bool. Read only the last two bars; False with fewer than two bars or NaN/infinity.
86
+ Valid positions match the ta.crossunder sequence; no registration, and calls in next are allowed.
87
+ """
88
+ return _cross_sides(left, right)[1]
@@ -0,0 +1,571 @@
1
+ """Reviewed explicit computation bindings; registration does not discover or expose provider functions automatically."""
2
+
3
+ from collections.abc import Callable
4
+ from dataclasses import dataclass
5
+ from inspect import Parameter as SignatureParameter
6
+ from inspect import signature
7
+
8
+ from .candles.cdl_doji import compute as cdl_doji
9
+ from .candles.cdl_engulfing import compute as cdl_engulfing
10
+ from .candles.cdl_eveningstar import compute as cdl_eveningstar
11
+ from .candles.cdl_hammer import compute as cdl_hammer
12
+ from .candles.cdl_harami import compute as cdl_harami
13
+ from .candles.cdl_inside import compute as cdl_inside
14
+ from .candles.cdl_marubozu import compute as cdl_marubozu
15
+ from .candles.cdl_morningstar import compute as cdl_morningstar
16
+ from .candles.cdl_shootingstar import compute as cdl_shootingstar
17
+ from .candles.cdl_z import compute as cdl_z
18
+ from .candles.ha import compute as ha
19
+ from .common import SPECS
20
+ from .cycles.dsp import compute as dsp
21
+ from .cycles.ebsw import compute as ebsw
22
+ from .cycles.ht_dcperiod import compute as ht_dcperiod
23
+ from .cycles.ht_dcphase import compute as ht_dcphase
24
+ from .cycles.ht_phasor import compute as ht_phasor
25
+ from .cycles.ht_sine import compute as ht_sine
26
+ from .cycles.ht_trendmode import compute as ht_trendmode
27
+ from .cycles.msw import compute as msw
28
+ from .momentum.ac import compute as ac
29
+ from .momentum.ao import compute as ao
30
+ from .momentum.apo import compute as apo
31
+ from .momentum.bias import compute as bias
32
+ from .momentum.bop import compute as bop
33
+ from .momentum.brar import compute as brar
34
+ from .momentum.cci import compute as cci
35
+ from .momentum.cfo import compute as cfo
36
+ from .momentum.cg import compute as cg
37
+ from .momentum.cmo import compute as cmo
38
+ from .momentum.coppock import compute as coppock
39
+ from .momentum.crsi import compute as crsi
40
+ from .momentum.cti import compute as cti
41
+ from .momentum.dm import compute as dm
42
+ from .momentum.er import compute as er
43
+ from .momentum.eri import compute as eri
44
+ from .momentum.fisher import compute as fisher
45
+ from .momentum.fosc import compute as fosc
46
+ from .momentum.gator import compute as gator
47
+ from .momentum.ibs import compute as ibs
48
+ from .momentum.inertia import compute as inertia
49
+ from .momentum.kdj import compute as kdj
50
+ from .momentum.kst import compute as kst
51
+ from .momentum.lrsi import compute as lrsi
52
+ from .momentum.macd import compute as macd
53
+ from .momentum.macdext import compute as macdext
54
+ from .momentum.macdfix import compute as macdfix
55
+ from .momentum.mom import compute as mom
56
+ from .momentum.pgo import compute as pgo
57
+ from .momentum.pmo import compute as pmo
58
+ from .momentum.po import compute as po
59
+ from .momentum.ppo import compute as ppo
60
+ from .momentum.psl import compute as psl
61
+ from .momentum.pvo import compute as pvo
62
+ from .momentum.qqe import compute as qqe
63
+ from .momentum.rci import compute as rci
64
+ from .momentum.rmi import compute as rmi
65
+ from .momentum.roc import compute as roc
66
+ from .momentum.rocp import compute as rocp
67
+ from .momentum.rocr import compute as rocr
68
+ from .momentum.rocr100 import compute as rocr100
69
+ from .momentum.rsi import compute as rsi
70
+ from .momentum.rsx import compute as rsx
71
+ from .momentum.rvgi import compute as rvgi
72
+ from .momentum.slope import compute as slope
73
+ from .momentum.smc_sweep import compute as smc_sweep
74
+ from .momentum.smi import compute as smi
75
+ from .momentum.smi_stochastic import compute as smi_stochastic
76
+ from .momentum.squeeze import compute as squeeze
77
+ from .momentum.squeeze_pro import compute as squeeze_pro
78
+ from .momentum.stc import compute as stc
79
+ from .momentum.stoch import compute as stoch
80
+ from .momentum.stochf import compute as stochf
81
+ from .momentum.stochrsi import compute as stochrsi
82
+ from .momentum.td_seq import compute as td_seq
83
+ from .momentum.trix import compute as trix
84
+ from .momentum.trixh import compute as trixh
85
+ from .momentum.tsi import compute as tsi
86
+ from .momentum.uo import compute as uo
87
+ from .momentum.vwmacd import compute as vwmacd
88
+ from .momentum.wavetrend import compute as wavetrend
89
+ from .momentum.willr import compute as willr
90
+ from .overlap.alligator import compute as alligator
91
+ from .overlap.alma import compute as alma
92
+ from .overlap.anchored_vwap import compute as anchored_vwap
93
+ from .overlap.anchored_vwap_bands import compute as anchored_vwap_bands
94
+ from .overlap.avgprice import compute as avgprice
95
+ from .overlap.dema import compute as dema
96
+ from .overlap.ema import compute as ema
97
+ from .overlap.frama import compute as frama
98
+ from .overlap.fwma import compute as fwma
99
+ from .overlap.hilo import compute as hilo
100
+ from .overlap.hl2 import compute as hl2
101
+ from .overlap.hlc3 import compute as hlc3
102
+ from .overlap.hma import compute as hma
103
+ from .overlap.ht_trendline import compute as ht_trendline
104
+ from .overlap.hwma import compute as hwma
105
+ from .overlap.ichimoku import compute as ichimoku
106
+ from .overlap.jma import compute as jma
107
+ from .overlap.kama import compute as kama
108
+ from .overlap.linreg import compute as linreg
109
+ from .overlap.linregangle import compute as linregangle
110
+ from .overlap.linregintercept import compute as linregintercept
111
+ from .overlap.linregslope import compute as linregslope
112
+ from .overlap.ma import compute as ma
113
+ from .overlap.ma_envelopes import compute as ma_envelopes
114
+ from .overlap.mama import compute as mama
115
+ from .overlap.mavp import compute as mavp
116
+ from .overlap.mcgd import compute as mcgd
117
+ from .overlap.medprice import compute as medprice
118
+ from .overlap.midpoint import compute as midpoint
119
+ from .overlap.midprice import compute as midprice
120
+ from .overlap.mmar import compute as mmar
121
+ from .overlap.ohlc4 import compute as ohlc4
122
+ from .overlap.pwma import compute as pwma
123
+ from .overlap.rainbow import compute as rainbow
124
+ from .overlap.rma import compute as rma
125
+ from .overlap.sinwma import compute as sinwma
126
+ from .overlap.sma import compute as sma
127
+ from .overlap.sma import compute_pandas as sma_pandas
128
+ from .overlap.ssf import compute as ssf
129
+ from .overlap.supertrend import compute as supertrend
130
+ from .overlap.swma import compute as swma
131
+ from .overlap.t3 import compute as t3
132
+ from .overlap.tema import compute as tema
133
+ from .overlap.trima import compute as trima
134
+ from .overlap.tsf import compute as tsf
135
+ from .overlap.typprice import compute as typprice
136
+ from .overlap.vidya import compute as vidya
137
+ from .overlap.vwap import compute as vwap
138
+ from .overlap.vwma import compute as vwma
139
+ from .overlap.wcp import compute as wcp
140
+ from .overlap.wma import compute as wma
141
+ from .overlap.zlma import compute as zlma
142
+ from .performance.drawdown import compute as drawdown
143
+ from .performance.log_return import compute as log_return
144
+ from .performance.percent_return import compute as percent_return
145
+ from .statistics.beta import compute as beta
146
+ from .statistics.correl import compute as correl
147
+ from .statistics.entropy import compute as entropy
148
+ from .statistics.kurtosis import compute as kurtosis
149
+ from .statistics.mad import compute as mad
150
+ from .statistics.md import compute as md
151
+ from .statistics.median import compute as median
152
+ from .statistics.mode import compute as mode
153
+ from .statistics.quantile import compute as quantile
154
+ from .statistics.skew import compute as skew
155
+ from .statistics.stderr import compute as stderr
156
+ from .statistics.stdev import compute as stdev
157
+ from .statistics.variance import compute as variance
158
+ from .statistics.zscore import compute as zscore
159
+ from .trend.adx import compute as adx
160
+ from .trend.adxr import compute as adxr
161
+ from .trend.amat import compute as amat
162
+ from .trend.aroon import compute as aroon
163
+ from .trend.atr_stop import compute as atr_stop
164
+ from .trend.chop import compute as chop
165
+ from .trend.cksp import compute as cksp
166
+ from .trend.cpr import compute as cpr
167
+ from .trend.decay import compute as decay
168
+ from .trend.decreasing import compute as decreasing
169
+ from .trend.dpo import compute as dpo
170
+ from .trend.dx import compute as dx
171
+ from .trend.edecay import compute as edecay
172
+ from .trend.increasing import compute as increasing
173
+ from .trend.long_run import compute as long_run
174
+ from .trend.minus_dm import compute as minus_dm
175
+ from .trend.pivot_points import compute as pivot_points
176
+ from .trend.pivothigh import compute as pivothigh
177
+ from .trend.pivotlow import compute as pivotlow
178
+ from .trend.plus_dm import compute as plus_dm
179
+ from .trend.pmax import compute as pmax
180
+ from .trend.psar import compute as psar
181
+ from .trend.qstick import compute as qstick
182
+ from .trend.sarext import compute as sarext
183
+ from .trend.short_run import compute as short_run
184
+ from .trend.tsignals import compute as tsignals
185
+ from .trend.ttm_trend import compute as ttm_trend
186
+ from .trend.vhf import compute as vhf
187
+ from .trend.volatility_stop import compute as volatility_stop
188
+ from .trend.vortex import compute as vortex
189
+ from .trend.xsignals import compute as xsignals
190
+ from .types import IndicatorError
191
+ from .utility.barssince import compute as barssince
192
+ from .utility.change import compute as change
193
+ from .utility.cross import compute as cross
194
+ from .utility.crossover import compute as crossover
195
+ from .utility.crossunder import compute as crossunder
196
+ from .utility.cum import compute as cum
197
+ from .utility.falling import compute as falling
198
+ from .utility.highest import compute as highest
199
+ from .utility.highestbars import compute as highestbars
200
+ from .utility.lowest import compute as lowest
201
+ from .utility.lowestbars import compute as lowestbars
202
+ from .utility.percentile_linear_interpolation import compute as percentile_linear_interpolation
203
+ from .utility.percentile_nearest_rank import compute as percentile_nearest_rank
204
+ from .utility.percentrank import compute as percentrank
205
+ from .utility.range import compute as range
206
+ from .utility.rising import compute as rising
207
+ from .utility.rolling_count import compute as rolling_count
208
+ from .utility.rolling_sum import compute as rolling_sum
209
+ from .utility.running_max import compute as running_max
210
+ from .utility.running_min import compute as running_min
211
+ from .utility.shift import compute as shift
212
+ from .utility.valuewhen import compute as valuewhen
213
+ from .volatility.aberration import compute as aberration
214
+ from .volatility.accbands import compute as accbands
215
+ from .volatility.adr import compute as adr
216
+ from .volatility.atr import compute as atr
217
+ from .volatility.avolume import compute as avolume
218
+ from .volatility.bbands import compute as bbands
219
+ from .volatility.ce import compute as ce
220
+ from .volatility.cvi import compute as cvi
221
+ from .volatility.donchian import compute as donchian
222
+ from .volatility.hvol import compute as hvol
223
+ from .volatility.hwc import compute as hwc
224
+ from .volatility.kc import compute as kc
225
+ from .volatility.massi import compute as massi
226
+ from .volatility.natr import compute as natr
227
+ from .volatility.pdist import compute as pdist
228
+ from .volatility.rvi import compute as rvi
229
+ from .volatility.starc import compute as starc
230
+ from .volatility.thermo import compute as thermo
231
+ from .volatility.true_range import compute as true_range
232
+ from .volatility.ui import compute as ui
233
+ from .volume.ad import compute as ad
234
+ from .volume.adosc import compute as adosc
235
+ from .volume.aobv import compute as aobv
236
+ from .volume.cmf import compute as cmf
237
+ from .volume.efi import compute as efi
238
+ from .volume.emv import compute as emv
239
+ from .volume.eom import compute as eom
240
+ from .volume.iii import compute as iii
241
+ from .volume.kvo import compute as kvo
242
+ from .volume.marketfi import compute as marketfi
243
+ from .volume.mfi import compute as mfi
244
+ from .volume.nvi import compute as nvi
245
+ from .volume.obv import compute as obv
246
+ from .volume.pvi import compute as pvi
247
+ from .volume.pvol import compute as pvol
248
+ from .volume.pvr import compute as pvr
249
+ from .volume.pvt import compute as pvt
250
+ from .volume.rvol import compute as rvol
251
+ from .volume.vfi import compute as vfi
252
+ from .volume.vosc import compute as vosc
253
+ from .volume.wad import compute as wad
254
+ from .volume.wvad import compute as wvad
255
+
256
+ NATIVE = "pandas-ta-classic.native"
257
+ PANDAS = "pandas.sma"
258
+ LOCAL = "openbacktesting.numpy"
259
+
260
+
261
+ @dataclass(frozen=True)
262
+ class Binding:
263
+ compute: Callable
264
+ implementation_version: str
265
+
266
+
267
+ def build_bindings(entries, specs):
268
+ available = {spec.id: spec for spec in specs if spec.status == "available"}
269
+ bindings = {}
270
+ for indicator, backend, compute, implementation_version in entries:
271
+ key = (indicator, backend)
272
+ if key in bindings or indicator not in available:
273
+ raise ValueError(f"Duplicate or unreviewed indicator binding: {key}")
274
+ if backend not in (NATIVE, PANDAS, LOCAL) or backend == PANDAS and indicator != "ta.sma":
275
+ raise ValueError(f"Unreviewed backend: {key}")
276
+ spec = available[indicator]
277
+ expected = set(spec.inputs) | dict(spec.parameters).keys() | dict(spec.fixed).keys()
278
+ if backend == NATIVE:
279
+ expected.add("talib")
280
+ parameters = signature(compute).parameters
281
+ if set(parameters) != expected or any(
282
+ p.kind != SignatureParameter.KEYWORD_ONLY or p.default != SignatureParameter.empty
283
+ for p in parameters.values()
284
+ ):
285
+ raise ValueError(f"Indicator binding signature does not match the catalog: {key}")
286
+ module = f"openbacktesting.indicators.{spec.category}.{spec.id.removeprefix('ta.')}"
287
+ if (
288
+ compute.__module__ != module
289
+ or not isinstance(implementation_version, str)
290
+ or not implementation_version
291
+ ):
292
+ raise ValueError(f"Invalid indicator ownership or implementation version: {key}")
293
+ bindings[key] = Binding(compute, implementation_version)
294
+ missing = {
295
+ name for name, spec in available.items() if (name, spec.default_backend) not in bindings
296
+ }
297
+ if missing:
298
+ raise ValueError(f"Available indicator has no default implementation: {sorted(missing)}")
299
+ return bindings
300
+
301
+
302
+ ENTRIES = (
303
+ ("ta.highest", LOCAL, highest, "1"),
304
+ ("ta.lowest", LOCAL, lowest, "1"),
305
+ ("ta.highestbars", LOCAL, highestbars, "1"),
306
+ ("ta.lowestbars", LOCAL, lowestbars, "1"),
307
+ ("ta.rolling_sum", LOCAL, rolling_sum, "1"),
308
+ ("ta.range", LOCAL, range, "1"),
309
+ ("ta.percentrank", LOCAL, percentrank, "1"),
310
+ ("ta.rolling_count", LOCAL, rolling_count, "1"),
311
+ ("ta.cum", LOCAL, cum, "1"),
312
+ ("ta.running_max", LOCAL, running_max, "1"),
313
+ ("ta.running_min", LOCAL, running_min, "1"),
314
+ ("ta.change", LOCAL, change, "1"),
315
+ ("ta.shift", LOCAL, shift, "1"),
316
+ ("ta.percentile_nearest_rank", LOCAL, percentile_nearest_rank, "1"),
317
+ ("ta.percentile_linear_interpolation", LOCAL, percentile_linear_interpolation, "1"),
318
+ ("ta.cross", LOCAL, cross, "1"),
319
+ ("ta.crossover", LOCAL, crossover, "1"),
320
+ ("ta.crossunder", LOCAL, crossunder, "1"),
321
+ ("ta.barssince", LOCAL, barssince, "1"),
322
+ ("ta.valuewhen", LOCAL, valuewhen, "1"),
323
+ ("ta.rising", LOCAL, rising, "1"),
324
+ ("ta.falling", LOCAL, falling, "1"),
325
+ ("ta.pivothigh", LOCAL, pivothigh, "1"),
326
+ ("ta.pivotlow", LOCAL, pivotlow, "1"),
327
+ ("ta.smi_stochastic", LOCAL, smi_stochastic, "1"),
328
+ ("ta.crsi", LOCAL, crsi, "1"),
329
+ ("ta.pmo", LOCAL, pmo, "1"),
330
+ ("ta.rmi", LOCAL, rmi, "1"),
331
+ ("ta.alligator", LOCAL, alligator, "1"),
332
+ ("ta.gator", LOCAL, gator, "1"),
333
+ ("ta.atr_stop", LOCAL, atr_stop, "1"),
334
+ ("ta.volatility_stop", LOCAL, volatility_stop, "1"),
335
+ ("ta.ma_envelopes", LOCAL, ma_envelopes, "1"),
336
+ ("ta.starc", LOCAL, starc, "1"),
337
+ ("ta.ac", LOCAL, ac, "1"),
338
+ ("ta.ibs", LOCAL, ibs, "1"),
339
+ ("ta.frama", LOCAL, frama, "1"),
340
+ ("ta.wavetrend", LOCAL, wavetrend, "1"),
341
+ ("ta.adr", LOCAL, adr, "1"),
342
+ ("ta.rvol", LOCAL, rvol, "1"),
343
+ ("ta.rci", LOCAL, rci, "1"),
344
+ ("ta.iii", LOCAL, iii, "1"),
345
+ ("ta.wvad", LOCAL, wvad, "1"),
346
+ ("ta.pivot_points", LOCAL, pivot_points, "2"),
347
+ ("ta.anchored_vwap", LOCAL, anchored_vwap, "1"),
348
+ ("ta.anchored_vwap_bands", LOCAL, anchored_vwap_bands, "1"),
349
+ ("ta.mode", LOCAL, mode, "1"),
350
+ ("ta.cdl_doji", LOCAL, cdl_doji, "1"),
351
+ ("ta.cdl_inside", NATIVE, cdl_inside, "1"),
352
+ ("ta.cdl_engulfing", NATIVE, cdl_engulfing, "1"),
353
+ ("ta.cdl_hammer", NATIVE, cdl_hammer, "1"),
354
+ ("ta.cdl_shootingstar", NATIVE, cdl_shootingstar, "1"),
355
+ ("ta.cdl_harami", NATIVE, cdl_harami, "1"),
356
+ ("ta.cdl_morningstar", NATIVE, cdl_morningstar, "1"),
357
+ ("ta.cdl_eveningstar", NATIVE, cdl_eveningstar, "1"),
358
+ ("ta.cdl_marubozu", NATIVE, cdl_marubozu, "1"),
359
+ ("ta.cdl_z", NATIVE, cdl_z, "1"),
360
+ ("ta.ha", NATIVE, ha, "1"),
361
+ ("ta.dsp", NATIVE, dsp, "1"),
362
+ ("ta.ebsw", NATIVE, ebsw, "1"),
363
+ ("ta.ht_dcperiod", NATIVE, ht_dcperiod, "1"),
364
+ ("ta.ht_dcphase", NATIVE, ht_dcphase, "1"),
365
+ ("ta.ht_phasor", NATIVE, ht_phasor, "1"),
366
+ ("ta.ht_sine", NATIVE, ht_sine, "1"),
367
+ ("ta.ht_trendmode", NATIVE, ht_trendmode, "1"),
368
+ ("ta.msw", NATIVE, msw, "2"),
369
+ ("ta.ao", NATIVE, ao, "1"),
370
+ ("ta.apo", NATIVE, apo, "1"),
371
+ ("ta.bias", NATIVE, bias, "1"),
372
+ ("ta.bop", NATIVE, bop, "1"),
373
+ ("ta.brar", NATIVE, brar, "1"),
374
+ ("ta.cci", NATIVE, cci, "1"),
375
+ ("ta.cfo", NATIVE, cfo, "1"),
376
+ ("ta.cg", NATIVE, cg, "1"),
377
+ ("ta.cmo", NATIVE, cmo, "1"),
378
+ ("ta.coppock", NATIVE, coppock, "1"),
379
+ ("ta.cti", NATIVE, cti, "1"),
380
+ ("ta.dm", NATIVE, dm, "1"),
381
+ ("ta.er", NATIVE, er, "1"),
382
+ ("ta.eri", NATIVE, eri, "1"),
383
+ ("ta.fisher", NATIVE, fisher, "1"),
384
+ ("ta.fosc", NATIVE, fosc, "1"),
385
+ ("ta.inertia", NATIVE, inertia, "1"),
386
+ ("ta.kdj", NATIVE, kdj, "1"),
387
+ ("ta.kst", NATIVE, kst, "1"),
388
+ ("ta.lrsi", NATIVE, lrsi, "1"),
389
+ ("ta.macd", NATIVE, macd, "1"),
390
+ ("ta.macdext", NATIVE, macdext, "1"),
391
+ ("ta.macdfix", NATIVE, macdfix, "1"),
392
+ ("ta.mom", NATIVE, mom, "1"),
393
+ ("ta.pgo", NATIVE, pgo, "1"),
394
+ ("ta.po", NATIVE, po, "1"),
395
+ ("ta.ppo", NATIVE, ppo, "1"),
396
+ ("ta.psl", NATIVE, psl, "1"),
397
+ ("ta.pvo", NATIVE, pvo, "1"),
398
+ ("ta.qqe", NATIVE, qqe, "1"),
399
+ ("ta.roc", NATIVE, roc, "1"),
400
+ ("ta.rocp", NATIVE, rocp, "1"),
401
+ ("ta.rocr", NATIVE, rocr, "1"),
402
+ ("ta.rocr100", NATIVE, rocr100, "1"),
403
+ ("ta.rsi", NATIVE, rsi, "1"),
404
+ ("ta.rsx", NATIVE, rsx, "1"),
405
+ ("ta.rvgi", NATIVE, rvgi, "1"),
406
+ ("ta.slope", NATIVE, slope, "1"),
407
+ ("ta.smc_sweep", NATIVE, smc_sweep, "1"),
408
+ ("ta.smi", NATIVE, smi, "1"),
409
+ ("ta.squeeze", NATIVE, squeeze, "2"),
410
+ ("ta.squeeze_pro", NATIVE, squeeze_pro, "2"),
411
+ ("ta.stc", NATIVE, stc, "1"),
412
+ ("ta.stoch", NATIVE, stoch, "1"),
413
+ ("ta.stochf", NATIVE, stochf, "1"),
414
+ ("ta.stochrsi", NATIVE, stochrsi, "1"),
415
+ ("ta.td_seq", NATIVE, td_seq, "1"),
416
+ ("ta.trix", NATIVE, trix, "1"),
417
+ ("ta.trixh", NATIVE, trixh, "1"),
418
+ ("ta.tsi", NATIVE, tsi, "1"),
419
+ ("ta.uo", NATIVE, uo, "1"),
420
+ ("ta.vwmacd", NATIVE, vwmacd, "1"),
421
+ ("ta.willr", NATIVE, willr, "1"),
422
+ ("ta.alma", NATIVE, alma, "2"),
423
+ ("ta.avgprice", NATIVE, avgprice, "1"),
424
+ ("ta.dema", NATIVE, dema, "1"),
425
+ ("ta.ema", NATIVE, ema, "1"),
426
+ ("ta.fwma", NATIVE, fwma, "1"),
427
+ ("ta.hilo", NATIVE, hilo, "1"),
428
+ ("ta.hl2", NATIVE, hl2, "1"),
429
+ ("ta.hlc3", NATIVE, hlc3, "1"),
430
+ ("ta.hma", NATIVE, hma, "1"),
431
+ ("ta.ht_trendline", NATIVE, ht_trendline, "1"),
432
+ ("ta.hwma", NATIVE, hwma, "1"),
433
+ ("ta.ichimoku", NATIVE, ichimoku, "1"),
434
+ ("ta.jma", NATIVE, jma, "1"),
435
+ ("ta.kama", NATIVE, kama, "1"),
436
+ ("ta.linreg", NATIVE, linreg, "2"),
437
+ ("ta.linregangle", NATIVE, linregangle, "1"),
438
+ ("ta.linregintercept", NATIVE, linregintercept, "1"),
439
+ ("ta.linregslope", NATIVE, linregslope, "1"),
440
+ ("ta.ma", NATIVE, ma, "1"),
441
+ ("ta.mama", NATIVE, mama, "1"),
442
+ ("ta.mavp", NATIVE, mavp, "1"),
443
+ ("ta.mcgd", NATIVE, mcgd, "1"),
444
+ ("ta.medprice", NATIVE, medprice, "1"),
445
+ ("ta.midpoint", NATIVE, midpoint, "1"),
446
+ ("ta.midprice", NATIVE, midprice, "1"),
447
+ ("ta.mmar", NATIVE, mmar, "1"),
448
+ ("ta.ohlc4", NATIVE, ohlc4, "1"),
449
+ ("ta.pwma", NATIVE, pwma, "1"),
450
+ ("ta.rainbow", NATIVE, rainbow, "1"),
451
+ ("ta.rma", NATIVE, rma, "1"),
452
+ ("ta.sinwma", NATIVE, sinwma, "1"),
453
+ ("ta.sma", NATIVE, sma, "1"),
454
+ ("ta.ssf", NATIVE, ssf, "1"),
455
+ ("ta.supertrend", NATIVE, supertrend, "1"),
456
+ ("ta.swma", NATIVE, swma, "1"),
457
+ ("ta.t3", NATIVE, t3, "1"),
458
+ ("ta.tema", NATIVE, tema, "1"),
459
+ ("ta.trima", NATIVE, trima, "1"),
460
+ ("ta.tsf", NATIVE, tsf, "1"),
461
+ ("ta.typprice", NATIVE, typprice, "1"),
462
+ ("ta.vidya", NATIVE, vidya, "1"),
463
+ ("ta.vwap", NATIVE, vwap, "1"),
464
+ ("ta.vwma", NATIVE, vwma, "1"),
465
+ ("ta.wcp", NATIVE, wcp, "1"),
466
+ ("ta.wma", NATIVE, wma, "1"),
467
+ ("ta.zlma", NATIVE, zlma, "1"),
468
+ ("ta.drawdown", NATIVE, drawdown, "1"),
469
+ ("ta.log_return", NATIVE, log_return, "1"),
470
+ ("ta.percent_return", NATIVE, percent_return, "1"),
471
+ ("ta.beta", NATIVE, beta, "1"),
472
+ ("ta.correl", NATIVE, correl, "1"),
473
+ ("ta.entropy", NATIVE, entropy, "1"),
474
+ ("ta.kurtosis", NATIVE, kurtosis, "1"),
475
+ ("ta.mad", NATIVE, mad, "1"),
476
+ ("ta.md", NATIVE, md, "1"),
477
+ ("ta.median", NATIVE, median, "1"),
478
+ ("ta.quantile", NATIVE, quantile, "1"),
479
+ ("ta.skew", NATIVE, skew, "1"),
480
+ ("ta.stderr", NATIVE, stderr, "1"),
481
+ ("ta.stdev", NATIVE, stdev, "1"),
482
+ ("ta.variance", NATIVE, variance, "1"),
483
+ ("ta.zscore", NATIVE, zscore, "1"),
484
+ ("ta.adx", NATIVE, adx, "1"),
485
+ ("ta.adxr", NATIVE, adxr, "1"),
486
+ ("ta.amat", NATIVE, amat, "1"),
487
+ ("ta.aroon", NATIVE, aroon, "1"),
488
+ ("ta.chop", NATIVE, chop, "1"),
489
+ ("ta.cksp", NATIVE, cksp, "1"),
490
+ ("ta.cpr", NATIVE, cpr, "1"),
491
+ ("ta.decay", NATIVE, decay, "1"),
492
+ ("ta.decreasing", NATIVE, decreasing, "1"),
493
+ ("ta.dpo", NATIVE, dpo, "1"),
494
+ ("ta.dx", NATIVE, dx, "1"),
495
+ ("ta.edecay", NATIVE, edecay, "1"),
496
+ ("ta.increasing", NATIVE, increasing, "1"),
497
+ ("ta.long_run", NATIVE, long_run, "1"),
498
+ ("ta.minus_dm", NATIVE, minus_dm, "1"),
499
+ ("ta.plus_dm", NATIVE, plus_dm, "1"),
500
+ ("ta.pmax", NATIVE, pmax, "1"),
501
+ ("ta.psar", NATIVE, psar, "1"),
502
+ ("ta.qstick", NATIVE, qstick, "1"),
503
+ ("ta.sarext", NATIVE, sarext, "1"),
504
+ ("ta.short_run", NATIVE, short_run, "1"),
505
+ ("ta.tsignals", NATIVE, tsignals, "1"),
506
+ ("ta.ttm_trend", NATIVE, ttm_trend, "1"),
507
+ ("ta.vhf", NATIVE, vhf, "1"),
508
+ ("ta.vortex", NATIVE, vortex, "1"),
509
+ ("ta.xsignals", NATIVE, xsignals, "1"),
510
+ ("ta.aberration", NATIVE, aberration, "1"),
511
+ ("ta.accbands", NATIVE, accbands, "1"),
512
+ ("ta.atr", NATIVE, atr, "1"),
513
+ ("ta.avolume", NATIVE, avolume, "1"),
514
+ ("ta.bbands", NATIVE, bbands, "1"),
515
+ ("ta.ce", NATIVE, ce, "1"),
516
+ ("ta.cvi", NATIVE, cvi, "1"),
517
+ ("ta.donchian", NATIVE, donchian, "1"),
518
+ ("ta.hvol", NATIVE, hvol, "1"),
519
+ ("ta.hwc", NATIVE, hwc, "1"),
520
+ ("ta.kc", NATIVE, kc, "2"),
521
+ ("ta.massi", NATIVE, massi, "1"),
522
+ ("ta.natr", NATIVE, natr, "1"),
523
+ ("ta.pdist", NATIVE, pdist, "1"),
524
+ ("ta.rvi", NATIVE, rvi, "1"),
525
+ ("ta.thermo", NATIVE, thermo, "1"),
526
+ ("ta.true_range", NATIVE, true_range, "2"),
527
+ ("ta.ui", NATIVE, ui, "1"),
528
+ ("ta.ad", NATIVE, ad, "1"),
529
+ ("ta.adosc", NATIVE, adosc, "1"),
530
+ ("ta.aobv", NATIVE, aobv, "1"),
531
+ ("ta.cmf", NATIVE, cmf, "1"),
532
+ ("ta.efi", NATIVE, efi, "1"),
533
+ ("ta.emv", NATIVE, emv, "1"),
534
+ ("ta.eom", NATIVE, eom, "1"),
535
+ ("ta.kvo", NATIVE, kvo, "1"),
536
+ ("ta.marketfi", NATIVE, marketfi, "1"),
537
+ ("ta.mfi", NATIVE, mfi, "1"),
538
+ ("ta.nvi", LOCAL, nvi, "2"),
539
+ ("ta.obv", NATIVE, obv, "1"),
540
+ ("ta.pvi", LOCAL, pvi, "2"),
541
+ ("ta.pvol", NATIVE, pvol, "1"),
542
+ ("ta.pvr", NATIVE, pvr, "1"),
543
+ ("ta.pvt", NATIVE, pvt, "1"),
544
+ ("ta.vfi", NATIVE, vfi, "1"),
545
+ ("ta.vosc", NATIVE, vosc, "1"),
546
+ ("ta.wad", NATIVE, wad, "1"),
547
+ ("ta.sma", PANDAS, sma_pandas, "1"),
548
+ )
549
+ BINDINGS = build_bindings(ENTRIES, SPECS)
550
+
551
+
552
+ def validate_backend(spec, backend):
553
+ if backend not in (NATIVE, PANDAS, LOCAL) or backend == PANDAS and spec.id != "ta.sma":
554
+ raise IndicatorError("backend-unavailable", spec.id, backend, backend=backend)
555
+ # The runtime reports the existing unavailable-indicator for unavailable entries, rather than disguising them as missing backends.
556
+ if spec.status != "available":
557
+ return None
558
+ try:
559
+ return BINDINGS[(spec.id, backend)]
560
+ except KeyError as error:
561
+ raise IndicatorError("backend-unavailable", spec.id, backend, backend=backend) from error
562
+
563
+
564
+ def execute(spec, inputs, parameters, backend):
565
+ if not len(next(iter(inputs.values()))):
566
+ return None
567
+ binding = BINDINGS[(spec.id, backend)]
568
+ options = dict(parameters) | dict(spec.fixed)
569
+ if backend == NATIVE:
570
+ options["talib"] = False
571
+ return binding.compute(**inputs, **options)