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,160 @@
|
|
|
1
|
+
"""Existing implementations moved from lib: SignalStrategy, TrailingStrategy."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
from openbacktesting.helpers import _set_legacy_module
|
|
11
|
+
from openbacktesting.strategy.base import Strategy
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SignalStrategy(Strategy):
|
|
15
|
+
"""Composable strategy base class driven by precomputed entry and exit signals.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
A simple helper strategy that operates on position entry/exit signals.
|
|
19
|
+
This makes the backtest of the strategy simulate a [vectorized backtest].
|
|
20
|
+
See runnable examples in the user guide.
|
|
21
|
+
|
|
22
|
+
[vectorized backtest]: https://altpower.app/?q=vectorized+backtest
|
|
23
|
+
|
|
24
|
+
To use this helper strategy, subclass it, override its
|
|
25
|
+
`openbacktesting.engine.Strategy.init` method,
|
|
26
|
+
and set the signal vector by calling
|
|
27
|
+
`openbacktesting.lib.SignalStrategy.set_signal` method from within it.
|
|
28
|
+
|
|
29
|
+
class ExampleStrategy(SignalStrategy):
|
|
30
|
+
def init(self):
|
|
31
|
+
super().init()
|
|
32
|
+
self.set_signal(sma1 > sma2, sma1 < sma2)
|
|
33
|
+
|
|
34
|
+
Remember to call `super().init()` and `super().next()` in your
|
|
35
|
+
overridden methods.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
__entry_signal = (0,)
|
|
39
|
+
__exit_signal = (False,)
|
|
40
|
+
|
|
41
|
+
def set_signal(
|
|
42
|
+
self,
|
|
43
|
+
entry_size: Sequence[float],
|
|
44
|
+
exit_portion: Sequence[float] | None = None,
|
|
45
|
+
):
|
|
46
|
+
"""Register actual asset quantities and exit-fraction sequences; positive opens long, negative opens short, zero does not enter.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Set entry/exit signal vectors (arrays).
|
|
50
|
+
|
|
51
|
+
A long entry signal is considered present wherever `entry_size`
|
|
52
|
+
is greater than zero, and a short signal wherever `entry_size`
|
|
53
|
+
is less than zero, following `openbacktesting.engine.Order.size` semantics.
|
|
54
|
+
|
|
55
|
+
If `exit_portion` is provided, a nonzero value closes portion the position
|
|
56
|
+
(see `openbacktesting.engine.Trade.close()`) in the respective direction
|
|
57
|
+
(positive values close long trades, negative short).
|
|
58
|
+
|
|
59
|
+
Sparse signals do not affect per-bar callbacks; NaN does not trigger trades.
|
|
60
|
+
"""
|
|
61
|
+
self.__entry_signal = self.ind( # type: ignore
|
|
62
|
+
lambda: pd.Series(entry_size, dtype=float).replace(0, np.nan).to_numpy(),
|
|
63
|
+
name="entry size",
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if exit_portion is not None:
|
|
67
|
+
self.__exit_signal = self.ind( # type: ignore
|
|
68
|
+
lambda: pd.Series(exit_portion, dtype=float).replace(0, np.nan).to_numpy(),
|
|
69
|
+
name="exit portion",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def next(self):
|
|
73
|
+
super().next()
|
|
74
|
+
|
|
75
|
+
exit_portion = self.__exit_signal[-1]
|
|
76
|
+
if exit_portion > 0:
|
|
77
|
+
for trade in self.trades:
|
|
78
|
+
if trade.is_long:
|
|
79
|
+
trade.close(exit_portion)
|
|
80
|
+
elif exit_portion < 0:
|
|
81
|
+
for trade in self.trades:
|
|
82
|
+
if trade.is_short:
|
|
83
|
+
trade.close(-exit_portion)
|
|
84
|
+
|
|
85
|
+
entry_size = self.__entry_signal[-1]
|
|
86
|
+
if entry_size > 0:
|
|
87
|
+
self.buy(qty=entry_size)
|
|
88
|
+
elif entry_size < 0:
|
|
89
|
+
self.sell(qty=-entry_size)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class TrailingStrategy(Strategy):
|
|
93
|
+
"""Composable strategy base class that updates trade stop losses using ATR.
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
A strategy with automatic trailing stop-loss, trailing the current
|
|
97
|
+
price at distance of some multiple of average true range (ATR). Call
|
|
98
|
+
`TrailingStrategy.set_trailing_sl()` to set said multiple
|
|
99
|
+
(`6` by default).
|
|
100
|
+
See runnable examples in the user guide.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
Remember to call `super().init()` and `super().next()` in your
|
|
104
|
+
overridden methods.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
__n_atr = 6.0
|
|
108
|
+
__atr = None
|
|
109
|
+
__pct = None
|
|
110
|
+
|
|
111
|
+
def init(self):
|
|
112
|
+
super().init()
|
|
113
|
+
self.set_atr_periods()
|
|
114
|
+
|
|
115
|
+
def set_atr_periods(self, periods: int = 100):
|
|
116
|
+
"""Set the causal ATR window, default 100; do not backfill or set ATR stops during warmup."""
|
|
117
|
+
hi, lo, c_prev = self.data.High, self.data.Low, pd.Series(self.data.Close).shift(1)
|
|
118
|
+
tr = np.max([hi - lo, (c_prev - hi).abs(), (c_prev - lo).abs()], axis=0)
|
|
119
|
+
atr = pd.Series(tr).rolling(periods).mean().values
|
|
120
|
+
self.__atr = atr
|
|
121
|
+
|
|
122
|
+
def set_trailing_sl(self, n_atr: float = 6):
|
|
123
|
+
"""Set the ATR multiple for subsequent trailing stops.
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
Set the future trailing stop-loss as some multiple (`n_atr`)
|
|
127
|
+
average true bar ranges away from the current price.
|
|
128
|
+
"""
|
|
129
|
+
self.__n_atr = n_atr
|
|
130
|
+
self.__pct = None
|
|
131
|
+
|
|
132
|
+
def set_trailing_pct(self, pct: float = 0.05):
|
|
133
|
+
"""Calculate percentage distance from the currently confirmed price, default 5%, without full-sample estimation.
|
|
134
|
+
|
|
135
|
+
pct must be between 0 and 1. Long stops move only upward, short stops only downward; updates take effect no earlier than the next bar.
|
|
136
|
+
next runs on each bar; skip stop updates until ATR is ready, while percentage mode is independent of ATR.
|
|
137
|
+
"""
|
|
138
|
+
assert 0 < pct < 1, "Need pct= as rate, i.e. 5% == 0.05"
|
|
139
|
+
self.__pct = pct
|
|
140
|
+
|
|
141
|
+
def next(self):
|
|
142
|
+
super().next()
|
|
143
|
+
# Can't use index=-1 because self.__atr is not an Indicator type
|
|
144
|
+
index = len(self.data) - 1
|
|
145
|
+
distance = (
|
|
146
|
+
self.data.Close[index] * self.__pct
|
|
147
|
+
if self.__pct is not None
|
|
148
|
+
else self.__atr[index] * self.__n_atr
|
|
149
|
+
)
|
|
150
|
+
if not np.isfinite(distance):
|
|
151
|
+
return
|
|
152
|
+
for trade in self.trades:
|
|
153
|
+
if trade.is_long:
|
|
154
|
+
trade.sl = max(trade.sl or -np.inf, self.data.Close[index] - distance)
|
|
155
|
+
else:
|
|
156
|
+
trade.sl = min(trade.sl or np.inf, self.data.Close[index] + distance)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
_set_legacy_module(SignalStrategy, "openbacktesting.lib")
|
|
160
|
+
_set_legacy_module(TrailingStrategy, "openbacktesting.lib")
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Compatibility exports for the old strategy_data path; implemented in data.strategy_data."""
|
|
2
|
+
|
|
3
|
+
from openbacktesting.data.strategy_data import (
|
|
4
|
+
DATA_NAMES,
|
|
5
|
+
DERIVED,
|
|
6
|
+
PRICE_COLUMNS,
|
|
7
|
+
StrategyData,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = ["DATA_NAMES", "DERIVED", "PRICE_COLUMNS", "StrategyData"]
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
,Open,High,Low,Close,Volume
|
|
2
|
+
2012-01-31,4.58,7.38,3.8,5.55,2012.25343589
|
|
3
|
+
2012-02-29,5.55,6.5,3.8,4.99,4761.6090813
|
|
4
|
+
2012-03-31,4.99,5.44,4.54,4.92,9049.62628191
|
|
5
|
+
2012-04-30,4.92,5.43,4.69,5.0,16484.16777244
|
|
6
|
+
2012-05-31,5.0,5.15,4.86,5.14,18520.10380101
|
|
7
|
+
2012-06-30,5.14,6.69,5.1,6.54,63694.81610669
|
|
8
|
+
2012-07-31,6.54,9.28,6.36,9.2,50656.18175026
|
|
9
|
+
2012-08-31,9.2,16.41,7.1,9.81,82848.67116895
|
|
10
|
+
2012-09-30,9.81,12.66,9.49,12.17,56093.62696716
|
|
11
|
+
2012-10-31,12.17,12.99,9.5,10.75,83104.04747408
|
|
12
|
+
2012-11-30,10.75,12.74,10.25,12.42,88709.95682488
|
|
13
|
+
2012-12-31,12.42,13.94,12.24,13.24,91377.2908879
|
|
14
|
+
2013-01-31,13.24,21.0,12.77,20.79,124484.80488994
|
|
15
|
+
2013-02-28,20.79,34.24,19.5,33.98,123510.87774069
|
|
16
|
+
2013-03-31,33.98,97.0,32.96,94.08,178272.83745384
|
|
17
|
+
2013-04-30,94.08,259.34,45.0,136.84,437933.47186852
|
|
18
|
+
2013-05-31,136.83,141.28,81.5,127.24,300589.36039921
|
|
19
|
+
2013-06-30,127.24,128.86,86.2,89.0,250031.2382886
|
|
20
|
+
2013-07-31,89.01,101.0,63.0,99.67,419753.86745611
|
|
21
|
+
2013-08-31,98.72,132.8,90.0,131.24,328441.27534982
|
|
22
|
+
2013-09-30,131.24,134.95,115.0,126.24,322672.50941772
|
|
23
|
+
2013-10-31,126.24,206.6,85.0,203.74,625096.57168529
|
|
24
|
+
2013-11-30,203.7,1163.0,200.23,1110.09,965802.16510373
|
|
25
|
+
2013-12-31,1110.09,1153.27,382.21,734.33,953353.15686456
|
|
26
|
+
2014-01-31,734.33,995.0,725.0,801.46,444928.559971
|
|
27
|
+
2014-02-28,801.46,827.38,400.0,575.5,817663.79165669
|
|
28
|
+
2014-03-31,575.5,710.0,436.0,454.0,499158.1329599
|
|
29
|
+
2014-04-30,454.0,548.0,339.79,447.56,517371.75097255
|
|
30
|
+
2014-05-31,445.23,629.4,420.27,622.0,302311.93173703
|
|
31
|
+
2014-06-30,621.01,683.26,538.38,643.41,288960.8787793
|
|
32
|
+
2014-07-31,643.5,658.88,555.9,588.5,161612.26069054
|
|
33
|
+
2014-08-31,588.98,607.2,442.0,477.78,314687.67223104
|
|
34
|
+
2014-09-30,477.75,497.0,365.2,392.64,343002.80183706
|
|
35
|
+
2014-10-31,392.83,417.99,275.0,341.82,599895.44176646
|
|
36
|
+
2014-11-30,341.82,453.92,316.61,376.43,439599.74922191
|
|
37
|
+
2014-12-31,376.43,383.0,304.99,316.67,294441.85716544
|
|
38
|
+
2015-01-31,316.67,321.0,152.4,230.59,780354.02856165
|
|
39
|
+
2015-02-28,230.58,267.92,208.48,252.0,351708.96955626
|
|
40
|
+
2015-03-31,252.0,297.95,236.4,242.92,297384.58919865
|
|
41
|
+
2015-04-30,242.92,262.98,210.0,236.76,254714.59684772
|
|
42
|
+
2015-05-31,236.69,247.01,227.01,231.52,201312.29784566
|
|
43
|
+
2015-06-30,231.5,268.0,219.03,261.78,232269.97896899
|
|
44
|
+
2015-07-31,261.7,317.99,252.4,286.11,397787.41249925003
|
|
45
|
+
2015-08-31,286.11,286.11,198.12,231.57,418565.66541576
|
|
46
|
+
2015-09-30,231.34,246.24,223.0,237.33,569485.98275971
|
|
47
|
+
2015-10-31,237.33,334.67,235.0,311.64,713856.53717602
|
|
48
|
+
2015-11-30,311.62,502.0,294.0,374.19,886628.21617438
|
|
49
|
+
2015-12-31,374.19,467.8,348.64,431.28,422649.12320094
|
|
50
|
+
2016-01-31,430.91,465.0,352.0,375.98,288372.04635443003
|
|
51
|
+
2016-02-29,375.19,447.99,364.7,435.9,216664.02664585
|
|
52
|
+
2016-03-31,435.9,437.5,382.0,416.43,157235.30346074
|
|
53
|
+
2016-04-30,416.52,470.02,412.0,449.02,121815.55977623
|
|
54
|
+
2016-05-31,449.46,548.5,435.0,522.72,135188.60074123
|
|
55
|
+
2016-06-30,522.72,778.85,518.0,664.01,287296.10902287
|
|
56
|
+
2016-07-31,662.6,704.99,605.5,631.09,118452.46361069
|
|
57
|
+
2016-08-31,632.15,632.35,465.28,571.78,147939.20461568
|
|
58
|
+
2016-09-30,571.78,628.99,566.86,604.84,91672.30316333
|
|
59
|
+
2016-10-31,604.84,717.99,604.27,704.89,100913.96726614
|
|
60
|
+
2016-11-30,704.89,755.07,670.32,741.55,154162.8690078
|
|
61
|
+
2016-12-31,741.38,980.74,740.18,963.16,172770.27429349
|
|
62
|
+
2017-01-31,963.16,1139.89,751.34,955.79,334633.61649253
|
|
63
|
+
2017-02-28,956.67,1220.0,913.73,1195.39,209911.79775014
|
|
64
|
+
2017-03-31,1198.65,1350.0,891.33,1069.99,321058.71480166
|
|
65
|
+
2017-04-30,1068.4,1347.02,1060.0,1334.83,163259.72058026
|
|
66
|
+
2017-05-31,1334.83,2760.1,1330.0,2304.63,463554.71382256
|
|
67
|
+
2017-06-30,2304.62,2980.0,2120.0,2519.89,447784.98744192
|
|
68
|
+
2017-07-31,2517.0,2938.0,1830.0,2837.44,442045.6083084
|
|
69
|
+
2017-08-31,2837.44,4765.21,2615.0,4719.85,376644.9184963
|
|
70
|
+
2017-09-30,4724.3,4979.9,2972.01,4318.07,517752.76661262
|
|
71
|
+
2017-10-31,4318.07,6420.0,4137.96,6343.37,372951.07664284
|
|
72
|
+
2017-11-30,6343.37,11395.0,5555.55,9639.17,483242.2094437
|
|
73
|
+
2017-12-31,9639.17,19666.0,9370.11,13808.19,565118.43385979
|
|
74
|
+
2018-01-31,13840.53,17234.99,9222.0,9974.52,464529.1276022
|
|
75
|
+
2018-02-28,9974.91,11780.0,5920.72,10483.3,579199.79782788
|
|
76
|
+
2018-03-31,10482.78,11688.0,6550.0,7058.0,478106.34717399
|
|
77
|
+
2018-04-30,7045.11,9755.53,6427.16,9326.6,383170.01395792
|
|
78
|
+
2018-05-31,9323.8,9948.98,7026.9,7539.49,315425.59588242
|
|
79
|
+
2018-06-30,7530.97,7790.69,5774.72,6325.68,245559.6538061
|
|
80
|
+
2018-07-31,6325.67,8496.96,6072.0,7751.32,241646.43315209
|
|
81
|
+
2018-08-31,7751.96,7777.0,5880.0,7041.0,241399.24730462
|
|
82
|
+
2018-09-30,7041.0,7411.85,6094.38,6575.99,161654.90973714
|
|
83
|
+
2018-10-31,6575.0,6756.0,6055.28,6305.0,118357.07729593
|
|
84
|
+
2018-11-30,6305.0,6544.0,3474.73,3970.2,342901.30674616
|
|
85
|
+
2018-12-31,3970.19,4265.0,3122.28,3750.76,360073.74259956
|
|
86
|
+
2019-01-31,3750.62,4112.0,3322.19,3400.32,206637.0603685
|
|
87
|
+
2019-02-28,3402.71,4190.0,3328.7,3815.17,203491.41348045
|
|
88
|
+
2019-03-31,3814.63,4130.36,3670.0,4095.43,164360.1407343
|
|
89
|
+
2019-04-30,4096.77,5627.0,4052.56,5234.42,294712.72910007
|
|
90
|
+
2019-05-31,5234.42,9096.79,5224.25,8439.24,369760.90186756
|
|
91
|
+
2019-06-30,8443.75,13880.0,7432.84,11231.06,334048.14503083
|
|
92
|
+
2019-07-31,11232.4,13200.0,9049.54,9999.82,371432.37053016
|
|
93
|
+
2019-08-31,9999.82,12325.0,9320.0,9571.07,249828.48704415
|
|
94
|
+
2019-09-30,9584.47,10949.0,7714.7,8279.81,212207.58622774
|
|
95
|
+
2019-10-31,8286.24,10350.0,7293.55,9235.75,272266.35117133
|
|
96
|
+
2019-11-30,9229.33,9586.5,6515.0,7484.43,187515.893454
|
|
97
|
+
2019-12-31,7486.4,7772.71,6425.0,7139.78,129187.45427156
|
|
98
|
+
2020-01-31,7145.05,9570.0,6853.53,9289.11,202205.00650995
|
|
99
|
+
2020-02-29,9297.2,10500.5,8421.49,8665.35,170803.9857347
|
|
100
|
+
2020-03-31,8668.38,9219.13,3850.0,6474.59,481627.36606521
|
|
101
|
+
2020-04-30,6472.89,9485.26,6137.71,8847.01,290721.68636726
|
|
102
|
+
2020-05-31,8845.12,10074.0,8109.0,9507.95,389152.9589669
|
|
103
|
+
2020-06-30,9511.65,10429.26,8830.63,9137.69,210537.6154726
|
|
104
|
+
2020-07-31,9130.01,11457.95,8905.0,11333.56,195823.3739246
|
|
105
|
+
2020-08-31,11333.15,12473.0,10559.59,11729.64,195276.00613798
|
|
106
|
+
2020-09-30,11726.45,12065.82,9825.07,10708.78,211186.60703888
|
|
107
|
+
2020-10-31,10703.81,14100.0,10380.0,13794.24,182466.93926815
|
|
108
|
+
2020-11-30,13788.52,19864.15,13220.0,19182.23,287212.66517677
|
|
109
|
+
2020-12-31,19169.68,29300.0,17569.58,28920.98,255441.8533217
|
|
110
|
+
2021-01-31,28912.47,42000.0,27734.0,32487.61,458594.99699076
|
|
111
|
+
2021-02-28,32489.13,58354.14,32333.01,43724.75,239530.1816549
|
|
112
|
+
2021-03-31,43741.54,61781.83,43500.0,58582.36,158944.2114241
|
|
113
|
+
2021-04-30,58601.17,64895.22,47004.2,57098.08,139436.88887224
|
|
114
|
+
2021-05-31,57092.42,59603.0,30066.0,36907.65,210064.3136653
|
|
115
|
+
2021-06-30,36903.62,41341.57,28600.0,34780.49,143938.56072363
|
|
116
|
+
2021-07-31,34786.46,42411.32,29296.39,41335.16,80418.08217585
|
|
117
|
+
2021-08-31,41317.48,50562.11,37300.0,47321.52,80413.50047533
|
|
118
|
+
2021-09-30,47306.81,52956.47,39573.21,43540.0,70069.98010061
|
|
119
|
+
2021-10-31,43545.62,67016.5,43094.68,60730.85,79149.8625657
|
|
120
|
+
2021-11-30,60726.59,69000.0,53308.93,58349.19,72105.12010534
|
|
121
|
+
2021-12-31,58383.09,59099.64,41967.5,46648.83,71785.05584799
|
|
122
|
+
2022-01-31,46659.24,47989.0,32950.72,38479.91,71899.99316572
|
|
123
|
+
2022-02-28,38495.66,45850.0,34324.05,41233.87,57380.73682106
|
|
124
|
+
2022-03-31,41228.49,48234.0,37169.52,45622.39,58763.17822661
|
|
125
|
+
2022-04-30,45617.11,47458.48,37701.0,38487.71,44056.48532558
|
|
126
|
+
2022-05-31,38484.87,40050.19,25401.05,31610.61,101260.23960562
|
|
127
|
+
2022-06-30,31610.61,31962.79,17592.78,18901.6,106576.31850953
|
|
128
|
+
2022-07-31,18892.96,24676.0,18595.6,23837.21,74680.83536261
|
|
129
|
+
2022-08-31,23848.21,25212.0,19526.0,20219.0,47733.30210383
|
|
130
|
+
2022-09-30,20222.0,22781.0,18157.0,19495.0,69753.68501266
|
|
131
|
+
2022-10-31,19486.0,21078.0,18183.0,20368.0,41439.48859683
|
|
132
|
+
2022-11-30,20364.0,21473.0,15479.0,16926.0,104475.30523474
|
|
133
|
+
2022-12-31,16924.0,18373.0,16293.0,16567.0,56088.35203051
|
|
134
|
+
2023-01-31,16567.0,23954.0,16471.0,23171.0,66320.27104302
|
|
135
|
+
2023-02-28,23170.0,25270.0,21376.0,23485.0,52595.32439011
|
|
136
|
+
2023-03-31,23486.0,29380.0,19569.0,28460.0,91293.2104313
|
|
137
|
+
2023-04-30,28462.0,31035.0,26981.0,29383.0,54257.14084866
|
|
138
|
+
2023-05-31,29374.0,29851.0,25800.0,27020.0,56558.53819176
|
|
139
|
+
2023-06-30,27024.0,31458.0,24756.0,30368.0,71551.9162833
|
|
140
|
+
2023-07-31,30364.0,31818.0,28842.0,29157.0,42732.81486405
|
|
141
|
+
2023-08-31,29153.0,30210.0,25350.0,26181.0,49687.89486586
|
|
142
|
+
2023-09-30,26147.0,27486.0,24920.0,27031.0,41507.07942807
|
|
143
|
+
2023-10-31,27031.0,35198.0,26533.0,34553.0,54795.56290504
|
|
144
|
+
2023-11-30,34541.0,38457.0,34102.0,37750.0,47345.71140283
|
|
145
|
+
2023-12-31,37750.0,44729.0,37619.0,42639.0,52898.75724539
|
|
146
|
+
2024-01-31,42652.0,49048.0,38505.0,43500.0,76690.93493603
|
|
147
|
+
2024-02-29,43500.0,64000.0,41859.0,60775.0,60701.55689144
|
|
148
|
+
2024-03-31,60791.0,73794.0,59313.0,71034.0,91665.33521704
|
|
149
|
+
2024-04-30,71088.0,72756.0,59068.0,59150.0,62854.23631911
|
|
150
|
+
2024-05-31,59160.0,71958.0,56500.0,67580.0,50415.87703833
|
|
151
|
+
2024-06-30,67584.0,71949.0,58456.0,61940.0,47461.77759895
|
|
152
|
+
2024-07-31,61931.0,70016.0,53550.0,65243.0,62827.71293164
|
|
153
|
+
2024-08-31,65228.0,65568.0,49577.0,58856.0,79937.43578756
|
|
154
|
+
2024-09-30,58857.0,65978.0,52546.0,63302.0,39381.43155523
|
|
155
|
+
2024-10-31,63331.0,72928.0,58867.0,72346.0,18285.91448949
|
|
156
|
+
2024-11-30,69109.0,99121.0,67459.0,97482.0,42421.51031367
|
|
157
|
+
2024-12-31,96515.0,108364.0,92092.0,93381.0,25342.80228337
|