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.
- openbacktesting/__init__.py +85 -0
- openbacktesting/aggregation.py +8 -0
- openbacktesting/broker/__init__.py +54 -0
- openbacktesting/broker/commission.py +57 -0
- openbacktesting/broker/core.py +1122 -0
- openbacktesting/broker/execution.py +62 -0
- openbacktesting/broker/instrument.py +106 -0
- openbacktesting/broker/ledger.py +60 -0
- openbacktesting/broker/models.py +236 -0
- openbacktesting/broker/observations.py +99 -0
- openbacktesting/broker/requests.py +192 -0
- openbacktesting/broker/sizing.py +76 -0
- openbacktesting/colors.py +175 -0
- openbacktesting/data/__init__.py +20 -0
- openbacktesting/data/aggregation.py +39 -0
- openbacktesting/data/context.py +30 -0
- openbacktesting/data/core.py +218 -0
- openbacktesting/data/generators.py +54 -0
- openbacktesting/data/strategy_data.py +103 -0
- openbacktesting/data/timeframe.py +69 -0
- openbacktesting/engine.py +34 -0
- openbacktesting/helpers.py +77 -0
- openbacktesting/indicator_api.py +10 -0
- openbacktesting/indicator_methods.py +123 -0
- openbacktesting/indicator_types.py +19 -0
- openbacktesting/indicators/__init__.py +7 -0
- openbacktesting/indicators/api.py +97 -0
- openbacktesting/indicators/calculus.py +75 -0
- openbacktesting/indicators/candles/__init__.py +0 -0
- openbacktesting/indicators/candles/cdl_doji.py +17 -0
- openbacktesting/indicators/candles/cdl_engulfing.py +14 -0
- openbacktesting/indicators/candles/cdl_eveningstar.py +15 -0
- openbacktesting/indicators/candles/cdl_hammer.py +14 -0
- openbacktesting/indicators/candles/cdl_harami.py +14 -0
- openbacktesting/indicators/candles/cdl_inside.py +14 -0
- openbacktesting/indicators/candles/cdl_marubozu.py +14 -0
- openbacktesting/indicators/candles/cdl_morningstar.py +15 -0
- openbacktesting/indicators/candles/cdl_shootingstar.py +14 -0
- openbacktesting/indicators/candles/cdl_z.py +28 -0
- openbacktesting/indicators/candles/ha.py +19 -0
- openbacktesting/indicators/catalog.json +8348 -0
- openbacktesting/indicators/common.py +94 -0
- openbacktesting/indicators/cycles/__init__.py +0 -0
- openbacktesting/indicators/cycles/dsp.py +10 -0
- openbacktesting/indicators/cycles/ebsw.py +10 -0
- openbacktesting/indicators/cycles/ht_dcperiod.py +10 -0
- openbacktesting/indicators/cycles/ht_dcphase.py +10 -0
- openbacktesting/indicators/cycles/ht_phasor.py +17 -0
- openbacktesting/indicators/cycles/ht_sine.py +17 -0
- openbacktesting/indicators/cycles/ht_trendmode.py +10 -0
- openbacktesting/indicators/cycles/msw.py +19 -0
- openbacktesting/indicators/methods.py +5762 -0
- openbacktesting/indicators/momentum/__init__.py +0 -0
- openbacktesting/indicators/momentum/ac.py +9 -0
- openbacktesting/indicators/momentum/ao.py +10 -0
- openbacktesting/indicators/momentum/apo.py +10 -0
- openbacktesting/indicators/momentum/bias.py +10 -0
- openbacktesting/indicators/momentum/bop.py +10 -0
- openbacktesting/indicators/momentum/brar.py +26 -0
- openbacktesting/indicators/momentum/cci.py +10 -0
- openbacktesting/indicators/momentum/cfo.py +10 -0
- openbacktesting/indicators/momentum/cg.py +10 -0
- openbacktesting/indicators/momentum/cmo.py +10 -0
- openbacktesting/indicators/momentum/coppock.py +10 -0
- openbacktesting/indicators/momentum/crsi.py +28 -0
- openbacktesting/indicators/momentum/cti.py +10 -0
- openbacktesting/indicators/momentum/dm.py +17 -0
- openbacktesting/indicators/momentum/er.py +10 -0
- openbacktesting/indicators/momentum/eri.py +17 -0
- openbacktesting/indicators/momentum/fisher.py +17 -0
- openbacktesting/indicators/momentum/fosc.py +10 -0
- openbacktesting/indicators/momentum/gator.py +13 -0
- openbacktesting/indicators/momentum/ibs.py +7 -0
- openbacktesting/indicators/momentum/inertia.py +22 -0
- openbacktesting/indicators/momentum/kdj.py +18 -0
- openbacktesting/indicators/momentum/kst.py +30 -0
- openbacktesting/indicators/momentum/lrsi.py +10 -0
- openbacktesting/indicators/momentum/macd.py +27 -0
- openbacktesting/indicators/momentum/macdext.py +27 -0
- openbacktesting/indicators/momentum/macdfix.py +18 -0
- openbacktesting/indicators/momentum/mom.py +10 -0
- openbacktesting/indicators/momentum/pgo.py +10 -0
- openbacktesting/indicators/momentum/pmo.py +13 -0
- openbacktesting/indicators/momentum/po.py +10 -0
- openbacktesting/indicators/momentum/ppo.py +20 -0
- openbacktesting/indicators/momentum/psl.py +12 -0
- openbacktesting/indicators/momentum/pvo.py +20 -0
- openbacktesting/indicators/momentum/qqe.py +31 -0
- openbacktesting/indicators/momentum/rci.py +20 -0
- openbacktesting/indicators/momentum/rmi.py +7 -0
- openbacktesting/indicators/momentum/roc.py +10 -0
- openbacktesting/indicators/momentum/rocp.py +10 -0
- openbacktesting/indicators/momentum/rocr.py +10 -0
- openbacktesting/indicators/momentum/rocr100.py +10 -0
- openbacktesting/indicators/momentum/rsi.py +10 -0
- openbacktesting/indicators/momentum/rsx.py +10 -0
- openbacktesting/indicators/momentum/rvgi.py +26 -0
- openbacktesting/indicators/momentum/slope.py +17 -0
- openbacktesting/indicators/momentum/smc_sweep.py +18 -0
- openbacktesting/indicators/momentum/smi.py +21 -0
- openbacktesting/indicators/momentum/smi_stochastic.py +15 -0
- openbacktesting/indicators/momentum/squeeze.py +47 -0
- openbacktesting/indicators/momentum/squeeze_pro.py +53 -0
- openbacktesting/indicators/momentum/stc.py +20 -0
- openbacktesting/indicators/momentum/stoch.py +19 -0
- openbacktesting/indicators/momentum/stochf.py +19 -0
- openbacktesting/indicators/momentum/stochrsi.py +19 -0
- openbacktesting/indicators/momentum/td_seq.py +17 -0
- openbacktesting/indicators/momentum/trix.py +19 -0
- openbacktesting/indicators/momentum/trixh.py +20 -0
- openbacktesting/indicators/momentum/tsi.py +26 -0
- openbacktesting/indicators/momentum/uo.py +22 -0
- openbacktesting/indicators/momentum/vwmacd.py +20 -0
- openbacktesting/indicators/momentum/wavetrend.py +15 -0
- openbacktesting/indicators/momentum/willr.py +10 -0
- openbacktesting/indicators/overlap/__init__.py +0 -0
- openbacktesting/indicators/overlap/alligator.py +13 -0
- openbacktesting/indicators/overlap/alma.py +33 -0
- openbacktesting/indicators/overlap/anchored_vwap.py +50 -0
- openbacktesting/indicators/overlap/anchored_vwap_bands.py +13 -0
- openbacktesting/indicators/overlap/avgprice.py +10 -0
- openbacktesting/indicators/overlap/dema.py +10 -0
- openbacktesting/indicators/overlap/ema.py +12 -0
- openbacktesting/indicators/overlap/frama.py +29 -0
- openbacktesting/indicators/overlap/fwma.py +10 -0
- openbacktesting/indicators/overlap/hilo.py +26 -0
- openbacktesting/indicators/overlap/hl2.py +10 -0
- openbacktesting/indicators/overlap/hlc3.py +10 -0
- openbacktesting/indicators/overlap/hma.py +10 -0
- openbacktesting/indicators/overlap/ht_trendline.py +10 -0
- openbacktesting/indicators/overlap/hwma.py +10 -0
- openbacktesting/indicators/overlap/ichimoku.py +44 -0
- openbacktesting/indicators/overlap/jma.py +10 -0
- openbacktesting/indicators/overlap/kama.py +10 -0
- openbacktesting/indicators/overlap/linreg.py +15 -0
- openbacktesting/indicators/overlap/linregangle.py +10 -0
- openbacktesting/indicators/overlap/linregintercept.py +10 -0
- openbacktesting/indicators/overlap/linregslope.py +10 -0
- openbacktesting/indicators/overlap/ma.py +10 -0
- openbacktesting/indicators/overlap/ma_envelopes.py +16 -0
- openbacktesting/indicators/overlap/mama.py +17 -0
- openbacktesting/indicators/overlap/mavp.py +17 -0
- openbacktesting/indicators/overlap/mcgd.py +10 -0
- openbacktesting/indicators/overlap/medprice.py +10 -0
- openbacktesting/indicators/overlap/midpoint.py +10 -0
- openbacktesting/indicators/overlap/midprice.py +10 -0
- openbacktesting/indicators/overlap/mmar.py +21 -0
- openbacktesting/indicators/overlap/ohlc4.py +10 -0
- openbacktesting/indicators/overlap/pwma.py +10 -0
- openbacktesting/indicators/overlap/rainbow.py +25 -0
- openbacktesting/indicators/overlap/rma.py +10 -0
- openbacktesting/indicators/overlap/sinwma.py +10 -0
- openbacktesting/indicators/overlap/sma.py +14 -0
- openbacktesting/indicators/overlap/ssf.py +10 -0
- openbacktesting/indicators/overlap/supertrend.py +21 -0
- openbacktesting/indicators/overlap/swma.py +10 -0
- openbacktesting/indicators/overlap/t3.py +10 -0
- openbacktesting/indicators/overlap/tema.py +10 -0
- openbacktesting/indicators/overlap/trima.py +10 -0
- openbacktesting/indicators/overlap/tsf.py +10 -0
- openbacktesting/indicators/overlap/typprice.py +10 -0
- openbacktesting/indicators/overlap/vidya.py +10 -0
- openbacktesting/indicators/overlap/vwap.py +10 -0
- openbacktesting/indicators/overlap/vwma.py +10 -0
- openbacktesting/indicators/overlap/wcp.py +10 -0
- openbacktesting/indicators/overlap/wma.py +10 -0
- openbacktesting/indicators/overlap/zlma.py +10 -0
- openbacktesting/indicators/performance/__init__.py +0 -0
- openbacktesting/indicators/performance/drawdown.py +18 -0
- openbacktesting/indicators/performance/log_return.py +10 -0
- openbacktesting/indicators/performance/percent_return.py +10 -0
- openbacktesting/indicators/predicates.py +88 -0
- openbacktesting/indicators/registry.py +571 -0
- openbacktesting/indicators/runtime.py +290 -0
- openbacktesting/indicators/statistics/__init__.py +0 -0
- openbacktesting/indicators/statistics/beta.py +10 -0
- openbacktesting/indicators/statistics/correl.py +10 -0
- openbacktesting/indicators/statistics/entropy.py +10 -0
- openbacktesting/indicators/statistics/kurtosis.py +10 -0
- openbacktesting/indicators/statistics/mad.py +10 -0
- openbacktesting/indicators/statistics/md.py +10 -0
- openbacktesting/indicators/statistics/median.py +10 -0
- openbacktesting/indicators/statistics/mode.py +48 -0
- openbacktesting/indicators/statistics/quantile.py +10 -0
- openbacktesting/indicators/statistics/skew.py +10 -0
- openbacktesting/indicators/statistics/stderr.py +10 -0
- openbacktesting/indicators/statistics/stdev.py +10 -0
- openbacktesting/indicators/statistics/variance.py +10 -0
- openbacktesting/indicators/statistics/zscore.py +10 -0
- openbacktesting/indicators/trend/__init__.py +0 -0
- openbacktesting/indicators/trend/adx.py +28 -0
- openbacktesting/indicators/trend/adxr.py +28 -0
- openbacktesting/indicators/trend/amat.py +19 -0
- openbacktesting/indicators/trend/aroon.py +18 -0
- openbacktesting/indicators/trend/atr_stop.py +33 -0
- openbacktesting/indicators/trend/chop.py +20 -0
- openbacktesting/indicators/trend/cksp.py +17 -0
- openbacktesting/indicators/trend/cpr.py +57 -0
- openbacktesting/indicators/trend/decay.py +10 -0
- openbacktesting/indicators/trend/decreasing.py +18 -0
- openbacktesting/indicators/trend/dpo.py +12 -0
- openbacktesting/indicators/trend/dx.py +19 -0
- openbacktesting/indicators/trend/edecay.py +10 -0
- openbacktesting/indicators/trend/increasing.py +18 -0
- openbacktesting/indicators/trend/long_run.py +10 -0
- openbacktesting/indicators/trend/minus_dm.py +10 -0
- openbacktesting/indicators/trend/pivot_points.py +89 -0
- openbacktesting/indicators/trend/pivothigh.py +23 -0
- openbacktesting/indicators/trend/pivotlow.py +23 -0
- openbacktesting/indicators/trend/plus_dm.py +10 -0
- openbacktesting/indicators/trend/pmax.py +18 -0
- openbacktesting/indicators/trend/psar.py +19 -0
- openbacktesting/indicators/trend/qstick.py +10 -0
- openbacktesting/indicators/trend/sarext.py +35 -0
- openbacktesting/indicators/trend/short_run.py +10 -0
- openbacktesting/indicators/trend/tsignals.py +26 -0
- openbacktesting/indicators/trend/ttm_trend.py +16 -0
- openbacktesting/indicators/trend/vhf.py +10 -0
- openbacktesting/indicators/trend/volatility_stop.py +33 -0
- openbacktesting/indicators/trend/vortex.py +17 -0
- openbacktesting/indicators/trend/xsignals.py +29 -0
- openbacktesting/indicators/types.py +344 -0
- openbacktesting/indicators/utility/__init__.py +0 -0
- openbacktesting/indicators/utility/barssince.py +21 -0
- openbacktesting/indicators/utility/change.py +7 -0
- openbacktesting/indicators/utility/cross.py +12 -0
- openbacktesting/indicators/utility/crossover.py +11 -0
- openbacktesting/indicators/utility/crossunder.py +11 -0
- openbacktesting/indicators/utility/cum.py +7 -0
- openbacktesting/indicators/utility/falling.py +10 -0
- openbacktesting/indicators/utility/highest.py +7 -0
- openbacktesting/indicators/utility/highestbars.py +29 -0
- openbacktesting/indicators/utility/lowest.py +7 -0
- openbacktesting/indicators/utility/lowestbars.py +29 -0
- openbacktesting/indicators/utility/percentile_linear_interpolation.py +12 -0
- openbacktesting/indicators/utility/percentile_nearest_rank.py +16 -0
- openbacktesting/indicators/utility/percentrank.py +7 -0
- openbacktesting/indicators/utility/range.py +8 -0
- openbacktesting/indicators/utility/rising.py +10 -0
- openbacktesting/indicators/utility/rolling_count.py +12 -0
- openbacktesting/indicators/utility/rolling_sum.py +7 -0
- openbacktesting/indicators/utility/running_max.py +7 -0
- openbacktesting/indicators/utility/running_min.py +7 -0
- openbacktesting/indicators/utility/shift.py +7 -0
- openbacktesting/indicators/utility/valuewhen.py +25 -0
- openbacktesting/indicators/volatility/__init__.py +0 -0
- openbacktesting/indicators/volatility/aberration.py +21 -0
- openbacktesting/indicators/volatility/accbands.py +20 -0
- openbacktesting/indicators/volatility/adr.py +7 -0
- openbacktesting/indicators/volatility/atr.py +12 -0
- openbacktesting/indicators/volatility/avolume.py +10 -0
- openbacktesting/indicators/volatility/bbands.py +20 -0
- openbacktesting/indicators/volatility/ce.py +25 -0
- openbacktesting/indicators/volatility/cvi.py +10 -0
- openbacktesting/indicators/volatility/donchian.py +20 -0
- openbacktesting/indicators/volatility/hvol.py +10 -0
- openbacktesting/indicators/volatility/hwc.py +27 -0
- openbacktesting/indicators/volatility/kc.py +27 -0
- openbacktesting/indicators/volatility/massi.py +10 -0
- openbacktesting/indicators/volatility/natr.py +19 -0
- openbacktesting/indicators/volatility/pdist.py +10 -0
- openbacktesting/indicators/volatility/rvi.py +21 -0
- openbacktesting/indicators/volatility/starc.py +11 -0
- openbacktesting/indicators/volatility/thermo.py +28 -0
- openbacktesting/indicators/volatility/true_range.py +31 -0
- openbacktesting/indicators/volatility/ui.py +10 -0
- openbacktesting/indicators/volume/__init__.py +0 -0
- openbacktesting/indicators/volume/ad.py +10 -0
- openbacktesting/indicators/volume/adosc.py +19 -0
- openbacktesting/indicators/volume/aobv.py +31 -0
- openbacktesting/indicators/volume/cmf.py +12 -0
- openbacktesting/indicators/volume/efi.py +12 -0
- openbacktesting/indicators/volume/emv.py +10 -0
- openbacktesting/indicators/volume/eom.py +19 -0
- openbacktesting/indicators/volume/iii.py +9 -0
- openbacktesting/indicators/volume/kvo.py +28 -0
- openbacktesting/indicators/volume/marketfi.py +10 -0
- openbacktesting/indicators/volume/mfi.py +12 -0
- openbacktesting/indicators/volume/nvi.py +26 -0
- openbacktesting/indicators/volume/obv.py +10 -0
- openbacktesting/indicators/volume/pvi.py +26 -0
- openbacktesting/indicators/volume/pvol.py +10 -0
- openbacktesting/indicators/volume/pvr.py +10 -0
- openbacktesting/indicators/volume/pvt.py +10 -0
- openbacktesting/indicators/volume/rvol.py +8 -0
- openbacktesting/indicators/volume/vfi.py +18 -0
- openbacktesting/indicators/volume/vosc.py +10 -0
- openbacktesting/indicators/volume/wad.py +10 -0
- openbacktesting/indicators/volume/wvad.py +9 -0
- openbacktesting/inputs.py +51 -0
- openbacktesting/lib.py +31 -0
- openbacktesting/logs.py +129 -0
- openbacktesting/optimization.py +8 -0
- openbacktesting/optimizer/__init__.py +25 -0
- openbacktesting/optimizer/_semantics.py +155 -0
- openbacktesting/optimizer/identity.py +45 -0
- openbacktesting/optimizer/models.py +92 -0
- openbacktesting/optimizer/plan.py +129 -0
- openbacktesting/optimizer/portfolio-result.schema.json +4984 -0
- openbacktesting/optimizer/query.py +257 -0
- openbacktesting/optimizer/runner.py +98 -0
- openbacktesting/optimizer/storage.py +261 -0
- openbacktesting/optimizer/validation.py +64 -0
- openbacktesting/parallel.py +9 -0
- openbacktesting/plotting/__init__.py +23 -0
- openbacktesting/plotting/collector.py +509 -0
- openbacktesting/plotting/encoding.py +102 -0
- openbacktesting/plotting/types.py +92 -0
- openbacktesting/portfolio/__init__.py +15 -0
- openbacktesting/portfolio/analysis.py +245 -0
- openbacktesting/portfolio/builder.py +381 -0
- openbacktesting/portfolio/catalog.json +1404 -0
- openbacktesting/portfolio/helpers.py +92 -0
- openbacktesting/portfolio/metrics.py +186 -0
- openbacktesting/portfolio/models.py +63 -0
- openbacktesting/portfolio/periods.py +164 -0
- openbacktesting/portfolio/rates.py +14 -0
- openbacktesting/portfolio/snapshot.py +111 -0
- openbacktesting/portfolio/stats.py +272 -0
- openbacktesting/portfolio/trades.py +136 -0
- openbacktesting/portfolio/trading.py +215 -0
- openbacktesting/py.typed +0 -0
- openbacktesting/runtime.py +330 -0
- openbacktesting/simulation/__init__.py +17 -0
- openbacktesting/simulation/collection.py +13 -0
- openbacktesting/simulation/config.py +241 -0
- openbacktesting/simulation/core.py +528 -0
- openbacktesting/simulation/optimization.py +326 -0
- openbacktesting/simulation/parallel.py +145 -0
- openbacktesting/simulation/variants.py +107 -0
- openbacktesting/strategy/__init__.py +19 -0
- openbacktesting/strategy/bar_state.py +14 -0
- openbacktesting/strategy/base.py +810 -0
- openbacktesting/strategy/declaration.py +90 -0
- openbacktesting/strategy/helpers.py +198 -0
- openbacktesting/strategy/inputs.py +460 -0
- openbacktesting/strategy/sizing.py +80 -0
- openbacktesting/strategy/templates.py +160 -0
- openbacktesting/strategy_data.py +10 -0
- openbacktesting/test/BTCUSD.csv +157 -0
- openbacktesting/test/EURUSD.csv +5001 -0
- openbacktesting/test/GOOG.csv +2149 -0
- openbacktesting/test/__init__.py +29 -0
- openbacktesting/test/__main__.py +11 -0
- openbacktesting/test/_test.py +1312 -0
- openbacktesting/util.py +31 -0
- openbacktesting-0.2.0.dist-info/METADATA +151 -0
- openbacktesting-0.2.0.dist-info/RECORD +350 -0
- openbacktesting-0.2.0.dist-info/WHEEL +4 -0
- openbacktesting-0.2.0.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Fixed indicator bindings; third-party defaults are not OpenBacktesting public contracts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
from .types import IndicatorError, IndicatorSpec, Parameter
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def load_specs():
|
|
12
|
+
import json
|
|
13
|
+
from importlib.resources import files
|
|
14
|
+
|
|
15
|
+
rows = json.loads(files("openbacktesting.indicators").joinpath("catalog.json").read_text())[
|
|
16
|
+
"entries"
|
|
17
|
+
]
|
|
18
|
+
specs = []
|
|
19
|
+
for row in rows:
|
|
20
|
+
row = row.copy()
|
|
21
|
+
del row["test"]
|
|
22
|
+
row["parameters"] = tuple(
|
|
23
|
+
(name, Parameter(**(rule | {"choices": tuple(rule.get("choices", ()))})))
|
|
24
|
+
for name, rule in row["parameters"].items()
|
|
25
|
+
)
|
|
26
|
+
row["fixed"] = tuple(row["fixed"].items())
|
|
27
|
+
row["aliases"] = tuple(row.get("aliases", {}).items())
|
|
28
|
+
row["input_args"] = tuple(row.get("input_args", ()))
|
|
29
|
+
row["input_defaults"] = tuple(row.get("input_defaults", {}).items())
|
|
30
|
+
row["history_sum"] = tuple(tuple(term) for term in row.get("history_sum", ()))
|
|
31
|
+
for key in ("inputs", "outputs", "windows"):
|
|
32
|
+
row[key] = tuple(row[key])
|
|
33
|
+
if row["required"] is not None:
|
|
34
|
+
row["required"] = tuple(row["required"])
|
|
35
|
+
specs.append(IndicatorSpec(**row))
|
|
36
|
+
if len({spec.id for spec in specs}) != len(specs):
|
|
37
|
+
raise ValueError("Duplicate indicator identity")
|
|
38
|
+
return tuple(specs)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
SPECS = load_specs()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def named_series(result, indicator, channel):
|
|
45
|
+
"""Each indicator file declares single-series semantics; values and index remain unchanged."""
|
|
46
|
+
if result is None:
|
|
47
|
+
return None
|
|
48
|
+
if not isinstance(result, pd.Series):
|
|
49
|
+
raise IndicatorError("output-contract", indicator, "A single-channel Series is required")
|
|
50
|
+
return result.rename(channel)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def named_frame(result, indicator, channels):
|
|
54
|
+
"""Validate the provider's column set, then order and convert columns to canonical channels by explicit names."""
|
|
55
|
+
if result is None:
|
|
56
|
+
return None
|
|
57
|
+
if (
|
|
58
|
+
not isinstance(result, pd.DataFrame)
|
|
59
|
+
or not result.columns.is_unique
|
|
60
|
+
or set(result.columns) != set(channels)
|
|
61
|
+
):
|
|
62
|
+
raise IndicatorError("output-contract", indicator, "Output columns do not match the fixed contract")
|
|
63
|
+
if tuple(result.columns) != tuple(channels):
|
|
64
|
+
result = result.loc[:, list(channels)]
|
|
65
|
+
return result.rename(columns=channels)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def to_arrays(spec, result, index, parameters):
|
|
69
|
+
if result is None:
|
|
70
|
+
minimum = spec.history_required(parameters)
|
|
71
|
+
if len(index) >= minimum:
|
|
72
|
+
raise IndicatorError("output-contract", spec.id, "Backend returned no result")
|
|
73
|
+
values = np.full((len(spec.outputs), len(index)), np.nan)
|
|
74
|
+
else:
|
|
75
|
+
if not isinstance(result, (pd.Series, pd.DataFrame)):
|
|
76
|
+
raise IndicatorError("output-contract", spec.id, "Backend must return an indexed series or table")
|
|
77
|
+
names = (result.name,) if isinstance(result, pd.Series) else tuple(result.columns)
|
|
78
|
+
if names != spec.outputs:
|
|
79
|
+
raise IndicatorError("output-contract", spec.id, "Canonical output names or order do not match")
|
|
80
|
+
if not result.index.equals(index):
|
|
81
|
+
raise IndicatorError("index-mismatch", spec.id, "Backend output index does not match")
|
|
82
|
+
try:
|
|
83
|
+
values = np.atleast_2d(result.to_numpy(dtype=float).T)
|
|
84
|
+
except (TypeError, ValueError) as error:
|
|
85
|
+
raise IndicatorError("output-contract", spec.id, "Backend output must be numeric") from error
|
|
86
|
+
if values.shape != (len(spec.outputs), len(index)):
|
|
87
|
+
raise IndicatorError("output-contract", spec.id, f"Invalid output shape: {values.shape}")
|
|
88
|
+
valid = np.isfinite(values)
|
|
89
|
+
if result is not None and "indicator_valid" in result.attrs:
|
|
90
|
+
declared = np.asarray(result.attrs["indicator_valid"])
|
|
91
|
+
if declared.dtype != np.dtype(bool) or declared.shape not in (values.shape, (len(index),)):
|
|
92
|
+
raise IndicatorError("output-contract", spec.id, "Invalid validity mask shape or type")
|
|
93
|
+
valid &= declared
|
|
94
|
+
return values, valid
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""ta.dsp: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.dsp import dsp as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_series
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, length, talib):
|
|
9
|
+
result = _calculate(close=close, length=length, talib=talib)
|
|
10
|
+
return named_series(result, "ta.dsp", "dsp")
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""ta.ebsw: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.ebsw import ebsw as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_series
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, length, bars, talib):
|
|
9
|
+
result = _calculate(close=close, length=length, bars=bars, talib=talib)
|
|
10
|
+
return named_series(result, "ta.ebsw", "ebsw")
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""ta.ht_dcperiod: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.ht_dcperiod import ht_dcperiod as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_series
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, talib):
|
|
9
|
+
result = _calculate(close=close, talib=talib)
|
|
10
|
+
return named_series(result, "ta.ht_dcperiod", "ht_dcperiod")
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""ta.ht_dcphase: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.ht_dcphase import ht_dcphase as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_series
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, talib):
|
|
9
|
+
result = _calculate(close=close, talib=talib)
|
|
10
|
+
return named_series(result, "ta.ht_dcphase", "ht_dcphase")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""ta.ht_phasor: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.ht_phasor import ht_phasor as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_frame
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, talib):
|
|
9
|
+
result = _calculate(close=close, talib=talib)
|
|
10
|
+
return named_frame(
|
|
11
|
+
result,
|
|
12
|
+
"ta.ht_phasor",
|
|
13
|
+
{
|
|
14
|
+
"HT_PHASOR_INPHASE": "inphase",
|
|
15
|
+
"HT_PHASOR_QUAD": "quadrature",
|
|
16
|
+
},
|
|
17
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""ta.ht_sine: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.ht_sine import ht_sine as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_frame
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, talib):
|
|
9
|
+
result = _calculate(close=close, talib=talib)
|
|
10
|
+
return named_frame(
|
|
11
|
+
result,
|
|
12
|
+
"ta.ht_sine",
|
|
13
|
+
{
|
|
14
|
+
"HT_SINE": "sine",
|
|
15
|
+
"HT_LEADSINE": "lead_sine",
|
|
16
|
+
},
|
|
17
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""ta.ht_trendmode: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.ht_trendmode import ht_trendmode as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_series
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, talib):
|
|
9
|
+
result = _calculate(close=close, talib=talib)
|
|
10
|
+
return named_series(result, "ta.ht_trendmode", "ht_trendmode")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""ta.msw: Computation wrapper for the pinned dependency with canonical outputs."""
|
|
2
|
+
|
|
3
|
+
from pandas_ta_classic.cycles.msw import msw as _calculate
|
|
4
|
+
|
|
5
|
+
from ..common import named_frame
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compute(*, close, period, talib):
|
|
9
|
+
result = _calculate(close=close, period=period, talib=talib)
|
|
10
|
+
# The pinned version interprets period=1 as 5; preserve existing calculations and naming.
|
|
11
|
+
period = period if period > 1 else 5
|
|
12
|
+
return named_frame(
|
|
13
|
+
result,
|
|
14
|
+
"ta.msw",
|
|
15
|
+
{
|
|
16
|
+
f"MSW_SINE_{period}": "sine",
|
|
17
|
+
f"MSW_LEAD_{period}": "lead_sine",
|
|
18
|
+
},
|
|
19
|
+
)
|