back-trader-python 1.4.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.
- back_trader_python-1.4.0.dist-info/METADATA +1491 -0
- back_trader_python-1.4.0.dist-info/RECORD +465 -0
- back_trader_python-1.4.0.dist-info/WHEEL +5 -0
- back_trader_python-1.4.0.dist-info/licenses/LICENSE +674 -0
- back_trader_python-1.4.0.dist-info/top_level.txt +1 -0
- backtrader/__init__.py +148 -0
- backtrader/_cerebro/__init__.py +5 -0
- backtrader/_cerebro/channel.py +382 -0
- backtrader/_cerebro/execution.py +377 -0
- backtrader/_cerebro/lifecycle.py +143 -0
- backtrader/_cerebro/notifications.py +150 -0
- backtrader/_cerebro/presentation.py +230 -0
- backtrader/_cerebro/registry.py +593 -0
- backtrader/_cerebro/runnext.py +551 -0
- backtrader/_cerebro/runonce.py +142 -0
- backtrader/analyzer.py +594 -0
- backtrader/analyzers/__init__.py +50 -0
- backtrader/analyzers/annualreturn.py +226 -0
- backtrader/analyzers/calmar.py +165 -0
- backtrader/analyzers/drawdown.py +287 -0
- backtrader/analyzers/leverage.py +112 -0
- backtrader/analyzers/logreturnsrolling.py +190 -0
- backtrader/analyzers/periodstats.py +153 -0
- backtrader/analyzers/positions.py +119 -0
- backtrader/analyzers/pyfolio.py +470 -0
- backtrader/analyzers/returns.py +192 -0
- backtrader/analyzers/sharpe.py +307 -0
- backtrader/analyzers/sharpe_ratio_stats.py +534 -0
- backtrader/analyzers/sqn.py +112 -0
- backtrader/analyzers/timereturn.py +192 -0
- backtrader/analyzers/total_value.py +75 -0
- backtrader/analyzers/tradeanalyzer.py +278 -0
- backtrader/analyzers/transactions.py +141 -0
- backtrader/analyzers/vwr.py +245 -0
- backtrader/bokeh/__init__.py +155 -0
- backtrader/bokeh/analyzers/__init__.py +13 -0
- backtrader/bokeh/analyzers/plot.py +192 -0
- backtrader/bokeh/analyzers/recorder.py +181 -0
- backtrader/bokeh/app.py +1094 -0
- backtrader/bokeh/live/__init__.py +11 -0
- backtrader/bokeh/live/client.py +352 -0
- backtrader/bokeh/live/datahandler.py +346 -0
- backtrader/bokeh/plot_adapter.py +200 -0
- backtrader/bokeh/schemes/__init__.py +14 -0
- backtrader/bokeh/schemes/blackly.py +76 -0
- backtrader/bokeh/schemes/scheme.py +150 -0
- backtrader/bokeh/schemes/tradimo.py +82 -0
- backtrader/bokeh/tab.py +125 -0
- backtrader/bokeh/tabs/__init__.py +30 -0
- backtrader/bokeh/tabs/analyzer.py +120 -0
- backtrader/bokeh/tabs/config.py +154 -0
- backtrader/bokeh/tabs/live.py +109 -0
- backtrader/bokeh/tabs/log.py +185 -0
- backtrader/bokeh/tabs/metadata.py +182 -0
- backtrader/bokeh/tabs/performance.py +359 -0
- backtrader/bokeh/tabs/source.py +70 -0
- backtrader/bokeh/utils/__init__.py +8 -0
- backtrader/bokeh/utils/helpers.py +167 -0
- backtrader/bokeh/webapp.py +164 -0
- backtrader/broker.py +478 -0
- backtrader/brokers/__init__.py +36 -0
- backtrader/brokers/bbroker.py +2576 -0
- backtrader/brokers/btapibroker.py +8227 -0
- backtrader/brokers/hft/__init__.py +89 -0
- backtrader/brokers/hft/binance_bbo.py +625 -0
- backtrader/brokers/hft/binance_bbo_compare.py +1398 -0
- backtrader/brokers/hft/examples.py +1228 -0
- backtrader/brokers/hft/exchange.py +380 -0
- backtrader/brokers/hft/latency.py +309 -0
- backtrader/brokers/hft/matching_core.py +572 -0
- backtrader/brokers/hft/queue.py +238 -0
- backtrader/brokers/hft/recorder.py +88 -0
- backtrader/brokers/hft/state.py +138 -0
- backtrader/brokers/impact_models.py +118 -0
- backtrader/brokers/mixbroker.py +895 -0
- backtrader/brokers/tickbroker.py +1991 -0
- backtrader/btrun/__init__.py +12 -0
- backtrader/btrun/btrun.py +1218 -0
- backtrader/cerebro.py +828 -0
- backtrader/channel.py +682 -0
- backtrader/channels/__init__.py +23 -0
- backtrader/channels/bridge.py +186 -0
- backtrader/channels/funding.py +248 -0
- backtrader/channels/live_queue.py +216 -0
- backtrader/channels/live_validator.py +294 -0
- backtrader/channels/orderbook.py +257 -0
- backtrader/channels/tick.py +202 -0
- backtrader/comminfo.py +665 -0
- backtrader/commissions/__init__.py +106 -0
- backtrader/commissions/ctpoption.py +993 -0
- backtrader/configs/account_config_example.yaml +8 -0
- backtrader/dataseries.py +379 -0
- backtrader/errors.py +106 -0
- backtrader/events.py +980 -0
- backtrader/feed.py +1523 -0
- backtrader/feeds/__init__.py +75 -0
- backtrader/feeds/barrier.py +2006 -0
- backtrader/feeds/blaze.py +118 -0
- backtrader/feeds/btapifeed.py +1538 -0
- backtrader/feeds/btcsv.py +203 -0
- backtrader/feeds/chainer.py +114 -0
- backtrader/feeds/cryptohftdata.py +164 -0
- backtrader/feeds/csvgeneric.py +1205 -0
- backtrader/feeds/ctpcohort.py +1051 -0
- backtrader/feeds/influxfeed.py +158 -0
- backtrader/feeds/livefeed.py +71 -0
- backtrader/feeds/mixed_channel.py +108 -0
- backtrader/feeds/mt4csv.py +42 -0
- backtrader/feeds/pandafeed.py +381 -0
- backtrader/feeds/quandl.py +256 -0
- backtrader/feeds/rollover.py +229 -0
- backtrader/feeds/sierrachart.py +30 -0
- backtrader/feeds/vchart.py +162 -0
- backtrader/feeds/vchartcsv.py +84 -0
- backtrader/feeds/vchartfile.py +153 -0
- backtrader/feeds/yahoo.py +399 -0
- backtrader/fillers.py +148 -0
- backtrader/filters/__init__.py +34 -0
- backtrader/filters/bsplitter.py +127 -0
- backtrader/filters/calendardays.py +121 -0
- backtrader/filters/datafiller.py +192 -0
- backtrader/filters/datafilter.py +74 -0
- backtrader/filters/daysteps.py +96 -0
- backtrader/filters/heikinashi.py +63 -0
- backtrader/filters/renko.py +164 -0
- backtrader/filters/session.py +289 -0
- backtrader/flt.py +80 -0
- backtrader/functions.py +960 -0
- backtrader/indicator.py +449 -0
- backtrader/indicators/__init__.py +148 -0
- backtrader/indicators/accdecoscillator.py +110 -0
- backtrader/indicators/aroon.py +300 -0
- backtrader/indicators/atr.py +315 -0
- backtrader/indicators/awesomeoscillator.py +122 -0
- backtrader/indicators/basicops.py +834 -0
- backtrader/indicators/bollinger.py +223 -0
- backtrader/indicators/cci.py +89 -0
- backtrader/indicators/channels_ext.py +83 -0
- backtrader/indicators/contrib/__init__.py +228 -0
- backtrader/indicators/contrib/absolutely_no_lag_lwma.py +28 -0
- backtrader/indicators/contrib/absolutely_no_lag_lwma_color.py +44 -0
- backtrader/indicators/contrib/accumulation_distribution_line.py +92 -0
- backtrader/indicators/contrib/adx_cross_hull_style_indicator.py +249 -0
- backtrader/indicators/contrib/adxdmi.py +34 -0
- backtrader/indicators/contrib/ai_acceleration_deceleration_oscillator.py +34 -0
- backtrader/indicators/contrib/altr_trend_signal_v22.py +85 -0
- backtrader/indicators/contrib/anchored_momentum_line.py +115 -0
- backtrader/indicators/contrib/any_range_cld_tail_indicator.py +82 -0
- backtrader/indicators/contrib/aroon_horn_sign_indicator.py +96 -0
- backtrader/indicators/contrib/aroon_oscillator_sign_alert.py +50 -0
- backtrader/indicators/contrib/arrows_curves_indicator.py +112 -0
- backtrader/indicators/contrib/as_ctrend_indicator.py +143 -0
- backtrader/indicators/contrib/asimmetric_stoch_nr_indicator.py +187 -0
- backtrader/indicators/contrib/atr_normalize_histogram.py +118 -0
- backtrader/indicators/contrib/average_change_candle.py +165 -0
- backtrader/indicators/contrib/bb_squeeze_indicator.py +60 -0
- backtrader/indicators/contrib/bezier_st_dev_indicator.py +135 -0
- backtrader/indicators/contrib/binary_wave_indicator.py +233 -0
- backtrader/indicators/contrib/blau_c_momentum_indicator.py +123 -0
- backtrader/indicators/contrib/blau_cmi_indicator.py +141 -0
- backtrader/indicators/contrib/blau_csi.py +76 -0
- backtrader/indicators/contrib/blau_ergodic.py +53 -0
- backtrader/indicators/contrib/blau_t_stoch_i.py +72 -0
- backtrader/indicators/contrib/blau_ts_stochastic.py +85 -0
- backtrader/indicators/contrib/blau_tvi.py +55 -0
- backtrader/indicators/contrib/brain_trend2_indicator.py +128 -0
- backtrader/indicators/contrib/brain_trend_signal_proxy.py +47 -0
- backtrader/indicators/contrib/brake_parb_indicator.py +85 -0
- backtrader/indicators/contrib/breakout_bars_trend_v2.py +121 -0
- backtrader/indicators/contrib/bsi_indicator.py +87 -0
- backtrader/indicators/contrib/bulls_bears_eyes.py +67 -0
- backtrader/indicators/contrib/bulls_power.py +56 -0
- backtrader/indicators/contrib/bw_wise_man1_signal.py +102 -0
- backtrader/indicators/contrib/bykov_trend_indicator.py +85 -0
- backtrader/indicators/contrib/candle_stop_color.py +46 -0
- backtrader/indicators/contrib/candles_x_smoothed_indicator.py +69 -0
- backtrader/indicators/contrib/candlesticks_bw.py +45 -0
- backtrader/indicators/contrib/caudate_x_period_candle_color.py +56 -0
- backtrader/indicators/contrib/cci_histogram_indicator.py +53 -0
- backtrader/indicators/contrib/cci_woodies_indicator.py +80 -0
- backtrader/indicators/contrib/center_of_gravity_candle_indicator.py +83 -0
- backtrader/indicators/contrib/center_of_gravity_indicator.py +70 -0
- backtrader/indicators/contrib/cg_oscillator.py +40 -0
- backtrader/indicators/contrib/close_line_cci.py +38 -0
- backtrader/indicators/contrib/close_price_fractals.py +47 -0
- backtrader/indicators/contrib/color3rd_gen_xma_indicator.py +122 -0
- backtrader/indicators/contrib/color_bb_candles_indicator.py +108 -0
- backtrader/indicators/contrib/color_coppock_indicator.py +157 -0
- backtrader/indicators/contrib/color_hma.py +71 -0
- backtrader/indicators/contrib/color_j_variation_indicator.py +53 -0
- backtrader/indicators/contrib/color_metro_de_marker_indicator.py +78 -0
- backtrader/indicators/contrib/color_metro_stochastic_indicator.py +93 -0
- backtrader/indicators/contrib/color_metro_wpr_indicator.py +85 -0
- backtrader/indicators/contrib/color_schaff_de_marker_trend_cycle.py +92 -0
- backtrader/indicators/contrib/color_schaff_trend_cycle_indicator.py +203 -0
- backtrader/indicators/contrib/color_step_xccx_indicator.py +193 -0
- backtrader/indicators/contrib/color_x2_ma.py +49 -0
- backtrader/indicators/contrib/color_x_derivative.py +63 -0
- backtrader/indicators/contrib/color_zerolag_de_marker.py +84 -0
- backtrader/indicators/contrib/corrected_average_indicator.py +127 -0
- backtrader/indicators/contrib/darvas_boxes_system.py +73 -0
- backtrader/indicators/contrib/dema_range_channel_color.py +42 -0
- backtrader/indicators/contrib/derivative_indicator.py +95 -0
- backtrader/indicators/contrib/digital_ft01_indicator.py +112 -0
- backtrader/indicators/contrib/digital_macd.py +200 -0
- backtrader/indicators/contrib/donchian_channels_system.py +45 -0
- backtrader/indicators/contrib/dots_indicator.py +93 -0
- backtrader/indicators/contrib/ef_distance_indicator.py +82 -0
- backtrader/indicators/contrib/ema_rsi_va.py +80 -0
- backtrader/indicators/contrib/envelopes_jp_alonso.py +32 -0
- backtrader/indicators/contrib/f2a_ao_indicator.py +120 -0
- backtrader/indicators/contrib/fatl_filter.py +179 -0
- backtrader/indicators/contrib/fibo_candles_indicator.py +78 -0
- backtrader/indicators/contrib/fine_tuning_ma.py +100 -0
- backtrader/indicators/contrib/fisher_org_v1.py +102 -0
- backtrader/indicators/contrib/fisher_org_v1_sign.py +118 -0
- backtrader/indicators/contrib/force_index_ema.py +96 -0
- backtrader/indicators/contrib/force_index_ema_2.py +27 -0
- backtrader/indicators/contrib/forecast_oscilator.py +145 -0
- backtrader/indicators/contrib/fractal_amambk.py +81 -0
- backtrader/indicators/contrib/frama_series.py +84 -0
- backtrader/indicators/contrib/frasm_av2_indicator.py +104 -0
- backtrader/indicators/contrib/go_indicator.py +93 -0
- backtrader/indicators/contrib/hlr_indicator.py +95 -0
- backtrader/indicators/contrib/hma.py +50 -0
- backtrader/indicators/contrib/i4_drfv2.py +34 -0
- backtrader/indicators/contrib/i4_drfv3.py +38 -0
- backtrader/indicators/contrib/i_anch_mom_indicator.py +72 -0
- backtrader/indicators/contrib/i_de_marker_sign_indicator.py +64 -0
- backtrader/indicators/contrib/i_gap_indicator.py +45 -0
- backtrader/indicators/contrib/i_stoch_komposter_indicator.py +77 -0
- backtrader/indicators/contrib/i_trend_indicator.py +125 -0
- backtrader/indicators/contrib/iamma_indicator.py +39 -0
- backtrader/indicators/contrib/indexed_moving_average.py +33 -0
- backtrader/indicators/contrib/instantaneous_trend_filter_indicator.py +51 -0
- backtrader/indicators/contrib/inverse_reaction_indicator.py +41 -0
- backtrader/indicators/contrib/irsi_sign_indicator.py +95 -0
- backtrader/indicators/contrib/iwpr_sign_indicator.py +59 -0
- backtrader/indicators/contrib/j_brain_trend1_sig_indicator.py +233 -0
- backtrader/indicators/contrib/j_tpo_proxy.py +32 -0
- backtrader/indicators/contrib/jma_slope_indicator.py +73 -0
- backtrader/indicators/contrib/kalman_filter_indicator.py +119 -0
- backtrader/indicators/contrib/kalman_filter_line.py +127 -0
- backtrader/indicators/contrib/kama_indicator.py +150 -0
- backtrader/indicators/contrib/karacatica_indicator.py +99 -0
- backtrader/indicators/contrib/kdj_indicator.py +59 -0
- backtrader/indicators/contrib/kwan_ccc_indicator.py +195 -0
- backtrader/indicators/contrib/kwan_nrp_indicator.py +113 -0
- backtrader/indicators/contrib/kwan_rdp_indicator.py +192 -0
- backtrader/indicators/contrib/laguerre_adx_indicator.py +85 -0
- backtrader/indicators/contrib/laguerre_filter_indicator.py +66 -0
- backtrader/indicators/contrib/laguerre_plus_di_proxy.py +57 -0
- backtrader/indicators/contrib/laguerre_roc_indicator.py +81 -0
- backtrader/indicators/contrib/le_man_signal_indicator.py +63 -0
- backtrader/indicators/contrib/linear_reg_slope_v2_indicator.py +136 -0
- backtrader/indicators/contrib/loco_indicator.py +88 -0
- backtrader/indicators/contrib/lrma_indicator.py +185 -0
- backtrader/indicators/contrib/lsma_angle_indicator.py +106 -0
- backtrader/indicators/contrib/ma_rounding_channel_indicator.py +149 -0
- backtrader/indicators/contrib/macd2_indicator.py +61 -0
- backtrader/indicators/contrib/macd_candle_indicator.py +80 -0
- backtrader/indicators/contrib/malr_indicator.py +77 -0
- backtrader/indicators/contrib/momentum_candle_sign_indicator.py +51 -0
- backtrader/indicators/contrib/moving_average_fn_indicator.py +139 -0
- backtrader/indicators/contrib/mt5_stochastic_close_close.py +57 -0
- backtrader/indicators/contrib/muv_nor_diff_cloud_indicator.py +107 -0
- backtrader/indicators/contrib/non_lag_dot_indicator.py +124 -0
- backtrader/indicators/contrib/nrtr_extr_indicator.py +95 -0
- backtrader/indicators/contrib/nrtr_indicator.py +95 -0
- backtrader/indicators/contrib/p_channel_system.py +40 -0
- backtrader/indicators/contrib/percent_envelope.py +37 -0
- backtrader/indicators/contrib/percentage_crossover_channel.py +47 -0
- backtrader/indicators/contrib/pivot_zig_zag_proxy.py +47 -0
- backtrader/indicators/contrib/price_channel_stop_indicator.py +104 -0
- backtrader/indicators/contrib/price_extreme_channel.py +35 -0
- backtrader/indicators/contrib/qqe_cloud_indicator.py +129 -0
- backtrader/indicators/contrib/ravi_indicator.py +40 -0
- backtrader/indicators/contrib/raw_close_close_stochastic.py +74 -0
- backtrader/indicators/contrib/rd_trend_trigger_indicator.py +51 -0
- backtrader/indicators/contrib/renko_level.py +85 -0
- backtrader/indicators/contrib/renko_line_break.py +91 -0
- backtrader/indicators/contrib/rftl_indicator.py +41 -0
- backtrader/indicators/contrib/rkd_indicator.py +53 -0
- backtrader/indicators/contrib/roc2_vg_indicator.py +68 -0
- backtrader/indicators/contrib/rsi_histogram_indicator.py +43 -0
- backtrader/indicators/contrib/rsi_slowdown.py +57 -0
- backtrader/indicators/contrib/rsioma_v2.py +41 -0
- backtrader/indicators/contrib/rvi_histogram_indicator.py +107 -0
- backtrader/indicators/contrib/safe_adx.py +89 -0
- backtrader/indicators/contrib/shared_strategy_indicators.py +1651 -0
- backtrader/indicators/contrib/sidus_indicator.py +105 -0
- backtrader/indicators/contrib/silver_trend_indicator.py +79 -0
- backtrader/indicators/contrib/sliding_range_color.py +56 -0
- backtrader/indicators/contrib/slow_stoch.py +42 -0
- backtrader/indicators/contrib/smoothed_adx_indicator.py +86 -0
- backtrader/indicators/contrib/smoothed_rsi.py +31 -0
- backtrader/indicators/contrib/spearman_rank_correlation_histogram.py +60 -0
- backtrader/indicators/contrib/stalin_indicator.py +152 -0
- backtrader/indicators/contrib/starter_laguerre_filter.py +62 -0
- backtrader/indicators/contrib/step_manrtr_indicator.py +137 -0
- backtrader/indicators/contrib/stochastic_histogram_indicator.py +143 -0
- backtrader/indicators/contrib/t3_alarm_indicator.py +125 -0
- backtrader/indicators/contrib/t3_average.py +76 -0
- backtrader/indicators/contrib/t3_indicator.py +40 -0
- backtrader/indicators/contrib/the20s_v020_signal.py +93 -0
- backtrader/indicators/contrib/three_candles_indicator.py +70 -0
- backtrader/indicators/contrib/three_line_break_indicator.py +64 -0
- backtrader/indicators/contrib/time_line.py +57 -0
- backtrader/indicators/contrib/trading_channel_index_proxy.py +48 -0
- backtrader/indicators/contrib/trend_arrows_indicator.py +109 -0
- backtrader/indicators/contrib/trend_continuation_indicator.py +127 -0
- backtrader/indicators/contrib/trend_intensity_index_proxy.py +51 -0
- backtrader/indicators/contrib/trend_manager_indicator.py +39 -0
- backtrader/indicators/contrib/tri_x_candle_indicator.py +51 -0
- backtrader/indicators/contrib/trigger_line.py +66 -0
- backtrader/indicators/contrib/triple_ema_rate.py +34 -0
- backtrader/indicators/contrib/trvi_indicator.py +194 -0
- backtrader/indicators/contrib/two_pb_ideal_xosma_indicator.py +127 -0
- backtrader/indicators/contrib/ultra_absolutely_no_lag_lwma_color.py +92 -0
- backtrader/indicators/contrib/ultra_wpr_indicator.py +173 -0
- backtrader/indicators/contrib/up_down_candle_strength.py +68 -0
- backtrader/indicators/contrib/vinin_i_trend_indicator.py +139 -0
- backtrader/indicators/contrib/volume_weighted_ma_indicator.py +78 -0
- backtrader/indicators/contrib/volume_weighted_ma_st_dev_indicator.py +111 -0
- backtrader/indicators/contrib/vwap_close_indicator.py +65 -0
- backtrader/indicators/contrib/vwma_candle.py +57 -0
- backtrader/indicators/contrib/vwma_digit_system.py +70 -0
- backtrader/indicators/contrib/wami.py +43 -0
- backtrader/indicators/contrib/wprsi_signal_indicator.py +105 -0
- backtrader/indicators/contrib/x_de_marker_histogram_vol_direct_indicator.py +145 -0
- backtrader/indicators/contrib/x_fisher_indicator.py +64 -0
- backtrader/indicators/contrib/xcci_histogram_vol_direct_indicator.py +56 -0
- backtrader/indicators/contrib/xcci_histogram_vol_indicator.py +85 -0
- backtrader/indicators/contrib/xma_ichimoku.py +163 -0
- backtrader/indicators/contrib/xma_ishimoku_channel_indicator.py +65 -0
- backtrader/indicators/contrib/xma_ishimoku_line.py +68 -0
- backtrader/indicators/contrib/xma_range_bands_indicator.py +107 -0
- backtrader/indicators/contrib/xmacd_indicator.py +70 -0
- backtrader/indicators/contrib/xrsi_de_marker_histogram.py +67 -0
- backtrader/indicators/contrib/xrsi_histogram_vol_direct_indicator.py +52 -0
- backtrader/indicators/contrib/xrsi_histogram_vol_indicator.py +81 -0
- backtrader/indicators/contrib/xrvi_indicator.py +130 -0
- backtrader/indicators/contrib/zero_lag_macd.py +36 -0
- backtrader/indicators/contrib/zig_zag_recent_pivot_signal.py +90 -0
- backtrader/indicators/contrib/zpf_indicator.py +115 -0
- backtrader/indicators/crossover.py +337 -0
- backtrader/indicators/dema.py +175 -0
- backtrader/indicators/demarker.py +270 -0
- backtrader/indicators/deviation.py +284 -0
- backtrader/indicators/directionalmove.py +1071 -0
- backtrader/indicators/dma.py +112 -0
- backtrader/indicators/dpo.py +96 -0
- backtrader/indicators/dv2.py +56 -0
- backtrader/indicators/ema.py +145 -0
- backtrader/indicators/envelope.py +475 -0
- backtrader/indicators/hadelta.py +198 -0
- backtrader/indicators/heikinashi.py +153 -0
- backtrader/indicators/hma.py +153 -0
- backtrader/indicators/hurst.py +151 -0
- backtrader/indicators/ichimoku.py +267 -0
- backtrader/indicators/kama.py +181 -0
- backtrader/indicators/kst.py +159 -0
- backtrader/indicators/lrsi.py +125 -0
- backtrader/indicators/mabase.py +147 -0
- backtrader/indicators/macd.py +322 -0
- backtrader/indicators/momentum.py +267 -0
- backtrader/indicators/moneyflow.py +237 -0
- backtrader/indicators/mt5atr.py +124 -0
- backtrader/indicators/myind.py +179 -0
- backtrader/indicators/obv.py +94 -0
- backtrader/indicators/ols.py +265 -0
- backtrader/indicators/oscillator.py +161 -0
- backtrader/indicators/percentchange.py +83 -0
- backtrader/indicators/percentrank.py +46 -0
- backtrader/indicators/pivotpoint.py +469 -0
- backtrader/indicators/prettygoodoscillator.py +113 -0
- backtrader/indicators/priceops_ext.py +123 -0
- backtrader/indicators/priceoscillator.py +262 -0
- backtrader/indicators/psar.py +212 -0
- backtrader/indicators/rmi.py +69 -0
- backtrader/indicators/rsi.py +440 -0
- backtrader/indicators/sma.py +141 -0
- backtrader/indicators/smma.py +116 -0
- backtrader/indicators/spread.py +54 -0
- backtrader/indicators/stochastic.py +263 -0
- backtrader/indicators/supertrend.py +436 -0
- backtrader/indicators/trend_ext.py +105 -0
- backtrader/indicators/trix.py +202 -0
- backtrader/indicators/tsi.py +155 -0
- backtrader/indicators/ultimateoscillator.py +158 -0
- backtrader/indicators/vortex.py +62 -0
- backtrader/indicators/williams.py +194 -0
- backtrader/indicators/wma.py +103 -0
- backtrader/indicators/zlema.py +135 -0
- backtrader/indicators/zlind.py +104 -0
- backtrader/linebuffer.py +3155 -0
- backtrader/lineiterator.py +2911 -0
- backtrader/lineroot.py +1106 -0
- backtrader/lineseries.py +2559 -0
- backtrader/live_trading/__init__.py +31 -0
- backtrader/live_trading/interface.py +404 -0
- backtrader/mathsupport.py +94 -0
- backtrader/metabase.py +1804 -0
- backtrader/mixins/__init__.py +21 -0
- backtrader/mixins/singleton.py +118 -0
- backtrader/observer.py +106 -0
- backtrader/observers/__init__.py +45 -0
- backtrader/observers/benchmark.py +126 -0
- backtrader/observers/broker.py +184 -0
- backtrader/observers/buysell.py +144 -0
- backtrader/observers/drawdown.py +161 -0
- backtrader/observers/logreturns.py +113 -0
- backtrader/observers/timereturn.py +86 -0
- backtrader/observers/trade_logger.py +2972 -0
- backtrader/observers/tradelogger.py +6 -0
- backtrader/observers/trades.py +258 -0
- backtrader/order.py +1114 -0
- backtrader/parameters.py +2345 -0
- backtrader/plot/__init__.py +54 -0
- backtrader/plot/finance.py +1022 -0
- backtrader/plot/formatters.py +200 -0
- backtrader/plot/locator.py +353 -0
- backtrader/plot/multicursor.py +495 -0
- backtrader/plot/plot.py +2500 -0
- backtrader/plot/plot_plotly.py +1351 -0
- backtrader/plot/scheme.py +253 -0
- backtrader/plot/utils.py +104 -0
- backtrader/position.py +290 -0
- backtrader/position_modes.py +132 -0
- backtrader/profiles.py +254 -0
- backtrader/reports/__init__.py +39 -0
- backtrader/reports/charts.py +371 -0
- backtrader/reports/performance.py +620 -0
- backtrader/reports/reporter.py +660 -0
- backtrader/resamplerfilter.py +1001 -0
- backtrader/signal.py +118 -0
- backtrader/signals/__init__.py +17 -0
- backtrader/sizer.py +114 -0
- backtrader/sizers/__init__.py +26 -0
- backtrader/sizers/fixedsize.py +161 -0
- backtrader/sizers/percents_sizer.py +119 -0
- backtrader/store.py +221 -0
- backtrader/stores/__init__.py +33 -0
- backtrader/stores/btapistore.py +15506 -0
- backtrader/stores/livestore.py +137 -0
- backtrader/stores/vchartfile.py +96 -0
- backtrader/strategy.py +3655 -0
- backtrader/talib.py +280 -0
- backtrader/test_helpers.py +96 -0
- backtrader/timer.py +358 -0
- backtrader/trade.py +442 -0
- backtrader/tradingcal.py +361 -0
- backtrader/utils/__init__.py +68 -0
- backtrader/utils/autodict.py +251 -0
- backtrader/utils/date.py +71 -0
- backtrader/utils/dateintern.py +509 -0
- backtrader/utils/flushfile.py +94 -0
- backtrader/utils/fractal.py +101 -0
- backtrader/utils/get_metrics.py +101 -0
- backtrader/utils/load_data.py +209 -0
- backtrader/utils/log_message.py +998 -0
- backtrader/utils/ordereddefaultdict.py +75 -0
- backtrader/utils/py3.py +296 -0
- backtrader/version.py +21 -0
- backtrader/writer.py +372 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
EMA,
|
|
10
|
+
SMA,
|
|
11
|
+
Indicator,
|
|
12
|
+
SmoothedMovingAverage,
|
|
13
|
+
WeightedMovingAverage,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"XMARangeBandsIndicator",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def resolve_ma_class(name):
|
|
22
|
+
"""Map a moving-average name to its backtrader indicator class.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
name: Moving-average mode name (e.g. ``'sma'``, ``'ema'``, ``'smma'``).
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
The matching backtrader moving-average indicator class, defaulting to
|
|
29
|
+
the weighted moving average for unrecognized names.
|
|
30
|
+
"""
|
|
31
|
+
mode = str(name).lower()
|
|
32
|
+
if mode in {"sma", "mode_sma"}:
|
|
33
|
+
return SMA
|
|
34
|
+
if mode in {"ema", "mode_ema"}:
|
|
35
|
+
return EMA
|
|
36
|
+
if mode in {"smma", "mode_smma"}:
|
|
37
|
+
return SmoothedMovingAverage
|
|
38
|
+
return WeightedMovingAverage
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def resolve_price_line(data, mode):
|
|
42
|
+
"""Map an applied-price mode to a price line built from the data feed.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
data: The data feed providing open/high/low/close lines.
|
|
46
|
+
mode: Applied-price mode name (e.g. ``'price_close'``, ``'median'``,
|
|
47
|
+
``'typical'``, ``'weighted'``).
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
A line expression for the requested applied price, defaulting to close.
|
|
51
|
+
"""
|
|
52
|
+
price_mode = str(mode).lower()
|
|
53
|
+
if price_mode in {"price_open", "open"}:
|
|
54
|
+
return data.open
|
|
55
|
+
if price_mode in {"price_high", "high"}:
|
|
56
|
+
return data.high
|
|
57
|
+
if price_mode in {"price_low", "low"}:
|
|
58
|
+
return data.low
|
|
59
|
+
if price_mode in {"price_median", "median"}:
|
|
60
|
+
return (data.high + data.low) / 2.0
|
|
61
|
+
if price_mode in {"price_typical", "typical"}:
|
|
62
|
+
return (data.high + data.low + data.close) / 3.0
|
|
63
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
64
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
65
|
+
if price_mode in {"price_simpl", "simpl"}:
|
|
66
|
+
return (data.open + data.close) / 2.0
|
|
67
|
+
if price_mode in {"price_quarter", "quarter"}:
|
|
68
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
69
|
+
if price_mode in {"price_trendfollow0", "trendfollow0"}:
|
|
70
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
71
|
+
if price_mode in {"price_trendfollow1", "trendfollow1"}:
|
|
72
|
+
return (data.high + data.low + data.open + data.close + data.close) / 5.0
|
|
73
|
+
return data.close
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class XMARangeBandsIndicator(Indicator):
|
|
77
|
+
"""Moving-average midline with range-scaled upper and lower bands."""
|
|
78
|
+
|
|
79
|
+
lines = (
|
|
80
|
+
"mid",
|
|
81
|
+
"upper",
|
|
82
|
+
"lower",
|
|
83
|
+
)
|
|
84
|
+
params = (
|
|
85
|
+
("ma_method1", "sma"),
|
|
86
|
+
("length1", 100),
|
|
87
|
+
("phase1", 15),
|
|
88
|
+
("ma_method2", "jjma"),
|
|
89
|
+
("length2", 20),
|
|
90
|
+
("phase2", 100),
|
|
91
|
+
("deviation", 2.0),
|
|
92
|
+
("ipc", "price_close"),
|
|
93
|
+
("price_shift", 0),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
def __init__(self):
|
|
97
|
+
"""Build the midline MA and range MA, then derive the band lines."""
|
|
98
|
+
price_line = resolve_price_line(self.data, self.p.ipc)
|
|
99
|
+
ma_cls_1 = resolve_ma_class(self.p.ma_method1)
|
|
100
|
+
ma_cls_2 = resolve_ma_class(self.p.ma_method2)
|
|
101
|
+
self._base = ma_cls_1(price_line, period=self.p.length1)
|
|
102
|
+
bar_range = self.data.high - self.data.low
|
|
103
|
+
self._range_ma = ma_cls_2(bar_range, period=self.p.length2)
|
|
104
|
+
self.lines.mid = self._base + self.p.price_shift
|
|
105
|
+
self.lines.upper = self.lines.mid + self._range_ma * self.p.deviation
|
|
106
|
+
self.lines.lower = self.lines.mid - self._range_ma * self.p.deviation
|
|
107
|
+
self.addminperiod(max(self.p.length1, self.p.length2) + 3)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
EMA,
|
|
10
|
+
SMA,
|
|
11
|
+
Indicator,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"XMACDIndicator",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class XMACDIndicator(Indicator):
|
|
20
|
+
"""Configurable MACD indicator with selectable MA methods and price.
|
|
21
|
+
|
|
22
|
+
Computes the MACD line as the difference of a fast and slow moving average
|
|
23
|
+
of a chosen applied price, then a signal line by smoothing the MACD. The
|
|
24
|
+
moving-average type, signal-smoothing type, periods and applied price are all
|
|
25
|
+
configurable via parameters.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
lines = (
|
|
29
|
+
"macd",
|
|
30
|
+
"signal",
|
|
31
|
+
)
|
|
32
|
+
params = (
|
|
33
|
+
("ma_method", "ema"),
|
|
34
|
+
("signal_method", "sma"),
|
|
35
|
+
("fast_period", 12),
|
|
36
|
+
("slow_period", 26),
|
|
37
|
+
("signal_period", 9),
|
|
38
|
+
("applied_price", "close"),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
"""Build the fast/slow MAs, MACD and signal lines and set min period."""
|
|
43
|
+
ma_cls = EMA if str(self.p.ma_method).lower() == "ema" else SMA
|
|
44
|
+
signal_cls = EMA if str(self.p.signal_method).lower() == "ema" else SMA
|
|
45
|
+
price = self._price_line()
|
|
46
|
+
fast = ma_cls(price, period=self.p.fast_period)
|
|
47
|
+
slow = ma_cls(price, period=self.p.slow_period)
|
|
48
|
+
self.lines.macd = fast - slow
|
|
49
|
+
self.lines.signal = signal_cls(self.lines.macd, period=self.p.signal_period)
|
|
50
|
+
self.addminperiod(max(self.p.fast_period, self.p.slow_period) + self.p.signal_period + 5)
|
|
51
|
+
|
|
52
|
+
def _price_line(self):
|
|
53
|
+
mode = str(self.p.applied_price).lower()
|
|
54
|
+
if mode == "open":
|
|
55
|
+
return self.data.open
|
|
56
|
+
if mode == "high":
|
|
57
|
+
return self.data.high
|
|
58
|
+
if mode == "low":
|
|
59
|
+
return self.data.low
|
|
60
|
+
if mode == "median":
|
|
61
|
+
return (self.data.high + self.data.low) / 2.0
|
|
62
|
+
if mode == "typical":
|
|
63
|
+
return (self.data.high + self.data.low + self.data.close) / 3.0
|
|
64
|
+
if mode == "weighted":
|
|
65
|
+
return (self.data.high + self.data.low + self.data.close + self.data.close) / 4.0
|
|
66
|
+
if mode == "simpl":
|
|
67
|
+
return (self.data.open + self.data.close) / 2.0
|
|
68
|
+
if mode == "quarter":
|
|
69
|
+
return (self.data.high + self.data.low + self.data.open + self.data.close) / 4.0
|
|
70
|
+
return self.data.close
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import math
|
|
9
|
+
|
|
10
|
+
from .. import (
|
|
11
|
+
RSI,
|
|
12
|
+
DeMarker,
|
|
13
|
+
Indicator,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"XrsiDeMarkerHistogram",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class XrsiDeMarkerHistogram(Indicator):
|
|
22
|
+
"""Blend RSI and DeMarker into a smoothed histogram line."""
|
|
23
|
+
|
|
24
|
+
lines = ("value",)
|
|
25
|
+
params = (
|
|
26
|
+
("ind_period", 14),
|
|
27
|
+
("rsi_price", "close"),
|
|
28
|
+
("high_level", 60.0),
|
|
29
|
+
("low_level", 40.0),
|
|
30
|
+
("xma_method", "SMA"),
|
|
31
|
+
("x_length", 5),
|
|
32
|
+
("x_phase", 15),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
"""Instantiate RSI and DeMarker and initialize smoothing buffers."""
|
|
37
|
+
self.rsi = RSI(self.data.close, period=self.p.ind_period)
|
|
38
|
+
self.demarker = DeMarker(self.data, period=self.p.ind_period)
|
|
39
|
+
self._raw_buf = []
|
|
40
|
+
self._smooth_prev = None
|
|
41
|
+
self.addminperiod(self.p.ind_period + self.p.x_length + 5)
|
|
42
|
+
|
|
43
|
+
def _smooth_value(self, raw_value):
|
|
44
|
+
method = str(self.p.xma_method).upper()
|
|
45
|
+
if method in ("MODE_SMA_", "SMA"):
|
|
46
|
+
period = max(1, int(self.p.x_length))
|
|
47
|
+
if len(self._raw_buf) < period:
|
|
48
|
+
return raw_value
|
|
49
|
+
return sum(self._raw_buf[-period:]) / float(period)
|
|
50
|
+
|
|
51
|
+
length = max(1, int(self.p.x_length))
|
|
52
|
+
phase = max(-100, min(100, int(self.p.x_phase)))
|
|
53
|
+
alpha = 2.0 / (length + 1.0)
|
|
54
|
+
alpha *= 1.0 + 0.35 * (phase / 100.0)
|
|
55
|
+
alpha = max(0.01, min(0.99, alpha))
|
|
56
|
+
if self._smooth_prev is None or not math.isfinite(self._smooth_prev):
|
|
57
|
+
smooth = raw_value
|
|
58
|
+
else:
|
|
59
|
+
smooth = self._smooth_prev + alpha * (raw_value - self._smooth_prev)
|
|
60
|
+
self._smooth_prev = smooth
|
|
61
|
+
return smooth
|
|
62
|
+
|
|
63
|
+
def next(self):
|
|
64
|
+
"""Compute and smooth the combined histogram value."""
|
|
65
|
+
raw_value = (float(self.rsi[0]) + 100.0 * float(self.demarker.demarker[0])) / 2.0
|
|
66
|
+
self._raw_buf.append(raw_value)
|
|
67
|
+
self.lines.value[0] = self._smooth_value(raw_value)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"XRSIHistogramVolDirectIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class XRSIHistogramVolDirectIndicator(Indicator):
|
|
16
|
+
"""Simple direct XRSI histogram indicator that emits color state transitions."""
|
|
17
|
+
|
|
18
|
+
lines = ("color_state", "value")
|
|
19
|
+
params = (
|
|
20
|
+
("rsi_period", 14),
|
|
21
|
+
("ma_length", 12),
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""Initialize rolling history for smoothed direct RSI histogram."""
|
|
26
|
+
self._scaled_history = []
|
|
27
|
+
self.addminperiod(max(self.p.rsi_period, self.p.ma_length) + 3)
|
|
28
|
+
|
|
29
|
+
def next(self):
|
|
30
|
+
"""Update scaled RSI values and binary color direction."""
|
|
31
|
+
gains = []
|
|
32
|
+
losses = []
|
|
33
|
+
for idx in range(self.p.rsi_period):
|
|
34
|
+
delta = float(self.data.close[-idx]) - float(self.data.close[-idx - 1])
|
|
35
|
+
gains.append(max(delta, 0.0))
|
|
36
|
+
losses.append(max(-delta, 0.0))
|
|
37
|
+
avg_gain = sum(gains) / float(len(gains))
|
|
38
|
+
avg_loss = sum(losses) / float(len(losses))
|
|
39
|
+
if avg_loss <= 1e-12:
|
|
40
|
+
rsi_value = 100.0 if avg_gain > 0 else 50.0
|
|
41
|
+
else:
|
|
42
|
+
rs = avg_gain / avg_loss
|
|
43
|
+
rsi_value = 100.0 - (100.0 / (1.0 + rs))
|
|
44
|
+
raw = (rsi_value - 50.0) * float(self.data.volume[0])
|
|
45
|
+
self._scaled_history.append(raw)
|
|
46
|
+
if len(self._scaled_history) > self.p.ma_length:
|
|
47
|
+
self._scaled_history.pop(0)
|
|
48
|
+
current = sum(self._scaled_history) / float(len(self._scaled_history))
|
|
49
|
+
previous = self.lines.value[-1] if len(self) else 0.0
|
|
50
|
+
color = 0.0 if current >= previous else 1.0
|
|
51
|
+
self.lines.value[0] = current
|
|
52
|
+
self.lines.color_state[0] = color
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"XRSIHistogramVolIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class XRSIHistogramVolIndicator(Indicator):
|
|
16
|
+
"""Volume-scaled RSI histogram indicator producing directional color states."""
|
|
17
|
+
|
|
18
|
+
lines = ("color_state", "value", "max_level", "up_level", "dn_level", "min_level")
|
|
19
|
+
params = (
|
|
20
|
+
("rsi_period", 14),
|
|
21
|
+
("high_level2", 17),
|
|
22
|
+
("high_level1", 5),
|
|
23
|
+
("low_level1", -5),
|
|
24
|
+
("low_level2", -17),
|
|
25
|
+
("ma_length", 12),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
"""Prepare rolling RSI and volume histories."""
|
|
30
|
+
self._scaled_history = []
|
|
31
|
+
self._volume_history = []
|
|
32
|
+
self.addminperiod(max(self.p.rsi_period, self.p.ma_length) + 3)
|
|
33
|
+
|
|
34
|
+
def next(self):
|
|
35
|
+
"""Calculate scaled histogram level and classify it into a color state."""
|
|
36
|
+
vol = float(self.data.volume[0]) if len(self.data.volume) else 0.0
|
|
37
|
+
gains = []
|
|
38
|
+
losses = []
|
|
39
|
+
for idx in range(self.p.rsi_period):
|
|
40
|
+
delta = float(self.data.close[-idx]) - float(self.data.close[-idx - 1])
|
|
41
|
+
gains.append(max(delta, 0.0))
|
|
42
|
+
losses.append(max(-delta, 0.0))
|
|
43
|
+
avg_gain = sum(gains) / float(len(gains))
|
|
44
|
+
avg_loss = sum(losses) / float(len(losses))
|
|
45
|
+
if avg_loss <= 1e-12:
|
|
46
|
+
rsi_value = 100.0 if avg_gain > 0 else 50.0
|
|
47
|
+
else:
|
|
48
|
+
rs = avg_gain / avg_loss
|
|
49
|
+
rsi_value = 100.0 - (100.0 / (1.0 + rs))
|
|
50
|
+
raw = (rsi_value - 50.0) * vol
|
|
51
|
+
self._scaled_history.append(raw)
|
|
52
|
+
self._volume_history.append(vol)
|
|
53
|
+
if len(self._scaled_history) > self.p.ma_length:
|
|
54
|
+
self._scaled_history.pop(0)
|
|
55
|
+
if len(self._volume_history) > self.p.ma_length:
|
|
56
|
+
self._volume_history.pop(0)
|
|
57
|
+
scaled = sum(self._scaled_history) / float(len(self._scaled_history))
|
|
58
|
+
avg_vol = (
|
|
59
|
+
sum(self._volume_history) / float(len(self._volume_history))
|
|
60
|
+
if self._volume_history
|
|
61
|
+
else max(vol, 1.0)
|
|
62
|
+
)
|
|
63
|
+
max_level = self.p.high_level2 * avg_vol
|
|
64
|
+
up_level = self.p.high_level1 * avg_vol
|
|
65
|
+
dn_level = self.p.low_level1 * avg_vol
|
|
66
|
+
min_level = self.p.low_level2 * avg_vol
|
|
67
|
+
clr = 2.0
|
|
68
|
+
if scaled > max_level:
|
|
69
|
+
clr = 0.0
|
|
70
|
+
elif scaled > up_level:
|
|
71
|
+
clr = 1.0
|
|
72
|
+
elif scaled < min_level:
|
|
73
|
+
clr = 4.0
|
|
74
|
+
elif scaled < dn_level:
|
|
75
|
+
clr = 3.0
|
|
76
|
+
self.lines.value[0] = scaled
|
|
77
|
+
self.lines.max_level[0] = max_level
|
|
78
|
+
self.lines.up_level[0] = up_level
|
|
79
|
+
self.lines.dn_level[0] = dn_level
|
|
80
|
+
self.lines.min_level[0] = min_level
|
|
81
|
+
self.lines.color_state[0] = clr
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"XRVIIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class XRVIIndicator(Indicator):
|
|
16
|
+
"""Compute a custom XRVI oscillator and its smoothed signal line.
|
|
17
|
+
|
|
18
|
+
The indicator relies on candle body delta normalized by range and applies
|
|
19
|
+
configurable moving-average methods to build both XRVI and signal streams.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
lines = (
|
|
23
|
+
"xrvi",
|
|
24
|
+
"signal",
|
|
25
|
+
)
|
|
26
|
+
params = (
|
|
27
|
+
("rvi_method", "jurx"),
|
|
28
|
+
("rvi_period", 10),
|
|
29
|
+
("rvi_phase", 15),
|
|
30
|
+
("sign_method", "jurx"),
|
|
31
|
+
("sign_period", 5),
|
|
32
|
+
("sign_phase", 15),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
"""Initialize XRVI indicator with a minimal required lookback length."""
|
|
37
|
+
self.addminperiod(self.p.rvi_period + self.p.sign_period + 3)
|
|
38
|
+
|
|
39
|
+
def _raw_rvi_at(self, i, open_array, high_array, low_array, close_array):
|
|
40
|
+
denom = float(high_array[i]) - float(low_array[i])
|
|
41
|
+
return (float(close_array[i]) - float(open_array[i])) / denom if denom else 0.0
|
|
42
|
+
|
|
43
|
+
def _window_ma(self, values, method, period, previous=None):
|
|
44
|
+
if not values:
|
|
45
|
+
return float("nan")
|
|
46
|
+
mode = str(method).lower()
|
|
47
|
+
value = float(values[-1])
|
|
48
|
+
if mode in {"ema", "mode_ema"}:
|
|
49
|
+
if previous is None or previous != previous:
|
|
50
|
+
return value
|
|
51
|
+
alpha = 2.0 / (period + 1.0)
|
|
52
|
+
return previous + alpha * (value - previous)
|
|
53
|
+
if mode in {"smma", "mode_smma"}:
|
|
54
|
+
if previous is None or previous != previous:
|
|
55
|
+
return value
|
|
56
|
+
return ((period - 1.0) * previous + value) / period
|
|
57
|
+
if mode in {"sma", "mode_sma"}:
|
|
58
|
+
return sum(values) / len(values)
|
|
59
|
+
weights = list(range(1, len(values) + 1))
|
|
60
|
+
return sum(v * w for v, w in zip(values, weights)) / sum(weights)
|
|
61
|
+
|
|
62
|
+
def _raw_rvi_ago(self, ago):
|
|
63
|
+
denom = float(self.data.high[-ago]) - float(self.data.low[-ago])
|
|
64
|
+
return (
|
|
65
|
+
(float(self.data.close[-ago]) - float(self.data.open[-ago])) / denom if denom else 0.0
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def next(self):
|
|
69
|
+
"""Advance XRVI and signal values for the current bar."""
|
|
70
|
+
rvi_period = max(1, int(self.p.rvi_period))
|
|
71
|
+
sign_period = max(1, int(self.p.sign_period))
|
|
72
|
+
raw_window = [
|
|
73
|
+
self._raw_rvi_ago(ago) for ago in range(min(len(self), rvi_period) - 1, -1, -1)
|
|
74
|
+
]
|
|
75
|
+
prev_xrvi = float(self.lines.xrvi[-1]) if len(self) > 1 else None
|
|
76
|
+
xrvi = self._window_ma(raw_window, self.p.rvi_method, rvi_period, prev_xrvi)
|
|
77
|
+
self.lines.xrvi[0] = xrvi
|
|
78
|
+
signal_values = []
|
|
79
|
+
for ago in range(min(len(self), sign_period) - 1, 0, -1):
|
|
80
|
+
value = float(self.lines.xrvi[-ago])
|
|
81
|
+
if value == value:
|
|
82
|
+
signal_values.append(value)
|
|
83
|
+
signal_values.append(xrvi)
|
|
84
|
+
prev_signal = float(self.lines.signal[-1]) if len(self) > 1 else None
|
|
85
|
+
self.lines.signal[0] = self._window_ma(
|
|
86
|
+
signal_values, self.p.sign_method, sign_period, prev_signal
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def once(self, start, end):
|
|
90
|
+
"""Vectorized XRVI and signal computation used by Backtrader runonce mode.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
start: First bar index to fill into line arrays.
|
|
94
|
+
end: Exclusive bar index end bound for computed slices.
|
|
95
|
+
"""
|
|
96
|
+
open_array = self.data.open.array
|
|
97
|
+
high_array = self.data.high.array
|
|
98
|
+
low_array = self.data.low.array
|
|
99
|
+
close_array = self.data.close.array
|
|
100
|
+
xrvi_line = self.lines.xrvi.array
|
|
101
|
+
signal_line = self.lines.signal.array
|
|
102
|
+
for line in (xrvi_line, signal_line):
|
|
103
|
+
while len(line) < end:
|
|
104
|
+
line.append(float("nan"))
|
|
105
|
+
|
|
106
|
+
rvi_period = max(1, int(self.p.rvi_period))
|
|
107
|
+
sign_period = max(1, int(self.p.sign_period))
|
|
108
|
+
prev_xrvi = None
|
|
109
|
+
prev_signal = None
|
|
110
|
+
actual_end = min(end, len(open_array), len(high_array), len(low_array), len(close_array))
|
|
111
|
+
raw_values = [
|
|
112
|
+
self._raw_rvi_at(i, open_array, high_array, low_array, close_array)
|
|
113
|
+
for i in range(actual_end)
|
|
114
|
+
]
|
|
115
|
+
xrvi_values = []
|
|
116
|
+
for i in range(actual_end):
|
|
117
|
+
raw_start = max(0, i - rvi_period + 1)
|
|
118
|
+
xrvi = self._window_ma(
|
|
119
|
+
raw_values[raw_start : i + 1], self.p.rvi_method, rvi_period, prev_xrvi
|
|
120
|
+
)
|
|
121
|
+
xrvi_values.append(xrvi)
|
|
122
|
+
if i >= start:
|
|
123
|
+
xrvi_line[i] = xrvi
|
|
124
|
+
prev_xrvi = xrvi
|
|
125
|
+
signal_start = max(0, i - sign_period + 1)
|
|
126
|
+
signal_values = xrvi_values[signal_start : i + 1]
|
|
127
|
+
signal = self._window_ma(signal_values, self.p.sign_method, sign_period, prev_signal)
|
|
128
|
+
if i >= start:
|
|
129
|
+
signal_line[i] = signal
|
|
130
|
+
prev_signal = signal
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
ExponentialMovingAverage,
|
|
10
|
+
Indicator,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ZeroLagMacd",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ZeroLagMacd(Indicator):
|
|
19
|
+
"""Zero-lag MACD indicator using double-smoothed EMA differences."""
|
|
20
|
+
|
|
21
|
+
lines = ("macd", "signal")
|
|
22
|
+
params = (
|
|
23
|
+
("fast", 12),
|
|
24
|
+
("slow", 26),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""Build fast/slow ZLEMA components and signal line."""
|
|
29
|
+
ema_fast = ExponentialMovingAverage(self.data, period=self.p.fast)
|
|
30
|
+
ema_fast2 = ExponentialMovingAverage(ema_fast, period=self.p.fast)
|
|
31
|
+
zlema_fast = 2.0 * ema_fast - ema_fast2
|
|
32
|
+
ema_slow = ExponentialMovingAverage(self.data, period=self.p.slow)
|
|
33
|
+
ema_slow2 = ExponentialMovingAverage(ema_slow, period=self.p.slow)
|
|
34
|
+
zlema_slow = 2.0 * ema_slow - ema_slow2
|
|
35
|
+
self.lines.macd = zlema_fast - zlema_slow
|
|
36
|
+
self.lines.signal = ExponentialMovingAverage(self.lines.macd, period=9)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ZigZagRecentPivotSignal",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ZigZagRecentPivotSignal(Indicator):
|
|
16
|
+
"""Custom indicator tracking local pivot age and pivot price breakout channels.
|
|
17
|
+
|
|
18
|
+
Lines:
|
|
19
|
+
signal (Line): Pivot direction signal line (1 for high, -1 for low).
|
|
20
|
+
pivot_age (Line): Age of the confirmed pivot in bars.
|
|
21
|
+
pivot_price (Line): Confirmed pivot price level.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
lines = ("signal", "pivot_age", "pivot_price")
|
|
25
|
+
params = (
|
|
26
|
+
("depth", 17),
|
|
27
|
+
("deviation", 7),
|
|
28
|
+
("backstep", 5),
|
|
29
|
+
("point", 0.01),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
"""Initialize indicator buffers and establish minimum warmup period."""
|
|
34
|
+
self.addminperiod(self.p.depth + self.p.backstep + 2)
|
|
35
|
+
self._last_pivot_type = 0
|
|
36
|
+
self._last_pivot_price = None
|
|
37
|
+
self._latest_signal = 0
|
|
38
|
+
self._latest_age = 999999
|
|
39
|
+
self._latest_pivot_price = 0.0
|
|
40
|
+
|
|
41
|
+
def next(self):
|
|
42
|
+
"""Calculate local ZigZag pivot high and low levels on each new bar."""
|
|
43
|
+
self.lines.signal[0] = 0
|
|
44
|
+
self.lines.pivot_age[0] = self._latest_age if self._latest_age < 999999 else 999999
|
|
45
|
+
self.lines.pivot_price[0] = self._latest_pivot_price
|
|
46
|
+
|
|
47
|
+
if len(self.data) <= self.p.depth + self.p.backstep:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
shift = self.p.backstep
|
|
51
|
+
candidate_high = float(self.data.high[-shift])
|
|
52
|
+
candidate_low = float(self.data.low[-shift])
|
|
53
|
+
high_window = [float(self.data.high[-shift - i]) for i in range(self.p.depth)]
|
|
54
|
+
low_window = [float(self.data.low[-shift - i]) for i in range(self.p.depth)]
|
|
55
|
+
deviation_abs = self.p.deviation * self.p.point
|
|
56
|
+
|
|
57
|
+
pivot_type = 0
|
|
58
|
+
pivot_price = None
|
|
59
|
+
if candidate_high >= max(high_window):
|
|
60
|
+
pivot_type = 1
|
|
61
|
+
pivot_price = candidate_high
|
|
62
|
+
elif candidate_low <= min(low_window):
|
|
63
|
+
pivot_type = -1
|
|
64
|
+
pivot_price = candidate_low
|
|
65
|
+
|
|
66
|
+
if pivot_type != 0 and pivot_price is not None:
|
|
67
|
+
is_new_pivot = False
|
|
68
|
+
if (
|
|
69
|
+
self._last_pivot_price is None
|
|
70
|
+
or pivot_type != self._last_pivot_type
|
|
71
|
+
and abs(pivot_price - self._last_pivot_price) >= deviation_abs
|
|
72
|
+
):
|
|
73
|
+
is_new_pivot = True
|
|
74
|
+
elif pivot_type == self._last_pivot_type:
|
|
75
|
+
if pivot_type == 1 and pivot_price > self._last_pivot_price:
|
|
76
|
+
is_new_pivot = True
|
|
77
|
+
if pivot_type == -1 and pivot_price < self._last_pivot_price:
|
|
78
|
+
is_new_pivot = True
|
|
79
|
+
if is_new_pivot:
|
|
80
|
+
self._last_pivot_type = pivot_type
|
|
81
|
+
self._last_pivot_price = pivot_price
|
|
82
|
+
self._latest_signal = 1 if pivot_type == 1 else -1
|
|
83
|
+
self._latest_age = 0
|
|
84
|
+
self._latest_pivot_price = pivot_price
|
|
85
|
+
|
|
86
|
+
if self._latest_age < 999999:
|
|
87
|
+
self.lines.signal[0] = self._latest_signal
|
|
88
|
+
self.lines.pivot_age[0] = self._latest_age
|
|
89
|
+
self.lines.pivot_price[0] = self._latest_pivot_price
|
|
90
|
+
self._latest_age += 1
|