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,194 @@
|
|
|
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 collections import deque
|
|
9
|
+
|
|
10
|
+
from .. import (
|
|
11
|
+
EMA,
|
|
12
|
+
RSI,
|
|
13
|
+
SMA,
|
|
14
|
+
Indicator,
|
|
15
|
+
SmoothedMovingAverage,
|
|
16
|
+
WeightedMovingAverage,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"TRVIIndicator",
|
|
21
|
+
"ColorRMACDIndicator",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def resolve_ma_class(name):
|
|
26
|
+
"""Return a Backtrader moving-average class by symbolic name.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
name: Indicator name alias like ``sma``, ``ema``, or ``smma``.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
class: A Backtrader indicator class object.
|
|
33
|
+
"""
|
|
34
|
+
mode = str(name).lower()
|
|
35
|
+
if mode in {"sma", "mode_sma"}:
|
|
36
|
+
return SMA
|
|
37
|
+
if mode in {"ema", "mode_ema"}:
|
|
38
|
+
return EMA
|
|
39
|
+
if mode in {"smma", "mode_smma"}:
|
|
40
|
+
return SmoothedMovingAverage
|
|
41
|
+
return WeightedMovingAverage
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class RollingWeightedAverage:
|
|
45
|
+
"""Weighted moving-average helper with recency-biased linear weights."""
|
|
46
|
+
|
|
47
|
+
def __init__(self, period):
|
|
48
|
+
"""Create deque state for the rolling weighted average window.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
period: Number of bars included in each weighted average.
|
|
52
|
+
"""
|
|
53
|
+
self.period = max(1, int(period))
|
|
54
|
+
self.values = deque(maxlen=self.period)
|
|
55
|
+
|
|
56
|
+
def update(self, value):
|
|
57
|
+
"""Push a value and return the weighted mean of the window.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
value: Incoming numeric sample.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
float: Linear recency-weighted average of buffered values.
|
|
64
|
+
"""
|
|
65
|
+
self.values.append(float(value))
|
|
66
|
+
weights = list(range(len(self.values), 0, -1))
|
|
67
|
+
return sum(v * w for v, w in zip(self.values, weights)) / sum(weights)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class TRVIIndicator(Indicator):
|
|
71
|
+
"""TRVI indicator combining price-range velocity with volume-weighted smoothing."""
|
|
72
|
+
|
|
73
|
+
lines = (
|
|
74
|
+
"trvi",
|
|
75
|
+
"signal",
|
|
76
|
+
)
|
|
77
|
+
params = (
|
|
78
|
+
("period", 26),
|
|
79
|
+
("volume_type", "tick"),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def __init__(self):
|
|
83
|
+
"""Create helper averages and internal signal buffer."""
|
|
84
|
+
self._num_avg = RollingWeightedAverage(self.p.period)
|
|
85
|
+
self._den_avg = RollingWeightedAverage(self.p.period)
|
|
86
|
+
self._signal_window = deque(maxlen=4)
|
|
87
|
+
self.addminperiod(self.p.period + 8)
|
|
88
|
+
|
|
89
|
+
def _volume(self):
|
|
90
|
+
if str(self.p.volume_type).lower() == "real":
|
|
91
|
+
return (
|
|
92
|
+
float(self.data.openinterest[0])
|
|
93
|
+
if len(self.data.openinterest)
|
|
94
|
+
else float(self.data.volume[0])
|
|
95
|
+
)
|
|
96
|
+
return float(self.data.volume[0])
|
|
97
|
+
|
|
98
|
+
def _count_val(
|
|
99
|
+
self,
|
|
100
|
+
a_now,
|
|
101
|
+
b_now,
|
|
102
|
+
a_prev1,
|
|
103
|
+
b_prev1,
|
|
104
|
+
a_prev2,
|
|
105
|
+
b_prev2,
|
|
106
|
+
a_prev3,
|
|
107
|
+
b_prev3,
|
|
108
|
+
vol_now,
|
|
109
|
+
vol_prev1,
|
|
110
|
+
vol_prev2,
|
|
111
|
+
vol_prev3,
|
|
112
|
+
):
|
|
113
|
+
return (
|
|
114
|
+
vol_now * (a_now - b_now)
|
|
115
|
+
+ 8.0 * vol_prev1 * (a_prev1 - b_prev1)
|
|
116
|
+
+ 8.0 * vol_prev2 * (a_prev2 - b_prev2)
|
|
117
|
+
+ vol_prev3 * (a_prev3 - b_prev3)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
def next(self):
|
|
121
|
+
"""Compute TRVI and smoothed signal for the current bar."""
|
|
122
|
+
volume_now = self._volume()
|
|
123
|
+
volume_prev1 = float(self.data.volume[-1])
|
|
124
|
+
volume_prev2 = float(self.data.volume[-2])
|
|
125
|
+
volume_prev3 = float(self.data.volume[-3])
|
|
126
|
+
num_value = self._count_val(
|
|
127
|
+
float(self.data.close[0]),
|
|
128
|
+
float(self.data.open[0]),
|
|
129
|
+
float(self.data.close[-1]),
|
|
130
|
+
float(self.data.open[-1]),
|
|
131
|
+
float(self.data.close[-2]),
|
|
132
|
+
float(self.data.open[-2]),
|
|
133
|
+
float(self.data.close[-3]),
|
|
134
|
+
float(self.data.open[-3]),
|
|
135
|
+
volume_now,
|
|
136
|
+
volume_prev1,
|
|
137
|
+
volume_prev2,
|
|
138
|
+
volume_prev3,
|
|
139
|
+
)
|
|
140
|
+
den_value = self._count_val(
|
|
141
|
+
float(self.data.high[0]),
|
|
142
|
+
float(self.data.low[0]),
|
|
143
|
+
float(self.data.high[-1]),
|
|
144
|
+
float(self.data.low[-1]),
|
|
145
|
+
float(self.data.high[-2]),
|
|
146
|
+
float(self.data.low[-2]),
|
|
147
|
+
float(self.data.high[-3]),
|
|
148
|
+
float(self.data.low[-3]),
|
|
149
|
+
volume_now,
|
|
150
|
+
volume_prev1,
|
|
151
|
+
volume_prev2,
|
|
152
|
+
volume_prev3,
|
|
153
|
+
)
|
|
154
|
+
smooth_num = self._num_avg.update(num_value)
|
|
155
|
+
smooth_den = self._den_avg.update(den_value)
|
|
156
|
+
trvi_value = smooth_num / smooth_den if smooth_den else 0.0
|
|
157
|
+
self.lines.trvi[0] = trvi_value
|
|
158
|
+
self._signal_window.appendleft(trvi_value)
|
|
159
|
+
if len(self._signal_window) == 4:
|
|
160
|
+
self.lines.signal[0] = (
|
|
161
|
+
4.0 * self._signal_window[0]
|
|
162
|
+
+ 3.0 * self._signal_window[1]
|
|
163
|
+
+ 2.0 * self._signal_window[2]
|
|
164
|
+
+ self._signal_window[3]
|
|
165
|
+
) / 10.0
|
|
166
|
+
else:
|
|
167
|
+
self.lines.signal[0] = trvi_value
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class ColorRMACDIndicator(Indicator):
|
|
171
|
+
"""Custom RMACD composite indicator with configurable signal MA."""
|
|
172
|
+
|
|
173
|
+
lines = (
|
|
174
|
+
"rmacd",
|
|
175
|
+
"signal",
|
|
176
|
+
)
|
|
177
|
+
params = (
|
|
178
|
+
("fast_rvi", 12),
|
|
179
|
+
("slow_trvi", 26),
|
|
180
|
+
("volume_type", "tick"),
|
|
181
|
+
("signal_method", "sma"),
|
|
182
|
+
("signal_xma", 9),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def __init__(self):
|
|
186
|
+
"""Build RMACD components and required minimum period."""
|
|
187
|
+
ma_cls = resolve_ma_class(self.p.signal_method)
|
|
188
|
+
self.rvi = RSI(self.data.close, period=self.p.fast_rvi, safediv=True)
|
|
189
|
+
self.trvi = TRVIIndicator(
|
|
190
|
+
self.data, period=self.p.slow_trvi, volume_type=self.p.volume_type
|
|
191
|
+
)
|
|
192
|
+
self.lines.rmacd = self.rvi - self.trvi.signal
|
|
193
|
+
self.lines.signal = ma_cls(self.lines.rmacd, period=self.p.signal_xma)
|
|
194
|
+
self.addminperiod(max(self.p.fast_rvi, self.p.slow_trvi + 8, self.p.signal_xma) + 5)
|
|
@@ -0,0 +1,127 @@
|
|
|
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 collections import deque
|
|
9
|
+
|
|
10
|
+
from .. import Indicator
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"TwoPbIdealXOSMAIndicator",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TwoPbIdealXOSMAIndicator(Indicator):
|
|
18
|
+
"""Compute the smoothed 2pbIdealXOSMA histogram from cascaded ideal-MAs."""
|
|
19
|
+
|
|
20
|
+
lines = ("signal",)
|
|
21
|
+
params = (
|
|
22
|
+
("period1", 10),
|
|
23
|
+
("period2", 10),
|
|
24
|
+
("periodx1", 10),
|
|
25
|
+
("periodx2", 10),
|
|
26
|
+
("periody1", 10),
|
|
27
|
+
("periody2", 10),
|
|
28
|
+
("periodz1", 10),
|
|
29
|
+
("periodz2", 10),
|
|
30
|
+
("smooth_method", "jjma"),
|
|
31
|
+
("smooth_period", 9),
|
|
32
|
+
("smooth_phase", 100),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
"""Initialize ideal-MA stage weights, recursive states, and min period."""
|
|
37
|
+
self._w1 = 1.0 / max(1, int(self.p.period1))
|
|
38
|
+
self._w2 = 1.0 / max(1, int(self.p.period2))
|
|
39
|
+
self._wx1 = 1.0 / max(1, int(self.p.periodx1))
|
|
40
|
+
self._wx2 = 1.0 / max(1, int(self.p.periodx2))
|
|
41
|
+
self._wy1 = 1.0 / max(1, int(self.p.periody1))
|
|
42
|
+
self._wy2 = 1.0 / max(1, int(self.p.periody2))
|
|
43
|
+
self._wz1 = 1.0 / max(1, int(self.p.periodz1))
|
|
44
|
+
self._wz2 = 1.0 / max(1, int(self.p.periodz2))
|
|
45
|
+
self._fast_state = None
|
|
46
|
+
self._moving01 = None
|
|
47
|
+
self._moving11 = None
|
|
48
|
+
self._moving21 = None
|
|
49
|
+
self._smooth_state = None
|
|
50
|
+
self._smooth_values = deque(maxlen=max(1, int(self.p.smooth_period)))
|
|
51
|
+
self.addminperiod(
|
|
52
|
+
max(
|
|
53
|
+
int(self.p.period1),
|
|
54
|
+
int(self.p.period2),
|
|
55
|
+
int(self.p.periodx1),
|
|
56
|
+
int(self.p.periodx2),
|
|
57
|
+
int(self.p.periody1),
|
|
58
|
+
int(self.p.periody2),
|
|
59
|
+
int(self.p.periodz1),
|
|
60
|
+
int(self.p.periodz2),
|
|
61
|
+
int(self.p.smooth_period),
|
|
62
|
+
)
|
|
63
|
+
+ 5
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
@staticmethod
|
|
67
|
+
def _ideal_ma_smooth(weight_1, weight_2, series_1, series_0, result_1):
|
|
68
|
+
dseries = series_0 - series_1
|
|
69
|
+
dseries2 = dseries * dseries - 1.0
|
|
70
|
+
denominator = 1.0 + weight_2 * dseries2
|
|
71
|
+
if denominator == 0:
|
|
72
|
+
return result_1
|
|
73
|
+
return (
|
|
74
|
+
weight_1 * (series_0 - result_1) + result_1 + weight_2 * result_1 * dseries2
|
|
75
|
+
) / denominator
|
|
76
|
+
|
|
77
|
+
def _smooth_histogram(self, value):
|
|
78
|
+
method = str(self.p.smooth_method).lower()
|
|
79
|
+
period = max(1, int(self.p.smooth_period))
|
|
80
|
+
if method == "sma":
|
|
81
|
+
self._smooth_values.append(value)
|
|
82
|
+
return sum(self._smooth_values) / len(self._smooth_values)
|
|
83
|
+
if method == "lwma":
|
|
84
|
+
self._smooth_values.append(value)
|
|
85
|
+
values = list(self._smooth_values)
|
|
86
|
+
weights = list(range(1, len(values) + 1))
|
|
87
|
+
return sum(v * w for v, w in zip(values, weights)) / sum(weights)
|
|
88
|
+
if method == "smma":
|
|
89
|
+
if self._smooth_state is None:
|
|
90
|
+
self._smooth_state = value
|
|
91
|
+
else:
|
|
92
|
+
self._smooth_state = ((period - 1) * self._smooth_state + value) / period
|
|
93
|
+
return self._smooth_state
|
|
94
|
+
alpha = 2.0 / (period + 1.0)
|
|
95
|
+
if self._smooth_state is None:
|
|
96
|
+
self._smooth_state = value
|
|
97
|
+
else:
|
|
98
|
+
self._smooth_state = self._smooth_state + alpha * (value - self._smooth_state)
|
|
99
|
+
return self._smooth_state
|
|
100
|
+
|
|
101
|
+
def next(self):
|
|
102
|
+
"""Advance the ideal-MA cascade and emit the smoothed histogram value."""
|
|
103
|
+
price = float(self.data.close[0])
|
|
104
|
+
prev_price = float(self.data.close[-1]) if len(self.data) > 1 else price
|
|
105
|
+
if self._fast_state is None:
|
|
106
|
+
self._fast_state = price
|
|
107
|
+
self._moving01 = price
|
|
108
|
+
self._moving11 = price
|
|
109
|
+
self._moving21 = price
|
|
110
|
+
|
|
111
|
+
self._fast_state = self._ideal_ma_smooth(
|
|
112
|
+
self._w1, self._w2, prev_price, price, self._fast_state
|
|
113
|
+
)
|
|
114
|
+
moving00 = self._ideal_ma_smooth(self._wx1, self._wx2, prev_price, price, self._moving01)
|
|
115
|
+
moving10 = self._ideal_ma_smooth(
|
|
116
|
+
self._wy1, self._wy2, self._moving01, moving00, self._moving11
|
|
117
|
+
)
|
|
118
|
+
moving20 = self._ideal_ma_smooth(
|
|
119
|
+
self._wz1, self._wz2, self._moving11, moving10, self._moving21
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
self._moving01 = moving00
|
|
123
|
+
self._moving11 = moving10
|
|
124
|
+
self._moving21 = moving20
|
|
125
|
+
|
|
126
|
+
raw_macd = self._fast_state - moving20
|
|
127
|
+
self.lines.signal[0] = self._smooth_histogram(raw_macd)
|
|
@@ -0,0 +1,92 @@
|
|
|
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
|
+
Highest,
|
|
12
|
+
Indicator,
|
|
13
|
+
Lowest,
|
|
14
|
+
WeightedMovingAverage,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"UltraAbsolutelyNoLagLwmaColor",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class UltraAbsolutelyNoLagLwmaColor(Indicator):
|
|
23
|
+
"""Low-lag LWMA range-position oscillator emitting bulls/bears and color.
|
|
24
|
+
|
|
25
|
+
Positions a smoothed weighted moving average within its recent high/low
|
|
26
|
+
range to produce bulls/bears strength lines and a color state encoding their
|
|
27
|
+
dominance and slope across configurable up/down levels.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
lines = ("bulls", "bears", "color_idx")
|
|
31
|
+
params = (
|
|
32
|
+
("flength", 7),
|
|
33
|
+
("start_length", 5),
|
|
34
|
+
("pstep", 2),
|
|
35
|
+
("psteps_total", 10),
|
|
36
|
+
("smooth_length", 3),
|
|
37
|
+
("up_level", 80.0),
|
|
38
|
+
("dn_level", 20.0),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
"""Build the range high/low and smoothing averages, set min period."""
|
|
43
|
+
lookback = max(
|
|
44
|
+
self.p.flength * 2,
|
|
45
|
+
self.p.start_length + self.p.pstep * self.p.psteps_total,
|
|
46
|
+
self.p.smooth_length + 2,
|
|
47
|
+
)
|
|
48
|
+
self.range_high = Highest(self.data.high, period=max(2, self.p.flength * 2))
|
|
49
|
+
self.range_low = Lowest(self.data.low, period=max(2, self.p.flength * 2))
|
|
50
|
+
self.smooth_close = WeightedMovingAverage(
|
|
51
|
+
self.data.close, period=max(2, self.p.start_length + self.p.pstep)
|
|
52
|
+
)
|
|
53
|
+
self.smooth_signal = WeightedMovingAverage(
|
|
54
|
+
self.smooth_close, period=max(2, self.p.smooth_length)
|
|
55
|
+
)
|
|
56
|
+
self.addminperiod(lookback + 2)
|
|
57
|
+
|
|
58
|
+
def next(self):
|
|
59
|
+
"""Compute bulls/bears strengths and the color state for this bar."""
|
|
60
|
+
high = float(self.range_high[0])
|
|
61
|
+
low = float(self.range_low[0])
|
|
62
|
+
spread = high - low
|
|
63
|
+
if spread <= 0:
|
|
64
|
+
bulls = 50.0
|
|
65
|
+
else:
|
|
66
|
+
bulls = (float(self.smooth_close[0]) - low) / spread * 100.0
|
|
67
|
+
bulls = max(0.0, min(100.0, bulls))
|
|
68
|
+
bears = 100.0 - bulls
|
|
69
|
+
self.lines.bulls[0] = bulls
|
|
70
|
+
self.lines.bears[0] = bears
|
|
71
|
+
prev_bulls = (
|
|
72
|
+
float(self.lines.bulls[-1])
|
|
73
|
+
if len(self) > 1 and math.isfinite(float(self.lines.bulls[-1]))
|
|
74
|
+
else bulls
|
|
75
|
+
)
|
|
76
|
+
prev_bears = (
|
|
77
|
+
float(self.lines.bears[-1])
|
|
78
|
+
if len(self) > 1 and math.isfinite(float(self.lines.bears[-1]))
|
|
79
|
+
else bears
|
|
80
|
+
)
|
|
81
|
+
color = 0.0
|
|
82
|
+
if bulls > bears:
|
|
83
|
+
if bulls > self.p.up_level or bears < self.p.dn_level:
|
|
84
|
+
color = 7.0 if prev_bulls <= bulls else 8.0
|
|
85
|
+
else:
|
|
86
|
+
color = 5.0 if prev_bulls <= bulls else 6.0
|
|
87
|
+
elif bulls < bears:
|
|
88
|
+
if bulls < self.p.dn_level or bears > self.p.up_level:
|
|
89
|
+
color = 1.0 if prev_bears <= bears else 2.0
|
|
90
|
+
else:
|
|
91
|
+
color = 3.0 if prev_bears <= bears else 4.0
|
|
92
|
+
self.lines.color_idx[0] = color
|
|
@@ -0,0 +1,173 @@
|
|
|
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
|
+
from collections import deque
|
|
10
|
+
|
|
11
|
+
from .. import (
|
|
12
|
+
Indicator,
|
|
13
|
+
WilliamsR,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"UltraWPRIndicator",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CountSmoother:
|
|
22
|
+
"""Incremental moving-average smoother supporting several MA methods.
|
|
23
|
+
|
|
24
|
+
Maintains rolling state so each ``update`` call returns the smoothed value
|
|
25
|
+
for one of the SMA, LWMA/JJMA, SMMA, or EMA methods.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, method, period):
|
|
29
|
+
"""Initialize the smoother.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
method: Smoothing method name (e.g. ``sma``, ``lwma``, ``smma``).
|
|
33
|
+
period: Smoothing window length (clamped to at least 1).
|
|
34
|
+
"""
|
|
35
|
+
self.method = str(method).lower()
|
|
36
|
+
self.period = max(1, int(period))
|
|
37
|
+
self.values = deque(maxlen=self.period)
|
|
38
|
+
self.state = None
|
|
39
|
+
|
|
40
|
+
def update(self, value):
|
|
41
|
+
"""Add a new sample and return the updated smoothed value.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
value: The new raw value to incorporate.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
The smoothed value after including ``value``.
|
|
48
|
+
"""
|
|
49
|
+
value = float(value)
|
|
50
|
+
if self.method in {"sma", "mode_sma"}:
|
|
51
|
+
self.values.append(value)
|
|
52
|
+
return sum(self.values) / len(self.values)
|
|
53
|
+
if self.method in {"lwma", "mode_lwma", "jjma", "mode_jjma"}:
|
|
54
|
+
self.values.append(value)
|
|
55
|
+
weights = list(range(1, len(self.values) + 1))
|
|
56
|
+
return sum(v * w for v, w in zip(self.values, weights)) / sum(weights)
|
|
57
|
+
if self.method in {"smma", "mode_smma"}:
|
|
58
|
+
if self.state is None:
|
|
59
|
+
self.state = value
|
|
60
|
+
else:
|
|
61
|
+
self.state = ((self.period - 1) * self.state + value) / self.period
|
|
62
|
+
return self.state
|
|
63
|
+
alpha = 2.0 / (self.period + 1.0)
|
|
64
|
+
if self.state is None:
|
|
65
|
+
self.state = value
|
|
66
|
+
else:
|
|
67
|
+
self.state = self.state + alpha * (value - self.state)
|
|
68
|
+
return self.state
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class UltraWPRIndicator(Indicator):
|
|
72
|
+
"""Ultra Williams %R oscillator emitting bulls and bears strength lines."""
|
|
73
|
+
|
|
74
|
+
lines = (
|
|
75
|
+
"bulls",
|
|
76
|
+
"bears",
|
|
77
|
+
)
|
|
78
|
+
params = (
|
|
79
|
+
("wpr_period", 13),
|
|
80
|
+
("w_method", "jjma"),
|
|
81
|
+
("start_length", 3),
|
|
82
|
+
("w_phase", 100),
|
|
83
|
+
("xstep", 5),
|
|
84
|
+
("xsteps_total", 10),
|
|
85
|
+
("smooth_method", "jjma"),
|
|
86
|
+
("smooth_length", 3),
|
|
87
|
+
("smooth_phase", 100),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def __init__(self):
|
|
91
|
+
"""Build the WPR fan, per-length smoothers, and output smoothers."""
|
|
92
|
+
self._periods = [
|
|
93
|
+
int(self.p.start_length + self.p.xstep * i) for i in range(int(self.p.xsteps_total) + 1)
|
|
94
|
+
]
|
|
95
|
+
self._wpr_indicators = [
|
|
96
|
+
WilliamsR(self.data, period=self.p.wpr_period) for _ in self._periods
|
|
97
|
+
]
|
|
98
|
+
self._smoothers = [CountSmoother(self.p.w_method, period) for period in self._periods]
|
|
99
|
+
self._prev_values = [None for _ in self._periods]
|
|
100
|
+
self._bull_smoother = CountSmoother(self.p.smooth_method, self.p.smooth_length)
|
|
101
|
+
self._bear_smoother = CountSmoother(self.p.smooth_method, self.p.smooth_length)
|
|
102
|
+
self.addminperiod(self.p.wpr_period + max(self._periods) + self.p.smooth_length + 5)
|
|
103
|
+
|
|
104
|
+
def next(self):
|
|
105
|
+
"""Count rising vs falling smoothed WPR lines and emit bulls/bears."""
|
|
106
|
+
upsch = 0.0
|
|
107
|
+
dnsch = 0.0
|
|
108
|
+
current_values = []
|
|
109
|
+
base_wpr = float(self._wpr_indicators[0][0])
|
|
110
|
+
if math.isnan(base_wpr):
|
|
111
|
+
self.lines.bulls[0] = float("nan")
|
|
112
|
+
self.lines.bears[0] = float("nan")
|
|
113
|
+
return
|
|
114
|
+
for index, smoother in enumerate(self._smoothers):
|
|
115
|
+
value = smoother.update(base_wpr)
|
|
116
|
+
current_values.append(value)
|
|
117
|
+
prev = self._prev_values[index]
|
|
118
|
+
if prev is None:
|
|
119
|
+
continue
|
|
120
|
+
if value > prev:
|
|
121
|
+
upsch += 1.0
|
|
122
|
+
else:
|
|
123
|
+
dnsch += 1.0
|
|
124
|
+
self.lines.bulls[0] = self._bull_smoother.update(upsch)
|
|
125
|
+
self.lines.bears[0] = self._bear_smoother.update(dnsch)
|
|
126
|
+
self._prev_values = current_values
|
|
127
|
+
|
|
128
|
+
def once(self, start, end):
|
|
129
|
+
"""Vectorized batch computation of bulls/bears over a bar range.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
start: Index of the first bar to compute (inclusive).
|
|
133
|
+
end: Index just past the last bar to compute (exclusive).
|
|
134
|
+
"""
|
|
135
|
+
base_wpr_array = self._wpr_indicators[0].lines[0].array
|
|
136
|
+
bulls_line = self.lines.bulls.array
|
|
137
|
+
bears_line = self.lines.bears.array
|
|
138
|
+
for line in (bulls_line, bears_line):
|
|
139
|
+
while len(line) < end:
|
|
140
|
+
line.append(float("nan"))
|
|
141
|
+
|
|
142
|
+
smoothers = [CountSmoother(self.p.w_method, period) for period in self._periods]
|
|
143
|
+
prev_values = [None for _ in self._periods]
|
|
144
|
+
bull_smoother = CountSmoother(self.p.smooth_method, self.p.smooth_length)
|
|
145
|
+
bear_smoother = CountSmoother(self.p.smooth_method, self.p.smooth_length)
|
|
146
|
+
actual_end = min(end, len(base_wpr_array))
|
|
147
|
+
for i in range(start, actual_end):
|
|
148
|
+
upsch = 0.0
|
|
149
|
+
dnsch = 0.0
|
|
150
|
+
current_values = []
|
|
151
|
+
base_wpr = float(base_wpr_array[i])
|
|
152
|
+
if math.isnan(base_wpr):
|
|
153
|
+
bulls_line[i] = float("nan")
|
|
154
|
+
bears_line[i] = float("nan")
|
|
155
|
+
continue
|
|
156
|
+
for index, smoother in enumerate(smoothers):
|
|
157
|
+
value = smoother.update(base_wpr)
|
|
158
|
+
current_values.append(value)
|
|
159
|
+
prev = prev_values[index]
|
|
160
|
+
if prev is None:
|
|
161
|
+
continue
|
|
162
|
+
if value > prev:
|
|
163
|
+
upsch += 1.0
|
|
164
|
+
else:
|
|
165
|
+
dnsch += 1.0
|
|
166
|
+
bulls_line[i] = bull_smoother.update(upsch)
|
|
167
|
+
bears_line[i] = bear_smoother.update(dnsch)
|
|
168
|
+
prev_values = current_values
|
|
169
|
+
|
|
170
|
+
self._smoothers = smoothers
|
|
171
|
+
self._prev_values = prev_values
|
|
172
|
+
self._bull_smoother = bull_smoother
|
|
173
|
+
self._bear_smoother = bear_smoother
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
"UpDownCandleStrength",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class UpDownCandleStrength(Indicator):
|
|
16
|
+
"""Up Down Candle Strength Indicator.
|
|
17
|
+
|
|
18
|
+
This indicator calculates the strength of price movement by measuring
|
|
19
|
+
the ratio of up candles to down candles over a specified period.
|
|
20
|
+
|
|
21
|
+
The strength value ranges from 0.0 (all down candles) to 1.0 (all up candles),
|
|
22
|
+
with 0.5 indicating an equal number of up and down candles.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
lines.strength: The calculated strength ratio (0.0 to 1.0).
|
|
26
|
+
params.period: The number of periods to analyze for candle strength.
|
|
27
|
+
|
|
28
|
+
Note:
|
|
29
|
+
A strength value of 0.5 is returned when there are no clear up or down
|
|
30
|
+
candles (i.e., all candles have equal open and close prices).
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
lines = ("strength",)
|
|
34
|
+
params = (("period", 20),)
|
|
35
|
+
|
|
36
|
+
def __init__(self):
|
|
37
|
+
"""Initialize the UpDownCandleStrength indicator.
|
|
38
|
+
|
|
39
|
+
Sets the minimum period required for calculation based on the
|
|
40
|
+
configured period parameter.
|
|
41
|
+
"""
|
|
42
|
+
self.addminperiod(self.p.period)
|
|
43
|
+
|
|
44
|
+
def next(self):
|
|
45
|
+
"""Calculate the candle strength ratio for the current bar.
|
|
46
|
+
|
|
47
|
+
Counts the number of up candles (close > open) and down candles
|
|
48
|
+
(close < open) over the specified period and calculates the ratio.
|
|
49
|
+
|
|
50
|
+
The strength value is calculated as:
|
|
51
|
+
strength = up_count / (up_count + down_count)
|
|
52
|
+
|
|
53
|
+
If no candles have clear directional movement (all open == close),
|
|
54
|
+
the strength is set to 0.5 (neutral).
|
|
55
|
+
"""
|
|
56
|
+
up_count = 0
|
|
57
|
+
down_count = 0
|
|
58
|
+
for i in range(self.p.period):
|
|
59
|
+
if self.data.close[-i] > self.data.open[-i]:
|
|
60
|
+
up_count += 1
|
|
61
|
+
elif self.data.close[-i] < self.data.open[-i]:
|
|
62
|
+
down_count += 1
|
|
63
|
+
|
|
64
|
+
total = up_count + down_count
|
|
65
|
+
if total == 0:
|
|
66
|
+
self.lines.strength[0] = 0.5
|
|
67
|
+
else:
|
|
68
|
+
self.lines.strength[0] = up_count / total
|