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,270 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""DeMarker, Williams %R and related delta/slowdown indicators."""
|
|
3
|
+
|
|
4
|
+
from . import Indicator
|
|
5
|
+
from .atr import ATR
|
|
6
|
+
from .rsi import RSI
|
|
7
|
+
from .williams import WilliamsR
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"DeMarker",
|
|
11
|
+
"DeMarkerIndicator",
|
|
12
|
+
"DeMarkerRollingIndicator",
|
|
13
|
+
"DeltaRSI",
|
|
14
|
+
"DeltaWPR",
|
|
15
|
+
"WilliamsPercentR",
|
|
16
|
+
"WPRHistogramIndicator",
|
|
17
|
+
"WPRSlowdown",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DeMarker(Indicator):
|
|
22
|
+
"""DeMarker oscillator with both ``demarker`` and ``dem`` output lines."""
|
|
23
|
+
|
|
24
|
+
lines = ("demarker", "dem")
|
|
25
|
+
params = (("period", 14), ("zero_value", 0.5))
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""Register the rolling window needed by the DeMarker formula."""
|
|
29
|
+
self.addminperiod(self.p.period + 1)
|
|
30
|
+
|
|
31
|
+
def next(self):
|
|
32
|
+
"""Compute the DeMarker value for the current bar.
|
|
33
|
+
|
|
34
|
+
Sums the positive high-deltas (``max(high_now - high_prev, 0)``)
|
|
35
|
+
and positive low-deltas (``max(low_prev - low_now, 0)``) across
|
|
36
|
+
the configured period, then writes ``de_max_sum / (de_max_sum +
|
|
37
|
+
de_min_sum)`` to both output lines. When the denominator is
|
|
38
|
+
zero the configurable ``zero_value`` is used instead.
|
|
39
|
+
"""
|
|
40
|
+
de_max_sum = 0.0
|
|
41
|
+
de_min_sum = 0.0
|
|
42
|
+
for i in range(self.p.period):
|
|
43
|
+
high_now = float(self.data.high[-i])
|
|
44
|
+
high_prev = float(self.data.high[-(i + 1)])
|
|
45
|
+
low_now = float(self.data.low[-i])
|
|
46
|
+
low_prev = float(self.data.low[-(i + 1)])
|
|
47
|
+
de_max_sum += max(high_now - high_prev, 0.0)
|
|
48
|
+
de_min_sum += max(low_prev - low_now, 0.0)
|
|
49
|
+
denom = de_max_sum + de_min_sum
|
|
50
|
+
value = float(self.p.zero_value) if denom == 0 else de_max_sum / denom
|
|
51
|
+
self.lines.demarker[0] = value
|
|
52
|
+
self.lines.dem[0] = value
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class DeMarkerIndicator(DeMarker):
|
|
56
|
+
"""Compatibility DeMarker variant whose zero-denominator value is ``0.0``."""
|
|
57
|
+
|
|
58
|
+
params = (("period", 14), ("zero_value", 0.0))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class DeMarkerRollingIndicator(Indicator):
|
|
62
|
+
"""Rolling-buffer DeMarker variant with ``0.5`` fallback."""
|
|
63
|
+
|
|
64
|
+
lines = ("demarker", "dem")
|
|
65
|
+
params = {"period": 14}
|
|
66
|
+
|
|
67
|
+
def __init__(self):
|
|
68
|
+
"""Register the minimum period and prepare the rolling move buffers."""
|
|
69
|
+
self.addminperiod(int(self.p.period) + 1)
|
|
70
|
+
self._up_moves = []
|
|
71
|
+
self._down_moves = []
|
|
72
|
+
|
|
73
|
+
def next(self):
|
|
74
|
+
"""Append today's up/down move and emit the rolling DeMarker value.
|
|
75
|
+
|
|
76
|
+
Maintains two Python lists capped at ``period`` entries. Until
|
|
77
|
+
the buffer is full, both output lines are set to ``NaN``;
|
|
78
|
+
afterwards the DeMarker formula is applied and the result is
|
|
79
|
+
written to both lines. A zero denominator falls back to ``0.5``.
|
|
80
|
+
"""
|
|
81
|
+
up_move = max(float(self.data.high[0]) - float(self.data.high[-1]), 0.0)
|
|
82
|
+
down_move = max(float(self.data.low[-1]) - float(self.data.low[0]), 0.0)
|
|
83
|
+
self._up_moves.append(up_move)
|
|
84
|
+
self._down_moves.append(down_move)
|
|
85
|
+
period = int(self.p.period)
|
|
86
|
+
if len(self._up_moves) > period:
|
|
87
|
+
self._up_moves.pop(0)
|
|
88
|
+
self._down_moves.pop(0)
|
|
89
|
+
if len(self._up_moves) < period:
|
|
90
|
+
self.lines.demarker[0] = float("nan")
|
|
91
|
+
self.lines.dem[0] = float("nan")
|
|
92
|
+
return
|
|
93
|
+
up_sum = sum(self._up_moves)
|
|
94
|
+
down_sum = sum(self._down_moves)
|
|
95
|
+
denom = up_sum + down_sum
|
|
96
|
+
value = 0.5 if denom == 0.0 else up_sum / denom
|
|
97
|
+
self.lines.demarker[0] = value
|
|
98
|
+
self.lines.dem[0] = value
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class WilliamsPercentR(Indicator):
|
|
102
|
+
"""Williams %R with line name ``wpr`` and zero-denominator fallback ``0``."""
|
|
103
|
+
|
|
104
|
+
lines = ("wpr",)
|
|
105
|
+
params = {"period": 14}
|
|
106
|
+
|
|
107
|
+
def __init__(self):
|
|
108
|
+
"""Register the minimum period needed for the lookback window."""
|
|
109
|
+
self.addminperiod(self.p.period)
|
|
110
|
+
|
|
111
|
+
def next(self):
|
|
112
|
+
"""Compute Williams %R using the highest-high / lowest-low window.
|
|
113
|
+
|
|
114
|
+
When the denominator ``highest - lowest`` is zero (flat window)
|
|
115
|
+
the value is forced to ``0.0``; otherwise the classic
|
|
116
|
+
``-100 * (highest - close) / (highest - lowest)`` formula is
|
|
117
|
+
written to ``self.lines.wpr``.
|
|
118
|
+
"""
|
|
119
|
+
period = int(self.p.period)
|
|
120
|
+
highest = max(float(self.data.high[-i]) for i in range(period))
|
|
121
|
+
lowest = min(float(self.data.low[-i]) for i in range(period))
|
|
122
|
+
denom = highest - lowest
|
|
123
|
+
if denom == 0.0:
|
|
124
|
+
self.lines.wpr[0] = 0.0
|
|
125
|
+
return
|
|
126
|
+
self.lines.wpr[0] = -100.0 * (highest - float(self.data.close[0])) / denom
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class DeltaRSI(Indicator):
|
|
130
|
+
"""Difference between fast/slow RSI and a regime color line."""
|
|
131
|
+
|
|
132
|
+
lines = ("color", "delta")
|
|
133
|
+
params = {"rsi_period1": 14, "rsi_period2": 50, "level": 50}
|
|
134
|
+
|
|
135
|
+
def __init__(self):
|
|
136
|
+
"""Set up the fast/slow RSI sub-indicators and regime thresholds."""
|
|
137
|
+
self.addminperiod(max(int(self.p.rsi_period1), int(self.p.rsi_period2)) + 3)
|
|
138
|
+
self.rsi1 = RSI(self.data, period=int(self.p.rsi_period1))
|
|
139
|
+
self.rsi2 = RSI(self.data, period=int(self.p.rsi_period2))
|
|
140
|
+
lvl = int(self.p.level)
|
|
141
|
+
self.max_level = 100 - (100 - lvl)
|
|
142
|
+
self.min_level = 100 - lvl
|
|
143
|
+
|
|
144
|
+
def next(self):
|
|
145
|
+
"""Compute the RSI delta and assign a regime color.
|
|
146
|
+
|
|
147
|
+
The fast RSI is subtracted from the slow RSI and written to
|
|
148
|
+
``self.lines.delta``. The color is ``0.0`` when the slow RSI is
|
|
149
|
+
above its upper threshold and the fast RSI is climbing,
|
|
150
|
+
``2.0`` when the slow RSI is below its lower threshold and the
|
|
151
|
+
fast RSI is falling, and ``1.0`` (neutral) otherwise.
|
|
152
|
+
"""
|
|
153
|
+
r1 = float(self.rsi1[0])
|
|
154
|
+
r2 = float(self.rsi2[0])
|
|
155
|
+
self.lines.delta[0] = r1 - r2
|
|
156
|
+
color = 1.0
|
|
157
|
+
if r2 > self.max_level and r1 > r2:
|
|
158
|
+
color = 0.0
|
|
159
|
+
if r2 < self.min_level and r1 < r2:
|
|
160
|
+
color = 2.0
|
|
161
|
+
self.lines.color[0] = color
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class DeltaWPR(Indicator):
|
|
165
|
+
"""Difference between fast/slow Williams %R and a regime color line."""
|
|
166
|
+
|
|
167
|
+
lines = ("color", "delta")
|
|
168
|
+
params = {"wpr_period1": 14, "wpr_period2": 30, "level": -50}
|
|
169
|
+
|
|
170
|
+
def __init__(self):
|
|
171
|
+
"""Set up the fast/slow Williams %R sub-indicators and thresholds."""
|
|
172
|
+
self.addminperiod(max(int(self.p.wpr_period1), int(self.p.wpr_period2)) + 3)
|
|
173
|
+
self.wpr1 = WilliamsR(self.data, period=int(self.p.wpr_period1))
|
|
174
|
+
self.wpr2 = WilliamsR(self.data, period=int(self.p.wpr_period2))
|
|
175
|
+
self.max_level = int(self.p.level)
|
|
176
|
+
self.min_level = int(-100 - self.p.level)
|
|
177
|
+
|
|
178
|
+
def next(self):
|
|
179
|
+
"""Compute the Williams %R delta and assign a regime color.
|
|
180
|
+
|
|
181
|
+
The fast WPR is subtracted from the slow WPR and written to
|
|
182
|
+
``self.lines.delta``. The color is ``0.0`` when the slow WPR
|
|
183
|
+
is above its upper threshold and the fast WPR is climbing,
|
|
184
|
+
``2.0`` when the slow WPR is below its lower threshold and the
|
|
185
|
+
fast WPR is falling, and ``1.0`` (neutral) otherwise.
|
|
186
|
+
"""
|
|
187
|
+
w1 = float(self.wpr1[0])
|
|
188
|
+
w2 = float(self.wpr2[0])
|
|
189
|
+
self.lines.delta[0] = w1 - w2
|
|
190
|
+
color = 1.0
|
|
191
|
+
if w2 > self.max_level and w1 > w2:
|
|
192
|
+
color = 0.0
|
|
193
|
+
if w2 < self.min_level and w1 < w2:
|
|
194
|
+
color = 2.0
|
|
195
|
+
self.lines.color[0] = color
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class WPRSlowdown(Indicator):
|
|
199
|
+
"""Williams %R extreme slowdown signal generator."""
|
|
200
|
+
|
|
201
|
+
lines = ("sell", "buy")
|
|
202
|
+
params = {"wpr_period": 12, "level_max": -20.0, "level_min": -80.0, "seek_slowdown": True}
|
|
203
|
+
|
|
204
|
+
def __init__(self):
|
|
205
|
+
"""Set up the Williams %R and ATR sub-indicators and the min period."""
|
|
206
|
+
self.addminperiod(max(int(self.p.wpr_period) + 2, 18))
|
|
207
|
+
self.wpr = WilliamsR(self.data, period=int(self.p.wpr_period))
|
|
208
|
+
self.atr = ATR(self.data, period=15)
|
|
209
|
+
|
|
210
|
+
def next(self):
|
|
211
|
+
"""Emit ATR-buffered stop levels when WPR touches an extreme.
|
|
212
|
+
|
|
213
|
+
When ``seek_slowdown`` is enabled, a signal is only emitted if
|
|
214
|
+
the WPR value at the previous bar differs from the current
|
|
215
|
+
value by less than ``1.0`` (i.e. the WPR is stalling at the
|
|
216
|
+
extreme). The buy line is placed ``atr * 3/8`` below the low,
|
|
217
|
+
and the sell line ``atr * 3/8`` above the high. Lines are
|
|
218
|
+
``NaN`` when no signal is produced.
|
|
219
|
+
"""
|
|
220
|
+
self.lines.buy[0] = float("nan")
|
|
221
|
+
self.lines.sell[0] = float("nan")
|
|
222
|
+
w0 = float(self.wpr[0])
|
|
223
|
+
w1 = float(self.wpr[-1])
|
|
224
|
+
atr = float(self.atr[0])
|
|
225
|
+
if w0 >= float(self.p.level_max):
|
|
226
|
+
if (not self.p.seek_slowdown) or abs(w1 - w0) < 1.0:
|
|
227
|
+
self.lines.buy[0] = float(self.data.low[0]) - atr * 3.0 / 8.0
|
|
228
|
+
if w0 <= float(self.p.level_min):
|
|
229
|
+
if (not self.p.seek_slowdown) or abs(w1 - w0) < 1.0:
|
|
230
|
+
self.lines.sell[0] = float(self.data.high[0]) + atr * 3.0 / 8.0
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class WPRHistogramIndicator(Indicator):
|
|
234
|
+
"""Williams %R value, midpoint and color-state histogram."""
|
|
235
|
+
|
|
236
|
+
lines = ("value", "midline", "color_state")
|
|
237
|
+
params = {"wpr_period": 14, "high_level": -30, "low_level": -70}
|
|
238
|
+
|
|
239
|
+
def __init__(self):
|
|
240
|
+
"""Register the minimum period needed for the WPR lookback."""
|
|
241
|
+
self.addminperiod(self.p.wpr_period)
|
|
242
|
+
|
|
243
|
+
def next(self):
|
|
244
|
+
"""Write the WPR value, the -50 midline and the regime color.
|
|
245
|
+
|
|
246
|
+
The ``value`` line carries the standard Williams %R formula
|
|
247
|
+
(with a ``-50`` fallback when the lookback is flat). The
|
|
248
|
+
``midline`` is fixed at ``-50``. The ``color_state`` is ``0.0``
|
|
249
|
+
when the value is above ``high_level``, ``2.0`` when it is
|
|
250
|
+
below ``low_level``, and ``1.0`` (neutral) in between.
|
|
251
|
+
"""
|
|
252
|
+
period = int(self.p.wpr_period)
|
|
253
|
+
highest_high = max(float(self.data.high[-i]) for i in range(period))
|
|
254
|
+
lowest_low = min(float(self.data.low[-i]) for i in range(period))
|
|
255
|
+
close = float(self.data.close[0])
|
|
256
|
+
denom = highest_high - lowest_low
|
|
257
|
+
if abs(denom) <= 1e-12:
|
|
258
|
+
value = -50.0
|
|
259
|
+
else:
|
|
260
|
+
value = -100.0 * (highest_high - close) / denom
|
|
261
|
+
|
|
262
|
+
color = 1.0
|
|
263
|
+
if value > float(self.p.high_level):
|
|
264
|
+
color = 0.0
|
|
265
|
+
elif value < float(self.p.low_level):
|
|
266
|
+
color = 2.0
|
|
267
|
+
|
|
268
|
+
self.lines.value[0] = value
|
|
269
|
+
self.lines.midline[0] = -50.0
|
|
270
|
+
self.lines.color_state[0] = color
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Deviation Indicator Module - Standard deviation and mean deviation.
|
|
3
|
+
|
|
4
|
+
This module provides deviation indicators for measuring data dispersion.
|
|
5
|
+
|
|
6
|
+
Classes:
|
|
7
|
+
StandardDeviation: Standard deviation indicator (alias: StdDev).
|
|
8
|
+
MeanDeviation: Mean absolute deviation (alias: MeanDev).
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
class MyStrategy(bt.Strategy):
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.sma = bt.indicators.SMA(self.data.close, period=20)
|
|
14
|
+
self.stddev = bt.indicators.StdDev(self.data.close, period=20)
|
|
15
|
+
self.upper_band = self.sma + 2 * self.stddev
|
|
16
|
+
self.lower_band = self.sma - 2 * self.stddev
|
|
17
|
+
|
|
18
|
+
def next(self):
|
|
19
|
+
if self.data.close[0] > self.upper_band[0]:
|
|
20
|
+
self.sell()
|
|
21
|
+
elif self.data.close[0] < self.lower_band[0]:
|
|
22
|
+
self.buy()
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import math
|
|
26
|
+
|
|
27
|
+
from . import Indicator, MovAv
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class StandardDeviation(Indicator):
|
|
31
|
+
"""
|
|
32
|
+
Calculates the standard deviation of the passed data for a given period
|
|
33
|
+
|
|
34
|
+
Note:
|
|
35
|
+
- If 2 datas are provided as parameters, the second is considered to be the
|
|
36
|
+
mean of the first
|
|
37
|
+
|
|
38
|
+
- ``safepow`` (default: False) If this parameter is True, the standard
|
|
39
|
+
deviation will be calculated as pow (abs(meansq - sqmean), 0.5) to
|
|
40
|
+
safeguard for possible negative results of ``meansq - sqmean`` caused by
|
|
41
|
+
the floating point representation.
|
|
42
|
+
|
|
43
|
+
Formula:
|
|
44
|
+
- meansquared = SimpleMovingAverage(pow (data, 2), period)
|
|
45
|
+
- squaredmean = pow(SimpleMovingAverage(data, period), 2)
|
|
46
|
+
- stddev = pow(meansquared - squaredmean, 0.5) # square root
|
|
47
|
+
|
|
48
|
+
See:
|
|
49
|
+
- http://en.wikipedia.org/wiki/Standard_deviation
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
alias = ("StdDev",)
|
|
53
|
+
|
|
54
|
+
lines = ("stddev",)
|
|
55
|
+
params = (
|
|
56
|
+
("period", 20),
|
|
57
|
+
("movav", MovAv.Simple),
|
|
58
|
+
("safepow", True),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def _plotlabel(self):
|
|
62
|
+
plabels = [self.p.period]
|
|
63
|
+
plabels += [self.p.movav] * self.p.notdefault("movav")
|
|
64
|
+
return plabels
|
|
65
|
+
|
|
66
|
+
def __init__(self):
|
|
67
|
+
"""Initialize the Standard Deviation indicator."""
|
|
68
|
+
super().__init__()
|
|
69
|
+
self.addminperiod(self.p.period)
|
|
70
|
+
self._use_external_mean = len(self.datas) > 1
|
|
71
|
+
self._mean_prev = None
|
|
72
|
+
self._meansq_prev = None
|
|
73
|
+
|
|
74
|
+
def _movav_kind(self):
|
|
75
|
+
movav = self.p.movav
|
|
76
|
+
names = {getattr(movav, "__name__", "")}
|
|
77
|
+
aliases = getattr(movav, "alias", ())
|
|
78
|
+
if isinstance(aliases, str):
|
|
79
|
+
names.add(aliases)
|
|
80
|
+
else:
|
|
81
|
+
names.update(aliases)
|
|
82
|
+
|
|
83
|
+
if names.intersection(
|
|
84
|
+
{
|
|
85
|
+
"SmoothedMovingAverage",
|
|
86
|
+
"SMMA",
|
|
87
|
+
"WilderMA",
|
|
88
|
+
"MovingAverageSmoothed",
|
|
89
|
+
"MovingAverageWilder",
|
|
90
|
+
"ModifiedMovingAverage",
|
|
91
|
+
"Smoothed",
|
|
92
|
+
}
|
|
93
|
+
):
|
|
94
|
+
return "smoothed"
|
|
95
|
+
|
|
96
|
+
if names.intersection(
|
|
97
|
+
{"ExponentialMovingAverage", "EMA", "MovingAverageExponential", "Exponential"}
|
|
98
|
+
):
|
|
99
|
+
return "exponential"
|
|
100
|
+
|
|
101
|
+
return "simple"
|
|
102
|
+
|
|
103
|
+
def _finish(self, meansq, mean):
|
|
104
|
+
diff = meansq - mean * mean
|
|
105
|
+
if self.p.safepow:
|
|
106
|
+
diff = abs(diff)
|
|
107
|
+
return math.sqrt(max(0.0, diff))
|
|
108
|
+
|
|
109
|
+
def next(self):
|
|
110
|
+
"""Calculate standard deviation for the current bar."""
|
|
111
|
+
period = self.p.period
|
|
112
|
+
if len(self) < period:
|
|
113
|
+
self.lines.stddev[0] = float("nan")
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
kind = self._movav_kind()
|
|
117
|
+
values = [float(self.data[i]) for i in range(1 - period, 1)]
|
|
118
|
+
if any(value != value for value in values):
|
|
119
|
+
self.lines.stddev[0] = float("nan")
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
if kind == "smoothed":
|
|
123
|
+
alpha = 1.0 / period
|
|
124
|
+
elif kind == "exponential":
|
|
125
|
+
alpha = 2.0 / (1.0 + period)
|
|
126
|
+
else:
|
|
127
|
+
alpha = None
|
|
128
|
+
|
|
129
|
+
if alpha is None or self._meansq_prev is None:
|
|
130
|
+
meansq = math.fsum(value * value for value in values) / period
|
|
131
|
+
else:
|
|
132
|
+
meansq = (
|
|
133
|
+
self._meansq_prev * (1.0 - alpha)
|
|
134
|
+
+ float(self.data[0]) * float(self.data[0]) * alpha
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if self._use_external_mean:
|
|
138
|
+
mean = float(self.data1[0])
|
|
139
|
+
elif alpha is None or self._mean_prev is None:
|
|
140
|
+
mean = math.fsum(values) / period
|
|
141
|
+
else:
|
|
142
|
+
mean = self._mean_prev * (1.0 - alpha) + float(self.data[0]) * alpha
|
|
143
|
+
|
|
144
|
+
self._meansq_prev = meansq
|
|
145
|
+
if not self._use_external_mean:
|
|
146
|
+
self._mean_prev = mean
|
|
147
|
+
|
|
148
|
+
self.lines.stddev[0] = self._finish(meansq, mean)
|
|
149
|
+
|
|
150
|
+
def once(self, start, end):
|
|
151
|
+
"""Calculate standard deviation in runonce mode."""
|
|
152
|
+
darray = self.data.array
|
|
153
|
+
larray = self.lines.stddev.array
|
|
154
|
+
period = self.p.period
|
|
155
|
+
actual_end = min(end, len(darray))
|
|
156
|
+
nan_val = float("nan")
|
|
157
|
+
|
|
158
|
+
while len(larray) < end:
|
|
159
|
+
larray.append(nan_val)
|
|
160
|
+
|
|
161
|
+
for i in range(min(period - 1, len(larray), actual_end)):
|
|
162
|
+
larray[i] = nan_val
|
|
163
|
+
|
|
164
|
+
if self._use_external_mean:
|
|
165
|
+
if hasattr(self.data1, "once"):
|
|
166
|
+
self.data1.once(0, end)
|
|
167
|
+
mean_array = self.data1.array
|
|
168
|
+
else:
|
|
169
|
+
mean_array = None
|
|
170
|
+
|
|
171
|
+
kind = self._movav_kind()
|
|
172
|
+
if kind == "smoothed":
|
|
173
|
+
alpha = 1.0 / period
|
|
174
|
+
elif kind == "exponential":
|
|
175
|
+
alpha = 2.0 / (1.0 + period)
|
|
176
|
+
else:
|
|
177
|
+
alpha = None
|
|
178
|
+
|
|
179
|
+
if alpha is None:
|
|
180
|
+
for i in range(period - 1, actual_end):
|
|
181
|
+
start_idx = i - period + 1
|
|
182
|
+
end_idx = i + 1
|
|
183
|
+
window = darray[start_idx:end_idx]
|
|
184
|
+
if len(window) != period or any(value != value for value in window):
|
|
185
|
+
larray[i] = nan_val
|
|
186
|
+
continue
|
|
187
|
+
|
|
188
|
+
meansq = math.fsum(value * value for value in window) / period
|
|
189
|
+
if mean_array is not None:
|
|
190
|
+
if i >= len(mean_array) or mean_array[i] != mean_array[i]:
|
|
191
|
+
larray[i] = nan_val
|
|
192
|
+
continue
|
|
193
|
+
mean = mean_array[i]
|
|
194
|
+
else:
|
|
195
|
+
mean = math.fsum(window) / period
|
|
196
|
+
|
|
197
|
+
larray[i] = self._finish(meansq, mean)
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
prev_mean = None
|
|
201
|
+
prev_meansq = None
|
|
202
|
+
for i in range(period - 1, actual_end):
|
|
203
|
+
if i == period - 1:
|
|
204
|
+
window = darray[0:period]
|
|
205
|
+
if len(window) != period or any(value != value for value in window):
|
|
206
|
+
larray[i] = nan_val
|
|
207
|
+
continue
|
|
208
|
+
prev_meansq = math.fsum(value * value for value in window) / period
|
|
209
|
+
if mean_array is None:
|
|
210
|
+
prev_mean = math.fsum(window) / period
|
|
211
|
+
else:
|
|
212
|
+
value = float(darray[i])
|
|
213
|
+
if value != value or prev_meansq is None:
|
|
214
|
+
larray[i] = nan_val
|
|
215
|
+
continue
|
|
216
|
+
prev_meansq = prev_meansq * (1.0 - alpha) + value * value * alpha
|
|
217
|
+
if mean_array is None:
|
|
218
|
+
if prev_mean is None:
|
|
219
|
+
larray[i] = nan_val
|
|
220
|
+
continue
|
|
221
|
+
prev_mean = prev_mean * (1.0 - alpha) + value * alpha
|
|
222
|
+
|
|
223
|
+
if mean_array is not None:
|
|
224
|
+
if i >= len(mean_array) or mean_array[i] != mean_array[i]:
|
|
225
|
+
larray[i] = nan_val
|
|
226
|
+
continue
|
|
227
|
+
mean = mean_array[i]
|
|
228
|
+
else:
|
|
229
|
+
mean = prev_mean
|
|
230
|
+
|
|
231
|
+
larray[i] = self._finish(prev_meansq, mean)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
# Average deviation
|
|
235
|
+
class MeanDeviation(Indicator):
|
|
236
|
+
"""MeanDeviation (alias MeanDev)
|
|
237
|
+
|
|
238
|
+
Calculates the Mean Deviation of the passed data for a given period
|
|
239
|
+
|
|
240
|
+
Note:
|
|
241
|
+
- If 2 datas are provided as parameters, the second is considered to be the
|
|
242
|
+
mean of the first
|
|
243
|
+
|
|
244
|
+
Formula:
|
|
245
|
+
- mean = MovingAverage(data, period) (or provided mean)
|
|
246
|
+
- absdeviation = abs (data - mean)
|
|
247
|
+
- meandev = MovingAverage(absdeviation, period)
|
|
248
|
+
|
|
249
|
+
See:
|
|
250
|
+
- https://en.wikipedia.org/wiki/Average_absolute_deviation
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
alias = ("MeanDev",)
|
|
254
|
+
|
|
255
|
+
lines = ("meandev",)
|
|
256
|
+
params = (
|
|
257
|
+
("period", 20),
|
|
258
|
+
("movav", MovAv.Simple),
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
def _plotlabel(self):
|
|
262
|
+
plabels = [self.p.period]
|
|
263
|
+
plabels += [self.p.movav] * self.p.notdefault("movav")
|
|
264
|
+
return plabels
|
|
265
|
+
|
|
266
|
+
def __init__(self):
|
|
267
|
+
"""Initialize the Mean Deviation indicator.
|
|
268
|
+
|
|
269
|
+
Creates the mean deviation calculation using either
|
|
270
|
+
external mean or calculated moving average.
|
|
271
|
+
"""
|
|
272
|
+
# CRITICAL: Match master branch behavior
|
|
273
|
+
# If 2 datas are provided, the 2nd is considered to be the mean of the first
|
|
274
|
+
if len(self.datas) > 1:
|
|
275
|
+
mean = self.data1
|
|
276
|
+
else:
|
|
277
|
+
mean = self.p.movav(self.data, period=self.p.period)
|
|
278
|
+
|
|
279
|
+
absdev = abs(self.data - mean)
|
|
280
|
+
self.lines.meandev = self.p.movav(absdev, period=self.p.period)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
StdDev = StandardDeviation
|
|
284
|
+
MeanDev = MeanDeviation
|